From 76c8d069c86f28ab3e80759255907eb3229dab69 Mon Sep 17 00:00:00 2001 From: pannal <1359593+pannal@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:41:42 +0200 Subject: [PATCH] [script.plexmod] 0.7.9 (#2645) * [script.plexmod] 0.7.9 * 0.7.9-rev4 --- script.plexmod/LICENSE.txt | 122 + script.plexmod/README.md | 22 +- script.plexmod/TESTING_SQUAD.md | 2 + script.plexmod/addon.xml | 10 +- script.plexmod/changelog.txt | 381 +- script.plexmod/default.py | 80 +- script.plexmod/fanart.jpg | Bin 71213 -> 0 bytes script.plexmod/fanart.png | Bin 0 -> 22613 bytes script.plexmod/icon.png | Bin 25724 -> 0 bytes script.plexmod/icon2.png | Bin 0 -> 5721 bytes .../lib/_included_packages/_ipaddress.py | 2420 +++++ .../lib/_included_packages/ibis/__init__.py | 17 + .../lib/_included_packages/ibis/compiler.py | 196 + .../lib/_included_packages/ibis/context.py | 179 + .../lib/_included_packages/ibis/errors.py | 65 + .../lib/_included_packages/ibis/filters.py | 306 + .../lib/_included_packages/ibis/loaders.py | 106 + .../lib/_included_packages/ibis/nodes.py | 849 ++ .../lib/_included_packages/ibis/template.py | 45 + .../lib/_included_packages/ibis/utils.py | 114 + .../plexnet/asyncadapter.py | 20 +- .../lib/_included_packages/plexnet/audio.py | 10 +- .../_included_packages/plexnet/audioobject.py | 2 +- .../plexnet/certs/ISRG Root X1.crt | 61 + .../_included_packages/plexnet/certs/R3.crt | 30 + .../USERTrust ECC Certification Authority.crt | 16 + .../ZeroSSL ECC Domain Secure Site CA.crt | 21 + .../ZeroSSL RSA Domain Secure Site CA.crt | 39 + .../plexnet/certs/acme.bundle.crt | 47 + .../plexnet/certs/plex.direct.bundle.crt | 61 + .../lib/_included_packages/plexnet/gdm.py | 4 +- .../lib/_included_packages/plexnet/http.py | 84 +- .../lib/_included_packages/plexnet/locks.py | 8 +- .../lib/_included_packages/plexnet/media.py | 29 +- .../_included_packages/plexnet/mediachoice.py | 4 +- .../plexnet/mediadecisionengine.py | 45 +- .../plexnet/myplexaccount.py | 103 +- .../plexnet/myplexmanager.py | 15 +- .../plexnet/myplexrequest.py | 1 + .../plexnet/nowplayingmanager.py | 108 +- .../lib/_included_packages/plexnet/photo.py | 2 +- .../_included_packages/plexnet/playqueue.py | 22 +- .../lib/_included_packages/plexnet/plexapp.py | 19 +- .../plexnet/plexconnection.py | 41 +- .../_included_packages/plexnet/plexlibrary.py | 90 +- .../_included_packages/plexnet/plexmedia.py | 2 + .../_included_packages/plexnet/plexobjects.py | 24 +- .../_included_packages/plexnet/plexpart.py | 44 +- .../_included_packages/plexnet/plexplayer.py | 294 +- .../plexnet/plexresource.py | 23 +- .../_included_packages/plexnet/plexserver.py | 69 +- .../plexnet/plexservermanager.py | 43 +- .../plexnet/serverdecision.py | 2 +- .../plexnet/signalsmixin.py | 11 +- .../lib/_included_packages/plexnet/util.py | 138 +- .../lib/_included_packages/plexnet/video.py | 91 +- .../plexnet/videosession.py | 22 +- .../lib/_included_packages/tendo_singleton.py | 102 + script.plexmod/lib/actions.py | 109 + script.plexmod/lib/advancedsettings.py | 42 + script.plexmod/lib/aspectratio.py | 14 + script.plexmod/lib/backgroundthread.py | 23 +- script.plexmod/lib/cache.py | 176 + script.plexmod/lib/data_cache.py | 121 + script.plexmod/lib/genres.py | 41 + script.plexmod/lib/i18n.py | 9 + script.plexmod/lib/kodi_util.py | 69 + script.plexmod/lib/logging.py | 34 + script.plexmod/lib/main.py | 109 +- script.plexmod/lib/os_utils.py | 18 + script.plexmod/lib/path_mapping.py | 123 + script.plexmod/lib/playback_utils.py | 15 +- script.plexmod/lib/player.py | 483 +- script.plexmod/lib/plex.py | 94 +- script.plexmod/lib/plex_hosts.py | 112 + script.plexmod/lib/templating/__init__.py | 3 + script.plexmod/lib/templating/context.py | 213 + script.plexmod/lib/templating/core.py | 159 + script.plexmod/lib/templating/filters.py | 130 + script.plexmod/lib/templating/render.py | 100 + script.plexmod/lib/templating/templates.py | 19 + script.plexmod/lib/templating/util.py | 31 + script.plexmod/lib/util.py | 582 +- script.plexmod/lib/windows/__init__.py | 3 +- script.plexmod/lib/windows/background.py | 4 +- script.plexmod/lib/windows/busy.py | 59 +- script.plexmod/lib/windows/currentplaylist.py | 65 +- script.plexmod/lib/windows/dropdown.py | 32 +- script.plexmod/lib/windows/episodes.py | 494 +- script.plexmod/lib/windows/home.py | 1192 ++- script.plexmod/lib/windows/info.py | 19 +- script.plexmod/lib/windows/kodigui.py | 215 +- script.plexmod/lib/windows/library.py | 135 +- script.plexmod/lib/windows/mixins.py | 123 +- script.plexmod/lib/windows/musicplayer.py | 33 +- script.plexmod/lib/windows/opener.py | 9 +- script.plexmod/lib/windows/optionsdialog.py | 4 +- script.plexmod/lib/windows/pagination.py | 9 +- script.plexmod/lib/windows/photos.py | 45 +- .../lib/windows/playbacksettings.py | 5 +- .../lib/windows/playerbackground.py | 4 +- script.plexmod/lib/windows/playersettings.py | 16 +- script.plexmod/lib/windows/playlist.py | 98 +- script.plexmod/lib/windows/playlists.py | 12 +- script.plexmod/lib/windows/preplay.py | 57 +- script.plexmod/lib/windows/preplayutils.py | 2 +- script.plexmod/lib/windows/search.py | 14 +- script.plexmod/lib/windows/seekdialog.py | 542 +- script.plexmod/lib/windows/settings.py | 660 +- script.plexmod/lib/windows/signin.py | 6 +- script.plexmod/lib/windows/slidehshow.py | 11 +- script.plexmod/lib/windows/subitems.py | 71 +- script.plexmod/lib/windows/tracks.py | 36 +- script.plexmod/lib/windows/userselect.py | 21 +- script.plexmod/lib/windows/videoplayer.py | 170 +- script.plexmod/lib/windows/windowutils.py | 85 +- script.plexmod/path_mapping.json.example | 45 + script.plexmod/plugin.py | 72 +- .../resource.language.de_de/strings.po | 1265 ++- .../resource.language.en_gb/strings.po | 598 +- .../resource.language.es_es/strings.po | 1501 ++- .../resource.language.it_it/strings.po | 2132 +++- .../resource.language.zh_cn/strings.po | 2078 +++- script.plexmod/resources/settings.xml | 198 +- .../skins/Main/1080i/script-plex-album.xml | 636 -- .../skins/Main/1080i/script-plex-artist.xml | 776 -- .../Main/1080i/script-plex-background.xml | 65 - .../skins/Main/1080i/script-plex-blank.xml | 12 - .../skins/Main/1080i/script-plex-busy.xml | 28 - .../skins/Main/1080i/script-plex-busy_msg.xml | 35 - .../skins/Main/1080i/script-plex-dropdown.xml | 201 - .../1080i/script-plex-dropdown_header.xml | 247 - .../skins/Main/1080i/script-plex-episodes.xml | 1962 ---- .../skins/Main/1080i/script-plex-home.xml | 8678 ---------------- .../skins/Main/1080i/script-plex-info.xml | 289 - .../script-plex-listview-16x9-chunked.xml | 879 -- .../Main/1080i/script-plex-listview-16x9.xml | 850 -- .../script-plex-listview-square-chunked.xml | 943 -- .../1080i/script-plex-listview-square.xml | 916 -- .../script-plex-music_current_playlist.xml | 790 -- .../Main/1080i/script-plex-music_player.xml | 578 -- .../Main/1080i/script-plex-options_dialog.xml | 136 - .../skins/Main/1080i/script-plex-photo.xml | 725 -- .../Main/1080i/script-plex-pin_login.xml | 82 - .../skins/Main/1080i/script-plex-playlist.xml | 891 -- .../Main/1080i/script-plex-playlists.xml | 575 -- .../Main/1080i/script-plex-plex_pass.xml | 39 - .../Main/1080i/script-plex-posters-small.xml | 885 -- .../skins/Main/1080i/script-plex-posters.xml | 859 -- .../skins/Main/1080i/script-plex-pre_play.xml | 1486 --- .../Main/1080i/script-plex-pre_signin.xml | 39 - .../Main/1080i/script-plex-refresh_code.xml | 39 - .../skins/Main/1080i/script-plex-search.xml | 8839 ----------------- .../skins/Main/1080i/script-plex-seasons.xml | 1437 --- .../Main/1080i/script-plex-seek_dialog.xml | 1101 -- .../skins/Main/1080i/script-plex-settings.xml | 684 -- .../script-plex-settings_select_dialog.xml | 142 - .../1080i/script-plex-signin_background.xml | 21 - .../Main/1080i/script-plex-signin_blank.xml | 49 - .../Main/1080i/script-plex-slideshow.xml | 63 - .../skins/Main/1080i/script-plex-squares.xml | 777 -- .../Main/1080i/script-plex-track_context.xml | 67 - .../Main/1080i/script-plex-user_select.xml | 941 -- .../script-plex-video_current_playlist.xml | 480 - .../Main/1080i/script-plex-video_player.xml | 1351 --- .../script-plex-video_settings_dialog.xml | 159 - .../skins/Main/1080i/templates/base.xml.tpl | 16 + .../Main/1080i/templates/default.xml.tpl | 221 + .../includes/default_background.xml.tpl | 39 + .../includes/music_player_buttons.xml.tpl | 238 + .../includes/scale_background.xml.tpl | 1 + .../templates/includes/themed_button.xml.tpl | 28 + .../includes/watched_indicator.xml.tpl | 81 + .../Main/1080i/templates/library.xml.tpl | 373 + .../1080i/templates/library_posters.xml.tpl | 96 + .../1080i/templates/script-plex-album.xml.tpl | 346 + .../templates/script-plex-artist.xml.tpl | 472 + .../templates/script-plex-background.xml.tpl | 59 + .../1080i/templates/script-plex-blank.xml.tpl | 1 + .../1080i/templates/script-plex-busy.xml.tpl | 22 + .../templates/script-plex-busy_msg.xml.tpl | 29 + .../templates/script-plex-dropdown.xml.tpl | 206 + .../script-plex-dropdown_header.xml.tpl | 256 + .../templates/script-plex-episodes.xml.tpl | 1437 +++ .../1080i/templates/script-plex-home.xml.tpl | 7496 ++++++++++++++ .../1080i/templates/script-plex-info.xml.tpl | 158 + .../script-plex-listview-16x9.xml.tpl | 404 + .../script-plex-listview-square.xml.tpl | 441 + ...script-plex-music_current_playlist.xml.tpl | 517 + .../script-plex-music_player.xml.tpl | 293 + .../script-plex-options_dialog.xml.tpl | 133 + .../1080i/templates/script-plex-photo.xml.tpl | 670 ++ .../templates/script-plex-pin_login.xml.tpl | 79 + .../templates/script-plex-playlist.xml.tpl | 581 ++ .../templates/script-plex-playlists.xml.tpl | 363 + .../templates/script-plex-plex_pass.xml.tpl | 29 + .../script-plex-posters-small.xml.tpl | 385 + .../templates/script-plex-posters.xml.tpl | 346 + .../templates/script-plex-pre_play.xml.tpl | 1076 ++ .../templates/script-plex-pre_signin.xml.tpl | 36 + .../script-plex-refresh_code.xml.tpl | 29 + .../templates/script-plex-search.xml.tpl | 8824 ++++++++++++++++ .../templates/script-plex-seasons.xml.tpl | 1016 ++ .../templates/script-plex-seek_dialog.xml.tpl | 1098 ++ .../templates/script-plex-settings.xml.tpl | 683 ++ ...script-plex-settings_select_dialog.xml.tpl | 134 + .../script-plex-signin_background.xml.tpl | 18 + .../script-plex-signin_blank.xml.tpl | 46 + .../templates/script-plex-slideshow.xml.tpl | 64 + .../templates/script-plex-squares.xml.tpl | 412 + .../script-plex-track_context.xml.tpl | 58 + .../templates/script-plex-user_select.xml.tpl | 934 ++ ...script-plex-video_current_playlist.xml.tpl | 451 + .../script-plex-video_player.xml.tpl | 1014 ++ .../script-plex-video_settings_dialog.xml.tpl | 151 + .../player/modern-dotted/chapters-focus.png | Bin 0 -> 451 bytes .../buttons/player/modern-dotted/chapters.png | Bin 0 -> 411 bytes .../player/modern-dotted/info-focus.png | Bin 0 -> 1777 bytes .../buttons/player/modern-dotted/info.png | Bin 0 -> 1755 bytes .../player/modern-dotted/media-focus.png | Bin 0 -> 998 bytes .../buttons/player/modern-dotted/media.png | Bin 0 -> 961 bytes .../player/modern-dotted/more-focus.png | Bin 0 -> 439 bytes .../buttons/player/modern-dotted/more.png | Bin 0 -> 399 bytes .../player/modern-dotted/next-focus.png | Bin 0 -> 713 bytes .../buttons/player/modern-dotted/next.png | Bin 0 -> 693 bytes .../player/modern-dotted/pause-focus.png | Bin 0 -> 281 bytes .../buttons/player/modern-dotted/pause.png | Bin 0 -> 240 bytes .../player/modern-dotted/play-focus.png | Bin 0 -> 823 bytes .../buttons/player/modern-dotted/play.png | Bin 0 -> 789 bytes .../player/modern-dotted/pqueue-focus.png | Bin 0 -> 717 bytes .../buttons/player/modern-dotted/pqueue.png | Bin 0 -> 688 bytes .../player/modern-dotted/repeat-focus.png | Bin 0 -> 611 bytes .../player/modern-dotted/repeat-one-focus.png | Bin 0 -> 687 bytes .../player/modern-dotted/repeat-one.png | Bin 0 -> 654 bytes .../buttons/player/modern-dotted/repeat.png | Bin 0 -> 576 bytes .../player/modern-dotted/rotate-focus.png | Bin 0 -> 818 bytes .../buttons/player/modern-dotted/rotate.png | Bin 0 -> 784 bytes .../player/modern-dotted/settings-focus.png | Bin 0 -> 761 bytes .../buttons/player/modern-dotted/settings.png | Bin 0 -> 744 bytes .../player/modern-dotted/shuffle-focus.png | Bin 0 -> 1370 bytes .../buttons/player/modern-dotted/shuffle.png | Bin 0 -> 1349 bytes .../modern-dotted/skip-forward-focus.png | Bin 0 -> 1046 bytes .../player/modern-dotted/skip-forward.png | Bin 0 -> 1017 bytes .../player/modern-dotted/square2x2-focus.png | Bin 0 -> 645 bytes .../player/modern-dotted/square2x2.png | Bin 0 -> 615 bytes .../player/modern-dotted/stop-focus.png | Bin 0 -> 244 bytes .../buttons/player/modern-dotted/stop.png | Bin 0 -> 205 bytes .../player/modern-dotted/subtitle-focus.png | Bin 0 -> 560 bytes .../buttons/player/modern-dotted/subtitle.png | Bin 0 -> 524 bytes .../player/modern-dotted/tags-focus.png | Bin 0 -> 1644 bytes .../buttons/player/modern-dotted/tags.png | Bin 0 -> 1614 bytes .../player/modern-dotted/trailer-focus.png | Bin 0 -> 1311 bytes .../buttons/player/modern-dotted/trailer.png | Bin 0 -> 1277 bytes .../buttons/player/modern/chapters.png | Bin 0 -> 411 bytes .../buttons/player/modern/info.png | Bin 0 -> 1755 bytes .../buttons/player/modern/media.png | Bin 0 -> 961 bytes .../buttons/player/modern/more.png | Bin 0 -> 399 bytes .../buttons/player/modern/next.png | Bin 0 -> 693 bytes .../buttons/player/modern/pause.png | Bin 0 -> 240 bytes .../buttons/player/modern/play.png | Bin 0 -> 789 bytes .../buttons/player/modern/pqueue.png | Bin 0 -> 688 bytes .../buttons/player/modern/repeat-one.png | Bin 0 -> 654 bytes .../buttons/player/modern/repeat.png | Bin 0 -> 576 bytes .../buttons/player/modern/rotate.png | Bin 0 -> 784 bytes .../buttons/player/modern/settings.png | Bin 0 -> 744 bytes .../buttons/player/modern/shuffle.png | Bin 0 -> 1349 bytes .../buttons/player/modern/skip-forward.png | Bin 0 -> 1017 bytes .../buttons/player/modern/square2x2.png | Bin 0 -> 615 bytes .../buttons/player/modern/stop.png | Bin 0 -> 205 bytes .../buttons/player/modern/subtitle.png | Bin 0 -> 524 bytes .../buttons/player/modern/tags.png | Bin 0 -> 1614 bytes .../buttons/player/modern/trailer.png | Bin 0 -> 1277 bytes .../Main/media/script.plex/home/plex.png | Bin 1579 -> 2046 bytes .../media/script.plex/indicators/watched.png | Bin 0 -> 585 bytes .../script.plex/indicators/watched_2024.png | Bin 0 -> 356 bytes .../skins/Main/media/script.plex/splash.png | Bin 9464 -> 15885 bytes .../media/script.plex/user_select/plex.png | Bin 5374 -> 4767 bytes .../script.plex/white-square-bl-rounded.png | Bin 0 -> 203 bytes .../script.plex/white-square-bl-rounded_w.png | Bin 0 -> 488 bytes .../white-square-right-rounded.png | Bin 0 -> 225 bytes .../white-square-tr-bl-rounded.png | Bin 0 -> 222 bytes script.plexmod/service.py | 3 +- 282 files changed, 50872 insertions(+), 42373 deletions(-) create mode 100644 script.plexmod/TESTING_SQUAD.md delete mode 100644 script.plexmod/fanart.jpg create mode 100644 script.plexmod/fanart.png delete mode 100644 script.plexmod/icon.png create mode 100644 script.plexmod/icon2.png create mode 100644 script.plexmod/lib/_included_packages/_ipaddress.py create mode 100644 script.plexmod/lib/_included_packages/ibis/__init__.py create mode 100644 script.plexmod/lib/_included_packages/ibis/compiler.py create mode 100644 script.plexmod/lib/_included_packages/ibis/context.py create mode 100644 script.plexmod/lib/_included_packages/ibis/errors.py create mode 100644 script.plexmod/lib/_included_packages/ibis/filters.py create mode 100644 script.plexmod/lib/_included_packages/ibis/loaders.py create mode 100644 script.plexmod/lib/_included_packages/ibis/nodes.py create mode 100644 script.plexmod/lib/_included_packages/ibis/template.py create mode 100644 script.plexmod/lib/_included_packages/ibis/utils.py create mode 100644 script.plexmod/lib/_included_packages/plexnet/certs/ISRG Root X1.crt create mode 100644 script.plexmod/lib/_included_packages/plexnet/certs/R3.crt create mode 100644 script.plexmod/lib/_included_packages/plexnet/certs/USERTrust ECC Certification Authority.crt create mode 100644 script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL ECC Domain Secure Site CA.crt create mode 100644 script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL RSA Domain Secure Site CA.crt create mode 100644 script.plexmod/lib/_included_packages/plexnet/certs/acme.bundle.crt create mode 100644 script.plexmod/lib/_included_packages/plexnet/certs/plex.direct.bundle.crt create mode 100644 script.plexmod/lib/_included_packages/tendo_singleton.py create mode 100644 script.plexmod/lib/actions.py create mode 100644 script.plexmod/lib/advancedsettings.py create mode 100644 script.plexmod/lib/aspectratio.py create mode 100644 script.plexmod/lib/cache.py create mode 100644 script.plexmod/lib/data_cache.py create mode 100644 script.plexmod/lib/genres.py create mode 100644 script.plexmod/lib/i18n.py create mode 100644 script.plexmod/lib/kodi_util.py create mode 100644 script.plexmod/lib/logging.py create mode 100644 script.plexmod/lib/os_utils.py create mode 100644 script.plexmod/lib/path_mapping.py create mode 100644 script.plexmod/lib/plex_hosts.py create mode 100644 script.plexmod/lib/templating/__init__.py create mode 100644 script.plexmod/lib/templating/context.py create mode 100644 script.plexmod/lib/templating/core.py create mode 100644 script.plexmod/lib/templating/filters.py create mode 100644 script.plexmod/lib/templating/render.py create mode 100644 script.plexmod/lib/templating/templates.py create mode 100644 script.plexmod/lib/templating/util.py create mode 100644 script.plexmod/path_mapping.json.example delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-album.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-artist.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-background.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-blank.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-busy.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-busy_msg.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-dropdown.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-dropdown_header.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-episodes.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-home.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-info.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9-chunked.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-listview-square-chunked.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-listview-square.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-music_current_playlist.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-music_player.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-options_dialog.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-photo.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-pin_login.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-playlist.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-playlists.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-plex_pass.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-posters-small.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-posters.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-pre_play.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-pre_signin.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-refresh_code.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-search.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-seasons.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-seek_dialog.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-settings.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-settings_select_dialog.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-signin_background.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-signin_blank.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-slideshow.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-squares.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-track_context.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-user_select.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-video_current_playlist.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-video_player.xml delete mode 100644 script.plexmod/resources/skins/Main/1080i/script-plex-video_settings_dialog.xml create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/base.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/default.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/includes/default_background.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/includes/music_player_buttons.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/includes/scale_background.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/includes/themed_button.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/includes/watched_indicator.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/library.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/library_posters.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-album.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-artist.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-background.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-blank.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy_msg.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown_header.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-episodes.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-home.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-info.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-16x9.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-square.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_current_playlist.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_player.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-options_dialog.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-photo.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-pin_login.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlist.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlists.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-plex_pass.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters-small.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_play.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_signin.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-refresh_code.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-search.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-seasons.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-seek_dialog.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings_select_dialog.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_background.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_blank.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-slideshow.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-squares.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-track_context.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-user_select.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_current_playlist.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_player.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_settings_dialog.xml.tpl create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/chapters-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/chapters.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/info-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/info.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/media-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/media.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/more-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/more.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/next-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/next.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pause-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pause.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/play-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/play.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pqueue-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pqueue.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-one-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-one.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/rotate-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/rotate.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/settings-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/settings.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/shuffle-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/shuffle.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/skip-forward-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/skip-forward.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/square2x2-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/square2x2.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/stop-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/stop.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/subtitle-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/subtitle.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/tags-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/tags.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/trailer-focus.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/trailer.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/chapters.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/info.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/media.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/more.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/next.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/pause.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/play.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/pqueue.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/repeat-one.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/repeat.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/rotate.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/settings.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/shuffle.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/skip-forward.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/square2x2.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/stop.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/subtitle.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/tags.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/trailer.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/indicators/watched.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/indicators/watched_2024.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/white-square-bl-rounded.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/white-square-bl-rounded_w.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/white-square-right-rounded.png create mode 100644 script.plexmod/resources/skins/Main/media/script.plex/white-square-tr-bl-rounded.png diff --git a/script.plexmod/LICENSE.txt b/script.plexmod/LICENSE.txt index 6bcffb4610..3163ab4046 100644 --- a/script.plexmod/LICENSE.txt +++ b/script.plexmod/LICENSE.txt @@ -485,8 +485,130 @@ apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. +------------------------------------------------------------------------- + +https://github.com/phihag/ipaddress + +This package is a modified version of cpython's ipaddress module. +It is therefore distributed under the PSF license, as follows: + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014 Python Software Foundation; All Rights Reserved" are +retained in Python alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + +------------------------------------------------------------------------- + +https://github.com/pycontribs/tendo + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python +alone or in any derivative version, provided, however, that PSF's +License Agreement and PSF's notice of copyright, i.e., "Copyright (c) +2001, 2002, 2003, 2004 Python Software Foundation; All Rights Reserved" +are retained in Python alone or in any derivative version prepared +by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + +------------------------------------------------------------------------- + +https://github.com/dmulholl/ibis/blob/master/license.txt + +------------------------------------------------------------------------- + +Partially sourced kcsaff/getkey, License: https://github.com/kcsaff/getkey/blob/master/LICENSE ------------------------------------------------------------------------- Fontawesome https://fontawesome.com/license/free CC BY 4.0 License: https://creativecommons.org/licenses/by/4.0/# + +------------------------------------------------------------------------- +Play queue by Sébastien Robaszkiewicz from Noun Project (CC BY 3.0) +fast forward by Adiyogi from Noun Project (CC BY 3.0) +subtitle by YANDI RS from Noun Project (CC BY 3.0) + +Other unlisted icons under CC BY 3.0, https://creativecommons.org/licenses/by/3.0/ \ No newline at end of file diff --git a/script.plexmod/README.md b/script.plexmod/README.md index 317bd7cab1..cd33b49671 100644 --- a/script.plexmod/README.md +++ b/script.plexmod/README.md @@ -1,4 +1,6 @@ -# PlexMod (for Kodi) +# PM4K / PlexMod for Kodi + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Z8Z8X6P9T) This is a modification of the official open-source Plex client for Kodi "plex-for-kodi" (Plex4Kodi) semi-maintained by me (pannal). @@ -6,7 +8,7 @@ Contrary to how this repository was handled before, this client does _not_ claim It implements features that are not implemented in other official Plex clients and may implement others in non-conform ways. -It is still based off of the original P4K source and critical bugfixes will be PR'd back. +It is still based off of the original P4K source and critical bugfixes might be PR'd back. ## Active branches * [develop-kodi21](https://github.com/pannal/plex-for-kodi/tree/develop_kodi21) (Kodi 19, 20, 21 cross-compatible) @@ -16,15 +18,21 @@ Master branch is based off of the official plex-for-kodi master branch. ## Installation -### Via repository -* Add `https://pannal.github.io/dontpanickodi/` to your Kodi installation as a file source -* Go back to addons, choose zip file, choose the file source you added and install the repository -* Install Plex via Addons->Install from repository->Don’t Panic->Video add-ons->Plex -* Optional, recommended: Install Plextuary via Addons->Install from repository->Don’t Panic->Look and Feel->Skin->Plextuary +### Via repository (recommended) +* Add `https://pm4k.eu` to your Kodi installation as a file source +* Go to Settings->Addons, choose "Install from zip file", choose the file source you added and install the repository +* Install Plex via Settings->Addons->Install from repository->Don't Panic->Video add-ons->Plex +* Optional, recommended: Install Plextuary via Settings->Addons->Install from repository->Don't Panic->Look and Feel->Skin->Plextuary + +### Installation (stable only, not optimized, possibly outdated) +* Install "PM4K for Kodi" from the official Kodi repository +* Optional, recommended: Install Plextuary skin using the above ### Manual * Checkout any branch of this GitHub repository, rename to `script.plexmod` and use as an addon +## Translation +You can help! Join the translation effort at [POEditor](https://poeditor.com/join/project/ASOl50YAXg) (thanks for the free open source license, guys). ## Help/Bug Reports https://forums.plex.tv/t/plexmod-for-kodi-18-19-20-21/481208 diff --git a/script.plexmod/TESTING_SQUAD.md b/script.plexmod/TESTING_SQUAD.md new file mode 100644 index 0000000000..39e4fded8f --- /dev/null +++ b/script.plexmod/TESTING_SQUAD.md @@ -0,0 +1,2 @@ +## The Squad (TM) +@sonofdibnah @ecsjjgg @Unknown3899 @THGhost @bowlingbeeg @Buttzy10169 @SmarthyMcFly @pl37919 @FortKnox1337 diff --git a/script.plexmod/addon.xml b/script.plexmod/addon.xml index 2e911137be..5f60499c98 100644 --- a/script.plexmod/addon.xml +++ b/script.plexmod/addon.xml @@ -1,7 +1,7 @@ @@ -33,11 +33,11 @@ https://github.com/pannal/plex-for-kodi all -- Based on 0.7.6-rev2 +- Based on 0.7.9-rev4 - icon.png - fanart.jpg + icon2.png + fanart.png - \ No newline at end of file + diff --git a/script.plexmod/changelog.txt b/script.plexmod/changelog.txt index 9f552aa800..b8920e287a 100644 --- a/script.plexmod/changelog.txt +++ b/script.plexmod/changelog.txt @@ -1,6 +1,366 @@ -[-0.7.6-rev2 -] -- Core: Avoid DNS rebind protection issues for plex.direct +[-0.7.9-rev4-] +- Episodes: Clear VIDEO_PROGRESS onFirstInit; Only redirect to episode from progress if shows match +- Collections: Fix shuffle play +- Core/Playback/CoreELEC: Increase CoreELEC resume seek wait fix to 350ms (was 250ms) +- Playlists: Fix shuffle/play button behaviour +- Player: Only send timeline events if playstate has changed or we haven't sent one for 15 seconds; fixes #137 +- AddonSettings: Fix default cert bundle setting +- Core/plexnet/http: Fix session cert bundle usage by using the correct attribute (verify vs cert); should fix kodi 18 connectivity +- Core/AddonSettings: Adjust proper defaults for plextv timeouts +- Core/Networking/MyPlex: Don't use custom certificate for plex.tv connections +- Core/SSL: Replace default plex.direct certificate with ACME root bundle (Letsencrypt, ZeroSSL), valid until 2035 +- Core/AddonSettings: Adjust default plex.tv timeouts to 1s (connect), 2s (read) +- Core/KodiGUI: When broken template is detected, make sure to stop current playback as well + +- Login/Pinlogin/Prelogin: Fix black screen +- i18n: Fix duplicate translations (de_de, es_es, zh_cn) +- Home: Fix hubs not translated +- Home: Fix double refocus; add logging +- i18n: Fix bad escapes in translations, update forgotten description + +- Episodes: After fully watching the last episode of a season, select the next unwatched episode of the next season, automatically, after returning to the episodes view +- Episodes: Carry progress data as long as we're visiting (nested) episodes views +- Episodes: Clear progress data after filling episodes when opened without nesting (episodes or postplay) +- Episodes: Correctly select next-up-episode even if we had progress data +- Episodes: Correctly show episode thumbnails at their 16:9 ratio +- Episodes: Correctly update unwatched counter in seasons list after marking an episode watched +- Episodes: Don't change focus after selecting a new episode (might need a better fix) +- Episodes: Don't reselect current season in seasons view after returning from visiting another season +- Episodes: Fix badly reported resume states +- Episodes: Fix episodes not playable after returning from playback +- Episodes: Fix focus handling (don't refocus already focussed elements) +- Episodes: Fix focussing after playing something in a different season +- Episodes: Fix no related shows shown; broken for half a year +- Episodes: Fix rare timing issue (with possible crash/freeze) when play was pressed before theme music started playing (thanks @MikeTeavee for reporting and testing the fix) +- Episodes: Fix refocus handling after visiting a sub-season +- Episodes: Fix round robining too early after returning from playback and pressing left after watching the first episode +- Episodes: Fix wrong top scroll when returning to episodes screen after visiting sub-season +- Episodes: Harden selectEpisode logic further +- Episodes: Only redirect to seasons when returning from playback (reinit) +- Episodes: Properly reselect play button if possible +- Episodes: Visually fix resume point still showing after rewinding to a non-resume-worthy point (<60s) in a video that had a resume point +- Episodes: When watching multiple episodes in a row, completely, until the end of the season, select the last episode in the season when returning from playback +- Episodes/Movies: Fix play button not working after cancelling the resume dialog; fix play button not working after returning to view after direct playing from home +- Episodes/Movies/Libraries: Don't allow multiple presses of play to avoid issues +- Episodes/Postplay: Fix behaviour when visiting episodes view from postplay +- Home: Allow hiding specific hubs via hubitem context menu +- Home: Avoid mis-selecting a hub item after watching something and returning to the hub, after updating the hub and a different selection has been made in the meantime +- Home: Avoid section button "jumping" on reInit after visiting a library +- Home: Bifurcate library dropdowns +- Home: Correctly re-enable home updates even if we're playing, after coming back from screensaver or sleep +- Home: Disable updates when screensaver activated +- Home: Don't refresh stale sections while we're not the active window; might improve UI performance after watching something +- Home: Fix extremely long/indefinite reload when revisiting home after watching something from another library for longer than 5 minutes +- Home: Fix setting correct background when round-robining hubs +- Home: Implement library features "Scan Library Files", "Empty Trash", "Analyze" for admins +- Home: Properly support cancelling library reordering (reverting to the previous order) +- Home: SectionHider: After hiding a section, go to the previous one +- Home: SectionMover: Stay on current section after moving +- Home: update On Deck hubs after revisiting home, not before +- Home: Wait 1 second before continuing (block input) after wake event (default); 5 seconds for CoreELEC (default) +- Home: When a hub goes missing (e.g. continue watching gets emptied) after reinit, focus next best valid hub, if a hub was focused before +- Home: When onWake is set to restart PM4K, close all active dialogs and non-home windows before exiting +- Home/Hubs: Try correctly reselecting the last selected item after item progress has been made and we're revisiting home (hubs update) +- Home/Hubs: When round-robining is enabled, limit the amount of items fetched to 250 (default); if the hub exceeds this value, the rest of the items are lazy loaded as before +- Home/Restart-after-wake: Prevent API calls when we're closing all windows and returning home to restart the app +- Home/Settings: Fix description for EZ mapping +- Home/Settings: Set home dirty when changing the option to show/hide path mapping indicators +- Home/Settings/Theming: When setting a theme-relevant setting, restart home +- Photos: Correctly focus play button on OSD open +- Player: Properly honor previous paused state when switching streams during transcode session (now pausing onAVStarted instead of onPlayBackStarted) +- Player/Audio: Fix zero-duration error; fix seeking impossible +- Player/Episodes/Seekdialog: Always correctly select the currently playing item in the current playlist +- Player/Episodes/Videoplayer: Avoid blocking play button based on wonky BGM state +- Player/Episodes/Videoplayer: Before starting playback, wait for BGM to finish being handled +- Player/Music: Fix broken shuffle handling (hopefully) +- Player/PlaybackState: Allow forcing a timestamp +- Player/PlaybackState: Avoid using the player's current time when reporting a stopped state via the tick() method; might fix resume issues on CoreELEC when switching audio streams that need transcoding; add logging +- Player/PlaybackState: Only store progress for episode view if updatePlaybackState has accepted and sent our new timestamp +- Player/SeekDialog: Show chapters when pressing down with OSD +- Player/SeekPlayerHandler: Possibly harden further against bad timeline events +- Player/Settings/Player UI: Add option to show OSD instead of skipping chapters when pressing up/down without OSD (Default: On) (called "Behave like official Plex clients") +- PlexPlayer: Music: Allow directplay of high resolution audio (e.g. FLAC >= 192 kHz) +- PlexPlayer: Music: When transcoding is necessary, use http/mp3/mp3 for compatibility and seeking reasons +- Postplay: Allow resuming in-progress episodes +- Postplay: Fix cosmetic "API: ERROR: FATAL: Container address is not an expected path: " +- SeasonsMixin: Don't auto-select unplayed specials/season 00 +- SeasonsMixin: Select the first unwatched season by default +- SeekDialog: Allow ACTION_PAGE_DOWN and ACTION_PAGE_UP to bring up the OSD when Behave like official Plex clients is active +- SeekDialog: Allow for seek-back on resume after pause (only Direct Play) +- SeekDialog: Blur chapter preview images if wanted +- SeekDialog: Fix issue with time fields not updating in OSD when transcoding video (thanks @bowlingbeeg) +- SeekDialog: Fix Kodi UI shining through when pressing INFO +- SeekDialog: Fix player settings scrollbar visible between native Kodi settings dialog fades (returning from subtitle offset adjust for example) +- SeekDialog: Normalize marker data before modifying it +- Seekdialog: Only react to DOWN with OSD shown if we should behave like official Plex clients and we want/have (virtual) chapters +- SeekDialog: Postplay: Fix replay error/issue +- SeekDialog: Re-evaluate MediaDecisionEngine decision when changing selected streams during playback; this allows switching between DirectPlay/DirectStream/Transcode, on the fly, based on the selected streams +- SeekDialog: Reduce skip-button "jumping" just before auto skipping a marker +- SeekDialog: Refocus playlist button after closing playlist dialog, after opening it more than once +- SeekDialog/CurrentPlaylist: Honor no TV spoilers setting as well +- SeekDialog/Player: Don't restart the video when changing audio or subtitles (possibly even video, not tested), if not necessary +- SeekDialog/Player: Fix resume-on-start sometimes not working when an embedded subtitle stream was selected +- SeekDialog/Player: Report selected streams correctly to PMS when switching streams in DirectPlay mode (activity/sessions tab in PlexWeb) +- SeekDialog/PPI: Correctly position CPUUsage when scaled +- SeekDialog/VideoSettings: Hide fade backdrop when we're using skin.plextuary +- SeekDialog/VideoSettingsDialog: Don't fade background when OSDBackgroundPause isn't activated in plextuary; never fade background when SliderDialog is active (audio/subtitle offset adjustments), regardless of the skin used +- Audio: Fix transcoding not working +- Audio: Support direct play of high-res audio (<= 384 kHz) +- Audio/CurrentPlayList: Allow round-robining +- Audio/CurrentPlaylist: Close current playlist view when pressing back/previous menu with current playlist view open instead of closing the music player +- Audio/Playqueues: Fix issue were track would skip back to the previous one +- Audio/Playqueues: Generic fixes +- Boot: Force home before starting via plugin mode (Program Addons, My Addons, Shortcuts) +- Core: Add customized templating engine +- Core: Add info to splash in log whether we need scaling or not, and the current aspect ratio +- Core: Add our own ibis-3.3.0 fork as a library +- Core: Add singleton from tendo library; add LICENSE; make singleton py2 compatible (hopefully) +- Core: Add the ability to use an addon-supplied CA-certificate bundle for plex.direct connections (might be slightly less resource-intensive; new default; non-plex.direct connections will use the system bundle), the system bundle (old default), or a custom bundle +- Core: Allow going home using a mapped button (thanks @Rick_Williams for testing) +- Core: Change the way we use onAction introduced with the goHome button +- Core: Detect whether we're using skin.plextuary +- Core: Dropdown with header: Limit vertical size, enable scrolling +- Core: Dump all user settings into the DEBUG log if requested (private information masked) +- Core: Fix certain network related issues +- Core: Fix hang after sleep/wake when network isn't immediately available on CoreELEC +- Core: Fix No data error upon startup when "Use new Continue Watching hub" is enabled +- Core: Fix usage of collections.Iterable with Kodi python > 3.9 +- Core: Make DEBUG_LOG calls cheaper in case DEBUG isn't enabled +- Core: Revert 2023 change to tick every 100ms; tick every 1 second +- Core: Separate version info and global property handling from util.py into kodi_util.py +- Core: Store active state in global property for skin.plextuary to detect whether we're the active window and not minimized +- Core: Support new JSON based settings (we had something similar before for lists) +- Core/AddonSettings: change stepping for non-local-check timeouts from 0.1 to 0.5 +- Core/AddonSettings: Correctly honor dynamic backgrounds setting +- Core/AddonSettings: Increase skip_intro_button_show_early_threshold1 from 60 to 70 seconds (by default) +- Core/AddonSettings: Set max_retries=3 (default) for HTTP/HTTPS adapters, possibly fixing section refresh failing after power states (hibernation) (thanks @stigger) +- Core/AddonSettings: Split connect and read timeouts for Plex and Plex.tv connections; correctly set default max_retries to 3; New defaults: Plex (connect: 5s, read: 10s), Plex.tv (connect: 5s, read: 20s) +- Core/Boot/Entrypoint: Make entrypoint leaner by only importing what's necessary +- Core/Boot/Entrypoint: Use both tenga.singleton and global "started" property on Window(10000) to determine whether we're already running +- Core/Boot/Kiosk: Allow delaying autostart/kiosk-mode; allow manual immediate start when requested +- Core/Cache/Settings: Disallow writing (and showing) cache settings from within the plugin when installed from the official Kodi repository and we don't have the modern API +- Core/GUI/Templating: Smaller aspect ratio support (16:10, 4:3, …) +- Core/Main: Make absolutely sure we never run more than one instance at a time (via tendo.singleton locks) +- Core/Mainloop: Clean up global properties +- Core/MyPlex/UserSettings: Use cached user/account while waiting for plex.tv response; fixes episode playback errors with bingeMode setting +- Core/Networking: Fix certain queries not timing out (thanks @evertonmdz for testing) +- Core/Networking/MyPlex: Adhere to max_retries when querying myplex; adhere to PLEXTV_TIMEOUT_READ (default: 20s) when doing so (used LONG_TIMEOUT=20 as a fixed value before) +- Core/Networking/MyPlex: Retry myplex query on account initialization 4 times; use util.LONG_TIMEOUT (default: 20s) for data and util.TIMEOUT (default: 5s) for connecting +- Core/PlaybackManager: Allow ACCOUNT.ID to be None to not fail on pbs.bingeMode in certain (rare) situations +- Core/Plugin: Make plugin entrypoint much leaner; remove old directory based play() feature; move ensureHome() to kodi_utll.py +- Core/Reactivate/Maximize: If unable to reactivate plugin, exit cleanly +- Core/SeekDialog: Workaround for seek issue on Ugoos am6b+ (On the Ugoos am6b+ after seeking it can take 2-15 seconds for audio to start while the video is playing. Playing the same file using the default kodi player does not exhibit this issue. Changing to use the executebuiltin(Seek) solves this issue.) thanks @bowlingbeeg +- Core/Settings: Add setting to System tab to dump all user settings +- Core/Settings: Allow setting DEBUG on the fly, without restarting the addon +- Core/Settings: Backport old separated boolean settings to multioptions +- Core/Settings: Implement MultiOptionsSetting +- Core/Settings: Implement theme-relevant settings flag; reapply theme if necessary after exiting settings and revisiting home +- Core/Templating: Allow full context overriding by using addon_data/script.plexmod/context_overrides.json (see lib/templating/context.py for structure) +- Core/Templating: Recompile templates if we're missing XMLs; fixes addon not starting after upgrade without theme version change +- Core/Theming: Allow overriding theme definition/defaults by supplying theme_overrides.json in userdata/addon_data/script.plexmod; see /lib/templating/context.py for the data structure +- Core/Theming: When rendering templates, show kodi progress dialog +- Core/Windows: Fix "Go to Home to {library}"; properly select and focus library in section list +- Dropdown/Libraries: Fix visual scrolling issues on dropdowns with many items (e.g.: Genres) +- Dropdowns: Be smarter when we're trying to display a dropdown that's out of bounds +- FireTV: Fix timeFormat (at least in InfoView) +- Fix seek issue with CoreELEC devices (thanks @bowlingbeeg) +- GUI: Clean up interface by removing most button focus zoom animations +- i18n/Chinese: Fix broken translation (incomplete) +- i18n: Update Chinese translations (thanks liquidion, wabisabi, x1ao4) +- i18n: Update German translations (thanks fuchs21, Martin) +- i18n: Update Spanish translations (thanks Deci8belios, Donovan_000) +- Indicators: Improve indicators resolution; add missing image +- Kodigui: Support dialog and window close signals +- Libraries: Fix play all and shuffle all buttons +- Library: Add "Episode Date Added" sort; rename "Name" sort to "Title" +- Library/Music: Support Tracks as type on Music libraries; partially fixes #133; should fix #132 +- Main/EventLoop: Allow setting a tickrate different than 1 Hz +- Movies/Episodes: Auto-scroll long summaries +- Music Libraries: Fix filters erroring +- Music: When stopping playback with open current playlist, close audio player window as well +- MyPlexAccount: Fix isAdmin based on homeUser (when caching home users) +- Settings: Add CONTEXT_MENU to clear bound home button to description +- Settings: Add MultiUAOptionsSetting (a user aware variant of MultiOptionsSetting) +- Settings: Add setting "Action on Wake event" (none, restart pm4k, wait Xs) +- Settings: Add setting for Hi-Res Music (default: on) +- Settings: Add setting to allow a delay for the autostart/kiosk-mode +- Settings: Add setting to enable or disable factor based scaling of modern watched indicators based on poster size (default: on) +- Settings: Add setting to only allow seek-back on Direct Play +- Settings: Add setting to only seek-back after a certain amount of time in paused state +- Settings: Add setting to seek-back on pause instead of resume +- Settings: Add setting to set seek-back on resume after pause (100ms, 250ms, 500ms, 750ms, 1-60s) +- Settings: Add user-setting to never show Post Play (default: off) +- Settings: Allow clearing home button mapping using CONTEXT_MENU/long press +- Settings: Disable "Stop video playback on screensaver" by default +- Settings: Focus setting categories when pressing back while inside a category instead of immediately backing out +- Settings: Implement new watched/unwatched status setting (default: Modern (2024)) +- Settings: Move "Behave like official Plex clients" further up +- Settings: Move "Player Theme" setting to Main section and rename it to "Theme" +- Settings: Move "Stop video playback on idle after" and "Stop video playback on screensaver" settings to Video Player tab +- Settings: Move autostart/kiosk-mode to Main (was in: System) +- Settings: Move Theme selection above Indicators +- Settings: Post play Auto Play: Honor postplay timeout in setting description (addonSetting; default: 16s) +- Settings: Re-arrange settings; add "User Interface" tab; move a lot of settings from Main to User Interface +- Settings: Remove visually "annoying" last main section item bottom border +- Settings: Rename "Hide black backdrop in inverted watched states" to "Hide background in modern indicators" +- Settings: Rename Player UI to Video Player +- Settings: TV Spoiler settings: Add setting to hide chapter preview images +- Settings: Unify TV spoiler settings further +- Settings: Update hubs round robin description, add warning +- Settings: Use unicode literals +- Settings/Audio/AC3/DTS: Change setting options from 2.1+ and 5.1+ to >2.0, >2.1, >5.0, >5.1 to allow for more fine-grained control +- Settings/Home-Map-Key: Show proper dialog while remapping; make use of skin.plextuary-pm4k-1.1's no-icon-dialog +- Settings/MultiOptionsSetting: Keep original options order when displaying currently selected options +- Settings/Player UI: Test new MultiOptionsSetting for a couple of Player UI button visibility settings (should auto-migrate over from old boolean settings) +- Settings/Player: Add "Skip intro" and "Skip credits" to button options, allowing per-user control of whether marker action buttons should be shown or not (default: On) +- Settings/Player: Make "Show buttons" setting user aware +- Settings/TV/Spoilers: Make allowed TV spoilers for specific genres configurable +- Settings/Video: Streamline playback features and video codecs to reduce the amount of settings available +- AddonSettings: Add setting for tickrate (default: 1 Hz, min: 0.5 Hz, max: 10 Hz) +- AddonSettings: Add setting to Cache Templates (default: on); Add setting to always recompile templates on start (default: off) +- AddonSettings: Add setting to choose the CA-certificate bundle (system, plex.direct (default), custom (userdata/addon_data/script.plexmod/custom_bundle.crt) +- AddonSettings: Add setting to specify the limit for round-robining hubs (default: 250, safe tested on SHIELD: 1000) +- AddonSettings: Increase CoreELEC resume seek wait to 250ms by default (was: 200ms); thanks @panaitwebbos for testing +- AddonSettings: Reset default Plex Requests timeout to 5s (was 10s); increase maximum to 60s (was 30s) +- Signals: Check whether we've actually registered a signal before trying to disconnect it +- Templating: Retry writing a template to disk once +- Templating: Try making sure the XMLs actually have been written (sadly xbmcvfs.File doesn't allow flush/sync()) +- Templating/Kodigui: Harden against corrupted XML files; recompile templates if encountered in any window/dialog +- Templating/Postplay: move hubs up a little (scaled) +- Templating/Watched_indicators: Implement factor based scaling of modern watched indicators based on poster size +- Theming: Apply button themes to all views +- Theming: Cache templates by default, making subsequent theme-related changes blazing fast (cache clears after restarting PM4K and is filled again when recompiling templates) +- Theming: Implement new 2024 watch status +- Theming: Make watch status indicator handling fully dynamic (templated) +- Theming/Playlists: Use different watched indicator location +- Tracks: Select last played track on window reinit +- TV Shows: Fix play button not working after returning from playback on TV Shows/Seasons screen +- Videoplayer/External: When using external player handle Ended events as always stopped manually +- VideoPlayer/Postplay: Fix vertical positioning of hubs to be about the same as in Movie/Preplay view +- Videoplayer/Postplay/Episodes/Movies: Try fixing rare timing error when clicking a role/actor +- VideoPlaylists: Fix returning to playlist after manually stopping a video +- VideoPlaylists: Properly select first unwatched item if possible; correctly set current item after returning from watching more than one + + +[-0.7.8-] +- Global: Use watched markers instead of unwatched markers (green checkmark vs. yellow triangle) +- Home: Blur in-progress episode thumbnails if Addon Setting "Use episode thumbnails in continue hub" is enabled and titles if requested +- Home: Refresh hubs when no episode spoiler setting changed +- Home/Settings: After changing home-relevant settings, reload Home on revisit, not immediately +- Home: Dynamically reload home when relevant settings have changed +- Home/Sections: Improve handling for sections that errored out once, and retry loading them just like any stale section every 5 minutes +- Home: Fix hubs not coming back after disconnect +- Home: Harden disconnect handling in general; PM4K should be able to "live" forever now +- Home: Refresh last section on: screensaver deactivated, DPMS deactivated, system wakeup after sleep +- Home/PowerEvents: Disable updates when system goes to sleep, enable them when it wakes up; force a hubs update when waking up +- Home: Probably fix long-running section change issue (partially reverting a previous change and being a little smarter about the current selection state); add debug logging for when we detect the "anomaly" +- Home: Don't let any tasks remain in a crashed state +- Core/Home: Add easy path mapping +- Core/Home: Add library context option to hide them for current user/server; Add context option for "Home" to unhide hidden libraries +- Home: Hide hidden library content from home hubs as well +- Home: Add library reordering functionality +- Home: Remove Hub round-robining altogether +- Home: Use ACTION_NAV_BACK/ACTION_PREVIOUS_MENU in home hubs to select the first item when any item other than the first item is selected +- Home: After refreshing stale section hubs (every 5m), re-select the last selected position in every hub, possibly re-extending the hubs to match the last position +- Episodes: Blur unwatched/in-progress episode thumbnails and redact spoiler texts, and episode titles if requested +- Episodes: Possibly use correct episode when playing TV Show from TV Show overview; always play latest in progress, unwatched, deprioritize specials +- Episodes: after watching an episode, remove chevron immediately +- Episodes: After watching multiple episodes in a row that span more than one season (e.g. watched S01E10, S02E01), properly redirect to the latest correct season view of the just watched episodes +- Episodes: Inject watched/progress state into listitem datasource (fixes wrong "Mark as (Un) Played" menu item behaviour immediately after watching an episode) +- Episodes: Don't play theme music when coming back from Home-Direct-Play (pressed P or ACTION_PLAYER_PLAY) +- Episodes: Select the correct episode after returning from direct playback from home (P/PLAY pressed) +- SeekDialog: Hide episode title if wanted +- SeekDialog: Properly update VideoPlaylist when using next/prev +- SeekDialog: Improve chapter visibility (selected and deselected (current)) +- SeekDialog: Throw away intro markers with an unreasonably late start offset (>10m) +- SeekDialog: Throw invalid markers away once, not every tick +- SeekDialog/Settings/Video Playlists: change the setting options for showing the prev/next and playlist buttons from "Only for Episodes" to "Only for Episodes/Playlists"; Show next/prev/playlist buttons in player for video playlists if wanted +- Core/Players: Remove all Kodi media-loading spinners when using Plextuary skin +- Core/Player: Always set infolabel "year" and remove it when downloading subtitles; don't set infolabels "episode" and "season" at all for non-TV-shows (fixes scrobbling issues with trakt plugin) +- Core/Player: Report all known Guids to script.trakt if it's installed; generate slug for movies +- Player/SeekDialog: Properly handle a manual stop action on episodes when OSD was visible (possibly other occasions) +- Player/PostPlay: Hide spoilers as well, if configured +- Postplay: Don't show the same episode on deck which is going to be played next +- TV Shows/Seasons: Try reloading instead of exiting to home when deleting a season if possible +- Libraries: Add movie/show year to label (thanks @bowlingbeeg) +- Libraries: Fix year display, fix Art display in listview 16x9; make small posters view a little less cramped +- VideoPlaylists: Show playback menu when an item can be resumed +- VideoPlaylists: Show playback menu when CONTEXT_MENU action is detected +- VideoPlaylists: Allow resuming, or, if possible, Start from Beginning +- Core: Ignore local IPv4 docker plex.direct hosts when checking for host mapping +- Core: Unify spoiler handling across multiple windows +- Core: API requests: Don't generally include markers, only for PlayableVideos +- Core: Open up translations to everyone, using POEditor +- Core/AddonSettings: Remove old compatibility profile code and setting +- Core/AddonSettings: Make caching home users optional; add setting (default: on) +- Core/Home: When home user caching is disabled, refresh home users when opening the user dropdown (once) +- Core: Add support for Guids in new library agents +- Core/Episodes/Player: Inject Show reference into episodes to speed up playback start and avoid additional API hits; Don't initiate a playlist if only one episode is being played +- Core: Compatibility with script.trakt +- Core: Add automated generic JSON data cache, stored as addon_data/script.plexmod/data_cache.json +- Core/TV: Store and use "once seen" genres for a show in the data cache to speed up certain views (such as postplay and continue watching, with no spoiler mode active) +- Core: Automatically clean up old unused data cache entries which haven't been accessed for 30 days +- Core/Settings: Add option to use watched markers instead of unwatched markers (default: on) +- Core/Settings: Add option to hide the black background on inverted watched markers (default: off) +- Core: Fix dialogs reverting the underlying window's watched marker setting temporarily +- Core: Memory usage and performance optimizations (possibly >10% in py3 and >30% in py2 by using __slots__ on massively used classes) +- Core: Allow for custom watched.png, unwatched.png, unwatched-rounded.png in addon_data/script.plexmod/media/ +- Core: Improve delete media clarity +- Core/Playlists: Fix context menu "play" action on playlist items when addonSetting playlist visit media is on +- Core/Windows: Optimize Imports +- Settings: Add setting to show indicators for libraries with active path mapping (default: on) +- Settings: Add setting to blur episode thumbnails and preview images, as well as redact spoilers for unwatched or unwatched+in progress episodes +- Settings: Add setting to also hide episode titles based on the above +- AddonSettings: Add setting to configure the blur amount for unwatched episodes (default: 16/255) +- AddonSettings: Add setting for ignoring local docker IPv4 hosts when checking for host mapping (default: enabled) +- AddonSettings: Change default of "Visit media in video playlist instead of playing it" to False +- AddonSettings: Add setting to define the maximum start offset of an intro marker to consider it (default: 600s/10m) +- Theme: Bump theme version to 3 + + +[-0.7.7-rev2-] +- UserSelect: When not switching user (startup), close the addon on cancel actions +- Libraries/Photos: Do autoplay when Play or Shuffle buttons are pressed in photo library view +- Libraries/Photos: Fix wonky thumbnail display on photodirectories +- SeekDialog: Fix final credits marker skipping wrongly on manual marker skip +- SeekDialog: Fix several marker issues (over-jumping, invalid markers) +- SeekDialog: Show stream transport type in video session info (smb, nfs, path mapped, http(s)) +- SeekDialog: Fix empty chapters list shown when watching an episode without markers via NEXT after watching one with markers +- SeekDialog/Settings: Add option to hide all time-related information from the user when the OSD isn't open +- SeekDialog: Transcode Session Only: Don't show subtitle download option in subtitle quick actions; properly show subtitles when toggling them via subtitle quick actions +- Core: Advanced/Addon settings: Set default Plex requests timeout to 10 (was 5) +- Core/Mainloop: Make sure we were able to open the Home/UserSelect window after our BACKGROUND successfully opened, even if another modal dialog opened in the meantime - Core: Firstrun: Refresh resources after signin and/or home user switch, otherwise the first time the addon's run the user sees no servers +- Core: UI: Fall back to black background image when we have backgrounds set but they didn't load +- Core: Finally fix and handle plex.direct mappings via advancedsettings.xml +- Core: Fix issues resulting in new devices being registered with plex.tv on every plugin start +- Core: Only use mapped file path if mapped file exists or verification is off +- Core: Backgrounds: More concise fallback handling +- Core/Player: Add optional DirectPlay path mapping via addon_data/script.plexmod/path_mapping.json (path_mapping.example.json included in addon directory). Allows for arbitrary replacements of HTTP playback with SMB, NFS, local mounts etc. +- Home: Rework and simplify section/library change logic +- Home: Never update hubs while playing a video to avoid hickups in high bitrate scenarios +- Home: Properly cache user thumbnail (by removing the ?c timestamp from the URL), increasing performance +- Home: Fix round robining on hubs (going left once before the last item, then right falsely round-robined to the start, early) +- Home: Add virtual hub 'home.VIRTUAL.movies.recentlyreleased' on index 3 if we encounter 'movie.recentlyreleased' on the home hubs +- Home/Settings: Add setting to use the modern Continue Watching hub on Home instead of the separated In Progress/On Deck hubs +- Episodes: Complete rework of the watch-state handler for TV; instantly update progress while watching +- Theme: Update assets, icon, splash +- Music: Rework music player and handler; remove plugin:// path and handle tracks directly; fixed all stability issues; massively improve performance +- Player: Add button theme support, use new modern colored theme; support custom themes +- Player: Improve handling when postplay screen is not wanted and we're at the end of a show; harden progressEvent handler +- Player: Remove all /file.xxx instances instead of just .mkv and .mp4 from non mapped stream URLs +- Musicplayer: Partially fix "dangling" playing tracks in Plex Dashboard after stopping playback +- Music: Hide spinner on prev/next button clicks as well (only with Plextuary skin 4.0.0-pm4k0.9 (omega), 3.0.10-pm4k0.8 (nexus and older)) +- Settings: Add setting to toggle path mapping dynamically +- Settings: Adjust cache recommendations down from 100MB to 50MB +- AddonSettings: Add advanced setting to verify mapped files before playing them (default: on) +- Account/HomeUsers: Use new API to determine the PlexPass subscription status of the Plex Home +- Account/HomeUsers: Refresh home users once a week if we've never seen a plex home +- Home/RefreshUsers/UserSelect: Refresh subscription state + + +[-0.7.6-] +- Core: Avoid DNS rebind protection issues for plex.direct - Core: Support ipv6 plex.direct hosts when checking for locality/LAN - Core: Network: Massively speed up local connection checks - Core: Network: Skip local connection checks for plex.tv @@ -25,7 +385,6 @@ - SeekDialog: Autoscroll episode/movie title lines for too long titles - SeekDialog: Hide non-autoskipping marker into the OSD using NAV_BACK/PREVIOUS_MENU - SeekDialog: Apply positive marker endtime offset to manually skipping markers as well (unifying with the autoskip handling), to avoid re-showing the marker occasionally after seeking -- SeekDialog: Fix final credits marker skipping wrongly on manual marker skip - Library: Show current total item count in title - Settings: Add description for Direct Stream @@ -35,7 +394,7 @@ - Fix: transcoding is broken due to deepcopy usage - Add IMDB ID to video info - Fix: Libraries: Missing items when filters applied and collections exist (thanks @bowlingbeeg ) -- Fix: Libraries: Removed most filters from collections view as they don’t work (thanks @bowlingbeeg) +- Fix: Libraries: Removed most filters from collections view as they don't work (thanks @bowlingbeeg) - Fix: Chapters not available in episodes during playback after manually changing watch status - Fix: next episode receives resume state from previously resumed episode when pressing NEXT - Fix: Items with non-existant files get removed from the home hubs when visited @@ -48,9 +407,9 @@ - TV Shows: Allow deleting seasons if possible - TV Shows: Add CONTEXT_MENU handler on seasons, allowing changing watched status and deletion - TV Shows: More accurately show progress bar including in progress episodes -- Player: Don’t use old resume info when going to next video in playlist +- Player: Don't use old resume info when going to next video in playlist - Player: Simplify and optimize stop/end/next logic -- Core: Fall back properly when Kodi version string couldn’t be parsed +- Core: Fall back properly when Kodi version string couldn't be parsed - Core: Correctly reload addon settings on maximize from minimized state (so yes, you can minimize the addon, change addon settings, then maximize it again and the settings will be applied) - Core: Edge-case: Ensure TV background music isn't recognized as audio - Core: Logging: Clean Plex tokens from constructed item for playback dict @@ -58,7 +417,7 @@ - Core: Home: Store last BG on minimize and on home select as well; don't store the same background URL if it hasn't changed - Core: VideoPlayer: Make sure we're the only active player, try to stop all other active players for 5 seconds - Core: Instead of using Action(back) before running addon, navigate to Home and try to guarantee that -- Home: Don’t round robin while loading the next hub pagination chunk +- Home: Don't round robin while loading the next hub pagination chunk - Home: Sections: Increase section select timeout from 300 to 500ms - Home: Fix autoplay from home on episodes (ACTION_PLAYER_PLAY) - Home: Don't fail on empty hub @@ -80,13 +439,13 @@ - SeekDialog: Ignore immediate OK/SELECT on auto-skipping marker with countdown during the first second of the marker shown - SeekDialog: Make sure we only send the correct timeline request on certain actions - SeekDialog: Make sure we send a timeline request on certain actions -- SeekDialog: Remove now unnecessary negative offset on manual marker skip on final credits marker, as we’ve got much more robust PostPlay handling now -- SeekDialog: Avoid showing the final credits marker twice (after it’s been manually skipped already) +- SeekDialog: Remove now unnecessary negative offset on manual marker skip on final credits marker, as we've got much more robust PostPlay handling now +- SeekDialog: Avoid showing the final credits marker twice (after it's been manually skipped already) - SeekDialog: Hide once-manually-skipped markers and move them to the OSD as well - SeekDialog: Don't react to SELECT/ENTER on counting down autoskip marker if marker is only visible in OSD -- SeekDialog: Bingemode: Don’t autoskip the credits of the last available episode of a TV show +- SeekDialog: Bingemode: Don't autoskip the credits of the last available episode of a TV show - Player/SeekDialog: Simplify and harden PostPlay behaviour -- Libraries: Clean up code, improve performance (memory usage, CPU load) and optimize viewing experience by properly chunking the view’s requests based on the view position (thanks @bowlingbeeg) +- Libraries: Clean up code, improve performance (memory usage, CPU load) and optimize viewing experience by properly chunking the view's requests based on the view position (thanks @bowlingbeeg) - Addon Settings: Add setting for Library view chunk size - Settings: Add separate playback setting to skip Post Play in TV shows (separate from binge mode) - Settings: Clarify and reorder playback settings diff --git a/script.plexmod/default.py b/script.plexmod/default.py index 3f0bb5be7e..2d642052bb 100644 --- a/script.plexmod/default.py +++ b/script.plexmod/default.py @@ -1,5 +1,81 @@ +# coding=utf-8 from __future__ import absolute_import -from lib import main +import logging +import tempfile +import sys +from lib.logging import log +# noinspection PyUnresolvedReferences +from lib.kodi_util import translatePath, xbmc, setGlobalProperty, getGlobalProperty +from tendo_singleton import SingleInstance, SingleInstanceException -main.main() + +# tempfile's standard temp dirs won't work on specific OS's (android) +tempfile.tempdir = translatePath("special://temp/") + + +class KodiLogProxyHandler(logging.Handler): + def emit(self, record): + try: + log(self.format(record)) + except: + self.handleError(record) + + +# add custom logger for tendo.singleton, so we can capture its messages +logger = logging.getLogger("tendo.singleton") +logger.addHandler(KodiLogProxyHandler()) +logger.setLevel(logging.DEBUG) + +boot_delay = False +if len(sys.argv) > 1: + boot_delay = int(sys.argv[1]) + +started = False +set_waiting_for_start = False +try: + if getGlobalProperty('running'): + try: + xbmc.executebuiltin('NotifyAll({0},{1},{2})'.format('script.plexmod', 'RESTORE', '{}')) + except: + log('Main: script.plex: Already running, couldn\'t reactivate other instance, exiting.') + else: + if not getGlobalProperty('started'): + if getGlobalProperty('waiting_for_start'): + setGlobalProperty('waiting_for_start', '') + log('Main: script.plex: Currently waiting for start, immediate start was requested.') + sys.exit(0) + + with SingleInstance("pm4k"): + started = True + from lib import main + waited = 0 + if boot_delay: + set_waiting_for_start = True + setGlobalProperty('waiting_for_start', '1') + log('Main: script.plex: Delaying start for {}s.', boot_delay) + while (not main.util.MONITOR.abortRequested() and waited < boot_delay + and getGlobalProperty('waiting_for_start')): + waited += 0.1 + main.util.MONITOR.waitForAbort(0.1) + if waited < boot_delay: + log('Main: script.plex: Forced start before auto-start delay ({:.1f}/{} s).', waited, boot_delay) + setGlobalProperty('waiting_for_start', '') + setGlobalProperty('started', '1') + + main.main() + else: + log('Main: script.plex: Already running, exiting') + +except SingleInstanceException: + pass + +except SystemExit as e: + if e.code not in (-1, 0): + raise + +finally: + if started: + setGlobalProperty('started', '') + if set_waiting_for_start: + setGlobalProperty('waiting_for_start', '') diff --git a/script.plexmod/fanart.jpg b/script.plexmod/fanart.jpg deleted file mode 100644 index 7548349f6a1dd3633c2dc7262c386ec461f361cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71213 zcmeFZcU)7;)-W98AY$VnBGOe91Vlu7KSwDlO@t6SLWD>QEeRcLC`G_RuL_btfFJ}2 z9i=K&h@lfoq(egQ<=c3!=Xjp?p7Y%M$Nlc_{XT~ud)A&cvu5ozGkexvvsQMycZWbf z-%!7<4x*!@1DODSpxu#uZ?9jyYI*aPuKIN?H2?tu?R(`2b#njd5(wl3N4VY6xN^$K z*yI%B80aSuJ%|~^1roJ_y1V>(^QIQ)FVjjV2%rQ45k>cC{bjX(jyQ71#vKX*(VYU& zzd&8w5CD7|fTcYUE_-k+03V0mwYmeq*#LaO4PX#}yZ6eie}iZCVAxl99{_@myBXZN z3Ow6!06qo#4z~UdhTe5^0_sQtb}g5E5huas(kjqCgG@O58!W0Q{A|XwUhz{Y{{iHPFfq1O-~C zf}BB4AgizKL3?8W)B(~TvURtWxcs$jHrc09k3ZfIxBaAdmnIpl$XS&wT)B@Vngp zw$4A~x7!E03fc!uU^=?J>%P786aC(m;isSIf7;KmfB)BiMy3P%8JQUO?>}(p0Mo&} z1VD!m9Xz~uvq$8&ru!J^=@||(?q~d3<=?vOz5}rw_(_)W9z7ikXdeq5Jqz7#Er=JG z`1|(J1FY@I;%lNmcz|i&PmKE+_V9OqrUTLKqyLHi;QqsmM;I9PGk(2gVA;=jfa%!j zUk|c!h|B32d&GP`&UwZ)y702>6(cLu{m0Mqi->F|_-}#nB=(aMQu>D0h{&kd?Hy;Y zx);2cgt|RQJty!YEwB2#s+z$a+j*cT9)N|foP6U07(05p13-^IF#+i7EC3^P`}h6C zbZFmC3_sBW{O<9^z;arA|F4XCR<6g`PMqPtY<>SF>+vhM3?4ksd*9vxo;z^X?S+J- zYW}d)>(r5RSJkR_dqIbR#`{?4SwJeF+_gV?`vLuszz+%hkiZWK{E)y83H*@24+;E` zzz+%hkiZWK{E)y83H*@24+;E`zz+%hkiZWK{E)y83H*@24+;E#SONt!_u!_!drs?a z(0=j~q3hkwgmjG^UYEi?m)!28GkZC^hA))nqZZdg7<4`PRLSEaLe!K1Pma=WM~B#j zX9Vqc@f7qj_Lf`=Sdn?YnZe6MHna#+=GzYY;y=asz#}RqP4~$z2 zybJ0kYfxYPU*7BhZ6RjVGAOO0e>A69HVnDWmGaRpg?REdQf$F*R3j+264K=C+AeRG zUePs*XqZ6P($BlYuW`R#%!sXbn;cN%T-#yFH@vh9BB{yKe?i5ReEyPC7(GU|d&k>k z61)@EyvTigd52qBAdGIT4BG$7O}p0z+5XaHvVcoTYCEhs!PBeIU87|#TWw z&PYvkrH^*AI&F2cQYodvu;P&C(>~Gq?zEP4soQsP0iy4q)Fq!MPdD29>fn%A3sx3f z#W-D|LIt)>qa|naWaIKy^sAE}E0rl#2`H))xsJNYQl?Zz(7{{Rx6b-`nyDdH9CV;i zW;H4QqwC^pzdkWt{<7J^`uJmoyU*4EXED0Kn%b5vqF7HtPxyXvN^9Nik=fW?(ELMg zS6PQOZtZ4X31&CaG`NM`$sBEm4M|1B+X~_Y1mCjU`_l@$fbY+7;eWRa`gtqMk;WXb z#Yx4$-Pg$iu8$K}9X&jvZ9PBYRjoEol&uKVA(wZ*cFb~Mp5<5 zw58g?65^80T3TAQ55_J2|FTy9zx*Eh^Rqq7Om=%c>f~^)-n_8M)I}1ke&P!etdRKe zjJ0)Khc)!j=Y#5di|t5~8@^fg)(8~A<|r`eLM!W6?{!SVib84D(hBt8{su-R!#sTn z2b1Z|(3f3G=h2xdqo;GW1={Nr(!KN{@_tVINlNh=*cB>6E?qsa zz@8CGd$bFacfu2=Fj1yH*x9aRt@NEGURLGh*#SSMcm9)O7KX06eY2IKm<5k2K^NwH zV_$g{=;kL+t<5e1a!HVGGp(^zXw#2SSFoe;vY4^wLM0Dh-u8r|fZudq=?3e)?eJY~CU+J4F>2+bAr%A;Cpwb*KdPKfdq_Tp==3xlXdCT*%1FJrKnU3xbeeZkdC5}K z{nIX}V~^K6k#io^%JFT7OiMOc?rk?>i>pE?yPyfvEug!$Zye{}@RT3sy4DpK*6+vo z&VQ6+Waq-pYiEGg3uRrG9m|EUY@bu)b_qqltgf8hc{sWYD!JPDt=4ny-xw!u0$jm= z9>12%MsQvW*bIx=8D*mIivC9Hr3AoNz;A4Qc5$d?HfuYWP_$Kc1gHgxRy5zfGDtBA zIP07Ij$bz(U_JnLeyHscQ)~oHe}Dk&##Cv`%}9I7#fxE37Q$L*%Et)7xvwJ3Wwe>)w)!450oaqb2X;Yk^4AbMAMJ)}9uCN_-5kgr?KZ1gJ+I3# zAF#|75N5X(yAS}{JQq`gS#ifapfaD4N@iWPQ;CfWpx#WDq%coO?}9jq>%6){e0TOJ zwIWL{WhL_&;ua9psdrg@l#Sn(D`EGS`#gtFTp$yadrW z+mphXP0|lf_m~N=v)-@OXe79a6vE@tu~`0e^(x^wY;u>-{iTRHPh~NvPhq7=pPuUa zXNaA-0ZCW3F*CMJ6eB7q1Z7>r&Nd+&7KTnxd*Hg|Sd^yi<=L0- z7KZy#0`v_msf~p=Hxypwb+_WmdZ-Rq>!C-?HuvT;P!=?Y?M))7! zcJD5hHubeyn#qnxyWhLWTrAU1ZgfiDSxj+0WVfP$D$!x&i?&kqRIGfe_Ebqm6ylAn zaudSFmkmfmaiOGNBtyOp%irhw1}mB(o~5~_Bn}p=zm?efC$;ImlwX zq{S{(5ea@+*L56B8bOmb3w1+vPrS~~p}{qMeN|?0f*xE;0~ViVPyvsU#O0)kce>un z#`7D8`3y|iVWC(=R-Mud=IHO9hR%M6GWcN~+KKYoD8B8q=aBg|F-ZHQ(nKwGK~Yd1$9!o4C>Rq4Mq9L*4iOjQ!*8DEd=Ckn7--N5HLLe;ESG=~m07 zofjR7Z3hK(E4IUN_7yRf6O>EtW<+(FLlAHun_UlBS!jBKbezP4sChJU;oxL#tXg{g ze4*Z(ZId(-Rsl2rl#&qj-qoR=DcG1i&W-z`%Gbg3oL0_?KMtSJ9cFv+>dOVi$nf;nt$lB94qhmV_T2pU8jny;N zk&%(=_}n;i)3fpYNF)lIg_4QP<5Uj<=W~^`Yps`#f=$y|T11bp@JmGU%crMGCHXdv zTb)(Mr_v`$PRn1Bay%QiBENMsQY7RK%f&?D!9b3;U}|`8pnM)d)gk-_~@!H&_3qG$Bn zB^&x<34!lT=eM#5*wiFMa+n0zeZlV8EuWyI9hyXl)B3C>i|Lm(Z1YN*Bfe}M?HZb7 z9ao0ROb$HW+;(N)_|o0fpeb~S5L!N!ZvL0=`u!VFbhE#B{h$oTddsG60=>$+e_EBX z+LfV(ommm$cy6HERj9-%q3`KqDxL$?VI!SqV1k3{tlK*TV_QDV;DXT^GqL-Vy&igS zmHMp;!<Ew)qm>Jn{VZR%6Vhn2lNG(1{iy>cb=g0`T0-C z?{4Tm_cG5PRoK>{O06SY42j$YF!>_@-A<> zzUV#*fsl7WWfcV{3YF@%(Naltt^CIA2j6I`BB#d;&Za7WNoP#>uXVNJ5YpFG?Ksy- zd0giRI(ez3>2d8+EWJ4#9o&;)Fg16@c1=}O)(ynd7er3gE3Db6(frri4W{IXI?r?- z+_39l(+WP1xz_1>_o(a)o-SduYay|V!GSfft_RmD$n4(_QR_ph))|1c>Z4R^o3(Tk z(VZRj9irzG(Mi@&&)D$;UD_uiTcp%oMOha`hN>VS1-{$RAmGBa-U)_&*m>MS&wI$$NZOMt}*uYOPEpFwy;R12{ zU%mT|z~6v$&g9XC4|>IIt0p1Q<`97SY z-(ftL2QF?VR5l(hXq>zY(s}-iq*(bt7md%Y&nu2f@abbpaBS_k(;Zhc)^oxqroVb* zF2-7FqQB7X3>J1hI1Gvt5RiYvckdg+`$*djRnHe1vS${TUEcNH{Z@X^aaE0MQn3s2 zmmK!bsir^p%QwvTIo+f$`*v{xW;y1$pVe*lyzg;;f_b!G0frDt)o1F?n+Nyb?ctc- z#+K{QvpH}*tnIR0j-SNs*;J(T40Q4gfK8@$d8!VfXQxUufU$132J0KN12cE@Qvd2j zf3Zvb#_)^v63X>`NjW{;X$%FOQb7rYlUvEcXOzcgC7avsK(t+X^p2=ZGCrCbc7)sI zNBnA+WayWK*dE+;i~ca@@w3LyR(eux>1j7My|J5v$&L?F70izzP@f|;?BgF5)IVQ* zt-xf5snfyQ_g`npo;(0P-*(FcY8-S0@#sZ64;Bk-d+op`r}F_=w)(y3oSrbEp04H4 zBjKK~4n5A+N*ko(S#**O>m6Wo#7dmGVb=-P$v>Bx1hc#>amGZbLuxTIj#s3i>wp|P zN5A5jX<>z0g4_zL8LH710@Zy8%|Lrgk{~u^&vQz*{J@BUICKnh=;)<#7YK{-AXF|t ztEB)lt*5X(cpzmf+ITg0a#Zv~!}; z19J>f&!Y@l^?CG}+srb)4JsYErzNqisOqi@mtcO6GXJIKMJ=an0rQxlnU<#RgjJCc z(caY9X>2JLD-;x75_iw6>4mN+_mik9x;~lWW<%y97Jar$^&aIhneQ7w>QtRcqCD zsmqU+&|;}ix9d-QZW*u@h$|uAO_{rgxo8#9Fn)4#9p?~U5mINJ3-)0Rt~HORnwJ3F0j6YgoKj&=gS>W z`|~Ysy=lhi0i>>>$dQh?&bqdj3)pyp0e9j(EJmVL-`8j%eUN=sW`y0=uI^4;R9}>1 zbpNO%*upru2kkvJ;Lh1wp{0eGfutiGavM|aaIfl5{ex?Utj&l3{?Q2Ip7E*S`vpJ@ z&2Q;=4>h#B&}V1Mu6o<_(f;H2z9GKP={wfMHeF?Or^U`}RKF9m{vP)ySU%y`ozo2g znFHI`8R+kQMR~XFSJWNf5}2+d!m#I@L)Kus#|2={C5ZNj&JP55S9OHil#b-2RK%*Yi= zZdRVo#PrYOEZGx*`dFciaME?1=PyhEMVP5mPm|@%T`UsVlliY8j@8<6UWt2tPIBdn z#H;9#09D~Q?oZqk7~SNXam_8+%HD}bd=IfWhaKs&0R{}5Eif?rcBM2U7aMwVGEBbI zQh?+>PSfw|z?xqDq`^~%Xge|}+$n*rhh=$ZZ<7m^l8?Iud9Ge7SBSEZdW*T(ney0FLtu;{Qj13R2z~U%QR&Toiund60KqFOUs>3Ah&Lt-SC4JAOu zvly6$N`iL|pH%&>r@saNB^7p$0xz;o<6y!g3dD82>uCRV>LO!7nMiWa#K>D&ECSc^ zq3d-J-Yq4{cA2$HyHP+G?c+U0cZ-TLdoI)0DCR3k4vlTe7`WJBJ&mz0njY%ama>xy zV5C^5ymVk!6PI8mX;0b3PY^YuXCEKF_Z!EDAgjDP8cn=-d>g5T-tN_Jr67gqQj(BpmGa2h- zt#Z&|7qmrM^|7dGuVNXM2(%EM#cz$JbSiC!g}1Y2H(6LzzX+Nlf%RjfV>^_Q?r+59 zuiSuM3;HGKqg3(q)C}0*WxhT1+7*PlhkL4m!Dm&NP!6&CQR_{e%)4R0Hij*-I>(Yd zJ*En1rD+Di=fg=7881S7d?%WN?ZWug^s~be8WzABdx?nD?**DYoxT{|?dad)On(P2 z8rXLsxz#Fi{3KVgViSYERO)sppnA5eC~DzK2AyS*)YfH>toH?YtS}lHSv!6#up%&O zsyd6y#2uZ{2*sVV+>tN7-U~lm9N0q8jQ5yc2P1VPY~3{rc0sen2d9!(4cbB+FxLr| z8wfDQptfy7jBehqD@+#Ex(k9uns^sQZktd75F4LYwA_OoWLSoxi;oJK_vS*pVYs-y zK`vcKMZ5mQZ(D*A`=iQ}1WbLvF$Jz_>gYml;4E)143)oi7|bd?x71o_UTaRoB^WyC zyUij|dhpC?hMqOCVHsrk;kmLrUm>b9Jvm=A>|@SQ_8_)j-<`|f)}hv#I!PLIw!n_| zE=^6ECCL}u^S<}pOgM6N)uf!b3#z#KXjAbh{N>%vdNS<^om=9@7$-Hxts*W2J+Of( ziqAu;8QJ@;OxCWUg%~W}eMjMM!4un5Gv7e2r(0v&n3nq~Lw{XanLYR-*Q$73{gQ1F1039nV!bO|5jxP>LxSCqxWFT&aigv$Xret7-;tV7ps|=yqNOGywErK9>3>fv z1%YTYrM0cObz-(qAJ`szyw)RGIy&v)kNsI{fs~+vEtpVG&x<4i|7WDX4=02p{ zMa%26sJNPGK{ST4w2^3Z)I8y^sY|k)c?S}oBHxNDg)N6+iX?ii@MaR>J+AxNwMUdZ zJBs&oyWyEg{gEfyNdtkR;@PkDSu3xf53@N~WFuATqc{aa$&E!Fe0Ck4ax9J%+rbK` zsg(%ffk%<`&u}ogWBNMJYA4PG%>+tadlBM$^XY^Du((P5k*dv;2U;JP2t~*kh*-nU zYpN;X*ME*{4*J-5#ugFiE{Df+$)&km4WuYM@l|KF&EIq{DihOg_HVT8IFq%EfL0ET z1tfUKTl3eYH##-9K9}FHRP%L*Fu3wanSysr`h=bMflYo;wQbWjV^HuWDg(4 zwZ@Ni$!B8YVzHMa55N6w=I;AY(J(H&HgIBWk=LedxTp1T`z)1n%(yJ{WSNQ>!*ilV zOkN(a7kDNVAna23yzs27l7r9S{ol=d#(LKyRTVvRCB?H@BmBN`%W}3&GjNRn$yV1W zB#4DHfssTlWb?k4{qJSF$j+Bq#Zbgh?I{b~Q}}1wC`im`(uM;e z%4TIpot?pXo6FEHHOZPE1G!PM4*tx{{#~bk51Ou)xGo%rODra=q)6`%xcAq!>G?`x z-Dv%}5;#^o^`y+lKy-^ysWLmB>ngk!67&IYiXfd3k1m{_?1*o#|rJa|=l`u}4F(8L>cG zEU4}XnaL3dp$LTu$fxHcNZN=xgI3pzEiAog4}N1!xKub9W=BqBMFAo@T3OV0s14@ z%lj?D!O7d=yuxC&TFtwlD0B{N{f1Ss68-#m*xcaHgZ4|E;z@~Z9r%rkCD=}XWp=sd z8)feGC|bQV%b1C7QV+zEytUc8=BUv8?yKxMARn`$$3DBOQSdfv$m*Wjo*pyNfa=Yf zmbrQHIqv8>#Og#y<=AX5HjNqXy@Xqq(n8o}uq$_OKko?}bPR{QO<;X)m0zB4wkdn) zaw4A5{yhFsjWI#H%+QI*W6-XBoT#O7N0ol*x9)x$Z%9lT>)7ip+up?7sG@P{i1d3O z;Z}oR#Swang)7HWBpkl54(MkTVfJudAC=YT<)25NFe8D)b%rT~tuvl7xS7~#pUGJu>rb?sjrVN`lvOh~VKbH{< zwg?7{Rp#5a-p5rLp!dEKHK{6IT~Ib!PD=L2o#fK~))Ad{@5IbC`Ky&#p>EO z#Gi5{u?M>#0xM!Ce?ct!!oHPLf5LuuL!Vi|H^S|)ku>=E*-hDhAm|D#G`DPbLA)#S zm24jO#Rszz!URw7h^eF>X+tX((c=cJ!HDTUfs z6M>@v;A1Li*6``_Idsx#vql{Q{p@Mwb3S>OqeFZU>Nde0mo>HJuVf~UCg%H6*F3J~ zajg!Zyh?c}qXv}A=C7KjtD#OvL}u_bdX!ZK>ISGLlUY=Ibli-atg^WOJ8@I)E8~!d zb~XlJ-C3oVoPZAaaej~r@l_u;?XnstJ+{+ZO3k3n{PH&Y@I`^*c@!NKuwLS%FiBDxIa;f_6b_w^ zPDSX!^4r~E9-2;*z220_hJYPjw;A}Qy`eb}j70=>{tEXW!$&=N`0)M(-cDx`nDU_t zo~iaHZPKk`y&XHIk0-Q-@;`Rr;tJuT;C{6C$ns`EYo6Mv?u_q-{jmF3ZZo^p`kgto zB5ngG=lAn+;q*sN@`QhM?kBF9%2%=J2iACw*d|$L5hSP4EeVAh-4CM5+Q=6Dv>4Cz zl~tLf0?((EyDJGYwYG6ohtMq3*mCpDD6=xR+!`=aYm!H=oB92B9sWJ|FB?h#GN+pJ z`^)5;@;H=T@8LtLt+TseY=O1Cq0ux`;M6Ju8($cb85Mh5=-eiWJ(Q`jR6szblI%1)ms6|rVP3aHF~QgL9Qe4pe49`6 z9E;_R?4y^1g37FOcQ`R7w$}0nBsEJ!d!^9u^xz?iVXf%%)Uxo*=qG&^z{3^bBDVICs!s={ib#nZQ1Kg9=41uecdn5s4k{{SxG zOb5<0Sb&wRo{t4|%XXd&1A(9pNqzZnL(1MJrlu4!^>x?6-ny=)l#I2^Z;g8X94;)wqCgs0(Ud6~w|d(peo_G?I_-Y>onO?JAjBL@ zd^14c2@n=W^RH`Lw0+9uTNjGhs$R8#m^Rny_~==D?&@KkBK1VJVJFJnYsj)Sm99|U z=q96;%yHdmz9-TV2_17k?@a^8#S*tsb6wtkc<*56(u(`ALViD$pE-Uk(%MP2rv)D# zNxJ{88B8)~0kZ~`>6#%f5Y_b3Cm7!DHU5_940xxm#y^^$tRHQ82gl#tVJQ=BwRYt& zG_~NQ7P&i)8>R7tPfg+C?NcwUU~ux%S-7~4rH4kRz7hD}a{|qc^5uL#Y+Pnm+41o1 z?+xg1%BOrX;f7|C&TS5B-ee0EPs!P%wN3&OXIm+B`7GYG)^EG8c#n#%!8DBSjo=PM z*loVk^Y2TPc0t!@G82maTg>4{KGHTcysCbstPc6Qz;y#U6k0Zz`KstC58Zrro|BzF zd2X-qadW*KTnbBU*s1?nqDpo!#eaLAtwkthf!SX?K74t5rX(0C(zqQ|G002^A z1D-LGy-kETqO=E#Fm7IfM*Uz^&a~T(S_pO^+lI&7ot*VlncsK{9SSMf6k;%W zw@2bcE>&qOB3cOsOUZh?pZLpO*HoMgYYtV-)()s- zmxoRt0#yWkLo)}Ds05T%4qLkP8P~#>aTL)Ra@`k?MMr9R)uF-Mdd?Ol;f)i^;YlW* zX*V6JC;@KBofNXhC;KXI#`>Kv)7vWL5wA%8OUz;0AG`-P8D(U!^RN^?U%K|{-glR>hmSeT=M<-suKBKkS>jX zLdvp&{{NPKrfmnhFoM}|aB#J88zF*N_5>G#?DkHTinrz8S!4TsEa;+qGuJ*Pv#$>7 z)H$J@$VFm~7yD{#k>6n}$5p7-H}? zzCWPOY)@?u>I8%Hh0gEUzxJ8%X8~5HlHj}Hxk*Ox{hn#f*i7ybsU$#;`K)1q9n(vG z0~{oE;%o%v`3p@XK1YYZwAq^T$|s`v^Vz78voEfN@m~X!ndIx|)9^dOXm_=VV~K*9Br`VnDvTsv9XFKR5Ha2bIhj!g%Y7&>naJdc z+rTepkq5$OQ54^@`VWNbWul3-wwr1NJ(YYS9~R2bDTx%9gEu4l02}Zk39QHCXMVf% zi7?!fi@8bg0nf8xn2qw0;O05mfG4xj$R}yK!;VwilC8j(W35&@>+xPfu9-33K5qKn z9hYw_1jvt|RN%q8^< zkag25nCl_-3~Fdwm~mWJ0pGjtX#FqXUwu8l$(0=xVLql@hKiXM8LI#El?>}>Pq5W8@#E zQny`PTkrEA!F3npp)E^ZHxCJzvnQxL;xZeODbwoac~g6PMI;u(95pjK4fx}=lni_} zs~yUWo0=py(IDVWgNAVXLe#Q;F1UFA*qYr)&10%K!5Qk4DCUeg)#sO7A+AMPxPX)q zsQVb^L)vstZ&vCKFCn1f9m2dP?|Gm6LkwFy6V$;wG9SydUk{v^%a0ddKl=HLXL*{! zd&o$wmAJG$-n$?0WY;s-TmMxZe$f-zi(@H%)wgr9sKY*2yxTmd;Z9c`tA@I`q)`R< z#QgDw#fzpP7xj0-T$ttedijsMHV+$(-~aM>M2w{Dw5|Fe>X$zr=YK#)Di^#dIv(q# z9Q`Qr7}4DUCBdY2;^JUQPIJSBu=50uHZZDE8#~@2Jrx&+HF@5#y5IBRiTS9`lwY0Y zM+>DBno(*Ng(}|CK|X^Z*W)9x0nM{hOGSEZllqN*eY#~iaYd9Jv6EPfKrRe{(?1ZY z$&?YE1Gs10P`n11#-Mcv?Ew`h;4`)5V=^zJTG{1# zw)~9D%vo4Jm9TWF^$J+a8%_gfhw){0*tl8$=R-yVH9>Pe+&4xcfiMT%K%OL5rGi#h z@kXm`!e$uda3usqc#2JROCc)=diuVM^1ThB_t|cMi7@r%;9BI~IETUn+_u8U_|Fcg zJq72!4B(P%DM#68>4uBy84Tx;x>(JdHA1rVPQCs9+nl+jcRQyi=U$H%5x&x;RAb{M ztr=t4FxC?-J);L>dW?r>#W4o3zN6qT8u+v7I9MQ+B zhWyAjvca)yCp4`~%bHsxR%FD$V9(I!UFjZJj76B_!{hJ%$9(#mTZSs17{1f$6cxED zyT#kE-_?$THx|Pd-p=z+6YTu+D-Q#|=lEOl4qz&`nU{My zH>I{(Rt!AF2i2Q}$ctMz#2{QemS$2mW!?#=)R;|=Kl^-lujzlrbZ6b5$b43Y#Xob= zdFt$O?C(7OAAnyjbKiWQGPg&?bK1+>^Ge+Q+M%IQM%c^{aYI{q8Ak{vJY*t1Gex?z z!A!N-|I|CGuf`*j;nj@Rc*=!!q9QiD7Y5-EwDw3m1Dxjgcdv3V!o#A zwfm>slxXl>5D)u8IgLSkQ_rA5r^R0++JRVS&ITM%@Os<4jvZt6dnfMT5IA)i*Xl+K z2W!~qWuv46j?`Z4POlCnJz6hp817>2V|`OuAJoCENZmYEi@K8e88Fh-dOgRg764~k zHu`eGPW4sk<|a&FCQ)LKN)%J4QCzzc3n@3rto4n$j=`Q`&+y9(;27z<5U8KUn*Al3 z-?)QKLh1S$sXfDngj}PE&~#UGE(%Z_rtV$WR(giJqp2pp^(ogix7CMxzxq1CRF`eD z;A3h9y1V%}vB1bzsVXMcMzWbCBcFyVS8M_Af`(gKtDb8~3%*i*2K}k7{8zu+PZomh z&9mCM5F~nVD#Uxt!nuR_=+?$0<?Dtc_PNWPpmbTsC zAr`anxqqcYyCR*u|HRWKPr@9*--3}J{be`qW`qP=-`<}@E z0{^?qn6B@`V)L}EL?Um8W2b9K(;{~jn=|XZh9OrrsQ;rv{Yq0yY;eU{PfeX|w*OR$s$xEu(@(y9Dq~6Kyjm(Bc7cSyt>QAbTk2#PS9Jy_FVfOF z!`lw!O>Fbd^M&SCT_R+)_qHat_*Rgd24fuHOB!ZZ_3V>)r(VQ%-UK#X>=baZl+OcB zru7Z00mtJju=B_I!pY=1ceyJP+34_$cJQqinuux6)ACp3rZ4YpzIr!q@E0;AzG~Cz z&;vZSBJ~01$}@6$y3P~ouSJjV#DOIegRLdQSmGKPxr!Z5_OT7;848uykFu&YA&DL6 zQd`N`*c9#?;^qcmHhnowRu%&r(F5+Vp&P)n`l?x!<$Kv6W-fMtJ^1no)^QV7uyj@* zdWrEuuwMIOA8ydB?fS-%PrD#KVgt7ni)Ypr>9IjClCKA;Ocx8i5L1ZZv0@LOt2}AssyX0a>6GIQWeZNgWLe z^RLe~chxzQt5oVj77BUA<^A0t(T#E2%v+X{8D($x=?JejMI^`_t-sSHPMB#o0}h{k z0Ou1;lV$C`E-b-5%)1oAZ_aPbARtQ^dE#wm=PFoacFQ?Ma?P-PHW}%`7dD~QQm!PC zF8#K%a5@w?;)au0delm9^SXW4dss?QmZ<_47IEvKs^%OyfEdB6ZE#YVC*wa|v+iL^5^)hlLqoe?^ilxE-jA zu^x;H%ymUng@Hun&!duE@iqwZBq?f4ddz8L4yhY%J22&d29zHIgh)_FF=OGqZ@t!C z^x}G%SId6B^^}Z<1y_|>VcAnS@=@XOX{nLRt>HHIfOY%^+)5~D>+(UPy+;2Lr;z;@ z+}|x+b!DGQk={xD^~S4j-2I<9_iR6|rMt|&1emRWbAOV6VB0Y*b>r)Jlv$SSXF^@_ zi0GFxt9Z4Rq8<^{TdysM0b;(WAQm6Cr6h~CuG$`D(|OKzt0O$h^P;CF&$?!X%4iNA z8)54o#XCE>Vk@7XXU0}*p;V)I$hft)?M4|i%3{Z_a_m++PwqvJvjz3f(66Ofx)x6> zFlB_D)}qSo82|+doVqOsr=t1IZ>c)S3n%p?ofc*34ZH?8P}u`2G|Uio?c<)m6q_b% zslCvwK@DK= z@~y`L=bCaky;3{O%}zw6sd0$q6=VXk)^no7Fv(lXLz#}EFureIH2fSihc_o(#iZ5m zE{#}?=?(faEc=8Zufe5}O4{fnDuLZnI(*nV`(_{YR&+bz9Lg%nKEg+PTCc~Nzqj?| znr8tgbWX+FV_KA4N#Z2&H}!9~1#0FGp+#KsE6qjbW@d##GO=>C^{(3sGzYaYniGP6 zt?vZR{%r*mtYUp1tlx&Nzn-6c;du1(sEorveSJ&$F33x^I5_0u?VSGb<$IGFA?4ui zP!rWUJ?AQj?wU+zx@%&U*gG59LmY9}Gns~tbEB`ws}dUX1P2#sURRLxsmh2E^e4-W*vk=XPl zMsOj5cnu>8@5$166urZfK0ApVHa`;zDQhXY)E1f$_f9;)_YiC9GAvs?O2b^D+<%}% zhEmp2-eW#7qpn}B{kUb8lK*s?-kBq2WOfZ_f{TsqR33wx3&c$a2M13-el!9(L}v3V zC?RLgIb8r|b$IvAQnG6n>>?rS&@4IBhZB#^Xg#-CP+#cVDxK4nPS~^M1KaAg7yX{E znUai>PAl=AyVZPm9Ed?sM<%}P!{7mX7jV$M=RtV|A@^p_M=WH|MUv$l3kfTA4LGV( zxe@pITG*8vLNl{b`f?wlLy%K5>af%2fUqBtxDO7jDFI@>@UG#xa$C5wt(Y}lQ_85R zXi&6iZqbc;F*x4IDlf8K%K?mNCfZg=#i5;a;`I!QvbGeKo-CXoR=1v!(d+dOGRi=J66e-j}_)B!(9IJWAJZtaWAihqZFImjv8(;I$hkJ zTg#SeDQK~FGw-+Y7!h96arF)~7Y@<-q|&diD|BRzz4(CAiVPC=#F_Lkvh#x@JHmW9s*v{%`PKh3qk$^QvDr z@_fGBS5ReaxnKI;?}QFN9M!CC<$u@;EsGx!NOT;Yi`zdil+g-T^A1>n3*|o ztGwm6hRQzt-s*f$^AoGgftX7zoA3ov2DUG#Iw0>?=JD`w^8|7(Yo2H5^0HCA zZe!WQPG5t8Xf#r#z63xLSC^r^RLI%C7+U5O~Xn0^5Si0+ew_lSYyEb z>iC`=s53ces;d=PD0d=(pn@!{QPPV(%=LDI=?iCrIuX{0uLdP-5vv}jM(d*qIUsZZ zi&p)t-+M1Q-siO0$9%v>tmdAXZ+29W<$hgH^Q9Pj0;;YTZd{@p9zPiyi&eG@GWDo1 z?WY|#?FLJB0r5Q~uG-phR-QcJ*$dgTGgy4V)5+L9m&v!SJTh$$22rzfeHv1F>NZb^ z%n8Gpo1yc3HY`2bt_x}7vGcW6*Gk1HSyg;46-let2x-lQ7;JIah;oiaq4I_Y+N7s; zjSWo~0=8NbG!g9Crr2$HRc=q<%KsRJqcRuu>_cz^I3aYrtvxogAZD?A6pE+}EN% zPjWqU@{|a2C?m2;v#oc!&um+4pi&Tvj+ld#70(^^6Zl=wu_Tdja^)0Z3;ObuQ-edB zFbX2ip9@A_n=y%CZw6ePWZZ#e0WnCIzvAH9i+dw@=W|2IacXk|pllZUHcnZ40AX_u zQVlAF-oUm@;iaHxeQy)x1R}3X5j0 zxOZek;!=lhRqj)jn3V1>^ zyf4ed0Sz_63Kj_nnp?g(A>9c{;B?By0{S8#d!yK-J?~J?VRN<~h$MtV%TB24%(qDf zqBrCr2}*Gc`8?@U0oeY00!=8<7H}B3G>Kw-gL{^wf zbmSk*{GGtR1pJlD)A6Wru2HKIjV^e{wvF$}-tUN&te$E~uPF3QSo3KSBS}aT{Gg1i zkOXGb7_Z8(JzdPZZ*_%A1~`Ux=vxT^MF?Vg!J0yR!2D<|a3Z<=uKG4m=|AIzAr4Ju ze8Ck|Ww1_IK6ViNjhTO%D-Fivp7d(iuXy#gGu1uo7hG0 zH0du)&L#7duMyYS=TfEKl?cIK zrH-$N#L2iDo=pvJTgysPea`c&wpB~31c)NV!UQB5Iqcp=Z;i`0+V_(?C{lH|om!e- z%r=%%jlxTF{5jGZShjj%=Wq7Y<|aGD+Nka|>{Hw4BDD=ARBlA1Yxr>yXU4g1&L=-x zLph52!mM-?45L=Sjky&CE35fxh0J2V4~OsAsz>fyuHXT9yK{8tG7j>B)3t2FCcI_UA#-;jXM6)LH$J)3dMOn+BK)h3^LmgP&2&f>-@gRQlP>; zokLyM);3Y#m}FcK_WU}sMG0(Pf~rt9693(F|9j7W3;bJWhF>W$G;Ag+bcwlX_w#r_ zanc@qTE6Y^6l;~?pAQdw>xxdBIx)^MM@4aMSB&*)u~qGY_Cp?~?Sgs_p9SjtMr#x_D7tp=@QKtHqH?TIf;!vb!wrg87hX?yF)0?#PY1z4&n zV(qm7wc02QrV6{ZXZXXi0v3VOhSi#gwaC^H;QfAZ@BO}rjr% znsucMpv6j+jKN*Vf=+%D*tEWaF0C(ND(U0zu|P){J*@kQl#5Mnm4*t5y}F}$h+%xo ztYtNMI`y-b`8yk=ow7VysIDLFBUIh269oq4zWS$w`Im+N{^tVdqSps@8|N7h0W$AG zq8i|i?{ixeni^m3t|PqMucbR0nx_)UaqnA?`(m~>@f*?!iOxTlgq5aRch1ernnT;H z2g+D?L0q?MF98+*`)_~HcG9E1q>O>+UK^kH-M%AK%Y-k*o1V>O9JUB7sSgQwa}EP> z(t=oPTS23krhsB|SIwyOjzx_?n4K2UKvy<}rn?<8kb9y_vrc+NBFX>=rgywR|6Yd8 zRJ2}}phBuJJqDFo8Le{Ca0O5*^=;oo5q{m8+^}N#ju;JJ=&uwVlH1JU&?_?@hTa;F}D3bJi zT3e$#GwDOeF(U7Ih~bP*Fc6`rbv9Lgd6C~BIHw`lfV%f}0Wo|4te2bdK$r&(7W)G5 zI%y8Ri^-k4Qqj_(uah6Be}D>@*TFj34wqkqAg5#1VFI>p9o(emFZFFk!y6R5* zG&fHV)u3H5%$~F(>ze0VJKIcrph?O*<`pxPU^LbmYb!~_T5SlivZ=dtbuFLzZT>Jm zap$JI^x!Tjmh02Guo`1tR#fC68t-O?&Z^*CbnKvgsJ=ZhyK`%X*nvIcePX0^OcF4U z@@&uuUfkE6W9(MfE04S`iJw*O8uxrkRA>NP9m=b`OK=%z<&hBN1W^^KuPq7ucET^p zdzPVpBmI>p>%JG|6yI#cYa9O$byptO)U~a#wpz7l5di^_7Ah!+8kxh?DuXCPF@!J$ zDik7NCM03T)`1zSG6n(_G(Z9YWC$S)3IUWMG{huK36sna=1B(M!TWA+-@Ui5_x{n} zea}B+=j5E7ea>F{>@|GrTXTKRMJ0Eozy7t)gE}^3XPSAY#x%KRI@TjMorBDnjZQjw z(e0&RLa?yfXfs1O6cJ4rrwf+Pyz-$(8XWqeJc`u3;r&YQFLV?@SD&2TeCCZ$7)Gg# z9P#!`0|$k*hwE5|9`M+KYVoKq=Rddcb8yIj8q>YKF{L`@M(D8kGw^e9T0M!3b#*i71O*-r0a;`_ zbhqv|k@TBoWAnE=6VY~C&h|-lso8H#&hwgn+=!yvJ~b+Or)-u>W)SNJwp4vBnrE~! zPq0DfZKE`2pcZH9YR?h#IX=CSSr7e9FY{3z#jB&zP`mcVky z)DB}Q;`F9%)_IQ;UCxQOrwNfCv-HBfm);8ZnFXopaNR0GXIBWJ zx{@4Jkgu%YIuHiaFHJJ>0B@;Bt_?Qmw^B8wJVYd`yvx0AJC zv=$S!x(**pkraliGRdpReai&tJ>wHF(BSB!fSV9_kmE!>?Y2l2t%=`B{HmGnd((xg zrMN#gb7vy7a9%?TCvT)@!KZ6&=B&(swA5uovmfvEzv%1m8T963DRzkspEAnBEcAg0 z3_2S>Q|U-@ZnwU>2;Aa--sJ>5QcdC4M-uG@^=A+dghvsgD33MGgJR!f7sa+~BOqqY zYD{v25=~T%X|PpOyzx%`hD8W!$ny9|y$+Q%sWQd9}6AC}-Hlk@HN zjAgUwd(%J$ue-kMEfqk@mDXh|OLaW6edaw&b==CiH7B!#H^?}IQ$kx9)C!i3E6gB7 zV0D^wO`;dFb#BEDAltgzinf#zh=g!l9vJc5S^P{CZ}CO~)*)!wGpUK_TBT?cApr8e zE}M_eCLZ)!i&(!QoKP;dqRt_qH;5G2yS<&XbHllyR+(PyD={Q~va+RUcFt9o%F=EJvlj=XgPm*51;5C#YghKn&so(r44zTR!xSulEG|z@hakrx;C zZRdS8eM1FTX>ljGGV8}8hz4_#@g~cDRm3U!6ljoCX0~c`IK-vQHY-A5TvIZdJU7Gc z!~*^+B(a8o#t{%?cSMQZ#~=FM>;GT;_j`HlH(^=6DN!-9aN3R4lm*w@f9tNa)gSdj zTp3Yi;2WGY$2V1T>>4S4)N>@QV1{%EIi`s^We(n$BCm>{XIZ1^!zHXf;iX@%Zguj} z8LX_%w$<6@-y3xmj@)09HO+7iL0BZJirk|(9H&4JrswvUlA#kLqU`OBH5J!t=?>m5wHkOt>gi%*0#$Mr^B}LzKuZjUMz;79b1f zW&!6W#B2=Ie~fapfq$ueP9pPA8&T1KuR~DFZhoNUI&$pRM&3a7)%v-?LGCA6!(eP_ zC07*nNp${OUef?eFiBR(X%Z1Lv2I!>#Ri4E7iz2?tC9>&0>^X*LoJy^9i@a&4ZgJY zy%B7f%dnB46`8k??XTCpA{|bq>S#-j16bdN&k9L_H%$^n@b@@d&<}wU_!S4Mku;c^yY(*>z;udKj9@4`IZ)K5xy^;MkdR)P7u^>MgqlmFl{ge{NcjAv}pYI{mDVH3JBG$Hz*+*(9 zzqBJnF3RbA1Ko2U|4BPklE{OyxH21Q375DkQi3w&0~1OoNdHn`WDM=gUF2B9EI>{A z_TZxC_XeGgl${5I+jn*qW}`Mq0Q|ZXKqmeqOXvOcUPwJ)a7{XLY5zv%bJ=mS!)}xB z?$?o`n5*0D_Q)P@0Kj-`#OGBcj_SK5+_1TC+r0PKGEC*Y&@IY)p)U;nZ~xLK=&h>l zJf*hk2LncuHg-`>Mxm0Ko&Hf}<|5YH7rK(JC47_j%U`GVzyI#bJe3wSnJ9%F+-b(% z&B7MP^%ucudTXnlDr3~FDWfbCXQ-NEf{J5~#0HoUNVzC7MY*$`|Dx6{Fkh#$Pa%*` z)0@t(@>nh0VoJT4-~NPdb#Fvgy(+7yIC6vC7QSU!6RhcM61P+lQJlT5qp%l8vSt)K z&6|B9*<*>+bq3=o#|=F}ho>I`4!i(PVKmsQ>VL7fiHk(C>1E61{atJpSpZ2 zXdh3UxsI>ma}JO)?XX9%H!^%WjZlCI?5*y40Rl~5oI!FF6fIINA8!4-S@`3R|E>>v z|19=UwaTLZ)w+%(zpWp6Yqu(;?J9!W{CbVeQ|+c4X^yJ^o9vW1Es!M&$111i#(EHm z1f0wF;&X3b}LM6mU+R|n%U*t~C? zlwt&C8I^Vp{dx~JGqmqU-1*!^tC|SWrFg~#+a7!peWJIL1YL#1b(A#MoF&T(Cd+>$ zRCAjx6nD-Yc(ixzpW+z&bx{A^I6RK^eJ|u?G2C#xJaU`&)9s$WKVx6*1&dSYRTFL=AUP4pl}HqzCc35g#qS;}tCb!U+& zF&X(P1tlQ`vq{e^-ThCKz6+9#uJwPgeZS(JgNkBbev0$cwVBQg%&6&hk|>YY%^cm1 zW|wBa2?7wdKsx-^S?ITWAJC9e+#r&8FLe}(K9ma{5o4civ)4r;ZUSoT-kKbk$^ zwsK`}oo$?!l&?AF`G5@Q#H~^rLZo1}m%yvek%3DRBcPBkmcID=+5V%?|E@PgQn~$c z^1PJpFY5`uu0gkXiE_1R!f^!7FWww)Bg|z-Tt>IMuZx0$GWA4DlH&l`(P}SP#;Vd%&5)=jX0h|fjm=h~;)O)_LP7== z+Ez&TPW9}s_i*YWyfUiXNnQklQ(>C1;b`_VHM()Rs@_kBO_tq8I6-g6HS72amol2?7f2ivux@Fam4AdFx*s&o6?S1mMEb3_hg!b_`uvmj@n1*#m&Qj_Jg_(Si&p#6 ziw55dX?`!I@poqk358f5K6QPLa>!xx)%tL0B^y3lF2d}%BpTq6CwsSqxOTcuM=8Hq zwZyo9P^?an@r|o?8ExM9q)IZRuX-6dVQw|emSJtQ_;ua&dJvBPG zIbC*i0$WxFkSZsd*6{}1nF+5kclY^9+-V@B1R@uijwU@^b1MK7yRHtg#u#XoWy$T_ z8L8?CU&=Ya0Um$B4!|*~9y1|&yf-stZ9bZJwzkJ25GL8W&Xu_0OM# zRHr7%zWvMMc0-lok|f3;HY0mlG@J4ES>9|4TU)+Mt!fl%bT0W#>sM8yrkhVBnfKPF z7OxcIKaM_hHowgARjQmjG||e;B=#iZ;F^mf(Ka@!Zo#fT=2bb8VqS5w?o#?zxf2B5 zR#WVpBSWrl+xFj0_ER<<;U6CO_h1c@rY{@L?7Hh>T}ol=`x_%z zj;}#AP-E_#`0;?EoVu>WF|AtIl{n^UZ9-RANvGMgFmq{Ipn=_AL!w43Qe%9L>qZdi zp>O#3=-wL?zYH-^Da$K6?+Wuo;}Sx4EniN};yja1`oJ(cBwqHIhU`UN;sho9u~!vi zOe2(I_i%RC&hyZ{M&{@w6UkO%Svr-2O&l5JoMS)#?M6>td@Gyo2eUr zn(fV(*uXy*F=r(7(nlxBaqG9!X9y(QYt8W3yk__b6Pwb*=sSBo{3%Y(zYXm#Eto1T za?1rPypfXmUTA#wuJMb%KSM}E{#9n;yZ~Mct~TU5`7?WWNX_fKWV*|Ruq<&8n}=FK zKsx_Lx}jlY3IQ+gkaEMZCTvJnYMB4+K*36tNXkLikf)T)t_7-+hZ6}xb_^wdqSsU(va74TBe-2QHUgI?jC8fd6*HOS z)lTphI}V4QJnZ0m(6_2RgoefY>I7vP#dI$3^sMH?vny6?3 z4Z}t|kXN9FonnS7$msOBgK=RH2F5wGg|T(Dts&xIv+ji3dac)dg)Rw5&j07RAx4f~F-1kB!B^#Oy6!@^P zFX3hBJ`z8g-)~2Krq*m5HlyB-(CARH%#L@`Cvhj=3jtK0j{!XM)31N~%$1sWKB%Kj z{_s}5>;qx`+-ELTR|9N4d!6KK9XTBN+ZWB%U1z2j*9&qP(xzKdvra5xDe~T45C3=e z=Y9GIrQ_SnFy*HjBvHqr%P^U#7kjB{FrOL(Kq6HDfO4bL(--AE5JttKM*dkAk3}o! zOUZ>qA~LqH`&NSmbin_+YW6ToINe(uJh;ep*Wo)?_5`KJlDW*?8q!^ge`kL@ts0szZzqyhw*vq=;_80lIco?2W$$) z-(LQH=d@x9?dFYeB2p$UoH#8C8A-}86P&4hFO&;7ihV1g*BGzoOyb62IDSyH0NW}J;jBIN3F519NRs;Whr9Lj`-7<4s%+7gKyNuLP zl|N(0SWe^QbMmV$_Z4=PEM7Q>NV=6`Ygr-%p!OqJ0L$ZWR&T_uA396LRn5vpjkYxu z*qUBW6fg_m`cY7dSvE5>_?C>NRqjq9LTE6tUalEX)1=axElF<;Q?Ku9<1}(e%GcV6 zh;xaBQMXn|)(ti2@h7JmwZ`Z^ndmK(g<`JY!J526?{w)px*RtSKbtR;Zj6Vr)S2Sm zKprbVs%C*-``Od%w{rWhwSO-s?VnvuC!@1oSD{ko_hmvFV*S??y-+ux-)C00`vf9M zqFI9!=MbuzWv_ji87!JwV$Jf*E4f~SK70#d$MLPmU|hUibyu|^p>=do6QnikuCy{h zi>`x1pjc%h86ajZ%m8K~B<-WVBZrn7Hj}F-%zia$d1yu=(*+@Bz-1zj?se9Kz){{`J%7It$J3^zQ4g`33a}doU^bq_?e@1eQ;m3PVrQh0AAJYEU^A)Zex zFgHnbvz|Rek=jjx`s{HtqO?VxfB-Xpjw*_K1Yb@@u@tpA0PyIf&Bqdc9>|Ql8YcYsIIzBb#{LyRbWx&04c9 zYWUm4IIJ8S0Cc#_z4Od>T7~%Wzb*XwpGoW=9Q(bv$Uk1TkJE|rDwk^qX^&&mdtMHe z+J?-JET)s*^jEsDPjo^D$V7r1&V!)fjv&hI`}V@5Wu}Ha&Q~gJS$J@K&qeJtU)b(g8fCRf>Lt zF?J2RKCjfg{{9T$v!>gt1A^TPe(1RT;K27n>lRr{Z+&)a4cUX^00LG)-if>@u{w!a z*;@bpCbMf%*ka!)gk?v=xbCN$VRg<&Cd1zg9ptQqoer)W&C8%Gew>r`UMOlfM8CE^ zjo0Nf(Ay8lWaVx#|4#NGQtVLSqDcopSNJ^;#E7}Q7y(uHil4=CcVnk}ZkQx3ox}Iw zS^bNx9SLR%d9$~GFk)p7u}r<54Jl3K?gG^K_{Wf^7SGAWt!va-7fq3YSzEf#gOU^5 z?S*cAy>@*{8u=IS59b>ib3UVN%kcHP8Upj4LIJ_-?rV za`0`0Q^}*QmyCd}Fe;+|F?_!8f5*oClSu-?Xn$NR>95yGofedA@~z4?jXm0$?st+1 zD6=kMbLr8(&x8fF3Q_u{` z!)x;DVWJ=qi)2eNwB!xsI~8OkrgR^Zglow@DE5~&Be2-z`7`zwOx|e#AY`eVHF0z( zwP)>|Q6K&szi^tMxsz9ABijRy?+qXD!oW&(L?7F=KabDc?|CrwJHM4Fqd1MJ*xR}4 z%Z4V7tL@9NKxK-$5m@^T-gqIoyBpA)@`H)!46nNT_ft5HnbK$5aIR+)Uq#f_b7gOG zT?Uag_ug#ejYD)EKKDd%{_fSB4R{&PsM17hLgCSG8bkD3#4JV}Ab=mjS|P86j6QCq z7mE}%oRNA0$`mQ38=K`(!86Neq<@NSC`)TQ&dsSauyHc&R{VS-RpORjrB+`qvx3=Rp6*9;6xsG1@D$4Jzgwmul2-mq)4HgPpaUeat4NZypB!(@QuZ za_g#y#be7xrKAOMV!~R5YpC;pKOwtNezLn%m{>Y*8qb zt@;!qB7;)Zv%f0FH9BFAW>|gJtZF?blGPr*U05yME2vEBYkz0R zb_r4C`&k)umYYLFC#dk(G2I@l<@smzx+Mu4j|xjk+r^22y(Z3_l6q=_UOGXuvn))u zX=O;u(dcQ2{VHiCU$7heJay2sO{VNjJzM=~b3Fj@_{&@TcpqT0I|}H6RKQCIc`U-Qif?L0VZq$LN;DIp<5OZX&qeif?k%nN@7O}9J4XeUK3{#;^B!)?ADGi9v$ zRN95I405u9tpX?dX5%6 zpg1_#^HqqI6Gn?7)F&-yn6BZu^>UR zg^o%BxG?sDBVn$_^;#TkGFN>bz2D*Ie-!jTI`S_oFj6ljSiIvt4XF`~(T%`iu5{X* z#SZGT6RZWF6ivU-FOAyN^TZMotI4~M#T*(p#?{CZ#xaD_xW8uok8L*ouxy2GZ{Hb+je!O*hT zDk>&6H?oaw{8&#=;7PG`3?GSCrAsK)sn>>>CgmYkL+60VwMC@;=``m2v9P7pQR$Gd zcJ1X*HvHy*`RR*oEGbGTGBlicFFEK95HI?mwgAA`#=?O;S-%XJv49SvR4fVj zkSB-+9|JD3-t!iZj}wb~@QZx3J-J4|BOE_Y7x7-&2U4Qbdp6n}YW#@nq|!RwT4qX)S+Vvo!Gi18 z$CCAgXDrD3B{p9yjrU%-t$Sq7Sy;RHq?bMu;<*9)t~}mc&kloi!Q~%wWUp%ojG#SK zy~x*tWEb`5PcCT8xM)x?p`Mw7QQxXa(c}s00Yr3rc~*(E?~~AjapeIdtQXhP&6;a& z-4Q$_oBR(`{D%jA56bcP7k+$lJ7T}mi@{D+pn8yogfNm+on;~S*2;%nHOnn#=7rKFT5gb!lWI>Bcp2?gtpO@Vsk=Y`< zN9v)VfF4+mheq1%s;=Aq{qV}oT}}1Qa$R_bja$aJEpdJXgcU&5VHhBchNQxwW^8rn zhYe`*&VP^dPjNY)_H8+MT*u($`jM^R=F{w1fvRRZ=9s&`9YgbcyTHnP+nlCm4)KX0 zhk&fg(hm91MRCPkBn%J;frapI z0Zk!h*1GvJPSKVP{kHY1)Cv0CLvvl*VjYK|F=t7X6;k?f!!RH#b zKg{cj3tTXF!K9EaqkG(gX^yzdIORlAb@bxE%wn@l&Xnal6%wHD)=39(k7u84U`~1| zDxb`G<{{1P7Z0nWvh2@{!@pcS)=Az~Db3MuaDJX$Qn!hH{-n0+q>zxC;-fHLbk+{%wM+F2{STg_~+eWsEW-Lcgqc`-$m11iE(?^qRE?$^T zBqjcA6Pei+h-f*crrjbSA;ydQeG*Bm6J8c3No3MyU3Jc5?Q8|GYRsZ1--8gR#=x=Q z*3B)7K^;klk7j9UZ(>1I2UZR7FzR+)C&gJ)~j{0h$4*hkppd(l>k=-g(`9 z^RukB98Ng%HO}VUg!7BVLp=V?zra3lZ#F8S0D1$jbRT-CxGRT2#E3HWLX?OfCtJGI z++*sMk_%h{?^Rf&D5bL#h~|bfhl!WDieSYu`*V||mFwzX<6<~!P*A~`+0@w%#7EbW zEV5XKyEc&25>^yx@x5LDHpo&_EWw3y@`4O}nw!ex!p`n)BD+-5dW&*gt3nSx z-#mK!{Lq5Nxk{J8p~T+h4o10Zzv|^3vzM2=45CWoPHBvq{NUzh1~J2!XwPKu5m_A_ z)11sX0sp;FD0$Iao9j4XFu2P+#thi2rXBoV=){1A4=w)mX^o}_<}2R=tE#uS;`K#0 zDt@mhM~zi6ZEf5oMAO?b_Ch~N;7KuC`{=Qw@524M)BA&n{Z69mP4^}zbY!z&_v7Ij zgv{Uv;x5Wfqbi2)g?RjOD6L|R4tu&vf1&&HuY&ilHhwPx_CKyaCORsgp8rYMzS;Yo zB_mDI-uPaFEp^yJu!f?v1j?*2ol6q_k<#4|X_uhB=ari!$QMbej9=wFn$HjBp!9l{ zMtJvTPg_RdW+MZIiz7om3GM3oV*Apsqx_S+-v0(!#okalFPPOH zF%j)wN|>KNcy^v9TG~UxmN?Y;Is~V>Nx=}pTsHIs8cvl7w=zQ8pXet2)h^PhW*E-`T)`!mdteEKU|RY(m@g`nzhhDIO*I!jN_32K$ff4xANxqi+gWRp~ zJms-*IpQ)uR+G^6JR&9H&6s|X?*4?0yRBMjuX?(2%e(ao`;a^GutPCWM|%*{j<%I-noB8CDfV&K0aQK|CU8rs6o`7v?+VW>t8U{j9d5s~ zcj>?L?_Y41931kM4+(ufF#dW3vm8omepTfl-v}XJ)b7*mV;ni+ZqQ8&A>Ph!?*D>& zQG&;DR9nacgV#^$3 zv8qX}Yq_>Pqg1}ZU*JsV3RlG{8oX8nWsAphZ6h5pa$p+mjB ztYOP30IfA9a%$W~)~#_gh+dKmFOmn7vhvmi31hb+#5aO^BE%@NKM72}E20kv#Gf}- zmed%@OrJG}W6LDewumzsc>QrT0=O`0!dYxlW-AWV?q#v6kA6CJs*s>(@A^D_8v!3H z4>Fd(z9frdZ^#r*aCIjJ4a%9fv+HD#n1HM?6@YsDnYqKysfwmCE@)A!(R9eSIPj>o zQqPS&yEG%g@Qo#`gN!{+Uu!Jw7)=zF;8 zr*aJXEw$I@PH(>LfK480{2Gu8AV=%6Zl=eQqkHF^I3%joZS#TnxU}pK&3%NiBBRXY zPO*OSUTqGb7*~3BVNCib>e_FYUNf{E{KqPEGTTbEVyi?AaOIu-?wXav3u7=6$xI#E z)eCPLh@FKNtq^0+Qb8gCKi&Ep)zEK*@qcUnf%TOJpd)18#B#pk}Cojg*?e*Km z(p@IYee^>}>34#RSE&^NEdy!clv;*9);w+G{LG-Ac-6!wG0l*Cpmfq0HuBv!v9tw2 z1y#c*b}Yy{h5w+(_xMgdan8%Qc`%yWDWNLa=s=nv6ecx(1|AWm1-~xtrKT-Bd%;m! zea)>M?{DlwdN=EP`=x`GrXtJ?gDU3UoIFEsK$|k;qia=W^Arc2ZqOWSw!6Y!3b=@= zm)v}3s8*2?c2O;8I}rZ#q;ws8b^dY0mbp{kd_$HT~DwK|c%z$QgJzzu&(`rH|cgv-mvXLAQ6r(X+k%C*vY7?n^PF zH@}KmghjY0akuem9tIZ*JSHr%uv#sOBg%NE2aVxhwRTrb3-Wwd5$t1rlj~6~W2nW1 z+K?O9mR*V24RxDtT$MWxc=@GDK|zSwDgnUF--OiI>!J=LzfrR&Bg)-CjlirAP3Alz zqfgB-Vv#@ePz)AOi&smLxrV+`-GD80g@7>aWGI@l zty^x=TW&szt(cj;buXEn@AxI?r=5fcJ=^m^I%OB0qnlH50GzAM*6#%2A-%`qL>hPtv=l5Uc=>ib;M1GW=$71} zb>4rC^(^a=iSOOAw|!|J>;ASS#fcm;4KNv2T9g~;kl<&87cXU2HGm+;jTKyT#9itPnb@kEg znzPf3x0LCo?@Fl&TN)~z?bX*wR3^m;)J-fT26EiLKdre))E?Pc>&2FbMGf59V4qry z*z%(F)?XET9fnK{Y6!1_&klaM{)N7}iLP^f|AjT*pSFIImCDP$IOv@gs`)DXm5dn- ztC~=o)gzmZHBJd7Bxx0XC5!J9Xnou|M8Lj=eOg1 zk86v9$(dvw7k;gdHTK>|b*!(W;ry`)|ws==4>frYc6>N|a)70D^O}~37=-fc$qOx0L zjmFmb!nL@_ja^r$p{@vp=3~O5w4ykZY#WIn5%PxJ<@Q1!B8L)f(<>D$?Kt>ygCgHD?HT9(8P=K zUg*WdVI9!R)?*pQlK~d1k)YTJiHcx+O<)#Azs9wGV0lIUT5fcX*a=99Q@KG-7^*pq ztU4m?c!hgi&jB1!EK-5(Duz|6zAitd_hZkH7F+_U=RKWWL)~TetSKREqi*1{mK=Z` zNk^V>3*gXH_c4C$kzJ5}g`oI7X99Zut3Bb&vp!VJ9!Y^z15{>J6UEnXG1DD_@Z^p*j4L>>Ai>G)kbQ3&!A~Y{-OS# zN<#ZzKUl$y-=R$L{!G&FuFa$0e+S*;nA z?8T*K4SdK|0;DF$;4=AR3c4fiu1fi^W>EMvkl_@@>)qzl;7ZTqIh@L2Q1TS_nS`8N zb%Fv7?U)Bw{^{o9@X$=Y;xQdwAH2oa7ja=s+Wfg4M^UNk@(h!U5OIIYbTr%mICa$t z1=GZgm;@J>ZJUmYavvloo`Qq%T9Kn-+2La$Lmlw*ramns~O zy?iT>2KDvUhL|BP_h^i*+okwKVtZ8L+ud;jrp&TzY&2{5WK8rFcNuMHg2TDU61Mlf zOuO*$aOSBCP4;<=3errUWibq^JsuYt}59-96yZ>h0v} zqc(q12^oz$M{1V1V39gG7n4CUja3Rv{3)oh6;KhnH=p*g$9q{^YanW4u3xb$IdN&$ z5p<`||G+u(2LQ0R3u;h1C!3_ORptA|YYoU3FTJWd$5Jn8V;t^L?!Wl1bS2Qcr`#u< z5En=fDvWiJlV4C1U-k74sRcyCnhi$*(Y)G@8CAWxwCB$O-cAC8ahZ_b24v?CQuLB= zPkC`DV$BmN$4UI2GBKOYb2IL}H?wD+CZ z(Llx{a=~$?UM&3$bR-4!(KSG62$iNXVZIrM;uE^*Gg4(VQAsKU_WiCAM6#?tzI4dI z|8dF~+c(F`gkU=DT&%9|zL>26)adAS5b zDsAwqAr)KN47M)nsl^wY4$fjd7RfWtUQ7AB+O@GauiZJizeeBpElW=h?9OZb$W!R{ z(Ft|XMriipi(dO{+XSaMZ%J=>a>ipv6kE;hEh^YDfou`bQ~I@YrX5Xp=7yL0M-9BH zE%?VG=#Yn_gf+&5gi4@C=Tc@L_g)Jm-=?y^TREC@mI@#iI57u*{OhXtU4i@`U;Mv+ z_3rCyzdX>S-BG%!0ZHREyDVZS%kMYY=6X^wV^AYCra1^eE~x_gs&=xsw^z~m>52-X z9L`lcqfbsVV>;3hoY~T7GyW0ubg@e zQ3V|*1iGW|Rdg8ApID1s0bbTOF9cdV&c{nti8_#W4-*Hj-*-54mQ)E?!Dn&{7K48w z-2xm?mTzH~wCPhof_Y*fv|l#GsfnrOIZ$;myuY>SE!KM=|6HR-G{gS{I?&s2)k?G% zidu4A2+S8aJ!Jas>-S$j(aTeciL1-W@rFSSY!qi;`d(;H7&Faoq$s3oU*mLT(ngAh zA!cFM%IIR4H?i!K-g#&9k;e?p(rB*1KC?9X4l>hVi}WOAXX zj{xbloiLkH8vnQg3cQ|UZj)>`e@Z_Nu_-0HD#+a&TG+^Pzra6o$lV8C7XTDduuLQp z0;7}k%at#zdjf`lxVRdCJp`G9q&hmLL}bd(_SsvxA~aGM)-C0FR>JoecvQ2~Z#8|R zUR|&8c~73Yo>6X zxix4)!CuN;)jrGJ$+VPbd^_D>cU!$5UwJkOnu6-K^m%jbnDO&NQ^biK()pO>VKPj_ z4BZt>b8!c}`gdOZt?PfG^?P`oeb?%J_&`pAUg#Wxv+=X*|MWHfw&VYBO);T^goT7A zW3InvLs%v%R9UQ#5=R{@k8eCXWxRjCA)Vi#hob|~MFTguHKcFG5l-h?9Dm{MFCFfV zKbH@@jEW74Rw1IgSuLO3<%0&U#}%jPA#+G(z6KPZZwIsIu%XW#2tDWXFtkI-RzJL6 zG83*P+>|LcI>brTmY{DAc#6v+pqZRUfGNrEcQ(!0+RLBop-gcwvsf|e~=NKo+fFne-DVG0dZ|0fQIIq6ngEDZp0 z6p*S6lyqXwk*dTxq$@MK%F``$Zats9c%UEG7usVsA<0JxS9Sz!8}`%gmWfJS+PLnS zKL&xLPVh=hV`9%yWc&jhZtTju)7|VG56XToWRhXnsR7cR?ju>!rde}Akh)7t7!ez+m<*#whSY@rFYhRV}5E~j)8H|X_;koyJ^KAa7}X&-16Tz z1;-Whnw%-tOki=5$hbnHf`TGhL17>3H$VA@&ENHCJ`Cg40^4TDdS6%Z;@7ReyJP&P zBFE$5@dQ@Pg5{kJ6JO(csW>!G_+ygBE@`N77{^Lx z-P1FOKu+j6>sCjr8`s~#MomX*QEz?Nk*TE&TnLdg1)J~7aaWyCi5kk5i9ZI=ecG;Y zaO~bwg*#iJ88E{&-D2KN7Pyg^_occh_c+=08+B23eg+h<5BEY|Kb!j$BcNz`DGO6M zz!A?rWKmemsJlLWPtm%9QA!Lk#Z^&y@CLBTrgbE)Q^bwQ0IcU z;&WVmE#^Rw=-rYm6g^eT?Ll%E-UIfgJjtHCYrV<_9hH!6@$x%=nZ^#CGefi64D4oM zkf6+$eLFJ%ZAEQeJ%c>1%?VA1w~X7ivx;Frfl4GX@?$ixhX9~ZDZ{HPnZixvAY)m# zfEue4c6Ka4KWUR+oykTOO>^Qp$N8H8KXPBuG|}BX)GclMZt%~eoAAY%NAvrUD9<-O z6JDWv>*b89s?ka5H2J#G-1J56eHsXB8$yR#1JCE#l^*y=<-jbf|BNa%1RwO)vZRzg4ZZf`-^8Zr-^8)*?zMZzv<);o4*&JyLmB_lHw3! z>9l3HT7UMW;CDOv5Bt8|8x;75T_Zw!@j%h!UC5vY%oP;KIKbWt>F+>Yizdbz2y3`_ zP+{*NNbm?UsKLz9V?6ejj8B)S*DUb0aZjZ~eGAGnD8`Raqr~``HS^b4DArAu3LX{pLsiu=)R9e+o|= zUO!irW$5es)qvo|u+F$Ee)L?Wgc89$UcGt~c9EMO8y9E)GqXzE}bK~uSlB|IMZ3?x$M!RFp5IN{GL{TYo)Dfh~5A41eqH!D^ z4UKeaDiP#rje3EOfnu*UGdNOC6AWgPAl$l0n*V%ct>^wUirkHwjUF?@K%}nTzElgI zzwdaqW)JKto8;K##VDx+oRWT(SLaO4WiVT576t*L1LryU?r=Lc^) zu+i*e#8z$&ANpYrd_j$W@X<1Jv|IDb8rxwMhRVH)TEEU)RZQY@J-3TTA)|n{!zaIfqR`=M?L6@AfTc{}dG0yl#+gYx%Sy zNvAg-Ko|3R*VGz$Q4j9y?*+(M3TydJweVS(cqowu4Vp{s^q?lSyU#Lx)nCB2vz0#y z2-!97SBDwbSQ-}+syD4)Txf2p0@fj-Sz{Cfi7xI$ycrJ#RoThJvlN-=_+ zyCpQ_)*?$pitTiIE?hvJ$zBf0$cXj&sQS(yu8qH)@c-Nybbv?IUT~03;OWjU`v#=v zA*;F$ncFJE3c70>l<~?GV|)rPoiOJ-*<3K4URa2~goP1aVINrAx?mO)HB16Tj8?P&p z3=Jy)EeNQ#D2Ap#0c9P!on5TkM*M*RyzG}rB-igb)9DGWWpD@iif6E!rYh{G$oT0* z`woR%au*o)^RvD4jM10h0*D5@BAs|klKH`*^EE1_8?9)yuzh{;SZUUIfrOz^+ zcbCmhaea@N`tXlC5oYv^t-WR<_6ab zX9?ZV2fNnUwOOsh+V#J<66r4P3L)Yi z(*zz)F3j2?_grrJEFpcd;aYX%{%Svtu2?A0>=*19v@7|5heB*uQ&fH($eeQQJ z=Lcs$hqL!SS$m(e_gd>+@5<2lb;bkPIEXd9+SathBrlb}8>};*%8dxIosbj9BkH*9 z@Gi29Z~;+r&_bujKREgRn3e|)ZkRgfnhKTSLR;1_hMsHfk0}`=~~VXeT4qlJGK}orDt1y6G)Qm^y@H`P71xnQPFQ z-dKV{lEBv>V#BH=s2zDk;Rk`@#K#=ZF*tB)xpoDKN--iR9YSlAGdYn{5 z!Zf@Ry9+m{d@e>vvO2*&!4qr4$=Kk4o`Gs#HA>{?UbrpK?K^T)GTrCLo#!ldzl=Gp z1>dT`&9JNn@N-^yLLNAOZxd6%-**6O{Efz-XY_H#z*~R2gZtHhNahD@eOoPraMiAJ zgC1LQT2&x9yFXFBWraTMS(5}W4%GtA|v}eN(st8vO9!gCFN;a zuEP^tvF(ZUjJ~sWa zQ%bwpf9D5|-QUH3FfuXgvQ(0Y+^9x}Q-qP6EaWx{D9}a#0lO?4&Hb<&+ zV9OF%>Z5o@Fmr0^@H=^Zx37945Io;b2XatE=N)Ac;WgAlj*D7c zGP_5qS?W?DH4KGjeTX!joMYBkZjT`S_+;q!;R9!xD!P5dV~ZF?jc?v*ks2ic1_uFK?-UEc?}OkM zDdB0eOGft*2zD5>mp{kA4acuTWjgzn>tk}mrbw#PCM6{b@)UfzrMI1v%)i8DixwAQ8>s91` zuxk3E*rm|47)cYqLTK48J?=_}6L>SaL;@wFGhy%UX`wyS3>ab!#HZduH;oiuJp~?J zGlqbP{Q@inlB;kY?;aZ^gF3&5!FllsAXD=jpAv2bH-Z;VH-r7<#3WD~w52ZA?7Cn*06yW-un@-dP@+1nlorZ$r^Lz7 zp?v~=7kFS>tV!_&Noy$Y3OLljVPJxyt%5g$n zff}O`-!I5=FLFW{PVSFwlhA%oXgPx66SfHB=+(mQy@BCYoQ2D0fED~IcNdwhTs(DM zWtvSf4y#mr{m<`W%cJdy7*KNSC{Rd~&r*ZxC_ppvn`Yf!i zX)QvOHct0w+2;1(9;ys(SyZ?Pz-LjmB9;`=pFHOeqI*!2U@751%*k zx8;AC+4Rr79+6pkwy3l4{S*|bLMl6^6#%{{?dy_TE^>NINrBDk*OGtDlcA9Ctj z{+aY0&BKR4#g7NK>R3rtn4?FNQQf0?R~$rps?JbWqi$1SzDIZ}=hVw}0wrA|?!y5g zc4ZfrY~@QXk6R^G&X#sg=*#zMyAh+5-_5CXJ4rgc9}QG-wj9;+#!fA#<|UzhXW_W% zZ9F>gUil4K9hCnFAp_*Pq`o4dA0RLaLb)(CR8s%S_S94l?mSRuNqE3P5)^EQv(~#* z`dm}pq+$4>mA%N$NkRtCh&v8M;1s|%&zrrktw-A7ynn%+3vK}rNHk0V0_ecA70RZy z&z7A_A^i%ys8-41!`;=B-7wpsI6z&XJ<|uK` zIGU~mW-V#1!D$wTny~hN5k0=(YM&}urJrS7)3z?0-XL|NokW=GFiG1KujY|-9ops3 zt)8Xn^P$bANWS*z6&_Pzsn3k1vP=fg)Dp}4miiPj$NA=3<-Jn#il6U|ihylgmyqV+ z5=uM?+18A?E5`T6S=4U#R5|ZETFsb`wcPA-&csdg2lXrv9Kr-YLqY4iW-=4HBsx1! zwX=qP9N6Ff)RUaBWge1ogNG8})vImLM>Ugj)Bayg12Y zG{G_w@Oh7aTmE-mCk_qBWAB7M9%1_5)JbT5)os^{O?VN}mjyo|b;3$ysTZpc*~|{)BUzn6AI>I*g9*!%a%p^SEo`*J^=MV zqsWiZD_}7;8?s;2>qQPZS-vVZ6~J8MflB2?F3a+uTkw)zUIG$reqV zilf?M;*y*qQ$id8$~`Pa`tjVN$9uqRGKFwYb&sCZeJNt2T+-z)5Giy!lKKpwfq+#= zHw~$0Vvnd38Rys|MyW06e3|<5(>+C-fIFw9w)*|g(Q#ceFokQAd*%3$^al2>2laO% z+Mfyv$~<&C{c>C#p8VoV5J@0@%3-OR{c9WQna7i94Hj!!w7$z%=tVB=Z;C8VaTVpC z2&62!#3lMh@Y$*~hMrJ%*)_}z4tG*3T6&K9V!@``^WK(TT2WY5ieGqg*IZ6a{%)pc z&b37KB}!|kqfm2d_Y9FZyX)KHDJwqlX;ytr80&2gwU>vxbmwiW4?9~qI~EC64uucf zeCHLn?xE#Z>a!ZT)7b=rY6$eB9b8+anQesUW*-h%d(_yhJC*X5bT3zf&=_wKbytJm}{2Xz@HGbjo5>-8t8k;D1lrN6k}Y#+3sJ|!H=B{CIMV&57;Y-c?c@L3ywU;KA|D`v;!Injmk z6Ku8~7_sv3W(W_gOqS(nU}~D{&eRkjw2FPq(*ixg{|IJE>!D|f6crMy@Ud}mxRkTT zQPGBmMXLq9z4d6A6rdVXl=FF=bIe%vE84@?j;ylN^j4QrYma1pl+4_EX=b=x2*rsO zegT*hAKAAHW+E{>F6v}X>!^Xs9rukQ_Z2A5N8rKFy-8fJ9gF>s;cFPw!dAFNffN5@ zxq=R5eTf(Y#WQxm?|}XZ()Bd1{pVQfNgWW81_O>~Sm#&g$VSc#m{erinRfbR`z5}>NZ{i$?Qsy?qu)ol<7ppO%VWy z2y>{rzW=HYF3UeUuaRgxJ$}{KEqxO!JT`@e*PaNlbc3-o9NHgu!yBh?_JApj1RxT&i2A`0vG;lTA!4H!!UfLSMP$W~!eB-Q zod%Pam@j|Ru#XF1__6N*8CPPnm)%?-Qo%?4)lG-Eq*=+49Bdg%6V~E9l!BNh*1$<3 zcqQM7)h8!(f{*+suNGGIWTMh+Lnv?6j58~3^3AAJZ+QN%lH+j|+{APaGmw>t3}J7h zpo;P1r$C0M5c`PY!-DHeLmgh*mFxK+j9aeI3IXX=>LXrutWJQcm$e=?Q*V}#?bqu! z&xdgdD7m*lwYPzjV|3{6U!y<%`!BOD{n5qmC8?ame>aKPYtp@ShOA*aQoU9YdXgQ+@Sfx#FB?S z&B~h!Bseo=6{5LNrz+CPzCF944Ar?buN&)0d7Zz&+m($FE{vTTh*#b%geS3?mAj?- zanCao4HwR6MEh<}tvT_QtX#Pr>H7?x^aezNfnYH^oTb^6_BlNIp`*sHPMuj(qzs{( zdTJ}k3E+@ZECHMZUhg`;)(Fo2Xl!k+zY!f@5CzQ#WJ2c;o@al_nACXj@dQ?iXs~+x zlyS1da1XZ6lS$MBkbU5>xV@_;WMC^_ngA>GQGT^08S9kPjo`d<+8lbXB(&M3IDS)h z+L)}}4M*$63kOHVn5Iqac&E%*f;0whz@1#yOx6F&)YKS0Z4cP6GVzeOsUSPH$9|Hs zq2b>MKy;?8ZFjhF!RU<6P7G*TL0c&=U(vf_ta$snS{N?;O zu09dpj%8l2D0HhVO*Tw=)9MwSzaSy+0ANezLf6k;wK{<77&EnbW?FBO3x7kHII``aarP)im$YTOA}4N?Zgjn$(fRWJyB~h*Z|{U; zmJW?u?kx37S{AR;`KXwgVmjX!r5-6=oLyu$<+yk}rBF9X;Z;;8Y<)q^q$D`5`}(a@ z|1_3;*3y4n{8wT3{@mNaaO~LjGwe0*$UZ${&KFOIz%9!a$9Ma6IyRf$RJ?k1yeHt# zwLV?>2LIMS$YpQ}NIhinU~(gz!{Iw6R(9US zO1bOk5aHmhQbsq?$Yf;p9A&=ZC=y%Hm7S5!gehLd$WI5ml_}mcwO&u-GEs(4B@wK> zcFq==R`tw0>!siC)uvc^Too?7+qjr@s!Z_EQCmUbLfeo%S~je&KCfH1xI~3{4%b!- zCe*u3gbA3hm~r%cvO{@zJD_3|aovMm=kXKOR(Q!A@F{v|X)~>Bx(bm3~ zP`2)6Ie{g4uC!t-@;98;>9d{gOEZ0=BnOykRX0jci$zAaw7l^)lB+${oi+Yb@a}<&pL70@=n(t8ruaVZh}H!AcNB$8v7|BC6?;(2pK|1O!b(M zN6p{0e#l#IyeoCfF5O`@I>D2kS|YWWh1T<~R@=yi8Z4KsbXu6>IG-;E)P6!4)4Y(P9TQjUO?~W#7T%7aEPS3BzJL~bo z5;j`a6FHm4V?ZEE-@;0VGOLxsCWo3%useb$KaUWV1kH zcVh)Plavv2u(o(S`ryM(Ph!^|Gh_O4_+;+$?5w`*6k2&kvq!6gn`!ZOhipB)ZsKyk zx=FX+N+Z6MNx&`{G?O82C4_iW=5!)Qytwp?w#5o^`n`# z+Pw+vQ~8)Nv$pkbddt^G7K-gX(Z&bA@mn9LNF`YwUsl$|qZHM4k` zIP%Yz=6~-HoR55s`H_b-U)H*Qv}F})oo9+6N4+XvQ>9l32uE!Av#VE*FYfp!gcR!e z1a%3|74(ougoC=<=ImTCBeO#;Jq~-c{V+DFFi*hHoq|um8@}?Uz5butuNmi-wtRG0eicoQOg8RPPb>qF!r)50w9t4x! zyOz|WkzHG$XF+}WaWw#YFMwyVx(?tP@57KOCL+miAL<_!BrE&E2}M^t_k7krSsR|D z5iJ^tx6^O#1(D&3n(f(c!L~}{%L3ipl#;vD5Q^$guj;H{d3k&@t14Aznj2U{ zBaAcGh#__$q&yoqa}}T`PCy{%jJuI$P&EYPrJ7r`2q9iLo`Cy4g=*VxZ+*FGg#ARq z?VGgZ+L^?;Sk`AXy1889%c&J36GF2&Fl{|EwK@(O-kTA<;%;3feFwn?RnPK|Eo>xe zP9+&&^v__{p)J|l7Pah;N1nmh-)FQ(43q)_$7eizVN(Hr%$(NU$*b`;RO4+go3=96 z7ev<5ow1g%KxYQUJo=SMx9XS8lP&W;g{{{~O>#L5cI9tPr#hQ3*&QC8F0fOzIx-y! zwY96Y_y3b(UW_qTBBnl&kPvrCErln}aaRoTDa=fF4VD7;pzm+PuZ;2r9YDTz%zXfO+koEB$r_Eqj0a3h-V*DVtA^vFu%BD;e%~ z;kKxaUccn@))AI1C67O=tsz1Xw5u9sFe!eO%XaC;9YyYVg$W+HZ>=%9yw&2)YvCE; zXK^rByyE2i;Iqi8c_LLNsFyB=AtoER#mxfReJ{l{y6qbj)MG<-YL!iLT^9EARz}UR z9Zmtp=!P{;7L`uL1J;^8LLAaoG}wG0?5D0RFQUSXko-<+-q~x@PDl7%D3)YJ#q0+* z>L()oc9zOkD}oy;Uh}-)TP%h&_f!u+R*FpKAQHaZi{2r`HmdEJtxla)&_xR41kWE0 zYX=4@k<8QWZaVB)_7CbEbt4S)tO!AgX)+*$I1+JV4YDpYj-(Cx@h+Sl5M zBfkou!z~S7zgEF0IoHp697|%yU=noXCps*xW;?CK%$QZ<`6D$VUW~lb*)gA z#uXIs+o9D!qpvnv?=Bkjm8hQBQ745qD+J7DmeR%|m2it+;IlseruaoiIaTOl(m^u!uaDh)vIi}AxS#jz-~ml%m_@aZVxeMF zW8StOdxaAx!h6uSW<-j^jNDP^N^kTwXt)k6#R~Xyr>lmo#%&m4!yx^e;MKVwJa3j5 zduv_xU;XvT)>}SK2}ARzRQ{d3+kVR|4@0A3Ugigaly!0Zc$`n|!}H zCy2MKM?9k`zxlDkphm}N9(M9VJ*{?Fs>iehFF-Mx9w0;1Y3MeX3=|HL?gabU=4(p7 zY4ZPtB#jXzCZm+QyL|G7z4VC>2i6J zVQn~(4$XG=g+sTK{qgAo)e) z?Go9QJglK4Z*WNfMTa8m*jL+vLBR~_q}#N0VA{26Up#*fCf~BkNw=&7+x0AZbej{O z)5E64?MhE$2_fEy`Vrwm1gmWrI-XeKS~?*N^1uei5o`qn1aEUG%;&o1El1z^aA4-y z*|q0NVrE(8=Mz=8Zok=i&vu+kR8kYcw%dD2)%#F&U1L+baSgzBYCj$b*su1#S0udJ zOYv)>4kZ$oI!QK)cS(eKGRQ15$fpT`NK>Dj_>T1IhVPu>#P(~Ea^M3cu@xbko1+TnN2c0ESA|pLYagLhf?rMWr8@v;@ z_I8%ZC_1#3Be|#-;#cJ~pRF2N>7^dvOKKX?-%1|ztws!9q2%Cu*ang`7xa3>D^8^^ zD5bns>9$$8u+utMF$|e|LGSKxWSP@Dx1K)DIe4sNJxTu-zeC=7q~EN;f`9dGJ=$Nl z(9ak>^q?4+PS#UDwG!2O)Wu+O_b1x0i9dUz*r6E@i<6J(=XoseJmZDd3C{W@45?xR zpPCu19(R6-+`hRO8n_FdMR=!Ozh3C*8KlyU*-1vlp|!@z2bW3yyS|mx1-oJ!zyF|@ zsbS_P3feu>>9yD`mw=r`zH2V#7Mq{$^12dW1CY*pKdc>EuliLfQpo@{3fxa?VJvgM zEM5s!O{Z;(>W$R8a2{NxNCxZ8PF_8&Byja{2#&VmwK^)fv&df6Z@Qy02%i0wh$RPu`17Yh+y#S}R@JXZv!>{!d->1BE=q>^;|Ek&!94iAok2(i$(lzH^$cx1 zF`ozDcC>9D&Fg11x_J7?l|oN#Ls4EoKOKreoBcQpDbu1XQV@&B0li%&W0l&XxlFtMJ?C;EC;PE^ZVlEX;4KC%N2fhelku&eB5 zbf#uAov%2OJIb(=-n7>(h|`IP;>`t5=F$iQHiD03z6TNX0BsNwj|^J4;(0MqV)CA4 zkP$gyqty-V>O(Nrl4tEo_+;SLvMW5)Msu+gZ_Q>tsuGW&50){@`4H?)vfo zi#STUNG_E1{#;L}yoB7)md>+2N?X|Ah4QrT%FZzr9ANw+!Ni*Y764-`9z^X#O&)Gc zckn<+^p&wm(HkrsZ9R`)rd)RH_KwqFKV=&lsqUiAU@~eQ25Pmh zRj>RX{>C2(-O9=i0Q~Z`M||@W{pa241t&eo4yd)nKu?-f?$(>e-1TkWcw}tVgn{M! z+Ej_FQ-}8OY_nSHm7%4VP*moT$bh|%=KirSfqe<=OJH9D`x4lfz`g|bC9p4neF^MK rU|$0J64;l(z6ACqurGmq3G7Q?Ujq9Q*q6Y*1okEHe_aABAA0`-mMVIv diff --git a/script.plexmod/fanart.png b/script.plexmod/fanart.png new file mode 100644 index 0000000000000000000000000000000000000000..851411a141147fbd238c610b541c903a109328ad GIT binary patch literal 22613 zcmeFZX*|^Z`!_t_VUn4mtd;F-rEHZ7*-Ax}LAGQoC6!{3EQ9$LB?*-zJIPXZvM=+E zB$Yk;G9%ft%-Dx9GxulC-|P3_zFznLzMtF=t_Roo#KdPl>#@F%_i=`r;Ptm+cVST| z)K-J@XD^{pd@u^dtG1a3{D!jih&%Yf>wMbiGzwK1iQBk_0sn?PFX`)|@>(RPz(4+) zTr@uie%f5IW-QIWj0~@>s+gV_+q-8EXJc(TAJyB{QAe)1bIX~B2d%GnZiBIW{FurT zeO5$7*wFyxX^G4i|CpXmJQ&IY9%a$!y9qfW1!TC8Ky*xd>HPn47%#V+aIeSL;l#ceB z*RPzeJGQs{Ah_Nm1rWDyMIG3`e>@u{C5rO%@$TwqwX(E0B!lXEhYG)q`uZBx9*;V8 z7c@RX<0O>`_I*sLQ8OE+(iye$M$Q)ITVLv!~5{`e%mt9R~F3 zkdZG}Z&p0N{rTz~voHETVZb$he5mJJ(N|9UdB2q{ z;KKgTfB)Ox0PI{9URPaO0#S2EOx{kEoN%obETAN7$?FKP=4y8|V1 z7$tWV{Eqvv0R8Wuv6mqpnENpYhEDx2A1x773ir42S5YS1kD}bK|KC6U50n1C%>Um> z!K(lL_`lBo-$}tz|NZzsYL+KuwhQrkP-%llM<7XtPm_?_hM(~-hlx#Z;kJ3YzCQ#cWaF8AFll{ z6v6Z2Wo%z`!;iG)u==R6u|(H0rpf2yaYKn?V^O(b&C{%=ire6EiQO3oR`XSjiNuyW zWouO9;h8*pMVfS;+pxV7zIj(Dv=0jh?Vuc5uu+F zqkmcY_G>z5xv;&qp~u}pjZOMrUqt3g=aYT3 zErv`lLz#zffWj@XLSQ5yTqXxGTBdAeAi991@! zB2Bq67g(@&sch7rKH>d9RW`<7_hDQHZOpQGxxHOE3LUuWpelxUXtlVBH-$)n^uz(R zq1&4D0QoTRCz{RBNZR7@Wb>4prEcEwGE%z5N>maj!*{{a5b8;VWm^Q?;fPiL-{^!`US%wd`hwFgCGFCIKZHNG4#*?(K-@XGilgu}95WcUr- zJ!ZnA(%Mr+6TLHx*`T;d%H+sVKZ?Erm*$vzGa|zQNzsdTpVMb8h8a=yeWQ9@xaN5h)C_W+6HlYJo$ux_z&OC)0mAw{zO49og|e|bHt4^J2`7Bt@F1> z=d3hLW@Q|6W6tQ#%zJk>w@qG0DNz}Tw@^tHwd<=p#HwHlJ9c#XsP-uXh`8j@>gP1{s!zg9DxoVY-Hz_a$FYD?W zGgo7VaQbWQHp|pHwc{AGv`=|oi^*1Ftp`#m<b zv%iHf8{OXr!n#h5$x}(SwN6^XQY4}E=}Xnis@d+$GT{?j_xwtSGauN{1j$YZsZ8?y zvhQAD3Yb9^Qt3e8=utdG!R2Ws{9KadD6MSX@a7+8Pxs2g17=^h-7!TLV{kNz zR_a~MM#iI_AD$Mk&`Eu2fj$gH8?cEnh_NpD=@8jYm6aiY(LBC_%<}xO zMpik8*ZnhiX+x*P>Awu7)5_9kFdH|eK3}uU+)9?F8%!2Im=SH$-?Z(H3DPqZ>6Yj) zjIQN`4+;6NN>S0Z>i0+<3`G}+tRCtf*Y5RMC*b(Es5YV%xV~P+f~-KORa)D>O~DQF zo-@Yilgv91pg#8&KflbyVm8L#y%%>mkjgCC$>b&UU~heNK*G{wHk}d0GFn>F(GkDb zx|~BON5$zZx7z+z#|vj2_@(BP+QMdgA^&@fl)o5F_couIP3uld)H0VVqj@3HKha4i zeeauR8$!tCiL0wGo&mj#uasPt_)Pke6wE$a zmscRlP^3>xa@8F#epL5pCt0p*sAm>m$rM zpBeV-jKoQ>7h_s2>7VSo&?>uFTgn9`{T3ZqOaE-+5QeUGX!0I#;N>uWq!{Tok~Y)d zybLlFr+;(b>~)Z;VKsqOGwz%goKaeqqYfK9XSeW@)UV2?P8d7#(d*(~1|0%Y)77~9 zN*}tGe5Bhe0rEMFWz2jYN*4p0;j?63xun5iUNzE{Ij0Q`-qunjn2e#d9axj)mfQ(tlk<*6ox2nTBx_|yZ_@1GA!-hBB1Ke} zg=4TI@1>KEkL8oMeBZa^tGa@n#HDQ#RiZ}E1-LMyGGrK3dXGfj;&FDkaZ z^lDp{F?d*4ucB{I`B$J5r1dhDQy71p$46gzc(Sxm@~J)Vba)weTHl^_!ZB`6w13Mo zfG8~Q)e>~e@2geIZ3E`3Xgq0;kM_#GB~IY?faIs_ZPc$7yMw-q(Pz4X&gj)(%gd`A zyDH(b$TJMay^lm_b@6T_BdX0|qT2ZGms-pl{#)R_FVrVLecmrZpwS|*67cjDL_Tfz zmK$Ji%*O_kA%hBE1gM2O_il<-q(M)$eCohKUYM-w94aQJKM-SAdgZ`~Dn(BkCVlhV zzvMK-R%B>v$Waw=jFrxC(`I3+`D1@-PfqLfo5Q? z8*|`{j~M?Gef&Y@i1%Ll+3h?8DI9}3!n*zfs}|gD-V?>K959#+ofL#zPl|fGdyqNqr z&k1VH*C{1!v4ld}E_&+6086ejQEYSZ9MC*^b^D`_Vg$yY%ceijE#!yOmk|}4$iYMR z+OXwOuDnT4wfR|AN>vS)frJmK2XSX^{bzStnW02Add|t}*>*MdzWXbS+VZpD4g|U5vMrI+lH^5{ zZ8q>!ejURqhcO9x54nmGy|!;@$zz6XCw0U;1(vr$Qfsnc<_zVtBK7{(jb%YE8~%Xp z0hp!qmuQS_1$r*`ee8EHRGulM(@hStMLz6eDOH~p zxRZF!Y-fZitcI0j_sXYuU*vAv8mJ<3b1IW|~26o`AGbv>A^2)u2sJ7(i{zCaXG;9!Snd9qRu$=MD2mTZA|MB*j(nIO?%70wpgm%!L;n7c0O8qa*4qjbMN0%luAw>a&#G{X9f|50(+2efQ8DsM02Akf)l7DapQ*H%R1p9E4|dlUlU;%Ug+qg>WW3(HuH zPJ?MAaxC408q;p2%ju^i6><%4xaeLmpBP3mB1VMX*iv~K(n*EQY@aW6az1MDv-YfG zCyjW(2x&|L>o)bI2)(&Zxb~bJRh3MRrgtRWG1g7i2Xeje90J>qLJNfV^a&!O%GC5i z5n}7rB%V3eN?34I8<18`N2B2+LlA12_#0q?YzOkbcD=^M1TiLdWP>Uw?_wBR)V*Ka7C~w0u5|eYH=}(k^=5x*$yWIWc zn2eGxM(^T|o4c{zQ286Pp*cIOf`FGXO9M0hHrCB7mul?4GsC{;Dj{Kll*m)thFb2U z@?0Ue{3pB`k!bd6{gH&3CrY9T!AhUc!1-IZ%2E3hd1{&QL!k>4IGIsLP0 zPaId=zIs2$U~Dtc0#+Adw<28%)M4KH`cNkLY1iN!1&o6|KP#ZlV6tY^hkvkFRUrj- zu|d2!gv36SZ4-J}LI7Kyj~1A2D)kvVkV?R!ODVGH& zuNb9l0XE*dDJkrj3~~Pw=M`R8=8GZq@$odU(bDV`8fn_`1NjLcu{93}(?uf)Dj0m9yD81FDGFTRWiI)(885~j{ zKH2LKn`j@$x#d3pWus$h<~#fINS7`%t?bAhNR}nA>fLo9)vEu|Te0w7y|J%&I;_yu7pwLuDmOi{R%ksY`IWJ*xLYIdF>Lt? zM)FEn&=sT;x4WSw$_rZEL@5j^?mJ5fTG0~=$*WA|o_MvfNemYtOcYuVc`u(D6J|_R z&<2Usj{pJ2Tyo5W%1$`j3W?u+2O_g**~=3LZJe2YF3YJm6f5B~Y9D*|Ew%EOEtwb7 zQPM~Eq;LbQGrg@hP}4u{v>~Z z`F%7w?gaQ=lsF;VJ#+E3{Q2+hU}4pDPJvY+JP~qc5U8h(1d+v&bQ!Im?ZqVA|7-#* zd45z4HFU(0S$5?1sZ)?n4P0d*(plcp%wSzufBDk?N&kj8F33F)!niXNarhj%>A&tSB2Z;sF|V!;)DDACa9t!ZZ8shw?=1LQ^pwI;uv6Aoq!JSD zDh4bWOmfoS1}n7`@!t}mJLA+89G)j@O<7*r8#OB4n7c|#HAzC_E1!a-%K!CWjWc=} z|F^6yqZ^B(K3r!K+}g}s4|$dwJg0R$yMTBqe}{kxlB_`e+S1KF|4x6WLU^@yfTwDj zMZ%(bPG6VN~NKR_$1n zRt&wb$HE3Aoi;zWe{=!XZG!+&q)r>l%C76+?WIp#us{M15W28Fj`CxwPqcC68n20i zIa^DvivYiuaKJy^;Y;8#x*NX({e1D$Gv*ZB(Uc4z*o`rJce2Vo^{pbSbAGo%t4hye zY2K*3OOSENnP9X){o_x~zb0kO8#nt&#Ill%NA8RKivI!VUhf#v|ioHguHV!}XSRJv#v~5Faco8?q*oR_XZ! z4cuCL?{LER4QKnEcVd1^f}KXpE~}%gvf#{JsSLEX68+ckF9O&{?t7hU8_{iG_eSj1 z;M(ItDXqM(zxkX zIqk7H;a0LNaBBe?5pKeG-By`#;{7|rJ2smjG(p#))R(rTg_o(W{MhpL#x2AWY&jW) zH$xiD8c0dq0yt$V;qB5nwur_<(uK0-k#4x#ST)-(C-ciF0h1cGt^nex-Bt;FQ)}sh20r%+@I8U5JH#TMo%Ct3 z&DYc78=RW>5NvUXT5(hE6D+a4rzB}s#0E)?_bHWI2Vo7rRYdsAp9i=6Tt!X+0Iw%^ z7Ojd5j_}Dlq)JLGavoZR-=pkyKt6Uzekt$VjC&T;9ON`{M&>s0f*1urP`>3|*HOW{p zy)9@tDk)N7x`FhMD_-{t8ejXg$4eT+q2|*QZo%2_O9oyV1}x$o&7FbXr2K(KRNRdWBY30&_&vl-&i#TS(4=gU;uQY z@Vd@{1%L1EfJ_iK_N?wN&FJtUU7}54qr>n7Zo7;-j14e0<)WmC2iZ+!#X1 z!Ii&sT>E0|a8CLm$yklQ=FQZ|$0JjWNOY}EQMFt>&u7;sXM#PE#5TjSm8wISjXmHA z(u&j9?;AY;dp-R6_cF`0#9%Vq@(EwMQ3wgd$&}Iy9><553|^!0>TXwF0+?DLc1|mj zt5nf5qh8j()T#Jh>kCKtS;Q_&-Q=6z)sSF9?GYhNW?;*niO{Xn z3edGmLlZ7p1!%n2g-{t%XpPXiQ(gYI*dgJ{`wrbEh$*=2i_y-+iwRFw7fWBD1!9gX zQI}23p%{7|R;B8kC?U@2^8U8~XBxrT-*xi*a;Wu=uL$86y7o}lC^D{$b-*O9P_4t! zNpnvev1-*<iKebhyAp6=A?_QXN#+PLQb-LdX-F6|rNbSb)3`wRbGA2Qy93vD?z-FL& zA%xK+OJEOCiiCi+j(@D zD1DG>6OwDD$jF`21RJN>zxC~^G_=4$*I>KH z=p=`h1F()2l3trjyLkktPp8*Vj75B~_Vi*>+rcC$%(6W7aYx|x*`c!qh(%kXc}$ym zDm)}Y;N|1}xRV6XD(n?8k7kUyO>dx*BbEq)2P zR`^Gzc-9pHcG6eB#JP2xt1z$WqU7^r2dOw%4~k(MR>zL$;?%at)^7WN<_h~IL^fR~ z!&MA?TYl_G*0AB^=qC-c#jmC^7+W?ibuaF*7-2!hY)lyh)@mm!@*fF=FHo$=Wh$a3 z$nA-gY*l`(Xb;!@v-_Z5AK?6qALM%{u(p^XgZX3e3*z(#RWH!mACULI+Z!no9&*%Q zp7V=ji+lU;e{YHwUIjZ+m3No#ZWfeYO>%)`$*)Q_F#bEi<9GXFR?^cSgGl3UdO!e$ z3&weYV7~Aev%4KyZ=N>hx<#6X53Ph?;6fW^^XJ6wVCSNnuj|`ef;a;sy7Jh zJ9B~qXJ51;;)L?7Z{5C&JC(Cw4Fh9zOf8&gbw--l%5>AuEH(`dxP5P_UOXuP%B+#O z-+C6LBOK8JA-|#R;0_XPQps|2C#io_zsUzcWLHsBsTB_%KpQ>~IjcLSq8g{RSlF^r^Z^t3^_DerK4h>kFMPU@{+2P-rdPN18G%fKt?RU^m$CO za22XtTdK(_nIv%U^6|5=@cG81u{d8yHgS(U5psL%-`z%5eKy--ay?A-C)-mHEyu#e_@rVA%+&lLOxl0{nZac1?RX&JR?CLf(R!yb z)ls($+$wNBALB`o)!g&1icjh=9p_9=@k+3uEQtSHyc~n^0S)wCq?=ELv1`ye+1zU9`ZuYY?fn+N`X8gib{{rW9lP}wA1dKpH z^3>Wo6W|}plzkheWy>EDy?ut=r7^Z2;>7~4j$0hTBuqZgN>`$OFgXPoTe#|9xdKce zvv%tDzdo6BQSD}4!0$YlX7v!@wtPygMrQAuUxZZM{$4_ueVgcKFp^>)%d*(DT?Z_eE}w^FcTE}EA@xA|MadnCr3=c`6>EyJ z3IH_g#5Jp~a&r?Ol!H0(jA9^Np(g>W)}-k2!xrgG!-&wcM+!ggw09kIK&*30vw)kM z*0YaCgVIythdXXrYl*sG^yn`z+H43&`bQ5XDqhT3+Gi)g63Sw8g0+tUw>Fpf?8Ew- zeuek2_nk|KL?U=_v#}A?9<+87wJu)fx-6Y$V5O@=(1_^T9^wP?pM2Iww-3=PA&s9k zvE}hsuertI7$-zbkwh%}&^uVa__DNgfYADn_YUj*GFmZp-0Y0~?B#cosNKmH&Pm`~ zW#4{K_JkaGF_QVPgtdP^7n53Wsk8FG!#yl@yMN7k{GH;b=(*~=b5QG+kh^K7knCFQ znFGcY=6uXEBVAJYg4?xbNE$O3kL%B3XT;qFvS6T;d(a&ehvcYFF$wLME71V{@h638 zdHaLtCop%;f@IdLECR;4?!EjQopkRY^)1Ffu1T7+u=>$Rm+U=$eP~1qlh8bL`^VMn zr)WGu>QX313iECery;+UAPWJ;t{duO*ve~4XIp{oj^uD1FajsV@*-RI}=)m>;onXqQQgnn3a=kD2bR0)zWpjd$ zkYDFRDa;1#)-j8i+~s#*pkLMNGI%wJJ1)PwXkePWmhLE@D$B*zIaNhBbCqmd3SqQ% z;DVOOcN;|iG}Nd_%~9g5UG<*fWw$)sg-KYM)H-1nliO9*;69A0PPm0qa)xArbGWj_ zjJ2_DIa%`@)Fh(z9>=PsuMb9z2YR`+UH|G zI^j}~)I2lpfP|mrA*kbgE^r6U%zbgEU5IKkX-3c8{dLpDC}$!-c@lq1Yi-8vHqM8A z7HU+Y-X$;NxuwwW`+$M#%IEb~RjLtR6DLeJMTMj*Qq!+vB&*<%qM>>6+KGkD8$kvj zaNU*WvfO7I1BBuoRQ?)MeLn}jE>8H$LoZgosCz~f=i^(e9q&>YO@wq<|1NdIg1b}> zOc)#t1d|;?#-SRuc=;kI!A+9_Yi~y3X z+z3W=IE;cJHINz&9k{R%%N?@<<-o#X^gAmWWP@8-_K-vOZKBkK17aNbIt*~OBE{+V zS2RcfMB~@LD?%tz-f;Hnx4#aqETLWhc#g|*>xH$1pL&q2+Jmz0J10=`RM{;ER?Pz{Tkz#I1eV{8?A`_n zJ$5dY_<;*xQ-&f0JP)^oLy`PsiU7pIm52V17(Ex9XMb!kd%#ozaHRM?z^cOc_F-%( z=)e`b8HgdMe@}!S6*-hxaq?b1q)5F{CTxL#dMHT0G}&xzS{AS`l~?SZ9819@_@FG2 zWd&*s#U>a7GW~wLC+}fVI-niMw4lzUW6Ldh=#^l#AR9y{P}FyW)yZ|3?c(ePF!eR= z;-zq!17;(PoA?~{@{_zqyS4?8^8{}}Bxm%lLzYO%E;y2}7%mgy?ywcjo+2GcNp-|% znx{3FEZsSbW9)0UJZZ*-;V0!&xOFvQ&PgCeS0toQpf0GtN=%6`CSDu73I_@-R`6{oc0l{=U8 zzLDW%O(%z|5N%()>@7JUbc0FXeR@{+UCnZY@?CqJJ;OmP!e|oImMeh8h3=)lyt%@k z14oGxR7Z{NHX65a5gB~y5$ojUe+|aM$N3I1f*ZI%cbwWNq{im`Bnm=1bA1}C|88#R zGPwD!vzgnw^|&hFI_Fe58V^6YBSxqjkc;jcz6@bD{z$}#Tt=E-?u)-Yb(yP5U4BNV zIGQ7u!8%?`!ylVNoO7*DK@M*U;Ha$#u^y}T0FvpsgI?#82U*oYMddChmwOe_<9ZbM9{_neT(GhmYPVL9cvX4fm@|#Zw?bax z%8#fb!fmqC0y6+CBF+B#bKnFwZt%I5@f?#d6ZW$XdGXZ9%$PoaG97qcY)L!RZG6so6 zbKOwLt)^7qZyCcvV-L0u8&MLlj6Y3QM&i~;QH>!p%#T@Wo1EmpEKgD<=(*(#^igwgojZDxi?gUhFfdkd_A9EMkm5x zS$0l8cCx}d>1@ErBnSbBDx8;p-99#1ZpS42b39Ce8tiR(rKtvv*RHByYOFAr`XDwW zEzButOi7&ud?o*GY7yMr<_+mwE7%#Z-qgJZr#2FOqd2!3S3dh7$d|bs15Qhul1-sy z4rSDY$WfW2V+Lc%{F*fzr`N~Lkn6_eAl+0Otcb}jD_-lHf1dJ8AXOmh~zvRoi5R$!Y=>I<|hW#2A1tSZQ{?wqk_wy!w-V-;&W z%TGSVO=i&Rfoye*9LTa&6k=a?(dUeOJ>{u4ALYq^g6kL04!F<`(a^3HKUH)9(dHCs z8APg@U4cGjUitt7sxj1wqRZVdMUrJ)z6w=m0DNQWU1pSjK2Kh&ijvVOoj*T8zH zJzj>^mcIv)4Ic=QN`)6{1k`w=!qnIDJcQeRB=@>|4}KB><$Q_G>Q#(JE86wIPV;Aq z)SE@#ZfuL%?36^_ym{XH9Z?qX)=8QV{lo~D^Cyo(!qcfKXl?w0WQ8NHJbK3Wd~3I- z@>S>6i>D|yQ#aT4DQ7uDA$sSO!;sX_#I?z>%#*;jr~=#K%k-2{QoVN? zqR5;rJLDtAs8K=Il6YK)_xWA}g#hn^eGfF6s^B4klYBZ>9_V#2+F9NNso~9|mLM|r z*WXeOO%_DS9mUyU0#^SD;T5ZA*e`~}KKv%u&PsnLfuWiDW-ZOMg~H{)ga2(F;qH^U^gV+POr9BDMvD+>y& zhKC$?o3&e=;zR=@O!m9q%IJ;ehNGLSL@Ry%u!Y{&VbwVI)uZ z2dgYv?UzkSPCzW;iD#gRg={ao#OC68WH!M=o~l=v^_LX#0<91*fw*7?XWbHt$RJ7EMj`O5xFP5dGt7EtWHRCDegNFj%7K>!4_ zs%CskTKIrTIgko4tT{U&lhA2ZXYaat^*3gaY{2E~BN)jiLbY{2HgLVdJBv&!MB7|6 zMn<~O$+rA8e-ibeknBUY+8#TKl&HqZpw4=-nt`r0WMJKPsV9SaIt$bIOW{Du^+>Xg zY(T?wC{Ow5a}217+}k>FfqXkcdhIMYQE24W2Jn(&o+?$lC%}0&Cx*HmQiW=^gG&B_ z{MM8RjO58tC(6;NS(CevZ0&^y?SLi_Xm`Lrw8xjbh`2>n#qFIe%M$*{;i=R=08%ci zE-C{Ra!^1Z)<0L!+=YP5aG~ogSmn3;!-=@vG*6_vbcIGU#Gmr+*jE4^pUyhi`tqn- zOwEvS&5ESu>CEyI*?=U`Xkc6(F%}?DUiRLtd%_2>RAs8_Hu$RuKR}wpXt^9})p{{O zd;NAxHXP*;Cz=Y|7|@9B0P&Fx!0(ZnnIY*(lgR4_N95;n;XwZi#Ce8M`!xkHW}TgC zs#izLSwAnd*1}Q4e|}pBTeNxW=yjN_?hUVQg{rEH9UQ(S!EB`|)hElwbBB_dCnlJ? zu;sr5qXyi9jmb+hIELC<_Hz(B(YlYj3oY1V0-Sxm%2regw^7I!*XQp(Hl96{%=*je zkB>kLgv#Wby>4**mI)UVg)Zfw=ML1s%%iKGNDWDKE-ImW!_6WdPO{q?AWFErV;+DVHiNE*FOmEFA6T9RrP|t7kB|J5fP2PSz23n;d6O|n zUte?cY*u&E0v_m6;fdMfBxtbloqm=b zmy8)}=?LauPIs=vo*eR^kH|&7(!^K7PF1lSb!vphB}-s+v%d(pW$y+=s@a2XI#@=a z)4khz)Z%totxknS^xW`!-x7C_jb0CvE!AZMsu7tc9TXi8v-eKPYj4b;!(~Bbpka$i zBY>~0H02t<_D&wSj3kbzgZl8_qNh6mhsS; z)|k=xq(^pZ`^}4>b{LY`c{Bm3a@Cp_PVj=tk}~~jUSb()^Y=3IxT{|fIo=b#nP&KG zgS18jF^&$0keew+kbQgPG{j-1s)v$f9|u{!ib(?N7rbz#J~c;%zBsokg&m}BD>XdA zF5Tmw)G_#cF%pE}#xqa0;MAU15^+GYDR$@VMG8wrlhl%&9FT)Drn^4CQTai0TGanE3F5E^?#v5^F7klw=n(w-U@?P`c0OQ~r5+R$~i zj+o5sFC|_kCQznt*7edAd~&sn(`|({r`)atxTOdl+J?hyv|P$*_Q|BLR2j22#)15} zVYg+&XMQs+BafW{=cQ~^mA9^5KIyw2_@*4F^g3VzYGocIcp|sw_=YC7rUDMzt%hpZv2X5=SaLs9kS21Sg(v!CCwk5& zVn3EKWN#bpv1F^xrb?VH1nBew#q*!g!v^aY>zqAvO%Qb|lQa-fR_^t;tF!UpMI9rF zP=~)iXnP~cq1a%nm#al zA<_~#2qd6;^SK0`z~Z<6wD?k44_>+d^TVMjdA}4(Op69M+&i2w+pw-0U9*NPQgUUE-!4nU%Xi z8JO9)%%28o?3AP}*G4L{oF6MnlL$|hYhjxynWq3AHPgIsvk;VN$h8`?;jF1x$zuYa9q`s>#F_k=f@eWqL}D5N8}s1&QJYseaD5T? zLS)RHygm1|CKG3GjU;od5}!`M^>`WQlqZfDf^75AoY1H}IEE|Vp}Tk7f0Hwn&jQ<} zx+(D~5VCV1wpNh@@Hhv5c?Tc3+UHMJIT^8(ZJGg}7AbUz5>TPIF}}wh3UOT^W+Zs) zUIWzpOr;Fm+GeAC(#9t7RfB#5%^qnI`s7qhnfUH16q_OFtvg!s5U?j)ErvNmbvKo8 z?|O!10{15I2&A!|Z|~Xdh|cs0UNm?Krt+yEr$mfx{L*fH0_WR-<*;zi$L>lmSv$PXFp0fZG zAKyuje=JT+rPqo zM9-M2A#cx5l9<7X>K-GNJLu$nqy`s_)Nh^$$6k2jWQdu6r~Z)l>hB$xgpDURNDa~? z5`HmJ@dqlf9Jsxa8^gB%8hp#&pQ(SP@l3v%zj5MlucS*bU|U@70aoGBpP-Q$i(gSl zxQMZvbfgKQRUhkctEh0JZCbt*cG%CdpI$qG&JxY-Xfh;)NClPi9xh=i-h^Hi0i*JL%X_(i0f_o=x`M^e|x|z%G zUD}6yaRY5I`R}V39(Ccdm9WO`xw%b2paG2i`RhV=``2I23+@lb*4n#0Mjr|(HgSu4 zt4|9=-yI-4i+9)5mP@*qA-}~4y%*=>dd{>1 zdv1*Se0)UL0_Z&29=Z%iab9GmQDh%(tT=gx^(fzk&el z5OAzZ7IH;!XFyu;X?bd<)SqGFwhmFcBgbu6Pu>G9D7u)tI}IJUNa~l?etTh!_xV~= zXQFrQ9zCF8@yEtT^I?2tpR(=>w}!l`luL9y3#gR2ung(T1Ycvr(Ig(c=k`|pj7rgq z)X+j7&~KF-~=bvW`0VxSD=4Pz?^@K zoa#r<4cQR;-vVm&ZHTklU*yX><^D7QX+9R2z3Z7Rc<1c7mZtHqzrHPvMpZ0c*z3vU ztIwX*zjE>lNL1}k)4gZrSF7GvHJz&*HFN;VbGirg9#|qcm)L4zX6iHk>SJ-g`&&S& zQ^Sd!>zZ31pJgu=e~6BsQti&L%n(aE;|kKJ6u-wubEv32)p=9k!+(>%rqo4S_Lc$&^$LbtRU?4Y^LITA92-^w~8NBHv(e3iKU?ji3n$rO=q%ehN z{n#I2B$;atoiCq)dKi)(hw*3>N^G9{{{VIeU+&J zwmjAceR4%Bg=}1nt`z+Zs7zSaelFj-7L(Ao%vPzN7xs~F#_3$xc+umCWxPzg--K10 zGWsIRejb2}kP)u^-Iw@+-QFG`Mjukrx_%X`4d9vV86~eB*mmLa=)aFX8etOpuXQ}G z?6QGslGx=PG{A+TUj^L-0XVfEnRzpf%0R@%>%wbzBhOs|Uc29*a&ETA0mKBXlgkHw z0>p|vUGfqzCVp77UDK*Bb4!;{hl#Bi{PJVRyjdO&(4*M|Q6rs}wE|JzI;=)~Ss`;@ewK>K;4a;?$}lkm-;qj_V2*(=;e&d@CBcxI2J&gKDp{iG<} zV?|!WZ}s&vJHTt}H(vf7lLy*o*Yn%IO!RZIe)BHrP?~?+@olUq8;S2tg{RGsSxN1- z&iwBn-8eQ>G5f&+vvFhSOW8Kgd^SiqDYTxnLT>j$nv$L_)RPViQ|ea@@IOqD4>37+ zHAgbqfHmT*ICX?e0ELf{>7?~c%x(+5K^$Fk;i&0CIFtsW^g+UXN$5&P-*`2&=h6A>HrY!52o*0vf97wIQmr z9wLOxM#R29P8T53_pm?lpVk2aDL>1dyk|W2As9P^p3D2Qen9#SfEwk!I+b>^{@A7R z)xyfJ+}e^IBgv$j#eR$vXLa}nZBD5>zdr?8mB13Mivhy2X?a0`-ktBY?M}RhWlEwq zZrlN=GUZ0GODpXw0MIzYeJ8kmSXYoTb#f@NasNT;QdHYwa=D}rg7Z;pSa=Ao-r>fB zK&Rc{E~~cp8XYv{wp?@$=8ut;^g+7Ga_vvgR|&x~PG3JbM-c*TEpC0Y0}{Cm%wSdP z&$!QE_n`Kf*u=84wUGm?YIpKxc2R+bR01SHBl4P#gw0Xgf6aKl>oXq-w@T2E zO-NXOHqp52Kf@OW$lz+oPE6jQ54^4CzUKl9^T6e+59r@A0koLEMn`C)CUOnxRBh>t zjL=Qey=eS#cDD<nXkUH*r&F#;*PsNB#xCL%Xxvy8l9APcHZSYSf7dtFbi1zyY z*vmYiB@K`;(QbP*IutKJA%vrpp3OO+accJcF48DKxfAP$YuY#Om%F<4IXVvym0<&( ze>VY)==?cjjP4n>dx91iF$Xhdn;_vVT}o45;wwNCA(eF`Zwfr& zxm|?teYv$Y2{hHAPbSweKeP`1tbmULmDq(Dlv_XYPJj37_b{`H$oc{Zrq`!h(nzd( zQnD$;jLNZpmscV|A&;14F%kLSLF@8BM%9!pdTlZ7CmMC7BIt&4%sDgW0RhF#`i^uL5XB8N}HBS=Og5 zwO;eZ`jn9kFV8#yeR7{dMY+YTe9yrex47M3>@m6EWk-rDJt17&0Bhb>#RDKg;CXY4J{7beK z&>dQUN*b3_?wkgaF&Fna=({NWv#{MRB!xknNM{ocK=s7S02^W znZ@&h0hNL}0;#N397IsSvIIpoQLG|?$}XD<5)?>K3SkYg6zGgntVoq5EK)&>2#O&D z$bu9?t00JgKth5G2?mm|FG*m&U}w&pIWzP3oHPHto4ofe_kQ2I@7;Ir{aqE^kb8u} zFwUMbF8avrFynVQ<_B014;EY8x%E#BPA6_NQd+lsq z45+XI5KFIN$g@*{l&uYw7E&%u5n_jbHkoXXE%13o+ zs6LU@5=2FJMoe@0F*J!@Y~16WQHQr`YLb#jv+l&~*harAm9vtpz}9l(`e zmUM}-09=`3)%Oxday8*0sq&*3zw$~xv35oNYUViTtr$@N~(!RiR(+CJ;vELdB}eAkFzpRu~)ISr@B^*nF}Z;xY} zJXACrHC7n=>u-n;%ijCk9|2!9J&WX@r@_kYCoJkGy>Ik61yRh@biL_B@g&8iUA0k+ zc$h>@()_C#4?DUYax2Oy)RZKzA>Gqak=uI~E46lM)u|F69D^KF5**IV!$-CEPT1Lz z&%{F6LRtF#{Kvqwh*ais2r?63f~DT#NL#k;(u}pWi1y4?Z0f>pZz>VL@LW1jg8ar$ zkY21cf@y4;z}HLW*BMP3V3|`?#8V%9On6%daKFn&ORQD* z@#+G5!ak=AMuE)j#4oSaOtYNOPK+H_b#@+svfVS3=K)SzoSO_PCeuoy z;}?}F_s?VP^rjL0aFziU4)?eB;M8@eHX>Ra&h?Z56cs-L1yp>b=mP_Z-l-;wu*UuP z(v`G>``{bk9M10=*Jf`Lq#x&?5STB5kvJpD!!NOs)%Xu))5wWLA$R?*=6`E+oO6Mw1iX~l_LDWasvEf=X(0tLw zEY!5Y9C(s=`GKe*c2dU-1Y$u22_DI^6=XO0TBBF#VG|Zy^MEm%;anSrZO}b9wgyA> zo~l|?1Ev#=oOgb6<1#zaIY+e-6`Z`pTk^jP$C8SD#P%hPo%3!!Y@ONtq6U-G%$&AU zxc-aqm70Qb^i8|6pZD=dni&YP8Lwop7Gzas=k=%FX6aDV?p+E!zB*)NL~*#xcrv3Q z@$K-ayQXkzCMAdyM#1-u>vc`=C>2lA{Eed^6uR3qW!vieBWUh@?OHcUpL-3;z_?%r zM7_HD9(n{RjOv=B23hsJH*ip?Xotz?M4%gSy=Gw$<(D%I9OdH)eeTm|M^5NpKZLLI zd<(~_U!Y@oLW5no3@*W|l9RGvQ3dKlDCHPZ80P`(Wi_&?-^>pn(2fl9O;&dlJ4S}D zrG32g$jXsB{Nak>tvaI1=d`Y|1HU=4)OqH=lT$o`@Gc?MWk{o(?Vp{37K?G@-@Ta? zDsk3{)yU)ZA}(j>v|a{suo+ZY$$Nen8?xjF_G9_U)Tmb*i0;@HTc5J{3c;?wG7K!J z?2c)IyTjF}s+v;__n4nVzrI=MjTF*of5w7{fBQ)@rTk3-l}S!QoH1|VN06)?393I> zfOT?)%paEa3pk^lX5Y45+ADUmI6$R)-GpP+3~D~iy3l1^8|E^$rOte(jP_-Qd39_A z^+r;#k3!q`@tR!(ZP01nw;qf4#u z9}Zf2u_~W~tM8e)4PNP}zLONcF}Zp-gP4-tQ{JS1gwK*Pj1n7V$15LHj13ra3gaL= zWdWz_e|Jd#5(c0mCWD%mzHbFxLofNE@n?={#YSP$t~7Osm*=ka_Y4kkg(n}n73`q0 zgN>Vrc=W=cF2!(5YgLzrx5Nv)H(7CY5pH*h-0Q76$OU(dd{d1R>ReGmSp2fzI8E|aqiy;6-z^mWOE2`jtggvvgqP9UV zH>GKMF5B$q<&T=$**MFfL_UA=py>DFf|I`Q|)I zC6?l9aK^kp9a_XDShr9Qd{vL`8w~qRh!XDEtPy^3h9~jaNY#kNwK9Kez1vC&A4fI# zdTC0YWsV^cvQE@UzOapApXUQ{Ke*v1&tAsz25Lm48hmNX?n9-4+Q^}!rtgFmQ{7>1 zx4pDt!{*;7T=_MCdwQ4<=X?g-48b{p&e`zQTLlk<^N&gBHAHHtIV-RW(a@?J-#vR}%y>}bQyIs^=t6eIC zFMb6v`h!ClX|%Wct@##DE?cnGb4#06@Q}1!XdMW`BH^=cQKq+50$H_MO*Ppb3*Y5t zbI|zsxux*gNWXf1j-D}PY0E!@I2tR^Ru>5iwH_ggb4HuJLfl{fw9dU?SH0!Hg> zJSJ&zE+Gs%EWcVkkF9kdof=ck4f%qdMwXs;@(sO9w4|WEBrnMX?Gq~^Np*kbc*gT= zE#KNK4|Fz`h4O9Ke`op4i`N~!J!8||>4SUXkw1B4fudN3NkxPOnc5DJ+47Y`O2XhvC0*lqjSTl4Qv{T$BGCdYWtvg(iUHIF6N@g z^g!gtuqjb6sU`6F zSUN=L3s=Zs=q=1M70Ml1C!v3kVel^zLK($eh5@ZqW5Tvp5SzUkY+)K9%&veyUD#%G zUgnNZR8L1225@HQK9TrOMClVr`$RMW0X;gtS5t=pU$@}tC;D5%EY^>wv+xD2ynX2&RNOnJ9vWON!a(EOf;nAG>u>fJ)uHn61YQg-8xMGLTiLF zr}lzsfWR)Y7;vB`mlE*QMY3i)kuc2_!Q3~1Gnwn!_P9V48ia{jI zm`-GESRd+IgB45z*!M#jH(+HTyWnZLVm|tC{W=|`kf1UF03w%UY*4VA@+v}^_)ImC zk$5moydM{9f(wjruWW#oi9vx0|JcoW@)|AG!nK;qYfN5 zo1X;@fEWD2AMFymd=>4MzIo}2AbzWAtJ}D?TQNZO%b2ef;?^yava_+4&->Aor=~EWemCYPJ);Gp%nx!om-J=0T&=Y;_6bo|se%Ndxjx7R83OXE1s< ztdk`h?t14Tx0C?J+Q+HUC_ZB|i_hk=OLfG)Jmu!ImA|tE_$Pihg5Rw34gb)%y#f69p zRumNxoJdu~g4GI0orvO~D7a@qiilc^Ra`jkAKa(4eR}Wh?fcjJyyu+f{LXpL4}cL8 zCXwc%Y5+M>g*-agACFH+#L2yY0u@N$1RxOR%fe>`#Q*^C19^CUbg)1C0k3ZW0swH; zE+i7i;s1lWP$pLZAdvvzA`<5d0gzGv$SzdK6adH=0I*ZDWC{S3003-xd_p1ssto|_ z^hrJi0NAOM+!p}Yq8zCR0F40vnJ7mj0zkU}U{!%qECRs70HCZuA}$2Lt^t5qwlYTo zfV~9(c8*w(4?ti5fSE!p%m5%b0suoE6U_r4Oaq`W(!b!TUvP!ENC5!A%azTSOVTqG zxRuZvck=My;vwR~Y_URN7by^C3FIQ2mzyIKNaq7g&I|wm8u`(|{y0C7=jP<$=4R(? z@ASo@{%i1WB0eGU-~POe0t5gMPS5Y!U*+Z218~Oyuywy{sapWrRsd+<`CT*H37}dE z(0cicc{uz)9-g64$UGe!3JVMEC1RnyFyo6p|1;rl;ER6t{6HT5+j{T-ahgDxt-zy$ z{c&M#cCJ#6=gR~_F>d$gBmT#QfBlXr(c(0*Tr3re@mPttP$EsodAU-NL?OwQ;u7h9 zGVvdl{RxwI4FIf$Pry#L2er#=z<%xl0*ek<(slqqe)BDi8VivC5N9+pdG`PSlfU_o zKq~;2Moa!tiTSO!5zH77Xo1hL_iEAz&sE_ z2IPPo3ZWR5K^auQI@koYumc*P5t`u;w81er4d>tzT!HIw7Y1M$p28Tsh6w~g$Osc* zAv%Z=Vvg7%&IlKojszlMNHmgwq#)^t6j36@$a16tsX}UzT}UJHEpik&ja)$bklV;0 zGK&0)yhkyVfwEBp)B<%txu_o+ipHRG(R4HqU4WLNYtb6C9zB4zqNmYI=yh}eeTt4_ zfYC7yW{lZkT#ScBV2M~7CdU?I?5=ix(HVZgM=}{CnA%mPqZa^68Xe5gFH?u96Et<2 zCC!@_L(8Nsqt(!wX=iEoXfNq>x(VHb9z~bXm(pwK2kGbOgYq4YG!XMxcgB zqf}$J#u<$v7REAV@mNCEa#jQDENhreVq3EL>`ZnA`x|yIdrVV9bE;;nW|3x{=5fsd z4#u(I@HyF>O3oq94bFQl11&!-vDRv>X03j$H`;pIzS?5#a_tuF>)P*iaGgM%ES>c_ zZ94aL3A#4AQM!e?+jYlFJ5+DSzi0S9#6BJCZ5(XZOGfi zTj0IRdtf>~J!SgN=>tB-J_4V5pNGDtz9Qc}z9W9tewls;{GR(e`pf-~_`l(K@)q$< z1z-We0p$U`ff|9c18V~x1epY-2Q>wa1-k|>3_cY?3<(WcA99m#z!&lx`C~KOXDpi0 z70L*m6G6C?@k ziR8rC#65}Qa{}jVnlqf_npBo_W3J`gqPZ95>CVfZcRX1&S&)1jiOPpx423?lIEROmG(H@JAFg?XogQlb;dIZPf{y+kr|S? zBlAsGMAqJ{&)IR=Ejg5&l$@hd4QZCNE7vf$D7Q~$D=U)?Nn}(WA6du22pZOfRS_cv~1-c(_QtNLti0-)8>m`6CO07JR*suu!$(^sg%jf zZm#rNxnmV!m1I@#YM0epR(~oNm0zrItf;Q|utvD%;#W>z)qM4NZQ9!2O1H}G>qzUQ z>u#*~S--DJy=p<#(1!30tsC);y-IHSJr>wyfLop*ExT zdYyk=%U1oZtGB+{Cfe4&-FJKQ4uc&PJKpb5^_C@dOYIJXG+^@gCvI%WcHjN%gI&kHifN$EH?V5MBa9S!3!a?Q1 zC*P)gd*e{(q0YnH!_D8Bf4B7r>qvPk(mKC&tSzH$pgp0z@92!9ogH2sN4~fJe(y2k zV|B+hk5`_cohUu=`Q(C=R&z?UQbnZ;IU-!xL z-sg{9@Vs#JBKKn3CAUkhJ+3`ResKNaNUvLO>t*-L?N>ambo5Q@JJIjcfBI^`)pOVQ z*DhV3dA;w(>>IakCfyvkCA#(acJ}QTcM9%I++BK)c(44v+WqPW`VZ=VwEnSWz-{38 zV8CF{!&wjS4he^z{*?dIhvCvk%tzHDMk9@nogW_?4H~`jWX_Y}r?RIL&&qyQ|9R_k ztLNYS;`>X_Sp3-V3;B!Bzpiphw{2H>9r(?CntNX_={+PN0YZqrktI2_ z#ux$#rrcsDvB9=%GF-M(siek8>VK$TQm&Dv+$4^{av<2{fJ2!9jDP_Hp|d5?gMml_ zB-9{1y{FgQd(PQ=)(?9%-&%X0d(UcgpT;QNA>;eHefQaWef|9A6nXON$*(8Bp8R_9 z>&dStzn=X1|J@h%{~N%3KAX?Crqk(UGCAnG>c6G=2BZL0egFj`0thJr!u$vv#ODHq z{SV*pC9MAt0zv{r{i%jI%sXJ=<;hh)A1G);5l=+UD` zj?CwC431rYS|}pyPm+1)6hYDR*N+qK>P2rB?$iOHMI~Ma0`WGO{W0M_Ptm#SpAJ%P zMLk@I5NmBdJk)z%4FZ4M2?zzo!Pwg@|FHgk*#8*!GW!!pgy*?!yWQQLvuDqqIdi6M z+hhYcbm-9KmtQ`g&qZXd85#d60)XaIkA2)ygHWFuIW9A@DFH}|c&pC2LAaYzo;b~% z2nOLO-2ena(UzU<9Y9GAu91~MAg}?|J&$V9$XpTrRN1&k`y9eg006+nix(ey=)rU6 z&W~PnJf%5){P?L;r>4{CUJ*n)6TqJ>^M@4w49Xt>;GQo^T#7j~5J0C4srLx?X(5pQ zVyTG`#Qf9#j&cmpoCy>h|0ph1IjFGlg(ysc5IGF7LC?5+Z4(%CLL_Ii+41AYx{enw zUfjq4jvYUC@`{t*yYCq^5IR;cj?MMT0oZ_BlBy#xO7|<|-C4n{n4{rOerj=p@U%&O z$VFh%WlkH~57x4%!AYY4z#!|v`nTR3J#w^d+nt@AeGK5xp+hH6olFW!&<_wc8W(2C zBcB}rvyU7Gwp#pt+`H!H9fjEA!X;11r=QOAkJKbccqniWggUHbrcyd$*E|E>Te+wL zlMZb91CAa&dhz1L<#HJmx>418`Q?{4Xg0kk_EE-sT$-Xds8(tmenx3S|65GCjQjh} zfB-QeF7;aWl7THU{iAa9M{~n}3LE14w42#ao2HfnO#sh&8ul>Q?9%=YS<3^ z(7nS1^8#??l~+cc%qB9C`Fzfld#3FLk)~LV&nU}2xp|_3@O&V@8x$49iPs7Y$iDK- z&q&j|AP4u9aCr0ExAcj!cija^o$tx^7tBvDL$B}5lIV+d!X2=Lhfng*p+hH5oESF% z07s4-Nvuk|qld6Bx<|8)%r8PYXfnP5W}JSSwi#)<2swuau9ffK6O-@AWFTbLp)-#K z&h=+KY)ar5;M-!&eT5tkfVAE&besrcD1d_*(A8(pw!~o{=`3CNv!|xF! zJwiB#7I&?3eUu3>gERw4?}sYM6@h8gG2>0sojXQVBhoFL0_FrWm0>e0E3}5(msYe- zIk$OX4-V0{e+sNJvd<{%)7N$V|4maza(jDwYin!V0QRj45mi|xtp;t90y6xw%;UPQ z{?GPL-bC&5GKPviV5gp26O*!&1^B)Xvb+PWkAWWqr`w-#S;{k%S8eo}W`zPEHfukB z?GGN2n71`ev%S4NVgS?WH2H3{mqrxWb#lgnQb6?z>HK(EN!1UI2vq_wYB!#xg~f{TJD}vvadac786=g-*+B0~Nz(}ONm9KjNS{~{e#n@c0)ZaEqWuOE zPfUMwbB~OfADd_8V@L+XL&dL*DB?VeyPNEn#^`o{g18i<{tTa-Gb~kV=Kr83%Ov%; z41!&skp>>WC}~GrW2q;?+$K(H19_}z0`$&~%=wHq>7esG>9NiHyM7{?*}0+rNST?~ zSXuy|0xQyHgSLkz^LaFC+cFFj76t^o$1+lkDL<|Tu4`vIUnDB#LUA- zRWIiCV`&>e%zo7RU+Sls(_fCOwi;a^?P*DvEN$F%@t_P~#3#aLu)a;B?iA%t#ZEn8 zldY`DtFB_wIwi?|KmUnU~ndAHmp$ZqT)+LnxZ53p&B3w2|riNH3X;vApb(t!_u^C zxP(~8!}R0@(8mh7XBK`63_;~BFu3!D;Q3cDucp)}U1dVjz~MmT53EMZPVp_n!qKuW z)d;vwOip9UwN8NCT#s(v3);4fM$lRQ#as)t> zNcz02a{lA%2`0DwJU&ksW+k_Yuq{{N+@y4&eLN%;I4ODZ1Xs*6oN6;W2U0OH-6wF* zKX9-?sF24P;mCt9fFKUh=6xm>*oF}6w15!zQ}YIlI(0SxoO~3gEdiLj@TT2HMi*0q zxZNZ-V~{hR_9MS_q53n-M=h>Ru}lYp8f(XdC{oP;sLp@X>{94GRtW-R+zv>`T?Vg~ zwoC(=8~H)%*N}ZsOm@eD4vsk%$aH`qXqkoBb@z#)Dxi4r$hOKT3LPKTf|);~ECr%J zjTkoKSaA%{m)8n%o`-)Y{Z3 zvl}7IoNnx61Kt*x3gW6|0I|jS<$v@LOE(1rYVE@H*2OAS59}B?x1FkH$=)FIa$Sl} z=5zW`)NB43j?k@dIh0NQR4-@;!7r^;r~w%@eoCHNsR1wyE&o3Yb@=hb*$VzXJxwcDIL^S!JnJ$$yFrhc3Yhpoz%0x}h!5T?+ zQ)rt$4TW3s);&-bRVcpl4H1t8h%KsR(iFrJ2Z;j(dKo40Mtme8r9v94+e^qQ-)b2EMw>PC-H57lz&K-P z(7i~dh6winO15;&`9<`8Hm~S3KT*QHurR0O=p%tk$V$AnEB_dEDN2JtzrSi*Z$Kr3 z%`^axW@m0zTX_y-7?gOUKlS|~&57Rf6#0{5O{Pvye6PWx8^(cpO4S+f|^V2B+MbNN44xE|# zp`2_6s(Q+!atQl{NJEf0W{&~4B2&*i#2&IDGPkfH02U@z95yJ6=W8l1*u-(Nd7JWW=H- z{|?IxNn-G3WSjKc3EcD*4pEmLhL8cv$j9H0ua>inz{YoX{oV#@oP4Ub0UR)hPXGhZ z`7GDh%GuZMQTuk~a^rsY`d~_r0%E=!vYn}MJ!upm@6+qpHP#+eW zLzsb!q$abrGeVf?fowoUAhVQJv-;{8maDpE;v?2R;X1Vz6Qi;YTnYoAgmB1cL#amO zgX6>Y%f|WW11JC!9i%z`;}6+ul9qIUc*Qj}-SA_$JU|d7-i6OdFs;AWt59TJ3-E1l zHx{U~a$L9&9|y_EwBx>t zR>&mgoqW0-V<4{Is+Gd3B#7(5Of#FNKJYy|8#MZu!AzZ{V;b1zkCuW+xhh4DZOgoo z&NLlOyizSXCY^r-mSu!-H@zhQ!kr~9uKI78^N|K`hI!PUn#&fBfi=?@oe{vYxYZE{ z1_B;!XnKfJCDLiJT_RlXQ;5qN%y9k@Q-YR#%2ih_UVP>1pT2Un>g0*=HEHDT)A&C= zzP-EDsybOR8H(zH>4z7-l($TarRNq#eaDBz;sd~lzqAKq)zKlHRyh6&+1n>Wa6K1F z9TqqHp{1vvOU&J;6MpWylfQdI`yntOwWtwwAsE8p!_brCjNEsJ4cx{H%+icnj(8>5E)_alhTO|@-mUc zx%e8Rguh^U3LM_58`dEVRw)Jx?Ck8EJ9n<24Z5a2HbmW?<%1P+z+eGUYg?o_nAwDP zJ<|L?Uz|=LPlT_Ia%@X}`R3(x5@9EiZkV7)VO-^&YnfhZaYja}Y|?VGZgg%hZ|*#tE;p;MBn!Ooml{fK{V_^11I$ET={m zAXJ>}QhN3SUB;DEu3i*LRRQ&hq7ftnwst@G8X%b8Q=HqUrdwbIIII%hfuK~%a5j-Y z|LXJ`4`KGiNQ8D*^4jZHuXskgTy6ZMAgUSQK$pye0>Qnt(xT0DKb<#xJaz#r-&PP_ zN{&QRa5pq?NZXb)Ng$OvcpZft7e`!+As=ehfM<7b+wHSOTU8vP89n$!)!PF zOja^eDe~qMEUF<6t>yu9-xKtv3ad1LeDY(>jK1_oaigiE4GJBWZ0b|mNn7`0Akl?0 zc?&3*G`#n0bHyRP@G3qL5}}TA>M#NR&Arn}lkOY*BWHndh(%Q+*Op+1;c#t>>c;>o z1=2i$3CUxv6bO+=l5oL7O0?S~_WWwvOcn@cJKB~B@_tUq`{(dok^@Qz6k2^q zJ>`lYWD_ky1d~R7Z~_16j#)>!Gz}pqC1i2*TQj-!mfd4>cAK+9*rl|9H!!^n_C)~1 z7jt=?3Qb;5)>@5%cw7N}md2rG+Cip3VT%f;B~1hsP$hn78w#LAUJ|bk@zQoenKW|G zqs_I)`Rr2%n+U;_jK?{-)C!hMrX5}_a^u#7Rt7rfB~)0ycd0xheGYGLY( ziCJCnD?o|Jm`W)SBBzQ`Ky4ivCn#~=0wO3kE3^d^NqOfNW)Gahq&dK&51LvDqHKTy zE<1ViOBT<+vR$?tdtLS`vM7Y|7ZB`9lp244d;qfm7)*pRQze$m!TfFt9yIZsUiB1>@^hrU-9d4&l z(jAs=_~~e-jG{CNb_Ci+d{q&+IDLbIUW!*JbPLedU>(%vNHmlvC{-T=;b`SS5t&cq zBj28U{@!LjecTSem!q)@Ox75N_OR^aho83k@#ifUE%tMVcI~jvqo(*(R-~VV9tvZ( z!8{NEHN+>q+o!`DFa(QUlBIa>j3DSSaKq40t^Z}YYzr5T&0?6t6>{0)w%ccCE}}j@ z!ut5|l>2j!Fa_%Ev!(pv&AZRMqFukeK<&Fx)^AfeMKPBrXc$33@k6m{MX>7R*~u#p zOd@G-e?(`IX5m(H!s#BTmL6G%%*zH;w*Jv!Hj!^X+`Q*2)4G|Ecl=?(;UhvG-52FhEE2DL-!Azwz3UAg*INfJ?~e~-TbaJ>Tws1c~w zhgoo5^-qS&c^!5*cX=?7HnS7U*@W-^`sB+GR04`dXI+AW?vB1QkEj|3xM<}^Z&<$e zIg7<=Pj~CV&~z1Ij(nyr+X`!GzY1T>VyteHmK4Z5IIxmHOhq(+kD`4?lmS;wsZb_D zN{nK2GCTvumKxx~61UwxyRa+bw9vK zgYQ3vBXha&srf)r-Qag^D;czXf}=ke2)IiB^26QsOg?khtZCNUn&XH@VBhIahK^w_ z*|nO}skYWJ+6^x>0tUjcFmoZ3b8LLjDsF_0t%ACM?=qKymW}5agIP21aV1~j)Sf~5 zMaw>3PaAp9m#5!)xS2JXr(dGezdj2ZH-@kpUUu@v7wo>``ql0V>pDTc4(6pvJ*8Y~)eW0uSQ-EvKn<{e47F4k;j1Wk1PV<^yJ@NSE%TyPUrz@tbLJNf z+6;V;9;KsTHot%fNwo60|a<%KJbbVH!1>#-YR)?9&KjzMXd z?+L?=aQDYWG- zi~f{L92q#Qh7Zm8>pybg$Xql~G$JF-Q_g|2N;k7bW{X)FpJS;*MIT5%UI<1Ut14Sc$@ACe^>6dUU5M@Em z>x(J_qEH}^Rfo5{^y2fbS{b0IW!<60hh)~k)NU12z%u6eXwYqH>h*x~B!GJR5sE6& zBsP|1tr1o=m%H{n+Wm9c6a45e*ByB*sGRk8+k5o6J7JGR)kBkW`2Vzv05jR*2~g8 zucS4GC<0U%gej#GC)Yz?m=|gq^*i@)B@puke$~IRr)sZViV5Vd)6H{E@o6XGb@lj^ zulrsGN&g`25sVyt1ugcC(Uy4TsntX0ny=hz6Cv?rktkXackiz_Pxl)~kV^Y7aDzHH zWpf05$ixm{wLzE%f77?A?BZInMu1=W@lv+&I%s;qP8|Uh7;Mz>?5^at+o$Jt1E46h zLR;49kA?syDH0tD`V=T`5OtJad)0+!ob*6Z>XlfEq|4qzwb*5^=dnSW8g470cmUwG z-RS0it{Y-=#KIh_cqKB6bwNKitlAbm4zOPNc_F&T! zX$7sGphLxx?`5rFK-OkK68?p#Al_~9h8OO>?)kfml@nOC`-e#fA(S@vT5n}@7R@(m z=5ys}XhYy-Id=#~;k>}YnhK`r(jh12h+-g=S}%=o>MYq>4epA5lCu7i4dmQHZo6Z) zSV`l2c~tlgtRgOmqvLK<1c=fY8_$9Uy-|?{{GVTQ{;K0$+xdW)v3W(&+88zHHsL!q znJg9S-<#Vwb4p}Y5{!a5fJlt_gV&BmCSY@~YS<8i7JP67eIQHAPww49m^5i1l#(CVG-2tsm7h=;w~5+9MB`zv!)F6Qf^+Ml(N61dDFX?eb zy6K)FC-bF+#UX3uSH);h_cA?2H}tdF!$9!3HEL$>hbFkVZRxM0@wQM6Cqr4S-WcSxo>YxoBWIzj#7)|?@MQv zCScd<1tM%J*`R||PSmPhAlHJn^&}Oz03K`4($DP~P`zS!=IM7bzZUt(&2NNw=N+>L z9>Zi3(l)AMH%=nLs@K0d)#HzgW6vuRXF=ZE^gz*8e&H48Z+ymLu}X6a`ft;KV>wWs z$gm^^2~RwiVD6z0ULke(Vv$O6K@FgCYL)Cbjbz22UJwM~N!)tK3w#$KXAq{gU({tb zCmNbIyzfl&&O7Flh}mIS28>w6SV^EP!G(yuLP5|lB}I-N>i(BEoISMFC4qs0zfAfN zR*qbt#M(;*xe()?m51%o$%Pj2V%1TJ)ZG;X1yEUZVTd@5R3eM?(KREuWk%lQdXq-( zdZc;Q$?p0qx{eZTx~xln`tO@{Ns<0v9U}J0g8JX@I$U?Eee^rbFJb$V1st3Ph=6rCnw=;rqWjyYt>=K4lOHbx9xrqo2py zBPfXd>Gu`z+JabAD9|RcXz|(?U3}9`7f1Oc_I=Dmc~jl6RNIin)X=&~CgAIffOfp- z`c08hLP>YgP5@!HG%BbBd!kWjTgHT0N^5|Lp(9? zYe)2ZA0ZaijRj5~>yB)9AN%T|edP`!#~dKx%4RhTYSeHdRBi&!5)7$Fz?OAjDNqpd z5im44Ogd4|^2KR;4WV|45ycOBtUz?K^P}zv@z3tu`o@Ek*;GanA(i}iH!sR6#L@`v zd-~(uc^eAC!eF<>PyX=5*S%y zyyo;HYzH9-1wk)J{9of_(*3VLe&*EiwrvyMWjL%V1nxlbSk-ZZ8pF=GrCO@UTbKgr z%v{v=CRJTkst}@sD#{4Al#mlZAlpA#1pTCu?>#!X;wWEo&3=i{a2D2#W=a9ZJ^1C? zP@u*F#MLKSKtA>LLzBsdA0 z5yDF>fStLmAX>6E3slJr_FfVh@~+QqedqLKHjxqcAMNl2Bw6Bi`qrL)=n7#h6zD7r z@Mfw203ZNKL_t(YOh@P+z3SY{pR<1=fysufZBg5Ku&>jXd~R^Nvq%Q!zV; zj9G%(aSIm4p`(i??Di(_FZ2-~9+9-4Rm>?h6~KiqAkxJpqoamf-2)08q!C>PZT z(xH-88}R5qb8ri(=1?UCQcY1mqLYe3soKW;4=uX3$$=Pp?UbpEZFEs44eok)^7PBQ z=Uvqf6QL07V3Qy5-v@ZoK`3yAa?}nQ9DTop*%41axw^1uKKsq>>12~sE+|%!eQN#6 z2H-ZgS&b(aAwg!pCLZPn``>llK^Vgtg`O6>oY#AmudAHePtmKs8?&!!rL`b~j zGusb7hDp;!?mtpbAAwKH+C*r0`ehIbbkXd7f7!{ez3$A7&)8k;IT~}V75YWnk~WYR z%JWp_RhmFPMj}uG0SfUpwG?7(;p?Q!>JcN-r3KT>daowvlN zK9yncsKpCSQQFWC9{SDss}t%hl0p;)?L zaWrIE{vc%MDwRl$k{^l}-*y^Fp%B+W8-U{!Fra!jHIE7%NVQ26SkNOu(!hEy*WhXm`!kXp)bz46SmpSoPO zd)R>aB%}(78QT^n>v6<@)U|!_0q`M{iYBeR$}T8^;pI9MW25`7pq3ixF&oN>-o}tm zJgj*9Q5LUs5^77xNh1$DHkmZ?@@FktyRJ9D^N4s5sEq4q489+!kF{-#)x`bVx$J0n z#nJA=UpOq|xk50>v1`g%&lOR(-ui9SLj`!ajpd=u+2AiOf|XWZbi#c{8mtrm>?F9~ z1%Umjxg8)X_+Ei_&p@-oecsuG@40>Zi{G2grwq~<3EQB-A&!%ubxW1;Khz*I5Tz8~ zMDCFY$%cuLkHm^d>&na8`CLBw zr8Pj&V2Mfl@vJ8cPY*)paVnex_=0^BO$ny3 z6^RCYja+Ej@Liuh^sNV{v#BERjI)}s4Z2Svv}Y*5u$-W#S>IXW=U?^MkG=S!$498+ zz?;z^!tGf*;ptL859Qnzn@R}FMj6q6-Qe`bFKDw zy?2q)jcY69M%GP!)XG)p$XLd@la~TvT^j&?!W94QQicdoYKTsVD${XWI6-);>9|7o zVaNXIq>+1mFunRj`{HX?Z8rpd5_%&n)|-i!X>@KA4Td*QgswTcYCC-LtA`CfA|5!{ znJ}_2ELwE|L%4Eg?&|@@e&g5?LC|GxNVv`N6i9V{!m`OtQ!+H-^0kNF7#?g2o z4Eh;9&jTR2CfL0FlZU@|x|vLfVfqxufi>=bxI(c0^p7S&t|PQu;a6UN_NC9=S*#jA z?a~dE68d>3)Jo5LP02^?MvOnUlpuY^81V7towibDI9ftn24kTrGk_@nH#j4f+LPki z%_nZP!d-hhy6HsjJ3aY>zdGEg%@~aK&h-Fm&{jvpwi35thsF>jLhkoFk)wyYfBEJ| zj%+&_a34&G@*Q(O8Z}}r#chxv(`K*-ZCqIap|#Z83HJ55<%40ZWl$ey5P(m!Z_|DU zN$2lUC^t_py4Uk<z2`)??pyVf0PK>T&V5j`m2{` zE;OJ0`r+w>cBUj?SQZy_*DS24E+z)L>1MMbZuAZwuP#tnjTqiRI*ovOty(V+LpYi1 zY*|pBvg9Bk7=U|JacqJZA9`81MxS8ar|KH{K@>!9_Yp8lHafl%4&B zmo0wtO^?3ly4~dpmc=cASr)x0PuS1F#%w_u;2;LzU@^Anl+~g}R6FusWudxAn0OH? z6t+PT(cmy`A;3X0Fw}<|27w39PCCk~pSS2bL^FZ4B`@{}1u_x})Im`T13?X7+lX@f zNO#p`s}KIoG3uvL#AFti>jUn<8UY{_UQq*vgtu2wCUvm5siX!`YbV;t+8Nnlr)N|; z2Z%bDNU}!FfwaK~Z5sLJ1G5)hySnZvtF{9g8QB;f$$uhh#8Ex^wWnV^-Y(3AAYCWV zzGiXXBhx#-z3mer8DWXY$p^f(<#*WDwHaypp71$VqDV~5K^Ws8?KQoMnm_~4ieWQX zo5;*}Qiiz&g`e8L*Zps&f$S{sdw+T4+zuwqaBwn`|AeBC3|deAL`1-o!Rc3PVk#Fh zDda!@nMba_da-Pwe?;yO(~Bkc85MPBhGh)SqVra3@!>TOlpPwQK02TS5KZh~pt%{9 zS5C<)x4;URl$6kB9v8CN$lFL&bkfLuk50B`@`@XFR|+2yuSAaLKZ8&(`n|3wqS1lk zR<%G;Tz0%WahM;zNRDQk>^eB<8?oAl>B=s5s~!w(6zRT#^M6~L>4 zl~n|~6ggLfu7xGL@n>o=z)n)Z{o#4DhVTCLp)cJ#o6mwp0%eR0LdzbZV9fmoO;s7R zLj~=ch2uDEscZvf9d%NJySyu--TsKEOPvCh+vA8CKr|G06rnH%&2}f z1}wZ!C?lXnmU1w`PrX@P{4&2i0k_lwdr$jCrKXXy7n}e4za86MAtsKY3>Q4c@}ICK z96Rx`F{qhZ{46L_@L#<7;j1ri+s>EC`Koq)UBeH^$+BTEtstTun=?Eemr^Mn16#EZ z(QRrLKmkK>3`G6={B}jqra%s90hBH>0%3`LA9o|){lWB#qrCZ<3yqK1tLojm6b=)f zap>s!AlG$x$`z|A92?gN`8Kk)R)vrcR0;YpO=H99(IYb0cnQ1r3Tw2!2L>@fT{LY7uk!Y|c>l-%E z2LSMR%YIERwC`CU<%xb`Wl#S)+V%Hhc*7&axlEj5ILpq4lc#Aj1=C^vp`Ab}SJO-H`=9gTng;iKPw)FeW2hi6UMI)*eKBkN9|z^+z! z+Z!Lf`PnLDnASJ^DfzY&mayQ(Y&=k97b0&p*69+l*0k zEL%m;Tn@!_%g%sHT2+gR15FQH8Uvswxv|f|G(%Z*YwlTwsVqa9ob!vw~lxe zkt`Yoh|DMQ7q=h&+_$#2rW`xc>z^Gq`1ACqvs~iUFS+oR*PdN0k@EIO?q?k@-sa{s z@CLyQAn^NTUnMfBK|ZYziIk8os5}ZdMH4d$$f!PJ7mCoEa?`iX@FgLC#@94ltmNN) z==hlnjp2_#diQNz=tzJ1q_nO4lb<^M+@~#;Nn(2pJ5!N5aBfwtZ_Mw)uJ$tvKl30wk1%|&V zvUZU&24^MN0FEE&o^q`H(CtUltQ#@QfD?ABgau{Ls)JWwO(h4dDUhMJ34suoQA2hx zD90#4cP&jI5TmIKeB&L-ufxzE)8|#m2^B;zpUNM9{OA|&na?Kcdl}f+q>8_mOT6)= z=YHlDk1f&^R~a0A&x(cO69C@_Rd36IE>L#TN(3^3!`ZLGFjR`Kp%d@*8(hbQ*-tZs z6crn%-O9s0ofD24b}jO}C&E{_rlOnnBE@8`uJ(hkG5bJhHZKcAc`K0PMsaWOL|ArW z;StQ9B09Cf=9q-xt8*d;RfniAVLNi0&E~w+AIy(mw7B&(=We`iv254ReDtfzKN_t&-w%3&4D5+hJ7eEN5L(u+$F0bF&WB+zYNoMhAxEBYy(N!f1R z=P`K0acRTKL+5)tCD)Nw@zdgW2wAjp<1-d-`H}Oh7W?HlIDqp%ned@Ur@#H4E7~@5 z)?y`m;rUl9-K$mGQ2Um&KpEzX=N2f%>v5_mUTtXJo>I0+!(w7xI7N~vFd_y88B}KJ zI>9tN`gRjwV?mGr&C_8%m4EievnLLBUAOj5xbM}tE@w!7p_4{__y4`@8{gZSO*0vC z`<#USfduTF$HQ z>4Sk(gYa8Db~*xU4mkvHfCk_+k<{1&ATbm(F17R&RmM6v&X>J#q9ScG5o> zC~WvLS1qnP)&9oo&l%sp&XErbWsZlh!J$tB2Q-bGJ>UGR|8nx;qG>YP_5t}LpniH8 zW{YF)ko|(Vo057?uJn^umI4tjLkSph{n~kji5Ojnn?X^HoLNmEY+=Z)GTevetYvbZ z*Cz^jYdYoIKXln0-`Y-h|F#$A+uuEN4Rz$M z)VbB{K&(K&Ulait%)6a+itIJlFUWw@`OPY>{H{LX8_ZCSWb-?s!+`5Sz@}fjEBxIT z?fm$SJByXyM&R&Ata*UkyS#|(XM;PN&-jIJZ~ftiF0-kBLA%DZ=8Z}U%T8z*6kTDh zA_JoMg99@Fy#(ul(4KR+h6O18yWosbGMPLrTP8PI;oT!F>t#J4t>4vla@Fzfx8Cqr zgMohIU^#(dLtq#U7=2G&8E=%B0kX4b{?(tIdi4CnN}D0WM~$tg$K*@-rvR32%5TSp z6hxP#4J!JM;H1kUb+ig&5VshuUw&RsL2quWu0B$43WHy9vq;i)c-w2v-*9Ey3)eA( z?{Lh%W5I6QlbKJcJO<1_4pXftLD#hVU#6p+IK+SY_a57tYVN2o zHjU)**xMLJGoPS4vc?8_-qQc;y(jNKJ)KTSDT3A`%2_!^WSyG@BVfpPRFpt*f!(AV zdGJ|%f+E#PTLyKmnKNhmCt4bJ5(UMC@~cVxpJj_*eC36gJZ-sH!n=y##A9d=VQYUZ z3tATh)b75FL1tz%zVFjVKk(N_wq_lR-y7r9U&77ZqC|rdf=lVdsY|tj3sWGS1Hncn zx|v0t7-+X3D@7D2R8>wT%&@bx;ShMS!b_gEe9J2@#3)OS4Yr1kf3)P?BM7Kp+Bje# z1Qb#x4exts`mg`|q)-}od|nZo6K%pu#tpn;GjRGCQNGAapcEhU_Iu5B&yGbxxyBmx zfZ;R-^Ytuz7f1qa*MeO&Pl&QX;Y&F*=RbM<`J>xi+hHK0rqFarj(-pY7-c?cQe+Mh z;iS9&&40b(uKQyx^yDUsbGH7{1py(kwX;k_ZHRDq+(JdY|J4SO|%@idFvwe-WZ zo*5{fk2245+YuOCZ<*;Izb9v6KU3iT?*C_RzWDMRc8&WV&Ep^=dC|U(Umtpo*?=-F z+W+QL`N*Az-}|X!Hu*8HPm4a~zc6u+rw$r2dOWs#s+bm~vyido_oDpSkO@#SK@je)UH$tlBVo`-PhLp;Cs%F!p_P=q0uR zCoAiMv`{9HhtE!a`#mQYE1*%Q-{l#3;v@d$qe#kX%m?}t5R{!2G-yia0936?i`b-7 zw3mA3&ou`l-Jk#&tk$H)5=$u5b4%=jC+f59-+b-)lgGNYgG$QdCi*Z7@)4HG*>jlv zV^EnZudhyIf8ptrzyE>DzH-leKBGFRO7bjk%il_`*67#8i=4*%E`Ijf=GrIE8V0V0Co#$W>=4=RJOL=!G1b~^0 zxRimp$|TqkqhlD(tBK<{bqj(-Cgr5>putPcq?W>i0Vmae!PlylYc6kp{Wa%1Y7x<~ z6kna-@$7%Z@rO1uv;q2_PyhRk$hnKn|M}i4&h0c!6DvTeD6AqtcKG7WJ7al7pt$xWyE; zy^x*z)QbQ%$%Kq$=&a;f6y%#DTU{yd$kW(K)+(LlRS(|Cz>6+c_>t!<-t>}Pjd~bn zL0ku$3J1d@1~aG}bjhpQKIs3OP2?;0Z2iaoc4FF$x=Vt-z|TFOYetJD%99AQO}ga} zKLsfHDYcm4?86o*=+tb|UK5s6&3M)#=9z$12;h3&eYxUD_nSX!CqH76pJ^j^eSh}5A2`trc8}eKjS2~i;xW>9Gsr2|a` zA1w+|@A1&UCc0Uh7TRDTyG-0u?GB(+7yO&QxcuHnrjyB-@C?l(=)G$Ri<5=L(kXb?Ert654vh{g zYmg7tDuR2;Qc&Cy99>OR!~Q8wfg|6uz!T%ziA}DFdQ5r@M_;b+bGPjL(9@PZ>LI9l zL-a_HxbKzx=w|<3$&WSzm;7u^`N6+A{DIpKZ%s$liQN-64+Ukjd-ubYo2YX1B~(bK zRM-bDGXSiO0=hsbwgBkQ9*93@^{SjQl6Fv;-K0PtLm(o{7SF$W^_G|JnAAV){i{Yk zWYG2ByXswQ0~+ig3SmKzm^5<#>FK|H|7C5rhUm&`Pm^`@Ed12D8acQG@+(xF!5noN z2V(%#QOV3z)wBnd7~I)c{Q%wMGP_Wt&HSy92MVe)cpBK==XI3Xgunjki^mTc)I(e) zQ}cnkL6!QOM10UCuz}d|t6rxb`nm%#f&AWwPJHY8v)P1uq?f9LQ=Vix0VCBTD|3Si z1YvRj3X~Fy4(|t>0%`67SS8n}Wl=8?G_*r3Gb$LF8IY1+quUCfq=Q*6R`RA7?Y`pr z#qLsL83uSYofnOD_k&D{@z^Uei9rqElcM>QpZwbPdp>=1KHHmJ&LAPoARrgSuXlN3 z^&ONQ0%)&cnpRQSe`#s}cf6q%V}l7sS)H!dwn(32<*&gRN)1o2RiHL3o(vWut5&YN zqPz7KJ8c)9`^W)AL12$c*JVn>L$6PKi1c*Lp9XT~eDkmW;xA2@AIqoRIH%iZk~Gnr z;Ne2mg9Co(@{+*qURZ=YF995SK;Wl9f9692C2oKGC&Ke1ie&Smc=!Pem>c1ao0$dg zuJB{eS-$Q$i(YFwPJY%^!1kmBCK1gF_ICVX)$5$lY{J|B$JV<(adbZ6{#`LGit3YV z$;F(r=de`UXhp3MgvnZO2e9aya?nvza8I5b+6@7SvYLF4d?WJT%(o>|yHYaOpTd8% zYUQe9-P>Nd<3Rw#x*!l#z;OW()Sy93F#6zu;};!6lo>#9anbzS_n$a>(Mpf)6Awdt zQtn2KXK6OWQB?_}(EUXjH(d!(j=XG2U9ya9=J)G)thfzebr9g0(zC6}Gzo3#&h$Yr z?2S-FI?7vLy7P?7yJf3f_-GJNhuAM|4aZ)Q4LC;M(DD10KNSH1Wj^Jf{`aGw{nqx@ z`s4?r!5~*W**w;$X)pEi0EGXE#vWg?Ie@Z1`vPElB39U))v_Q9Ypk$ouZev!%jv#> z1V9$8yzIK=|Ma58Vih83M$dh~oEmZ)bG;478pj{D{B7#bzrAnv_KzO3B!~OBRfj1+ zoM+@0su^snoAum04G;Td1B2Lb;9VeKWOrOl7`1`uuSGS$F#i!j+cy91gC~A)b~0%;{4DfYOMkYA zB0ueAY^#BRpthoXz{a2pc}aw_8ESPHw(y9px5io+Y#z?pVtJ^o< z7$iSrgf|TXf~Z7DJsrvhHV`>}h5YGFdfM>bho`^);p6Gar6X}pCxsqsF?eTHYu8e_ zK&_g}_>}PyL;y2Zb$PMJ>z9sfCGJzwqSu*`|AY+6gjU>0|7t}J&G@#L?;e_Uo%8q6 z1eb9@&^!))4nWPv7TW+v9e-#BjyCi6K63oKk4&eN#RVv zY^~Cdp19`3fu@3owyHReB&zQKWtXZLsnwjVMSspTVrQj^L1xdwuw3CMU%0sG+IF#O zB9S8P<44Hb7<7k*9nZ)HL_7Xr*Iy++AN$Io58QERD@ELn3K=U-zOp0{FbcL7pHT@B z9o3N(1;ql!TGIz<0OH99B8q`RKA50_fLFp)5T0Z@2e=6^5cT3WkHo81o^`7Ig`1bF zENlpnU6Ls4G5n+SZDODh|$eULfKT^oE*QXkbGb|;bg*J{X2`xw!5|s&%Ffe zGC@F4bcL}EP}#ts`J-8#aKD1*o_X#V(AMF+Wp&?%VVCeE#r!#_Wu_a_m(PJfVVEQ8)5=gpw5!Z zz}4iQq9{o-qN)185*4NZ;aX)O3PQK5A?eaO6nX2-%cmZrNq%JASszfy@66}Zf|m%5+&~Z|GcM?+0j$Jct0w186~=5ZM_d7Na6;LE zGEKDiJ+rteS50*YvfcqhxyAlFB?e5 z5vsO05n5XW2V-3c7P~-|4*B1SIBxB$Uo4y7{m9WrFHR;s4}TVh!L#hyWea9eC5a;) zc2AU!)3Tf!je&-g(n$&x3J=Zz%!`aj{){EMiJe-HEXlL{hh)GHi`<6^u8FaGX8-@- zC97xlkWUr+)+IuF7Qqq@vvmF7(;*cN5EZ_C%Ho%^T;P$zy+_$s2SyC0hV(Wj0y5I=OvItKJan-zNY+C57s z>Rh7|a8JRh7!bvUMw5FkeH>7{CBYc9aO*HAeR>u88e}jC<^cPTDm%*2x!ij5az2%= zTXXJZoWFM59(?Hr#h&L6{kRz@#)pph4WjGZ^@dGeD-#-0eu`sezSm@b?_P)<$E6+RC{p<@@HuVp7 z7xyoGhX@~S9*o1ny8Oq2?a)B(KQsBmPaNs2BD-OVDOtOPk{>CUv%?S;iWdkaD)~S= z`Em^eAlTd~IAxW%K~3?)y3$}653tOOFM3d~mdN*VjayURdduqA7Q0xqE2Z!iVK@Av z2q-$5|HLU!19``PKXT8*lUYNzlnEa|nB%p@Zrla4j2zG6BeiEtszi?9(FJZ`M`SBJ zR5XAdmjTO@%ydxgUWt!(xwc&EV*=BkE!`9uwu`V|?fdti)82ATyJ$zdhkF*jgIp;3 zqjmWY2aexa!hFI{e{1UlU)q{a7-+c|O`>E`(wM|t^G~I_Xq61ZHAO19!H^Hff+8Zi z&;vAp!6t-CO(3;kP>QQmrK&HH=LdD)4n~Qs+8`)6Y#6~@9H;?s zy+LTA%2F~sO@9g_Kk2)exiQ5>Dy)6m6loy8bkp+GVYb~K?;Hb!^I98-Y5;PN{Kx;M zvxI5G|NObb-*{j;n}jm=91<|(s#_FxF9PWXR2B#b3Qf|@hPmI_eEe&G;N$n@YNb+@ zV;yTju}!&g&$`NSv63IXzWtHw+MeiY@0o%^|6`pE&Pg?5NP2xLY z{;`Eo<8mO7tRjP6;93-eMZj7sBGPtp)iM6kP0LN)rudQ8Iva=qaH`T3O%P-mi?k&` z_FgHIhkzmO&nc(G|e!v*oQH>bz;aBaOJXlYLjXJ$7Qd*SN;ltxwID6A=V`j!&j zRqHBok>ZsdYLD$8h6P0i90r+GeAfPg9px8Zvby#-SKa2R!=5%U`b+QWN3ah%1)4Q{ z@10wBes?yX4El}$(R&?8&WzAa)fG*tlt5PuVxfrhWQ7R39|4m+@X_F2ucF+cn zY=n*EKQdAVxcJ~en#+~^;inHja=w{htfi|uFeq3R_2f>OLv}=!i8W?c8iToRZw!qX zF2Wo{4G@y^gxqItq*$};*Tou8`XF^7K@G58cJgyCTHSE6TXtDDJETG1FaH_Mh~ z?NN)zpea&tx?tTa?a(Rxr8$x+Tc1&?6~K@H0}yZrpwz^ge0vNFODa?n*Sx2KNdqm6 zGq>Rpr$Q=YppbHS##?V$9-c{8tZYnsrlY2(XM~m@+X-4go*YGP``p(3XEDn1>4qaF zH!K;s^aB>P7?~~>?BBB^L=RYu%htkaMQx#3T_Jh}D0>UPsbQX$VAY?ndX#u^F65KU z{5LLM%cJiDEnE4C=dWITRkvvC+-*=21XJEX%VUpkg>$ra>; zSSk+-tV4$OLPUm12F$&sYvF#`CRCjX_GB+b8`K_t5C8K-iIoZ;7oSzLy3E7?Pqx|L z=CYM%o$P+@MeVAqYO}f|7)$zPP3_x={NQ|Z+vm624Kf>_Z!qVvBS3_(TzcK8C1$o| z_kM9u6^3wp8iWHifRF&t9(~rRf`jUTnpUJ-am1IsASu&{{K_rM6NlK<9o);B{D;`H z_LT|b-M4Su{m5k6Z0IF`td#(G)^QtIktschFd4BisRlKorGup(h8laQ@{XEfPYtyI z$ygb;p8dP=cai!kLbY9yMJI2#VfC_WyQIc{rWtT(1_3sXlv#t@zc>Bh*Jpdndr8DT zNXcYHtnsSo`{4$br=oNzTse?}_33XGH|E&aw8r}t?^WT}1M1cR5g0Z%RI9NGD63Yk zJ;q=7p}M)xy0hjq)hv?NY3YcWV>OU-yZEEeZ|$zIFVA5>Uy?g;rAi7TQr8R#Lb%;B zuaj5hl&?rnj;@D%)(-_i z(jTQjvqs+g<@whioNUVS$s$>=&?``16gfvhtGBQSwmbgr=o+<9_28u}f=A$*o)v?r zar*6?-bEHcHUmNkeq6Njs_WVxduIFiB|m$Z0SC43w2`kqFnQlsX46T^XF|Yd$P9l# zsFb>(y&RyjYaV^K4MSK7C%ML{Uzrus*XYcs>na6tcHCXG%XzD){g_=`x%#TB~oEA ztYm?xj1s7Dal>CMmGD&%k(Tn0Ub4FGGOjwgv|mQyqQM8hG5^AS8z(=Gkcpa(JySY7 zfU*{L*Nl%g)je4S4ur5G9uU}F>ZN$N{y&_QMTG{K<(f1ALnjhY=w!H9;g)OKH$Hc@ zyOJlu*R+wlA8r2Z%d;jSaj>A^LU@pnLa)=fIpQlW3@30{2MD zA9n+QTClRdEbP-)@Yb5RlNByX%JD7UddqS)xkSm&z<+d0hSc>E2(tHOJMBvfRD=&w$f^<%hbmPmpCh%7t&%nMh~ zdkUAWJQ2R;6Z!aE)6aZony&8xN5;B&uN~`hDf)?HLAV~#+pd5MK){6y-Ce>ZGyrM{ zuF{`oO^sN%ZW=VcP^I0{tN1M2FG!OBv~2kywNiQIbg z^5|STJ|PUCfxP>R^ZU+XnoCn}C3EwZPXcCLmSWcQP=fKBDmeCj0~S8nuBE|Vr44Ek zP$LsC)`A6*K*+q2`o5Q~yyCRLyUnN1)!M|HqG7QCo_ zL)jgMVraS3HPqRjz1f1=w~he>?Vi!{w-z7}05qvHQ`7%dC)Z!m{lgpE_6g(rAKR7x zbmwf<+96afZw4KkN&4CmqjrkX{LD{R4JV>s_9?9~!$N|JFHliA7W|lLp@AyXCj$Tw zYmEagkjmy37In)-3jijlO&wyA@l zl@qcFt^B#C6ljDY;F%$-A_64Dff-m~k`2fd4)%Lu7D{Go-S$XHg)7jJdRf<=L2qOxc<}8=^{sG51r~H2_L9 zg=8&_cnnRgP;*BUY*0$J_rr+lviONI7=zn216FvNU?EBu+JTyIjPx=BGP*I#jc=iB-tKjleEw6I zX2K``f~bE}@oUidy+rirjMmdl%bpCxT+1vULBkO>n8pmYyr5&qAfL)u(qxo_F|zxV zD`dief;N!p3ltGesZCg&)v?Z5H}zl`wHYR+2WJ2nzBN6D1Xzt3+sc}1d9NavIou8B zUWj8AWI_|QU*}ew5W$&GWqo(vhM9}fDvT7xMQHy-y~9{1{jms8GSDLpm*Wq}04QMr z;_=FsBnx$zvBgQ?dVP14QKGJysN@|Tb5l(FXADjTqPjM@2VuHe*(Zy%tR+NJuM|d zDXAn<2*tPxpK-pXqo;mJHoOSP><1%fv!(LUQM=3p=71)^iY z?|FrlXeaB106JwTvOs$_RGCM?@*0%fs+8UevvMHVfQ!7C7^%ADZf_wrNJZCEpgSK% zIlmC2>CIS!h^4R%szg_)G3lyJ!cvFgOGm)K7MXvqYVOGr8ACgtF7lZ@MIChi1)DyW zegF|*Cz55dEv7PB=ScZX@l>033{X)e2zDu6@y?Mzc;*hy00KoQ`jXO;j4@DSFXrr% zkYO?c+9o9}V#x(8zn*U-sB`z`!X+e6CQ(kEqi&~VRR((%R z^68{O{2Rz>gEiTArBH<8YZBU~xZ+DMeE@#QP~oxqx-snAC0@goKPt{K@%Z|-BXe$p z+6W6UB3dY$1?82Wt3{8ad@Y#b7ncq9u6uim>>dYX0Q%GUb8hwP8ChcaPB5J+A{_Hj z(bbejMi$i&4T?d5zmidpj6z&q{*5qnlywJ~zi+Kw6BU&$YYgrg+XJeZR~aoz{B3_Y z0RgJ31F%R6aU}2q0x1{o5xcOBY_S4(fs6DU%nhD$@!X>8OQKXHM(a0JssvO$38xSt zWkZ}wMQ~UTnw>?KYa)!E6S_E077Ng_d_qrEqot=H+S9VAlA{_WBg1*Q9)@TFk|LMr z=n+{_7=ViZk#_rDY%^%T5BPX>fs~0xsNQ$^&m~%0YT@2Pk>cjx?HwwQdyB5EJ$HxFLmY-2nGYTP5id3+# zo@-cB0)Y8%+_8X=1!uCfY7;=Kw&r0a&Fn_W0+*+wnqxtp%ojDtD%gP z6Y8mj(5?=m00-fzYl7x+fhq)h6ipH#1cvt%uDK=6U>WpCGMbKlrC5Zenvr8nR`tHZ z)B=&=XA5!_w?PeOTMvQ79#18!O{n=V-0nybz#?Gm$nLAEF;?^ zvKvT1syon4v0m7*tbqr|HN(nMNh&dN+u<1RZ5(6@B)aqKyFo)@yi83~i!T@3U!@kK z$}(7$MP|||I7oIGa?*31BEm(dc-kQkPvX0V5z_jO7R%&qIzVnFbzEnDcgwgz0d;8muKb713@TH767W! z0iAj#ID$q<$q$*Bh%%l49eoH zQcu?=nO50rzvezSMZb~G=*GyRYq+mI2Y>@HOFq@yn5}d8t7=%FJlv9t!YG?a@6qdv z12#+e>s8;+z~M?{hn=s>bilAZvkZYc=%z?+&f*%WjK;!+l`01ukEQyP2v<$|4qO=w zHZp*&Yg1ny!eH*H4yur%#Q)rGL}Uj&#`jK0Y7<@I_dT4!Qz9j0A8w$XV?*8{`95H~!VzD8=WdvJ+s7R!{02Nzb#=N4yogYyMiDlgqYT%fiVDM=-e~h|)l5yH7 zemg&%H&TabqTIC@Kq+k*jcNw~eY?k<166jV-f`D;J3Bk$2C!HxHrdSM+L-QAGnbo| zDKEQY3cX!HsRL$4k)P9A&D<+>TVFvyP~o5ya^=B}*l7#cBIjZuL3L_Dw=d@z3>>Yh zdY2p9Er6Y!o!#Bt(IS}V&!5le2vVO(iw!`rjHO51Gwdf62t_h#)M|`*s%-`W_W4W2 zhUyi0lQlTkpUZ01GZ|K3@X#y}7!5M{?#6(CT+T;T6Eh{@25|Q5*{;ufP5}=@H z4fIi2F$=Pf+)yK`xYz$Y?0f0}T)cSk%$YOeU7$WaI(_-rf z786YvWfdZ?__KT*xnoYM6X)QdNgWLYr0OVDWbk;3Vqsr~#Zj#S&^&jj)&unLb(0MN zk`F%kpl$()$RzqptJR9+;lqcs0OoKT!MU{cBiD474kf;_t27q_7zoUzx;ag7o_QN$ zl}?ex^b*jJ=Sw_7S6m{wL|gu!I)YH4RM7`;2LVol#WL}a=h=e;2mpBCfd|f>JsbVi z$?zxb?(TM7cW8Tiqk9h~0svfESF^9nA+9Kpz3OCtfQC=*Q*r?R9TJD^{ZS{ijc#9{#<_=)d0G-CZme^Z9%_o$m9J zqfKDg56^1r0EoOx9StT=s+?BEA{ff(VGq)Ee!aJJZi~UH%ZBBIKfif_1WtVrDA0=Z z(b`y>>2%gK4IVeG^_W#c ztKz|AlPuG+jZMOHP77E|;C>UMHd!2VfSd@I4H@|H$M^R4FaQ?<==b8~(tNdTyId~& ze!uQ`KKb?J*OOmQem(j168uu0g=1E`##To?qB!LA2XltoHKLI_sp4iJ`q@bEm|rR6##(trZ&b100;>}00oTH zJS3Q#kQ%syx}G`!<+0R%Y!UyFdKhVGfRbL$p8!BJDglaQw*Cc)5`yS+JoD7&j-|uWGPL0PTrzRu*>gOROS-Y*X(chc#fm1n8?W zrg~928qrPULgmC*=onFnZdBJ5m}%%qF+ho3Wa~UB!ov1lE*;-y9 z7K$J)rgZzYp!x;*Y6)<+xL~hO-~Sfoi=)+2WV(HwG1i4D>;a9n4!yJp%PnQ5k5Oce zF^JMo@^o*CZz=GTkHA=i;m;?qRYv+v)M6oo5KLAcPL5(n7CfWC+tVOX$ftK{t+W_^ zH-f%2_*gcCjfLb9iWKC5v#}l0+H-pv=^Jm&=cXKeT?e91cGH_EWl&?~MbT;jw1>;+ zX|9$(mA0j%G-D#(#HgEiPi&?ic}%v~;9t+bnNIiH?%9H}5wqd|Jcu(Hs&u_yNHgN{ z8`0o+L5m7Y6M}Qc)c3|C6i#VL@MG7)%x|FB)f06_JqkbGdGUH>EU%M&>v`qM#<+@K zjZ50p^tnw(2Tygi{$%}9Lf^I1oY4b0t3UP~eu04;RVI_i?Qaau56SVHj{_(z%QpR= zo>GI!8BCV!WZI+)2=uEpJ*6XB@%;1fbbhGTs^;8gJ?3aqbrNb>*Lb8pxq_>a!plFY z3aF@j4cYip_u;)306f($E-t{uWxGla|8!!)@-ECDr~)259g%z%wgdSM{_oGXa-sB^ z`^ujsnyLQ^wlo+?D1RF|rvt*kH8Mv#a_B)I6b8HF}unQyl1+v}~Yvw|&+mVf^G z^}(_ja_Dd5Ucx+ogn(vII%9c2r;%OJwNfhz$Ki+Uu<&xdRvcnq$M#I(4&8fiOISha z&k}z5!#gt`Yr}=5O()KM87i{JY~?E>ttXvRkj9W);XbHZBIc4-uj)zP*5S_(^2w*Q zwYA&Rji-VGe|01q{d|2-o>SrlLKR}6Wuz^$(R}P(MTH0!pop)6@5ZBXV&?PMKf6nR zdmHX+DnEofy=QFjkj<;W#NW42r+3~H*YJK%4-cjn`hL{+E0npt63|odJ+uFZG5&Lz zvj&CUkpE4h8TCHBZ47Hnl1CNB*cxH;5}HnBtrU0p{RjP5aL;~S?PNR7jPZ?cD~=aj zr{Tb{P};bO=N9H>u|W(lCz{JK7-Ul2(sJ?8@L|MjNJr*u-!*su6ZQN-F{&HGBhIf9 z+@J^tg7^2N|ID>22#6tE3!weXw-zRj^)nzQ_Md|l^}{|mXf3TqNnly@I)J$_v(eY5 zr%L=)X0pTzD4J1j>&n*$AYQ)%e<@jlH*-Y#HnzY2CpLf$Q!wPeT#@4b4`S0G4$JLt zUPXZ}bq2H8oy?ErKDT8kR{;7UtKC{;3&40-j{vy-e)|=VLhO3;f*YE;%Y*5vQUSq& zS-gZ&YSdHJU+hgaL5;Y3kLVky?57Z|RuGgB=GZ6i2^YOi-Z*eA69^fw3(gQ z!(MVy+z9;U7~}A5rKh=GsJ?<^H@4 zCW`XjA?yoHk3+>h9sGV!MMurOW~w+)NGET9gx79cz8G9hOePKSOZm}>E6fNHieN!@ zIGA<(3ddlsKxQ4=jDI}E##9J|^U@?2jxnhe$e<;j+=9jJ;l2b#td$CmwwZJD&Rdi# zGW70Otp}A`0p_oG!*)wKy;Oy$w%ayuRXMjHRGX%>W%+H*VfzkD6_jo!M5^fObz7DB zljt!O(0Q_@5=EYHvFH);BUN&aP>ncVKjyH642_k%oJ2h?93{z)j?j2(PRj;a*}F%) z4tPZ*M)&1c?h)7}o#GRk?z|~V=Jvc zN-m%L7@XzQx6$pnU%l{pT3OT21olXa$Z~bT7AK`MOQ6>fj$9GRrdn9`?7RzJyeS9@ zJ9ziPo=iJvgTvBt6)-}##Axf%MS3v7cWaH^p%*2DvV^EEUi_UiZ#Nh^37G4pUgKo- zj42dwf**v)mj)*c8|6wd+#?`s=cL^fJRHqXFDB_COM=1@Jrq|R-7Vs31rx;@13ECVom`#MdO9qam(6Su9Fz!0N?#~MAA@ng+Ysy^F%uY}JZTVw*%;C}9bU7$e(uCm)BWt_; z!}bYe=7&*T>vPBEU2BaVO7uuEW$B|F*S7R~d*Pg^8fub6OPnI0vo(ikFfDEi`3gro z;rA<&1O(z(Cl9M>4-whUJ>xEt(jW<#nTxW*1TF9iBB8Dd5>oC(V4?}DDYn(#{~L!219e#NFW;#QD-(6Xl= zTd7Zn3E|}q7ZAa5eO#2rEZffbbp4qjFTp$^UB=H$6nXTSxIaz8BU21A7x1knt>@NU z8^w&su0@EO#1-po&u;y6byCP5A{XDPGD*6n#nO2$$U!NJztrCx7(fThn^HZjKD#q866<~A(iA; zoS>d*ooU{~TWyIKA?8gI3G$a6zOYfl^i8u;RT(~&i5PDbIberZQGD8S9f#WqdYmF^ z@j_P>8(mXtHf*M9s8AOGe(TRMtf)Ozp=&XVYeeTy?A{WcH70{216ML&v*1q$4d!3P8{(Ulv zmM`3ms+)c#QI`Jw=2YQz+z&@x-}YHMeigTkLp3Q`WvabKYW>|6va{4 zN$gN%pT(Fu3PtV9}u?GMDx11fEI;#`6jChlK-R-CtEZd1L5TPdqR-wR*3FJ5TgtiYnq095nQgGbuN)=qnkSBXvPsDbA#8 z(O+-th8nvGWPQ^U4`<&=9m;<2W~3Twuh<}`AeG#9Gc#l%_w!LC*BKXSuVY27h1ZKe zuwdf%dLaOn$f&c!QZ1Nr*s#%1U3aH8LlEw{2jlIE&X5{!9Uy?7az#3A<<#VDs?u!% z7QGuhZwv=MX_Br?VX0Tw*uSMJWT4T`g)n)frcb(8P#%=RqLQ~i{aS^W}Wu;9?GjucJClxdq;K%kxB_nHSD=QU5OU$C{l1*%t23Q_KVCkTVuvB zfHC1zY*J zQpfms^6MTY;RO0fHtlbA4;FtY3f4avFP(M;3u$r10zX07G|M^K*>MDeKv?t7-WhR~ zTVpAFF_Z^~1gbY=8lzjew^9V~?O82Rr;_AmavscE)WCO<3#7#fv$IM@>< zE8x2EJw?mV_+N_tvC9CPZ1?xHBq8jc(}mo6vH=G-tMyry=}#b7*P-KJoHx5vN8t$M zScLV7kO>+lnmr9)^?x-Z%g8UoYA=ZCzw(j?x2lFe+L}f~jn8V|Fon1eAJY_Ej$3)t zcdLHbDyei34uqvDorG&QD2P7u{u)tY`8vf@SL^l1E57yP(Sq!L-$$;#n1jFqOp$(` z(Q{X0g>*)B(Gp}CM_)GM+IJPR-b+aCcQKb@y%d#)yg?PzbDvZEI;XbuOl+A;|=ri}aYd=QTr|vnyfAw_xb~in5yBds<_4zpv9$J@WR4e88 z5@GW*P*7U(T86$&;$+xJ_T#|x#vxPgg*EelrWRDcG3DO1ZYL&tS{V>Fc<;{+Mt^=) zku}YwjBN2Z=u?3E>o0|3WX~5?!jD}86-@d{hs{C0lE+ddpRM9G4Sfvaz)jQ_^QzA7 z?qfS=0dQ(Py(4QOcj_vqaYIi}dHi60wcsKIi$-2LyyIZX7wJZ6fVSw2$$WnidoQ}= zp=^412G@;~a=)Ui@?IAFOQDD{aWlD&de8SwVGlUSL6Co)_rB3Yn>j+4S*V!{b!VN& zM&qFAZH+BRv_S-|Z%VaM1z&gZbo6CF9yF)b8iEaxLXW7UN@%Z~u)x^dtJMT4aY+62 z!7>K|T+-3n(&hEyqm_K1K2heZdM-4CJA6dT5DB&C(i*iNxrOBJXO1Ud6nsF2X1ikl zhz5ksMP`3Fy-gp@0EM@yISG65+q*`ZiQKfn-5GezGfoKiQoz#|ggBf;-K7XsrXp5= z^p;Gmd*&<>H-MFPuZlU%fKF_1gA;56ZJt@j#>9j?C5EP`(sRsw^|G>DyrI$J1W{oJs+ z$#&&>6*SZwrC6TyDp@}ksz#+Z)Tz*uM|E?BO%HDFDD*|zm%+QPq>KeFZScUDeqCtd zoe%|GKeO0C)vcwGyFAb;nfC2~M8$UuyD9LM z=B6l4cISymxR7y$He%(oG{fxFo zLAkl>l~VdYF~Wyk2^_v*PtN!5Cjns^93*ACXP~vfp3Pi|{ykL^xhKNV8bL&S%z1XI z5p7e9OcIMU4LS?@${V9$jfm@7U)6rJ7Z>ieS$3(wOrCz;8{y3ajDm?{cf?W<)sd12 zn_Oq#m*Tp%-`p;#l1VTRxQW@?0-YC*De3M!9I#1p>q8%BG&G8K)ioU4!?EZkhs zL`ID9U``6(c)>o*@PWIx>o4zGbrI$zQx3I|T-embz6b?}96g5A!lucVm{LvJwPtD* zeSCDcLC83?7lrrf()~8QF(NpO=9z^8%kHdC>+ZvxU$n^`suiv_GjM9Q+~^6O0{A-J zz&z!26DEn-ABfxbv4JC7m{v6i>Co#pK2CBIQ;KbkmvOeOCR(O(#dif448dwui@~>qP!DnnCPQ_9Q974UW+kp4xqv<=s^|XgaLUyN z%dPBz0;lN>x?9zLT@4gOee!M55_&1p5?@%+FWB|-WXCuzj_~5uVw)ty8BrXr85c?- zFl&<+&pZW&BkC03k3o(Dp)@AWT^|AH~JFs*eXb-YzDn5}D)M%Zis!VFN z=A9J@Ykc}cUZ#SviUvTZM?koWt)#P|MAKFf^0ZD zI(p(?w@C*kn|^QX8`L~?<= 2 ** 32: + raise struct.error("integer out of range for 'I' format code") + return struct.pack(b'!I', intval) + elif length == 16: + if intval < 0 or intval >= 2 ** 128: + raise struct.error("integer out of range for 'QQ' format code") + return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) + else: + raise NotImplementedError() + + +if hasattr(int, 'bit_length'): + # Not int.bit_length , since that won't work in 2.7 where long exists + def _compat_bit_length(i): + return i.bit_length() +else: + def _compat_bit_length(i): + for res in itertools.count(): + if i >> res == 0: + return res + + +def _compat_range(start, end, step=1): + assert step > 0 + i = start + while i < end: + yield i + i += step + + +class _TotalOrderingMixin(object): + __slots__ = () + + # Helper that derives the other comparison operations from + # __lt__ and __eq__ + # We avoid functools.total_ordering because it doesn't handle + # NotImplemented correctly yet (http://bugs.python.org/issue10042) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not equal + + def __lt__(self, other): + raise NotImplementedError + + def __le__(self, other): + less = self.__lt__(other) + if less is NotImplemented or not less: + return self.__eq__(other) + return less + + def __gt__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not (less or equal) + + def __ge__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + return not less + + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def ip_address(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the *address* passed isn't either a v4 or a v6 + address + + """ + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def ip_network(address, strict=True): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP network. Either IPv4 or + IPv6 networks may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if the network has host bits set. + + """ + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 network. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def ip_interface(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Interface or IPv6Interface object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + Notes: + The IPv?Interface classes describe an Address on a particular + Network, so they're basically a combination of both the Address + and Network classes. + + """ + try: + return IPv4Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % + address) + + +def v4_int_to_packed(address): + """Represent an address as 4 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The integer address packed as 4 bytes in network (big-endian) order. + + Raises: + ValueError: If the integer is negative or too large to be an + IPv4 IP address. + + """ + try: + return _compat_to_bytes(address, 4, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv4") + + +def v6_int_to_packed(address): + """Represent an address as 16 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv6 IP address. + + Returns: + The integer address packed as 16 bytes in network (big-endian) order. + + """ + try: + return _compat_to_bytes(address, 16, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv6") + + +def _split_optional_netmask(address): + """Helper to split the netmask and raise AddressValueError if needed""" + addr = _compat_str(address).split('/') + if len(addr) > 2: + raise AddressValueError("Only one '/' permitted in %r" % address) + return addr + + +def _find_address_range(addresses): + """Find a sequence of sorted deduplicated IPv#Address. + + Args: + addresses: a list of IPv#Address objects. + + Yields: + A tuple containing the first and last IP addresses in the sequence. + + """ + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last + + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + return min(bits, _compat_bit_length(~number & (number - 1))) + + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> list(summarize_address_range(IPv4Address('192.0.2.0'), + ... IPv4Address('192.0.2.130'))) + ... #doctest: +NORMALIZE_WHITESPACE + [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), + IPv4Network('192.0.2.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + An iterator of the summarized IPv(4|6) network objects. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version of the first address is not 4 or 6. + + """ + if (not (isinstance(first, _BaseAddress) and + isinstance(last, _BaseAddress))): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + first, last)) + if first > last: + raise ValueError('last IP address must be greater than first') + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = min(_count_righthand_zero_bits(first_int, ip_bits), + _compat_bit_length(last_int - first_int + 1) - 1) + net = ip((first_int, ip_bits - nbits)) + yield net + first_int += 1 << nbits + if first_int - 1 == ip._ALL_ONES: + break + + +def _collapse_addresses_internal(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('192.0.2.0/26') + ip2 = IPv4Network('192.0.2.64/26') + ip3 = IPv4Network('192.0.2.128/26') + ip4 = IPv4Network('192.0.2.192/26') + + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> + [IPv4Network('192.0.2.0/24')] + + This shouldn't be called directly; it is called via + collapse_addresses([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, + # last.network_address <= net.network_address is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net + + +def collapse_addresses(addresses): + """Collapse a list of IP objects. + + Example: + collapse_addresses([IPv4Network('192.0.2.0/25'), + IPv4Network('192.0.2.128/25')]) -> + [IPv4Network('192.0.2.0/24')] + + Args: + addresses: An iterator of IPv4Network or IPv6Network objects. + + Returns: + An iterator of the collapsed IPv(4|6)Network objects. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseAddress): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + try: + ips.append(ip.ip) + except AttributeError: + ips.append(ip.network_address) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, nets[-1])) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) + + return _collapse_addresses_internal(addrs + nets) + + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddress sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNetwork): + return obj._get_networks_key() + elif isinstance(obj, _BaseAddress): + return obj._get_address_key() + return NotImplemented + + +class _IPAddressBase(_TotalOrderingMixin): + + """The mother class.""" + + __slots__ = () + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return _compat_str(self) + + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + + @property + def version(self): + msg = '%200s has no version specified' % (type(self),) + raise NotImplementedError(msg) + + def _check_int_address(self, address): + if address < 0: + msg = "%d (< 0) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._version)) + if address > self._ALL_ONES: + msg = "%d (>= 2**%d) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._max_prefixlen, + self._version)) + + def _check_packed_address(self, address, expected_len): + address_len = len(address) + if address_len != expected_len: + msg = ( + '%r (len %d != %d) is not permitted as an IPv%d address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?') + raise AddressValueError(msg % (address, address_len, + expected_len, self._version)) + + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) + + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. + + Args: + ip_int: An integer, the netmask in expanded bitwise format + + Returns: + An integer, the prefix length. + + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = _compat_to_bytes(ip_int, byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask + """ + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen + + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length + + Args: + ip_str: The netmask/hostmask to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (_compat_str(self),) + + +class _BaseAddress(_IPAddressBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + """ + + __slots__ = () + + def __int__(self): + return self._ip + + def __eq__(self, other): + try: + return (self._ip == other._ip and + self._version == other._version) + except AttributeError: + return NotImplemented + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseAddress): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self._ip != other._ip: + return self._ip < other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) + other) + + def __sub__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) - other) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return _compat_str(self._string_from_ip_int(self._ip)) + + def __hash__(self): + return hash(hex(int(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + def __reduce__(self): + return self.__class__, (self._ip,) + + +class _BaseNetwork(_IPAddressBase): + + """A generic IP network object. + + This IP class contains the version independent methods which are + used by networks. + + """ + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return '%s/%d' % (self.network_address, self.prefixlen) + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast): + yield self._address_class(x) + + def __iter__(self): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network, broadcast + 1): + yield self._address_class(x) + + def __getitem__(self, n): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + if n >= 0: + if network + n > broadcast: + raise IndexError('address out of range') + return self._address_class(network + n) + else: + n += 1 + if broadcast + n < network: + raise IndexError('address out of range') + return self._address_class(broadcast + n) + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseNetwork): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self.network_address != other.network_address: + return self.network_address < other.network_address + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __eq__(self, other): + try: + return (self._version == other._version and + self.network_address == other.network_address and + int(self.netmask) == int(other.netmask)) + except AttributeError: + return NotImplemented + + def __hash__(self): + return hash(int(self.network_address) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNetwork): + return False + # dealing with another address + else: + # address + return (int(self.network_address) <= int(other._ip) <= + int(self.broadcast_address)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network_address in other or ( + self.broadcast_address in other or ( + other.network_address in self or ( + other.broadcast_address in self))) + + @property + def broadcast_address(self): + x = self._cache.get('broadcast_address') + if x is None: + x = self._address_class(int(self.network_address) | + int(self.hostmask)) + self._cache['broadcast_address'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = self._address_class(int(self.netmask) ^ self._ALL_ONES) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (self.network_address, self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self.network_address, self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self.network_address, self.hostmask) + + @property + def num_addresses(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast_address) - int(self.network_address) + 1 + + @property + def _address_class(self): + # Returning bare address objects (rather than interfaces) allows for + # more consistent behaviour across the network address, broadcast + # address and individual host addresses. + msg = '%200s has no associated address class' % (type(self),) + raise NotImplementedError(msg) + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = ip_network('192.0.2.0/28') + addr2 = ip_network('192.0.2.1/32') + list(addr1.address_exclude(addr2)) = + [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), + IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] + + or IPv6: + + addr1 = ip_network('2001:db8::1/32') + addr2 = ip_network('2001:db8::1/128') + list(addr1.address_exclude(addr2)) = + [ip_network('2001:db8::1/128'), + ip_network('2001:db8::2/127'), + ip_network('2001:db8::4/126'), + ip_network('2001:db8::8/125'), + ... + ip_network('2001:db8:8000::/33')] + + Args: + other: An IPv4Network or IPv6Network object of the same type. + + Returns: + An iterator of the IPv(4|6)Network objects which is self + minus other. + + Raises: + TypeError: If self and other are of differing address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + self, other)) + + if not isinstance(other, _BaseNetwork): + raise TypeError("%s is not a network object" % other) + + if not other.subnet_of(self): + raise ValueError('%s not contained in %s' % (other, self)) + if other == self: + return + + # Make sure we're comparing the network of other. + other = other.__class__('%s/%s' % (other.network_address, + other.prefixlen)) + + s1, s2 = self.subnets() + while s1 != other and s2 != other: + if other.subnet_of(s1): + yield s2 + s1, s2 = s1.subnets() + elif other.subnet_of(s2): + yield s1 + s1, s2 = s2.subnets() + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + if s1 == other: + yield s2 + elif s2 == other: + yield s1 + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') + IPv6Network('2001:db8::1000/124') < + IPv6Network('2001:db8::2000/124') + 0 if self == other + eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') + IPv6Network('2001:db8::1000/124') == + IPv6Network('2001:db8::1000/124') + 1 if self > other + eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') + IPv6Network('2001:db8::2000/124') > + IPv6Network('2001:db8::1000/124') + + Raises: + TypeError if the IP versions are different. + + """ + # does this need to raise a ValueError? + if self._version != other._version: + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + # self._version == other._version below here: + if self.network_address < other.network_address: + return -1 + if self.network_address > other.network_address: + return 1 + # self.network_address == other.network_address below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network_address, self.netmask) + + def subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), yield an iterator with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if new_prefixlen > self._max_prefixlen: + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, self)) + + start = int(self.network_address) + end = int(self.broadcast_address) + 1 + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in _compat_range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) + yield current + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have + a negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen)) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return (self.network_address.is_multicast and + self.broadcast_address.is_multicast) + + @staticmethod + def _is_subnet_of(a, b): + try: + # Always false if one is v4 and the other is v6. + if a._version != b._version: + raise TypeError( + "%s and %s are not of the same version" % (a, b)) + return (b.network_address <= a.network_address and + b.broadcast_address >= a.broadcast_address) + except AttributeError: + raise TypeError("Unable to test subnet containment " + "between %s and %s" % (a, b)) + + def subnet_of(self, other): + """Return True if this network is a subnet of other.""" + return self._is_subnet_of(self, other) + + def supernet_of(self, other): + """Return True if this network is a supernet of other.""" + return self._is_subnet_of(other, self) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self.network_address.is_reserved and + self.broadcast_address.is_reserved) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return (self.network_address.is_link_local and + self.broadcast_address.is_link_local) + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return (self.network_address.is_private and + self.broadcast_address.is_private) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return (self.network_address.is_unspecified and + self.broadcast_address.is_unspecified) + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return (self.network_address.is_loopback and + self.broadcast_address.is_loopback) + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 4 + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2 ** IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + def _explode_shorthand_ip_string(self): + return _compat_str(self) + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError("Expected 4 octets in %r" % ip_str) + + try: + return _compat_int_from_byte_vals( + map(cls._parse_octet, octets), 'big') + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_octet(cls, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + if not octet_str: + raise ValueError("Empty octet not permitted") + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._DECIMAL_DIGITS.issuperset(octet_str): + msg = "Only decimal digits permitted in %r" + raise ValueError(msg % octet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(octet_str) > 3: + msg = "At most 3 characters permitted in %r" + raise ValueError(msg % octet_str) + # Convert to integer (we know digits are legal) + octet_int = int(octet_str, 10) + # Any octets that look like they *might* be written in octal, + # and which don't look exactly the same in both octal and + # decimal are rejected as ambiguous + if octet_int > 7 and octet_str[0] == '0': + msg = "Ambiguous (octal/decimal) value in %r not permitted" + raise ValueError(msg % octet_str) + if octet_int > 255: + raise ValueError("Octet %d (> 255) not permitted" % octet_int) + return octet_int + + @classmethod + def _string_from_ip_int(cls, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] + if isinstance(b, bytes) + else b) + for b in _compat_to_bytes(ip_int, 4, 'big')) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [x for x in map(int, bits) if x in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = _compat_str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv4Address(_BaseV4, _BaseAddress): + + """Represent and manipulate single IPv4 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv4Address('192.0.2.1') == IPv4Address(3221225985). + or, more generally + IPv4Address(int(IPv4Address('192.0.2.1'))) == + IPv4Address('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 4) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in self._constants._reserved_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + return ( + self not in self._constants._public_network and + not self.is_private) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self == self._constants._unspecified_address + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in self._constants._loopback_network + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in self._constants._linklocal_network + + +class IPv4Interface(IPv4Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv4Address.__init__(self, address) + self.network = IPv4Network(self._ip) + self._prefixlen = self._max_prefixlen + return + + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv4Address.__init__(self, addr[0]) + + self.network = IPv4Network(address, strict=False) + self._prefixlen = self.network._prefixlen + + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv4Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv4Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv4Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + +class IPv4Network(_BaseV4, _BaseNetwork): + + """This class represents and manipulates 32-bit IPv4 network + addresses.. + + Attributes: [examples for IPv4Network('192.0.2.0/27')] + .network_address: IPv4Address('192.0.2.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast_address: IPv4Address('192.0.2.32') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + # Class to use when creating address objects + _address_class = IPv4Address + + def __init__(self, address, strict=True): + + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.0.2.0/24' + '192.0.2.0/255.255.255.0' + '192.0.0.2/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.0.2.1' + '192.0.2.1/255.255.255.255' + '192.0.2.1/32' + are also functionally equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.0.2.1') == IPv4Network(3221225985) + or, more generally + IPv4Interface(int(IPv4Interface('192.0.2.1'))) == + IPv4Interface('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict is True and a network address is not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Constructing from a packed address or integer + if isinstance(address, (_compat_int_types, bytes)): + self.network_address = IPv4Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + # fixme: address/network test here. + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv4Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv4Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry. + + """ + return (not (self.network_address in IPv4Network('100.64.0.0/10') and + self.broadcast_address in IPv4Network('100.64.0.0/10')) and + not self.is_private) + + +class _IPv4Constants(object): + + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _public_network = IPv4Network('100.64.0.0/10') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 6 + _ALL_ONES = (2 ** IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + An int, the IPv6 address + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + _min_parts = 3 + if len(parts) < _min_parts: + msg = "At least %d parts expected in %r" % (_min_parts, ip_str) + raise AddressValueError(msg) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + try: + ipv4_int = IPv4Address(parts.pop())._ip + except AddressValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + # The extra colon comes from using the "::" notation for a single + # leading or trailing zero part. + _max_parts = cls._HEXTET_COUNT + 1 + if len(parts) > _max_parts: + msg = "At most %d colons permitted in %r" % ( + _max_parts - 1, ip_str) + raise AddressValueError(msg) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + skip_index = None + for i in _compat_range(1, len(parts) - 1): + if not parts[i]: + if skip_index is not None: + # Can't have more than one '::' + msg = "At most one '::' permitted in %r" % ip_str + raise AddressValueError(msg) + skip_index = i + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + msg = "Expected at most %d other parts with '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) + else: + # Otherwise, allocate the entire address to parts_hi. The + # endpoints could still be empty, but _parse_hextet() will check + # for that. + if len(parts) != cls._HEXTET_COUNT: + msg = "Exactly %d parts expected without '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) + if not parts[0]: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0 + for i in range(parts_hi): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in range(-parts_lo, 0): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + return ip_int + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_hextet(cls, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from + [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._HEX_DIGITS.issuperset(hextet_str): + raise ValueError("Only hex digits permitted in %r" % hextet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(hextet_str) > 4: + msg = "At most 4 characters permitted in %r" + raise ValueError(msg % hextet_str) + # Length check means we can skip checking the integer value + return int(hextet_str, 16) + + @classmethod + def _compress_hextets(cls, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index, hextet in enumerate(hextets): + if hextet == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + @classmethod + def _string_from_ip_int(cls, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if ip_int is None: + ip_int = int(cls._ip) + + if ip_int > cls._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] + + hextets = cls._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if isinstance(self, IPv6Network): + ip_str = _compat_str(self.network_address) + elif isinstance(self, IPv6Interface): + ip_str = _compat_str(self.ip) + else: + ip_str = _compat_str(self) + + ip_int = self._ip_int_from_string(ip_str) + hex_str = '%032x' % ip_int + parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] + if isinstance(self, (_BaseNetwork, IPv6Interface)): + return '%s/%d' % (':'.join(parts), self._prefixlen) + return ':'.join(parts) + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv6Address(_BaseV6, _BaseAddress): + + """Represent and manipulate single IPv6 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:db8::') == + IPv6Address(42540766411282592856903984951653826560) + or, more generally + IPv6Address(int(IPv6Address('2001:db8::'))) == + IPv6Address('2001:db8::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 16) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return any(self in x for x in self._constants._reserved_networks) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in self._constants._linklocal_network + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in self._constants._sitelocal_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv6-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, true if the address is not reserved per + iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Interface(IPv6Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv6Address.__init__(self, address) + self.network = IPv6Network(self._ip) + self._prefixlen = self._max_prefixlen + return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv6Address.__init__(self, addr[0]) + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self._prefixlen = self.network._prefixlen + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv6Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv6Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv6Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + @property + def is_unspecified(self): + return self._ip == 0 and self.network.is_unspecified + + @property + def is_loopback(self): + return self._ip == 1 and self.network.is_loopback + + +class IPv6Network(_BaseV6, _BaseNetwork): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:db8::1000/124')] + .network_address: IPv6Address('2001:db8::1000') + .hostmask: IPv6Address('::f') + .broadcast_address: IPv6Address('2001:db8::100f') + .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') + .prefixlen: 124 + + """ + + # Class to use when creating address objects + _address_class = IPv6Address + + def __init__(self, address, strict=True): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the + IP and prefix/netmask. + '2001:db8::/128' + '2001:db8:0000:0000:0000:0000:0000:0000/128' + '2001:db8::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:db8::') == + IPv6Network(42540766411282592856903984951653826560) + or, more generally + IPv6Network(int(IPv6Network('2001:db8::'))) == + IPv6Network('2001:db8::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 2001:db8::1000/124 and not an + IP address on a network, eg, 2001:db8::1/124. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, _compat_int_types)): + self.network_address = IPv6Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + + self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv6Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv6Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast + 1): + yield self._address_class(x) + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return (self.network_address.is_site_local and + self.broadcast_address.is_site_local) + + +class _IPv6Constants(object): + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/script.plexmod/lib/_included_packages/ibis/__init__.py b/script.plexmod/lib/_included_packages/ibis/__init__.py new file mode 100644 index 0000000000..eecb0476de --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/__init__.py @@ -0,0 +1,17 @@ +from . import filters +from . import nodes +from . import loaders +from . import errors +from . import compiler + +from .template import Template + + +# Library version. +__version__ = "3.3.0" + + +# Assign a template-loading callable here to enable the {% include %} and {% extends %} tags. +# The callable should accept a single string argument and either return an instance of the +# corresponding Template class or raise a TemplateLoadError exception. +loader = None diff --git a/script.plexmod/lib/_included_packages/ibis/compiler.py b/script.plexmod/lib/_included_packages/ibis/compiler.py new file mode 100644 index 0000000000..6754878e4d --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/compiler.py @@ -0,0 +1,196 @@ +# coding=utf-8 + +from . import nodes +from . import errors + + +# Token delimiters. +comment_start = '{#' +comment_end = '#}' +print_start = '{{' +print_end = '}}' +eprint_start = '{$' +eprint_end = '$}' +instruction_start = '{%' +instruction_end = '%}' + + +# Returns the root node of the compiled node tree. +def compile(template_string, template_id): + return Parser(template_string, template_id).parse() + + +# Tokens come in four different types: TEXT, PRINT, EPRINT, and INSTRUCTION. +class Token: + + def __init__(self, token_type, token_text, template_id, line_number): + words = token_text.split() + self.keyword = words[0] if words else '' + self.type = token_type + self.text = token_text + self.template_id = template_id + self.line_number = line_number + + def __str__(self): + return "({type}, {text}, {template_id}, {line_number})".format(type=self.type, text=repr(self.text), + template_id=self.template_id, + line_number=self.line_number) + + +# The Lexer takes a template string as input and chops it into a list of Tokens. +class Lexer: + + def __init__(self, template_string, template_id): + self.template_string = template_string + self.template_id = template_id + self.tokens = [] + self.index = 0 + self.line_number = 1 + + def tokenize(self): + while self.index < len(self.template_string): + if self.match(comment_start): + self.read_comment_tag() + elif self.match(eprint_start): + self.read_eprint_tag() + elif self.match(print_start): + self.read_print_tag() + elif self.match(instruction_start): + self.read_instruction_tag() + else: + self.read_text() + return self.tokens + + def match(self, target): + if self.template_string.startswith(target, self.index): + return True + return False + + def advance(self): + if self.template_string[self.index] == '\n': + self.line_number += 1 + self.index += 1 + + def read_comment_tag(self): + self.index += len(comment_start) + start_line_number = self.line_number + while self.index < len(self.template_string): + if self.match(comment_end): + self.index += len(comment_end) + return + self.advance() + msg = "Unclosed comment tag." + raise errors.TemplateLexingError(msg, self.template_id, start_line_number) + + def read_eprint_tag(self): + self.index += len(eprint_start) + start_index = self.index + start_line_number = self.line_number + while self.index < len(self.template_string): + if self.match(eprint_end): + text = self.template_string[start_index:self.index].strip() + self.tokens.append(Token("EPRINT", text, self.template_id, start_line_number)) + self.index += len(eprint_end) + return + self.advance() + msg = "Unclosed escaped-print tag." + raise errors.TemplateLexingError(msg, self.template_id, start_line_number) + + def read_print_tag(self): + self.index += len(print_start) + start_index = self.index + start_line_number = self.line_number + while self.index < len(self.template_string): + if self.match(print_end): + text = self.template_string[start_index:self.index].strip() + self.tokens.append(Token("PRINT", text, self.template_id, start_line_number)) + self.index += len(print_end) + return + self.advance() + msg = "Unclosed print tag." + raise errors.TemplateLexingError(msg, self.template_id, start_line_number) + + def read_instruction_tag(self): + self.index += len(instruction_start) + start_index = self.index + start_line_number = self.line_number + while self.index < len(self.template_string): + if self.match(instruction_end): + text = self.template_string[start_index:self.index].strip() + self.tokens.append(Token("INSTRUCTION", text, self.template_id, start_line_number)) + self.index += len(instruction_end) + return + self.advance() + msg = "Unclosed instruction tag." + raise errors.TemplateLexingError(msg, self.template_id, start_line_number) + + def read_text(self): + start_index = self.index + start_line_number = self.line_number + while self.index < len(self.template_string): + if self.match(comment_start): + break + elif self.match(eprint_start): + break + elif self.match(print_start): + break + elif self.match(instruction_start): + break + self.advance() + text = self.template_string[start_index:self.index] + self.tokens.append(Token("TEXT", text, self.template_id, start_line_number)) + + +# The Parser takes a template string as input, lexes it into a token stream, then compiles the +# token stream into a tree of nodes. +class Parser: + + def __init__(self, template_string, template_id): + self.template_string = template_string + self.template_id = template_id + + def parse(self): + stack = [nodes.Node()] + expecting = [] + + for token in Lexer(self.template_string, self.template_id).tokenize(): + if token.type == "TEXT": + stack[-1].children.append(nodes.TextNode(token)) + elif token.type in ("PRINT", "EPRINT"): + stack[-1].children.append(nodes.PrintNode(token)) + elif token.keyword in nodes.instruction_keywords: + node_class, endword = nodes.instruction_keywords[token.keyword] + node = node_class(token) + stack[-1].children.append(node) + if endword: + stack.append(node) + expecting.append(endword) + elif token.keyword in nodes.instruction_endwords: + if len(expecting) == 0: + msg = "Unexpected '{}' tag.".format(token.keyword) + raise errors.TemplateSyntaxError(msg, token) + elif expecting[-1] != token.keyword: + msg = "Unexpected '{}' tag. ".format(token.keyword) + msg += "Ibis was expecting the following closing tag: '{}'.".format(expecting[-1]) + raise errors.TemplateSyntaxError(msg, token) + else: + stack[-1].exit_scope() + stack.pop() + expecting.pop() + elif token.keyword == '': + msg = "Empty instruction tag." + raise errors.TemplateSyntaxError(msg, token) + else: + msg = "Unrecognised instruction tag '{}'.".format(token.keyword) + raise errors.TemplateSyntaxError(msg, token) + + if expecting: + token = stack[-1].token + msg = "Unexpected end of template. " + msg += "Ibis was expecting a closing '{}' tag to close the ".format(expecting[-1]) + msg += "'{keyword}' tag opened in line {line_number}.".format(keyword=token.keyword, + line_number=token.line_number) + raise errors.TemplateSyntaxError(msg, token) + + return stack.pop() + diff --git a/script.plexmod/lib/_included_packages/ibis/context.py b/script.plexmod/lib/_included_packages/ibis/context.py new file mode 100644 index 0000000000..94f67e26db --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/context.py @@ -0,0 +1,179 @@ +# coding=utf-8 + +import datetime +from . import errors + + +# User-configurable functions and variables available in all contexts. +builtins = { + 'now': datetime.datetime.now, + 'range': range, +} + + +class ContextDict(dict): + def __getattr__(self, attr): + return self.get(attr) + + def __setattr__(self, attr, value): + self[attr] = value + + +# A wrapper around a stack of dictionaries. +class DataStack: + strict_mode = False + + def __init__(self, strict_mode): + self.stack = [] + self.strict_mode = strict_mode + + def __getitem__(self, key): + for d in reversed(self.stack): + if key in d: + try: + return d[key] + except KeyError: + if self.strict_mode: + raise + return + raise KeyError(key) + + def __getattr__(self, key): + if key not in self.__dict__: + try: + return self[key] + except KeyError: + if self.strict_mode: + raise + return + return self.__dict__[key] + + +# A Context object is a wrapper around the user's input data. Its `.resolve()` method contains +# the lookup-logic for resolving dotted variable names. +class Context(object): + + def __init__(self, data_dict, strict_mode): + # Stack of data dictionaries for the .resolve() method. + self.data = DataStack(strict_mode) + + # Standard builtins. + self.data.stack.append(ContextDict({ + 'context': self, + 'is_defined': self.is_defined, + })) + + # User-configurable builtins. + self.data.stack.append(ContextDict(builtins)) + + # Instance-specific data. + self.data.stack.append(ContextDict(data_dict)) + + # Nodes can store state information here to avoid threading issues. + self.stash = {} + + # Chain of ancestor templates. + self.templates = [] + + # In strict mode undefined variables raise an UndefinedVariable exception. + self.strict_mode = strict_mode + + def __setitem__(self, key, value): + self.data.stack[-1][key] = value + + def __getitem__(self, key): + return self.data[key] + + def __getattr__(self, key): + if key not in self.__dict__: + try: + return self.get(key) + except KeyError: + if self.strict_mode: + raise + return + return self.__dict__[key] + + def push(self, data=None): + self.data.stack.append(ContextDict(data or {})) + + def pop(self): + self.data.stack.pop() + + def get(self, key, default=None): + for d in reversed(self.data.stack): + if key in d: + return d[key] + return default + + def set_global(self, key, value): + self.data.stack[2][key] = value + + def update(self, data_dict): + self.data.stack[-1].update(data_dict) + + def resolve(self, varstring, token): + words = [] + result = self.data + for word in varstring.split('.'): + words.append(word) + if hasattr(result, word): + result = getattr(result, word) + else: + try: + result = result[word] + except: + try: + result = result[int(word)] + except: + if self.strict_mode: + msg = "Cannot resolve the variable '{}' in template ".format('.'.join(words)) + msg += "'{template_id}', line {line_number}.".format(template_id=token.template_id, + line_number=token.line_number) + errors.raise_(errors.UndefinedVariable(msg, token), None) + return Undefined() + return result + + def is_defined(self, varstring): + current = self.data + for word in varstring.split('.'): + if hasattr(current, word): + current = getattr(current, word) + else: + try: + current = current[word] + except: + try: + current = current[int(word)] + except: + return False + return True + + +# Null type returned when a context lookup fails. +class Undefined: + + def __str__(self): + return '' + + def __bool__(self): + return False + + def __len__(self): + return 0 + + def __contains__(self, key): + return False + + def __iter__(self): + return self + + def __next__(self): + raise StopIteration + + def __eq__(self, other): + return False + + def __ne__(self, other): + return True + diff --git a/script.plexmod/lib/_included_packages/ibis/errors.py b/script.plexmod/lib/_included_packages/ibis/errors.py new file mode 100644 index 0000000000..1f4deebf27 --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/errors.py @@ -0,0 +1,65 @@ +# coding=utf-8 + +from six import reraise as raise_from + + +def raise_(value, exc=None, *args, **kwargs): + raise_from(type(value), value, exc and getattr(exc, "__traceback__", None) or None) + + +# Base class for all exception types raised by the template engine. +class TemplateError(Exception): + + def __init__(self, msg): + self.msg = msg + + def __str__(self): + if hasattr(self, "token") and self.token is not None: + return "Template '{template_id}', line {line_number}: {msg}".format(template_id=self.token.template_id, + line_number=self.token.line_number, + msg=self.msg) + return self.msg + + +# This exception type may be raised while attempting to load a template file. +class TemplateLoadError(TemplateError): + pass + + +# This exception type is raised if the lexer cannot tokenize a template string. +class TemplateLexingError(TemplateError): + + def __init__(self, msg, template_id, line_number): + super(TemplateLexingError, self).__init__(msg) + self.template_id = template_id + self.line_number = line_number + + def __str__(self): + return "Template '{template_id}', line {line_number}: {msg}".format(template_id=self.template_id, + line_number=self.line_number, + msg=self.msg) + + +# This exception type may be raised while a template is being compiled. +class TemplateSyntaxError(TemplateError): + + def __init__(self, msg, token): + super(TemplateSyntaxError, self).__init__(msg) + self.token = token + + +# This exception type may be raised while a template is being rendered. +class TemplateRenderingError(TemplateError): + + def __init__(self, msg, token): + super(TemplateRenderingError, self).__init__(msg) + self.token = token + + +# This exception type is raised in strict mode if a variable cannot be resolved. +class UndefinedVariable(TemplateError): + + def __init__(self, msg, token): + super(UndefinedVariable, self).__init__(msg) + self.token = token + diff --git a/script.plexmod/lib/_included_packages/ibis/filters.py b/script.plexmod/lib/_included_packages/ibis/filters.py new file mode 100644 index 0000000000..36aa3679fe --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/filters.py @@ -0,0 +1,306 @@ +# coding=utf-8 + +import re +import pprint +import random + +from . import context + +try: + import pygments + import pygments.lexers + import pygments.formatters +except ImportError: + pygments = None + +try: + from html import escape as html_escape +except ImportError: + from cgi import escape as html_escape + + +# Dictionary of registered filter functions. +filtermap = {} + + +# Decorator function for registering filters. A filter function should accept at least one +# argument - the value to be filtered - and return the filtered result. It can optionally +# accept any number of additional arguments. +# +# This decorator can be used as: +# +# @register +# @register() +# @register('name') +# +# If no name is supplied the function name will be used. +def register(nameorfunc=None, with_context=False): + + if callable(nameorfunc): + nameorfunc.with_context = with_context + filtermap[nameorfunc.__name__] = nameorfunc + return nameorfunc + + def register_filter_function(func): + func.with_context = with_context + filtermap[nameorfunc or func.__name__] = func + return func + + return register_filter_function + + +@register +def argtest(*args): + """ Test filter: returns arguments as a concatenated string. """ + return '|'.join(str(arg) for arg in args) + + +@register +def default(obj, fallback): + """ Returns `obj` if `obj` is truthy, otherwise `fallback`. """ + return obj or fallback + + +@register +def dtformat(dt, format='%Y-%m-%d %H:%M'): + """ Formats a datetime object using the specified format string. """ + return dt.strftime(format) + + +@register +def endswith(s, suffix): + """ True if the string ends with the specified suffix. """ + return s.endswith(suffix) + + +@register +@register('e') +@register('esc') +def escape(s, quotes=True): + """ Converts html syntax characters to character entities. """ + return html_escape(s, quotes) + + +@register +def first(seq): + """ Returns the first element in the sequence `seq`. """ + return seq[0] + + +@register +def firsth(html): + """ Returns the content of the first heading element. """ + match = re.search(r']*>(.*?)', html, flags=re.DOTALL) + return match.group(2) if match else '' + + +@register +def firsth1(html): + """ Returns the content of the first h1 element. """ + match = re.search(r']*>(.*?)', html, flags=re.DOTALL) + return match.group(1) if match else '' + + +@register +def firstp(html): + """ Returns the content of the first p element. """ + match = re.search(r']*>(.*?)

', html, flags=re.DOTALL) + return match.group(1) if match else '' + + +@register('reversed') +def get_reversed(seq): + """ Returns a reverse iterator over the sequence `seq`. """ + return reversed(seq) + + +@register +def index(seq, i): + """ Returns the ith element in the sequence `seq`. """ + return seq[i] + + +@register('divisible_by') +def is_divisible_by(n, d): + """ True if the integer `n` is a multiple of the integer `d`. """ + return n % d == 0 + + +@register('even') +def is_even(n): + """ True if the integer `n` is even. """ + return n % 2 == 0 + + +@register('odd') +def is_odd(n): + """ True if the integer `n` is odd. """ + return n % 2 != 0 + + +@register +def join(seq, sep=''): + """ Joins elements of the sequence `seq` with the string `sep`. """ + return sep.join(str(item) for item in seq) + + +@register +def last(seq): + """ Returns the last element in the sequence `seq`. """ + return seq[-1] + + +@register('len') +def length(seq): + """ Returns the length of the sequence `seq`. """ + return len(seq) + + +@register +def lower(s): + """ Returns the string `s` converted to lowercase. """ + return s.lower() + + +@register('pprint') +def prettyprint(obj): + """ Returns a pretty-printed representation of `obj`. """ + return pprint.pformat(obj) + + +@register +def pygmentize(text, lang=None): + """ Applies syntax highlighting using Pygments. + + If no language is specified, Pygments will attempt to guess the correct + lexer to use. If Pygments is not available or if an appropriate lexer + cannot be found then the filter will return the input text with any + html special characters escaped. + """ + if pygments: + if lang: + try: + lexer = pygments.lexers.get_lexer_by_name(lang) + except pygments.util.ClassNotFound: + lexer = None + else: + try: + lexer = pygments.lexers.guess_lexer(text) + except pygments.util.ClassNotFound: + lexer = None + if lexer: + formatter = pygments.formatters.HtmlFormatter(nowrap=True) + text = pygments.highlight(text, lexer, formatter) + else: + text = html_escape(text) + else: + text = html_escape(text) + return text + + +@register +def random(seq): + """ Returns a random element from the sequence `seq`. """ + return random.choice(seq) + + +@register('repr') +def to_repr(obj): + """ Returns the result of calling repr() on `obj`. """ + return repr(obj) + + +@register +def slice(seq, start, stop=None, step=None): + """ Returns the start:stop:step slice of the sequence `seq`. """ + return seq[start:stop:step] + + +@register +def spaceless(html): + """ Strips all whitespace between html/xml tags. """ + return re.sub(r'>\s+<', '><', html) + + +@register +def startswith(s, prefix): + """ True if the string starts with the specified prefix. """ + return s.startswith(prefix) + + +@register('str') +def to_str(obj): + """ Returns the result of calling str() on `obj`. """ + return str(obj) + + +@register +def striptags(html): + """ Returns the string `html` with all html tags stripped. """ + return re.sub(r'<[^>]*>', '', html) + + +@register +def teaser(s, delimiter=''): + """ Returns the portion of the string `s` before `delimiter`, + or an empty string if `delimiter` is not found. """ + index = s.find(delimiter) + if index == -1: + return '' + else: + return s[:index] + + +@register +@register('title') +def titlecase(s): + """ Returns the string `s` converted to titlecase. """ + return re.sub( + r"[A-Za-z]+('[A-Za-z]+)?", + lambda m: m.group(0)[0].upper() + m.group(0)[1:], + s + ) + + +@register +def truncatechars(s, n, ellipsis='...'): + """ Truncates the string `s` to at most `n` characters. """ + if len(s) > n: + return s[:n - 3].rstrip(' .,;:?!') + ellipsis + else: + return s + + +@register +def truncatewords(s, n, ellipsis=' [...]'): + """ Truncates the string `s` to at most `n` words. """ + words = s.split() + if len(words) > n: + return ' '.join(words[:n]) + ellipsis + else: + return ' '.join(words) + + +@register +def upper(s): + """ Returns the string `s` converted to uppercase. """ + return s.upper() + + +@register +def wrap(s, tag): + """ Wraps a string in opening and closing tags. """ + return '<%s>%s' % (tag, str(s), tag) + + +@register +def if_undefined(obj, fallback): + """ Returns `obj` if `obj` is defined, otherwise `fallback`. """ + return fallback if isinstance(obj, context.Undefined) else obj + + +@register +def is_defined(obj): + """ Returns true if `obj` is defined, otherwise false. """ + return not isinstance(obj, context.Undefined) + diff --git a/script.plexmod/lib/_included_packages/ibis/loaders.py b/script.plexmod/lib/_included_packages/ibis/loaders.py new file mode 100644 index 0000000000..dd06de6633 --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/loaders.py @@ -0,0 +1,106 @@ +# coding=utf-8 + +import os + +from io import open + +from .template import Template +from .errors import TemplateLoadError, raise_ + + +# Loads templates from the file system. Assumes files are utf-8 encoded. Compiled templates are +# cached in memory, so they only need to be compiled once. Templates are *not* automatically +# recompiled if the underlying template file changes. +# +# A FileLoader instance should be initialized with a path to a base template directory: +# +# loader = FileLoader('/path/to/base/dir') +# +# Multiple base directories can be specified: +# +# loader = FileLoader('/path/to/base/dir1', '/path/to/base/dir2') +# +# The loader instance can then be called with a filename string. The loader will return the +# template object corresponding the template file or raise a TemplateLoadError if no file can +# be located. Note that the filename string may include subdirectory paths: +# +# template = loader('foo.txt') +# template = loader('subdir/foo.txt') +# +class FileLoader: + + def __init__(self, *base_dirs): + self.base_dirs = base_dirs + self.cache = {} + + def __call__(self, filename): + if filename in self.cache: + return self.cache[filename] + + for base_dir in self.base_dirs: + path = os.path.join(base_dir, filename) + if os.path.isfile(path): + try: + with open(path, encoding='utf-8') as file: + template_string = file.read() + except OSError as err: + msg = "FileLoader cannot load the template file '{}'.".format(path) + raise_(TemplateLoadError(msg), err) + + template = Template(template_string, filename) + self.cache[filename] = template + return template + + msg = "FileLoader cannot locate the template file '{}'.".format(filename) + raise TemplateLoadError(msg) + + +# Like FileLoader but templates are automatically recompiled if the underlying template file +# is modified. +class FileReloader: + + def __init__(self, *base_dirs): + self.base_dirs = base_dirs + self.cache = {} + + def __call__(self, filename): + for base_dir in self.base_dirs: + path = os.path.join(base_dir, filename) + if os.path.isfile(path): + mtime = os.path.getmtime(path) + if filename in self.cache: + if mtime == self.cache[filename][0]: + return self.cache[filename][1] + + try: + with open(path, encoding='utf-8') as file: + template_string = file.read() + except OSError as err: + msg = "FileReloader cannot load the template file '{}'.".format(path) + raise_(TemplateLoadError(msg), err) + + template = Template(template_string, filename) + self.cache[filename] = (mtime, template) + return template + + msg = "FileReloader cannot locate the template file '{}'.".format(filename) + raise TemplateLoadError(msg) + + +# Loads templates from a dictionary of template strings. Templates are compiled once and cached for +# future use. +class DictLoader: + + def __init__(self, template_strings): + self.templates = {} + self.template_strings = template_strings + + def __call__(self, name): + if name in self.templates: + return self.templates[name] + elif name in self.template_strings: + template = Template(self.template_strings[name], name) + self.templates[name] = template + return template + msg = "DictLoader has no entry matching the template name '{}'.".format(name) + raise TemplateLoadError(msg) diff --git a/script.plexmod/lib/_included_packages/ibis/nodes.py b/script.plexmod/lib/_included_packages/ibis/nodes.py new file mode 100644 index 0000000000..d78bb95cb6 --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/nodes.py @@ -0,0 +1,849 @@ +# coding=utf-8 + +import ast +import operator +import re +import itertools +import collections +import math + +import six + +import ibis + +from . import utils +from . import filters +from . import errors + + +# Dictionary of registered keywords for instruction tags. +instruction_keywords = {} + + +# Set of registered endwords for instruction tags with block scope. +instruction_endwords = set() + + +# Decorator function for registering handler classes for instruction tags. +# Registering an endword gives the instruction tag block scope. +def register(keyword, endword=None): + + def register_node_class(node_class): + instruction_keywords[keyword] = (node_class, endword) + if endword: + instruction_endwords.add(endword) + return node_class + + return register_node_class + + +# Helper class for evaluating expression strings. +# +# An Expression object is initialized with an expression string parsed from a template. An +# expression string can contain a variable name or a Python literal, optionally followed by a +# sequence of filters. +# +# The Expression object handles the rather convoluted process of parsing the string, evaluating +# the literal or resolving the variable, calling the variable if it resolves to a callable, and +# applying the filters to the resulting object. The consumer simply needs to call the expression's +# .eval() method and supply an appropriate Context object. +# +# Examples of valid expression syntax include: +# +# foo.bar.baz|default('bam')|escape +# 'foo', 'bar', 'baz'|random +# +# Arguments can be passed to callables using bracket syntax: +# +# foo.bar.baz('bam')|filter(25, 'text') +# + +class ContextVariable(str): + pass + + +class ResolveContextVariable(str): + pass + + +class KeepExpr(Exception): + pass + + +def safe_math_eval(s): + def checkmath(x, *args): + if x not in [a for a in dir(math) if "__" not in a]: + if x in filters.filtermap or x in ibis.context.builtins: + raise KeepExpr + msg = "Unknown func {}()".format(x) + raise SyntaxError(msg) + fun = getattr(math, x) + return fun(*args) + + bin_ops = { + ast.Add: operator.add, + ast.Sub: operator.sub, + ast.Mult: operator.mul, + ast.Div: operator.truediv, + ast.Mod: operator.mod, + ast.Pow: operator.pow, + ast.Call: checkmath, + ast.BinOp: ast.BinOp, + } + + un_ops = { + ast.USub: operator.neg, + ast.UAdd: operator.pos, + ast.UnaryOp: ast.UnaryOp, + } + + ops = tuple(bin_ops) + tuple(un_ops) + + tree = ast.parse(s, mode="eval") + + def _eval(node): + if isinstance(node, ast.Expression): + return _eval(node.body) + if isinstance(node, utils.Constant): + return getattr(node, 'value', getattr(node, 'n')) + if isinstance(node, ast.Name): + return node.id + if isinstance(node, ast.BinOp): + left = _eval(node.left) + right = _eval(node.right) + + # collect lists of possible variables and return them + ret = [] + if isinstance(left, list): + ret += left + elif isinstance(left, six.string_types): + ret.append(left) + if isinstance(right, list): + ret += right + elif isinstance(right, six.string_types): + ret.append(right) + + if ret: + return ret + return bin_ops[type(node.op)](left, right) + if isinstance(node, ast.UnaryOp): + if isinstance(node.operand, ops): + operand = _eval(node.operand) + else: + operand = node.operand.value + return un_ops[type(node.op)](operand) + if isinstance(node, ast.Call): + args = [_eval(x) for x in node.args] + try: + return checkmath(node.func.id, *args) + except KeepExpr as e: + return "{}({})".format(node.func.id, ",".join(map(str, args))) + msg = "Bad syntax, {}".format(type(node)) + raise SyntaxError(msg) + + return _eval(tree) + + +def apply_math_context(expr, argnames, args): + """ + Takes an unparsable math expression, replaces argnames with args, then evaluates it again. + """ + for index, arg in enumerate(argnames): + expr = expr.replace(arg, str(args[index])) + + # re-evaluate math expr after resolving variables + ret = safe_math_eval(expr) + return ret + + +class Expression: + + re_func_call = re.compile(r'^([\w.]+)\((.*)\)$') + re_varstring = re.compile(r'^[\w.]+$') + + def __init__(self, expr, token): + self.token = token + self.filters = [] + self.literal = None + self.is_literal = False + self.varstring = None + self.func_args = None + self.func_kwargs = None + self.is_func_call = False + self.dyn_args = False + pipe_split = utils.splitc(expr.strip(), '|', strip=True) + self._parse_primary_expr(pipe_split[0]) + self._parse_filters(pipe_split[1:]) + if self.is_literal and not self.dyn_args: + self.literal = self._apply_filters_to_literal(self.literal) + + def _parse_primary_expr(self, expr): + try: + self.literal = ast.literal_eval(expr) + self.is_literal = True + except: + if any(ext in expr for ext in ('+', '- ', '/', '*', '**', '%')): + # fixme: this currently doesn't work with variables with filters applied, e.g.: a|default(10) + 20 + try: + matheval = safe_math_eval(expr) + if isinstance(matheval, list): + # we've found possible variables in the math evaluation + self.is_literal = False + self.is_func_call = True + + func_args = [] + for index, arg in enumerate(matheval): + if isinstance(arg, six.string_types): + # try resolving as variable + if utils.isidentifier(arg): + func_args.append(ContextVariable(arg)) + continue + elif self.re_func_call.match(arg): + # func call + func_args.append(Expression(arg, self.token)) + continue + func_args.append(arg) + + self.varstring = lambda *args: apply_math_context(expr, matheval, args) + + self.func_args = func_args + self.func_kwargs = {} + return + + self.literal = matheval + self.is_literal = True + return + except: + pass + + self.is_literal = False + self.is_func_call, self.dyn_args, self.varstring, self.func_args, self.func_kwargs = self._try_parse_as_func_call(expr) + if not self.is_func_call and not self.re_varstring.match(expr): + msg = "Unparsable expression '{}'.".format(expr) + errors.raise_(errors.TemplateSyntaxError(msg, self.token), None) + + def _try_parse_as_func_call(self, expr): + match = self.re_func_call.match(expr) + if not match: + return False, False, expr, [], {} + func_name = match.group(1) + func_args = utils.splitc(match.group(2), ',', True, True) + func_kwargs = {} + dyn_args = False + for index, arg in enumerate(func_args[:]): + kwarg = None + if "=" in arg: + func_args.remove(arg) + kwarg, arg = arg.split("=", 1) + try: + if kwarg: + func_kwargs[kwarg] = ast.literal_eval(arg) + else: + func_args[index] = ast.literal_eval(arg) + except Exception: + # try resolving as variable + if utils.isidentifier(arg): + if kwarg: + func_kwargs[kwarg] = ContextVariable(arg) + else: + func_args[index] = ContextVariable(arg) + dyn_args = True + continue + + # arg is a func call? + arg_is_func = self.re_func_call.match(expr) + if arg_is_func: + func_ret = Expression(arg, self.token) + if kwarg: + func_kwargs[kwarg] = func_ret + else: + func_args[index] = func_ret + continue + + msg = "Unparsable argument '{}'. Arguments must be valid Python literals.".format(arg) + errors.raise_(errors.TemplateSyntaxError(msg, self.token)) + + return True, dyn_args, func_name, func_args, func_kwargs + + def _parse_filters(self, filter_list): + for filter_expr in filter_list: + _, dyn_args, filter_name, filter_args, filter_kwargs = self._try_parse_as_func_call(filter_expr) + if filter_name in filters.filtermap: + self.filters.append((filter_name, filters.filtermap[filter_name], filter_args, filter_kwargs, dyn_args)) + else: + msg = "Unrecognised filter name '{}'.".format(filter_name) + raise errors.TemplateSyntaxError(msg, self.token) + + def _apply_filters_to_literal(self, obj): + for filt in self.filters[:]: + name, func, args, kwargs, dyn_args = filt + if dyn_args or any(isinstance(a, Expression) for a in args) or any(isinstance(a, Expression) + for a in kwargs.values()): + continue + try: + obj = func(obj, *args, **kwargs) + self.filters.remove(filt) + except Exception as err: + msg = "Error applying filter '{}'. ".format(name) + errors.raise_(errors.TemplateSyntaxError(msg, self.token), err) + return obj + + def eval(self, context): + if self.is_literal and not self.dyn_args: + if self.filters: + # we have filters left + return self._apply_filters_to_variable(self.literal, context) + return self.literal + else: + return self._resolve_variable(context) + + def _resolve_arg_to_variable(self, arg, context): + if isinstance(arg, ContextVariable): + return context.resolve(arg, self.token) + elif isinstance(arg, Expression): + return arg.eval(context) + return arg + + def _resolve_variable(self, context): + if isinstance(self.varstring, six.string_types): + obj = context.resolve(self.varstring, self.token) + else: + obj = self.varstring + + if self.is_func_call: + try: + func_args = [] + for index, arg in enumerate(self.func_args): + func_args.append(self._resolve_arg_to_variable(arg, context)) + + fkw = {} + for kwarg, value in self.func_kwargs.items(): + fkw[kwarg] = self._resolve_arg_to_variable(value, context) + + if getattr(obj, "with_context", False): + fkw["context"] = context + obj = obj(*func_args, **fkw) + else: + obj = obj(*func_args, **fkw) + + # a filter/builtin might return a masked variable name whose content should be resolved in the current + # context. try to do so. + if isinstance(obj, ResolveContextVariable): + value = context.resolve(obj, self.token) + obj = context.resolve(value, self.token) + + except Exception as err: + msg = "Error calling function '{}'.".format(self.varstring) + errors.raise_(errors.TemplateRenderingError(msg, self.token), err) + return self._apply_filters_to_variable(obj, context) + + def _apply_filters_to_variable(self, obj, context): + for name, func, args, kwargs, _ in self.filters: + try: + _args = [] + for arg in args: + if isinstance(arg, Expression): + _args.append(arg.eval(context)) + continue + _args.append(self._resolve_arg_to_variable(arg, context)) + + fkw = {} + for kwarg, value in kwargs.items(): + if isinstance(value, Expression): + fkw[kwarg] = value.eval(context) + continue + fkw[kwarg] = self._resolve_arg_to_variable(value, context) + + if getattr(func, "with_context", False): + fkw["context"] = context + obj = func(obj, *_args, **fkw) + else: + obj = func(obj, *_args, **fkw) + except Exception as err: + msg = "Error applying filter '{}'.".format(name) + errors.raise_(errors.TemplateRenderingError(msg, self.token), err) + return obj + + +# Base class for all node objects. To render a node into a string call its .render() method. +# Subclasses shouldn't override the base .render() method; instead they should override +# .wrender() which ensures that any uncaught exceptions are wrapped in a TemplateRenderingError. +class Node: + + def __init__(self, token=None, children=None): + self.token = token + self.children = children or [] + try: + self.process_token(token) + except errors.TemplateError: + raise + except Exception as err: + if token: + tagname = "'{}'".format(token.keyword) if token.type == "INSTRUCTION" else token.type + msg = "An unexpected error occurred while parsing the {} tag: ".format(tagname) + msg += "{name}: {err}".format(name=err.__class__.__name__, err=err) + else: + msg = "Unexpected syntax error: {name}: {err}".format(name=err.__class__.__name__, err=err) + errors.raise_(errors.TemplateSyntaxError(msg, token), err) + + def __str__(self): + return self.to_str() + + def to_str(self, depth=0): + output = ["· " * depth + "{}".format(self.__class__.__name__)] + for child in self.children: + output.append(child.to_str(depth + 1)) + return "\n".join(output) + + def render(self, context): + try: + return self.wrender(context) + except errors.TemplateError: + raise + except Exception as err: + if self.token: + tagname = "'{}'".format(self.token.keyword) if self.token.type == "INSTRUCTION" else self.token.type + msg = "An unexpected error occurred while rendering the {} tag: ".format(tagname) + msg += "{name}: {err}".format(name=err.__class__.__name__, err=err) + else: + msg = "Unexpected rendering error: {name}: {err}".format(name=err.__class__.__name__, err=err) + errors.raise_(errors.TemplateRenderingError(msg, self.token), err) + + def wrender(self, context): + return ''.join(child.render(context) for child in self.children) + + def process_token(self, token): + pass + + def exit_scope(self): + pass + + def split_children(self, delimiter_class): + for index, child in enumerate(self.children): + if isinstance(child, delimiter_class): + return self.children[:index], child, self.children[index+1:] + return self.children, None, [] + + +# TextNodes represent ordinary template text, i.e. text not enclosed in tag delimiters. +class TextNode(Node): + + def wrender(self, context): + return self.token.text + + +# A PrintNode evaluates an expression and prints its result. Multiple expressions can be listed +# separated by 'or' or '||'. The first expression to resolve to a truthy value will be printed. +# (If none of the expressions are truthy the final value will be printed regardless.) +# +# {{ or or }} +# +# Alternatively, print statements can use the ternary operator: ?? :: +# +# {{ ?? :: }} +# +# If is truthy, will be printed, otherwise will be printed. +# +# Note that either OR-chaining or the ternary operator can be used in a single print statement, +# but not both. +class PrintNode(Node): + + def process_token(self, token): + chunks = utils.splitre(token.text, (r'\?\?', r'\:\:'), True) + if len(chunks) == 5 and chunks[1] == '??' and chunks[3] == '::': + self.is_ternary = True + self.test_expr = Expression(chunks[0], token) + self.true_branch_expr = Expression(chunks[2], token) + self.false_branch_expr = Expression(chunks[4], token) + else: + self.is_ternary = False + exprs = utils.splitre(token.text, (r'\s+or\s+', r'\|\|')) + self.exprs = [Expression(e, token) for e in exprs] + + def wrender(self, context): + if self.is_ternary: + if self.test_expr.eval(context): + content = self.true_branch_expr.eval(context) + else: + content = self.false_branch_expr.eval(context) + else: + for expr in self.exprs: + content = expr.eval(context) + if content: + break + return filters.escape(str(content)) if self.token.type == "EPRINT" else str(content) + + +# ForNodes implement `for ... in ...` looping over iterables. +# +# {% for in %} ... [ {% empty %} ... ] {% endfor %} +# +# ForNodes support unpacking into multiple loop variables: +# +# {% for , in %} +# +@register('for', 'endfor') +class ForNode(Node): + + regex = re.compile(r'for\s+(\w+(?:,\s*\w+)*)\s+in\s+(.+)') + + def process_token(self, token): + match = self.regex.match(token.text) + if match is None: + msg = "Malformed 'for' tag." + raise errors.TemplateSyntaxError(msg, token) + self.loopvars = [var.strip() for var in match.group(1).split(',')] + self.expr = Expression(match.group(2), token) + + def wrender(self, context): + collection = self.expr.eval(context) + if collection and hasattr(collection, '__iter__'): + collection = list(collection) + length = len(collection) + unpack = len(self.loopvars) > 1 + output = [] + for index, item in enumerate(collection): + context.push() + if unpack: + try: + unpacked = dict(zip(self.loopvars, item)) + except Exception as err: + msg = "Unpacking error." + errors.raise_(errors.TemplateRenderingError(msg, self.token), err) + else: + context.update(unpacked) + else: + context[self.loopvars[0]] = item + context['loop'] = { + 'index': index, + 'count': index + 1, + 'length': length, + 'is_first': index == 0, + 'is_last': index == length - 1, + 'parent': context.get('loop'), + } + output.append(self.for_branch.render(context)) + context.pop() + return ''.join(output) + else: + return self.empty_branch.render(context) + + def exit_scope(self): + for_nodes, _, empty_nodes = self.split_children(EmptyNode) + self.for_branch = Node(None, for_nodes) + self.empty_branch = Node(None, empty_nodes) + + +# Delimiter node to implement for/empty branching. +@register('empty') +class EmptyNode(Node): + pass + + +# IfNodes implement if/elif/else branching. +# +# {% if [not] %} ... {% endif %} +# {% if [not] %} ... {% endif %} +# {% if <...> %} ... {% elif <...> %} ... {% else %} ... {% endif %} +# +# IfNodes support 'and' and 'or' conjunctions; 'and' has higher precedence so: +# +# if a and b or c and d +# +# is treated as: +# +# if (a and b) or (c and d) +# +# Note that explicit brackets are not supported. +@register('if', 'endif') +class IfNode(Node): + + condition = collections.namedtuple('Condition', 'negated lhs op rhs') + + re_condition = re.compile(r''' + (not\s+)?(.+?)\s+(==|!=|<|>|<=|>=|not[ ]in|in)\s+(.+) + | + (not\s+)?(.+) + ''', re.VERBOSE + ) + + operators = { + '==': operator.eq, + '!=': operator.ne, + '<': operator.lt, + '>': operator.gt, + '<=': operator.le, + '>=': operator.ge, + 'in': lambda a, b: a in b, + 'not in': lambda a, b: a not in b, + } + + def process_token(self, token): + self.tag = token.keyword + try: + conditions = token.text.split(None, 1)[1] + except: + msg = "Malformed '{}' tag.".format(self.tag) + errors.raise_(errors.TemplateSyntaxError(msg, token), None) + + self.condition_groups = [ + [ + self.parse_condition(condstr) + for condstr in utils.splitre(or_block, (r'\s+and\s+', r'&&')) + ] + for or_block in utils.splitre(conditions, (r'\s+or\s+', r'\|\|')) + ] + + def parse_condition(self, condstr): + match = self.re_condition.match(condstr) + if match.group(2): + return self.condition( + negated = bool(match.group(1)), + lhs = Expression(match.group(2), self.token), + op = self.operators[match.group(3)], + rhs = Expression(match.group(4), self.token), + ) + else: + return self.condition( + negated = bool(match.group(5)), + lhs = Expression(match.group(6), self.token), + op = None, + rhs = None, + ) + + def eval_condition(self, cond, context): + try: + if cond.op: + result = cond.op(cond.lhs.eval(context), cond.rhs.eval(context)) + else: + result = operator.truth(cond.lhs.eval(context)) + except Exception as err: + msg = "An exception was raised while evaluating the condition in the " + msg += "'{}' tag.".format(self.tag) + errors.raise_(errors.TemplateRenderingError(msg, self.token), err) + if cond.negated: + result = not result + return result + + def wrender(self, context): + for condition_group in self.condition_groups: + for condition in condition_group: + is_true = self.eval_condition(condition, context) + if not is_true: + break + if is_true: + break + if is_true: + return self.true_branch.render(context) + else: + return self.false_branch.render(context) + + def exit_scope(self): + if_nodes, elif_node, elif_nodes = self.split_children(ElifNode) + if elif_node: + self.true_branch = Node(None, if_nodes) + self.false_branch = IfNode(elif_node.token, elif_nodes) + self.false_branch.exit_scope() + return + if_nodes, _, else_nodes = self.split_children(ElseNode) + self.true_branch = Node(None, if_nodes) + self.false_branch = Node(None, else_nodes) + + +# Delimiter node to implement if/elif branching. +@register('elif') +class ElifNode(Node): + pass + + +# Delimiter node to implement if/else branching. +@register('else') +class ElseNode(Node): + pass + + +# CycleNodes cycle over an iterable expression. +# +# {% cycle %} +# +# Each time the node is evaluated it will render the next value in the sequence, looping once it +# reaches the end; e.g. +# +# {% cycle 'odd', 'even' %} +# +# will alternate continuously between printing 'odd' and 'even'. +@register('cycle') +class CycleNode(Node): + + def process_token(self, token): + try: + tag, arg = token.text.split(None, 1) + except: + msg = "Malformed 'cycle' tag." + errors.raise_(errors.TemplateSyntaxError(msg, token), None) + self.expr = Expression(arg, token) + + def wrender(self, context): + # We store our state info on the context object to avoid a threading mess if + # the template is being simultaneously rendered by multiple threads. + if not self in context.stash: + items = self.expr.eval(context) + if not hasattr(items, '__iter__'): + items = '' + context.stash[self] = itertools.cycle(items) + iterator = context.stash[self] + return str(next(iterator, '')) + + +# IncludeNodes include a sub-template. +# +# {% include %} +# +# {% include with = %} +# +# {% include with = & = %} +# +# Requires a template name which can be supplied as either a string literal or a variable +# resolving to a string. This name will be passed to the registered template loader. +@register('include') +class IncludeNode(Node): + def process_token(self, token): + self.variables = {} + parts = utils.splitre(token.text[7:], [r"with\s"]) + if len(parts) == 1: + self.template_arg = parts[0] + self.template_expr = Expression(parts[0], token) + elif len(parts) == 2: + self.template_arg = parts[0] + self.template_expr = Expression(parts[0], token) + chunks = utils.splitc(parts[1], "&", strip=True, discard_empty=True) + for chunk in chunks: + try: + name, expr = chunk.split('=', 1) + self.variables[name.strip()] = Expression(expr.strip(), token) + except Exception as e: + raise + errors.raise_(errors.TemplateSyntaxError("Malformed 'include' tag.", token), None) + else: + raise errors.TemplateSyntaxError("Malformed 'include' tag.", token) + + def wrender(self, context): + template_name = self.template_expr.eval(context) + if isinstance(template_name, str): + if ibis.loader: + template = ibis.loader(template_name) + context.push() + for name, expr in self.variables.items(): + context[name] = expr.eval(context) + rendered = template.root_node.render(context) + context.pop() + return rendered + else: + msg = "No template loader has been specified. " + msg += "A template loader is required by the 'include' tag in " + msg += "template '{template_id}', line {line_number}.".format(template_id=self.token.template_id, + line_number=self.token.line_number) + raise errors.TemplateLoadError(msg) + else: + msg = "Invalid argument for the 'include' tag. " + msg += "The variable '{}' should evaluate to a string. ".format(self.template_arg) + msg += "This variable has the value: {}.".format(repr(template_name)) + raise errors.TemplateRenderingError(msg, self.token) + + +# ExtendsNodes implement template inheritance. They indicate that the current template inherits +# from or 'extends' the specified parent template. +# +# {% extends "parent.txt" %} +# +# Requires the parent name as a string literal to pass to the registered template loader. +@register('extends') +class ExtendsNode(Node): + + def process_token(self, token): + try: + tag, arg = token.text.split(None, 1) + except: + errors.raise_(errors.TemplateSyntaxError("Malformed 'extends' tag.", token), None) + + expr = Expression(arg, token) + if expr.is_literal and isinstance(expr.literal, str): + self.parent_name = expr.literal + else: + msg = "Malformed 'extends' tag. The template name must be a string literal." + raise errors.TemplateSyntaxError(msg, token) + + +# BlockNodes implement template inheritance. +# +# {% block %} ... {% endblock %} +# +# A block tag defines a titled block of content that can be overridden in child templates. +@register('block', 'endblock') +class BlockNode(Node): + + def process_token(self, token): + self.title = token.text[5:].strip() + + def wrender(self, context): + block_list = [] + for template in context.templates: + block_node = template.blocks.get(self.title) + if block_node: + block_list.append(block_node) + return self.render_block(context, block_list) + + def render_block(self, context, block_list): + if block_list: + current_block = block_list.pop(0) + context.push() + context['super'] = lambda: self.render_block(context, block_list) + output = ''.join(child.render(context) for child in current_block.children) + context.pop() + return output + else: + return '' + + +# Strips leading and trailing whitespace along with all whitespace between HTML tags. +@register('spaceless', 'endspaceless') +class SpacelessNode(Node): + + def wrender(self, context): + output = ''.join(child.render(context) for child in self.children) + return filters.spaceless(output).strip() + + +# Trims leading and trailing whitespace. +@register('trim', 'endtrim') +class TrimNode(Node): + + def wrender(self, context): + return ''.join(child.render(context) for child in self.children).strip() + + +# Caches a complex expression under a simpler alias. +# +# {% with <name> = <expr> %} ... {% endwith %} +# +# {% with <name1> = <expr> & <name2> = <expr> %} ... {% endwith %} +# +@register('with', 'endwith') +class WithNode(Node): + def process_token(self, token): + self.variables = {} + chunks = utils.splitc(token.text[4:], "&", strip=True, discard_empty=True) + for chunk in chunks: + try: + name, expr = chunk.split('=', 1) + self.variables[name.strip()] = Expression(expr.strip(), token) + except: + errors.raise_(errors.TemplateSyntaxError("Malformed 'with' tag.", token), None) + + def wrender(self, context): + context.push() + for name, expr in self.variables.items(): + context[name] = expr.eval(context) + rendered = ''.join(child.render(context) for child in self.children) + context.pop() + return rendered diff --git a/script.plexmod/lib/_included_packages/ibis/template.py b/script.plexmod/lib/_included_packages/ibis/template.py new file mode 100644 index 0000000000..f9cf689699 --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/template.py @@ -0,0 +1,45 @@ +# coding=utf-8 + +import ibis +from .context import Context +from .nodes import ExtendsNode, BlockNode + + +# A Template object is initialized with a template string containing template markup and a +# template ID which is used to identify the template in error messages. The .render() method +# accepts a data dictionary or a set of keyword arguments and returns a rendered output string. +class Template: + + def __init__(self, template_string, template_id="UNIDENTIFIED"): + self.root_node = ibis.compiler.compile(template_string, template_id) + self.blocks = self._register_blocks(self.root_node, {}) + + def __str__(self): + return str(self.root_node) + + def render(self, *pargs, **kwargs): + data_dict = pargs[0] if pargs else kwargs + strict_mode = kwargs.get("strict_mode", False) + context = Context(data_dict, strict_mode) + return self._render(context) + + def _render(self, context): + context.templates.append(self) + if self.root_node.children and isinstance(self.root_node.children[0], ExtendsNode): + if ibis.loader: + parent_template = ibis.loader(self.root_node.children[0].parent_name) + return parent_template._render(context) + else: + msg = "No template loader has been specified. A template loader is required " + msg += "by the 'extends' tag in template '{}'.".format(self.template_id) + raise ibis.errors.TemplateLoadError(msg) + else: + return self.root_node.render(context) + + def _register_blocks(self, node, blocks): + if isinstance(node, BlockNode): + blocks[node.title] = node + for child in node.children: + self._register_blocks(child, blocks) + return blocks + diff --git a/script.plexmod/lib/_included_packages/ibis/utils.py b/script.plexmod/lib/_included_packages/ibis/utils.py new file mode 100644 index 0000000000..1c44ae40ad --- /dev/null +++ b/script.plexmod/lib/_included_packages/ibis/utils.py @@ -0,0 +1,114 @@ +# coding=utf-8 + +import ast +import re +import keyword + + +# Splits a string on instances of a delimiter character. Ignores quoted delimiters. +def splitc(s, delimiter, strip=False, discard_empty=False, maxsplit=-1): + + tokens, buf, expecting, escaped = [], [], None, False + + for index, char in enumerate(s): + if expecting: + buf.append(char) + if char == expecting and not escaped: + expecting = None + else: + if char == delimiter: + tokens.append(''.join(buf)) + buf = [] + if len(tokens) == maxsplit: + buf.append(s[index+1:]) + break + else: + buf.append(char) + if char in ('"', "'"): + expecting = char + escaped = not escaped if char == '\\' else False + + tokens.append(''.join(buf)) + + if strip: + tokens = [t.strip() for t in tokens] + + if discard_empty: + tokens = [t for t in tokens if t] + + return tokens + + +# Splits a string on blocks of whitespace. Strips leading and trailing whitespace. +# Ignores quoted whitespace. +def splitws(s, maxsplit=-1): + tokens, buf, expecting, escaped, wsrun = [], [], None, False, False + + for index, char in enumerate(s.strip()): + if expecting: + buf.append(char) + if char == expecting and not escaped: + expecting = None + else: + if char.isspace(): + if wsrun: + continue + tokens.append(''.join(buf)) + buf = [] + wsrun = True + if len(tokens) == maxsplit: + buf.append(s[index+1:].lstrip()) + break + else: + buf.append(char) + wsrun = False + if char in ('"', "'"): + expecting = char + escaped = not escaped if char == '\\' else False + + tokens.append(''.join(buf)) + return tokens + + +# Splits a string using a list of regular expression patterns. Ignores quoted delimiter matches. +def splitre(s, delimiters, keep_delimiters=False): + tokens, buf = [], [] + end_last_match = 0 + + pattern = r'''"(?:[^\\"]|\\.)*"|'(?:[^\\']|\\.)*'|%s''' + pattern %= '|'.join(delimiters) + + for match in re.finditer(pattern, s): + if match.group()[0] in ["'", '"']: + buf.append(s[end_last_match:match.end()]) + end_last_match = match.end() + continue + buf.append(s[end_last_match:match.start()]) + tokens.append(''.join(buf)) + buf = [] + end_last_match = match.end() + if keep_delimiters: + tokens.append(match.group()) + + buf.append(s[end_last_match:]) + tokens.append(''.join(buf)) + + return tokens + + +ISIDENTIFIER_RE = re.compile(r'^[a-z_][a-z0-9_]*$', re.I) + + +def isidentifier(s): + try: + return s.isidentifier() + except AttributeError: + if s in keyword.kwlist: + return False + return ISIDENTIFIER_RE.match(s) is not None + + +try: + Constant = ast.Constant +except AttributeError: + Constant = ast.Num diff --git a/script.plexmod/lib/_included_packages/plexnet/asyncadapter.py b/script.plexmod/lib/_included_packages/plexnet/asyncadapter.py index 97fbcd741b..798c7eae4f 100644 --- a/script.plexmod/lib/_included_packages/plexnet/asyncadapter.py +++ b/script.plexmod/lib/_included_packages/plexnet/asyncadapter.py @@ -9,6 +9,7 @@ from requests.packages.urllib3 import HTTPConnectionPool, HTTPSConnectionPool from requests.packages.urllib3.connection import HTTPConnection from requests.packages.urllib3.poolmanager import PoolManager, proxy_from_url +from requests.packages.urllib3.exceptions import ConnectTimeoutError try: from requests.packages.urllib3.connectionpool import VerifiedHTTPSConnection except ImportError: @@ -32,16 +33,18 @@ WIN_ENOTCONN = 10057 WIN_EHOSTUNREACH = 10065 +MAX_RETRIES = 3 + def ABORT_FLAG_FUNCTION(): return False -class TimeoutException(Exception): +class CanceledException(Exception): pass -class CanceledException(Exception): +class TimeoutException(ConnectTimeoutError): pass @@ -77,6 +80,8 @@ def getConnectTimeout(self): class AsyncVerifiedHTTPSConnection(VerifiedHTTPSConnection): + __slots__ = ("_canceled", "deadline", "_timeout") + def __init__(self, *args, **kwargs): VerifiedHTTPSConnection.__init__(self, *args, **kwargs) self._canceled = False @@ -85,7 +90,7 @@ def __init__(self, *args, **kwargs): def _check_timeout(self): if time.time() > self.deadline: - raise TimeoutException('connection timed out') + raise ConnectTimeoutError('connection timed out') def create_connection(self, address, timeout=None, source_address=None): """Connect to *address* and return the socket object. @@ -166,6 +171,7 @@ def cancel(self): class AsyncHTTPConnection(HTTPConnection): + __slots__ = ("_canceled", "deadline") def __init__(self, *args, **kwargs): HTTPConnection.__init__(self, *args, **kwargs) self._canceled = False @@ -176,6 +182,8 @@ def cancel(self): class AsyncHTTPConnectionPool(HTTPConnectionPool): + __slots__ = ("connections",) + def __init__(self, *args, **kwargs): HTTPConnectionPool.__init__(self, *args, **kwargs) self.connections = [] @@ -209,6 +217,8 @@ def cancel(self): class AsyncHTTPSConnectionPool(HTTPSConnectionPool): + __slots__ = ("connections",) + def __init__(self, *args, **kwargs): HTTPSConnectionPool.__init__(self, *args, **kwargs) self.connections = [] @@ -329,8 +339,8 @@ def get_connection(self, url, proxies=None): class Session(requests.Session): def __init__(self, *args, **kwargs): requests.Session.__init__(self, *args, **kwargs) - self.mount('https://', AsyncHTTPAdapter()) - self.mount('http://', AsyncHTTPAdapter()) + self.mount('https://', AsyncHTTPAdapter(max_retries=MAX_RETRIES)) + self.mount('http://', AsyncHTTPAdapter(max_retries=MAX_RETRIES)) def cancel(self): for v in self.adapters.values(): diff --git a/script.plexmod/lib/_included_packages/plexnet/audio.py b/script.plexmod/lib/_included_packages/plexnet/audio.py index 5c06a31ad3..0a969dac74 100644 --- a/script.plexmod/lib/_included_packages/plexnet/audio.py +++ b/script.plexmod/lib/_included_packages/plexnet/audio.py @@ -10,12 +10,6 @@ def __init__(self, *args, **kwargs): self._settings = None media.MediaItem.__init__(self, *args, **kwargs) - def __eq__(self, other): - return self.ratingKey == other.ratingKey - - def __ne__(self, other): - return not self.__eq__(other) - def _setData(self, data): for k, v in data.attrib.items(): setattr(self, k, plexobjects.PlexValue(v, self)) @@ -56,7 +50,7 @@ def tracks(self, watched=None): leavesKey = '/library/metadata/%s/allLeaves' % self.ratingKey return plexobjects.listItems(self.server, leavesKey, watched=watched) - def all(self): + def all(self, *args, **kwargs): return self.tracks() def track(self, title): @@ -93,7 +87,7 @@ def track(self, title): path = '%s/children' % self.key return plexobjects.findItem(self.server, path, title) - def all(self): + def all(self, *args, **kwargs): return self.tracks() def isFullObject(self): diff --git a/script.plexmod/lib/_included_packages/plexnet/audioobject.py b/script.plexmod/lib/_included_packages/plexnet/audioobject.py index a980dea6f1..4d46155bb8 100644 --- a/script.plexmod/lib/_included_packages/plexnet/audioobject.py +++ b/script.plexmod/lib/_included_packages/plexnet/audioobject.py @@ -30,7 +30,7 @@ def build(self, directPlay=None): self.metadata = obj - util.LOG("Constructed audio item for playback: {0}".format(util.cleanObjTokens(obj))) + util.LOG("Constructed audio item for playback: {0}", util.cleanObjTokens(obj)) return self.metadata diff --git a/script.plexmod/lib/_included_packages/plexnet/certs/ISRG Root X1.crt b/script.plexmod/lib/_included_packages/plexnet/certs/ISRG Root X1.crt new file mode 100644 index 0000000000..e693fb3457 --- /dev/null +++ b/script.plexmod/lib/_included_packages/plexnet/certs/ISRG Root X1.crt @@ -0,0 +1,61 @@ +-----BEGIN CERTIFICATE----- +MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw +WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP +R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx +sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm +NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg +Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG +/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB +Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA +FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw +Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB +gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W +PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl +ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz +CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm +lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 +avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 +yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O +yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids +hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ +HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv +MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX +nLRbwHOoq7hHwg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/script.plexmod/lib/_included_packages/plexnet/certs/R3.crt b/script.plexmod/lib/_included_packages/plexnet/certs/R3.crt new file mode 100644 index 0000000000..43b222a60a --- /dev/null +++ b/script.plexmod/lib/_included_packages/plexnet/certs/R3.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw +WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP +R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx +sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm +NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg +Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG +/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB +Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA +FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw +Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB +gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W +PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl +ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz +CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm +lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 +avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 +yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O +yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids +hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ +HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv +MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX +nLRbwHOoq7hHwg== +-----END CERTIFICATE----- diff --git a/script.plexmod/lib/_included_packages/plexnet/certs/USERTrust ECC Certification Authority.crt b/script.plexmod/lib/_included_packages/plexnet/certs/USERTrust ECC Certification Authority.crt new file mode 100644 index 0000000000..b1cf1fd3a1 --- /dev/null +++ b/script.plexmod/lib/_included_packages/plexnet/certs/USERTrust ECC Certification Authority.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- diff --git a/script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL ECC Domain Secure Site CA.crt b/script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL ECC Domain Secure Site CA.crt new file mode 100644 index 0000000000..d582c66ab4 --- /dev/null +++ b/script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL ECC Domain Secure Site CA.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAwygAwIBAgIQI7dt48G7KxpRlh4I6rdk6DAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMjAwMTMw +MDAwMDAwWhcNMzAwMTI5MjM1OTU5WjBLMQswCQYDVQQGEwJBVDEQMA4GA1UEChMH +WmVyb1NTTDEqMCgGA1UEAxMhWmVyb1NTTCBFQ0MgRG9tYWluIFNlY3VyZSBTaXRl +IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAENkFhFytTJe2qypTk1tpIV+9QuoRk +gte7BRvWHwYk9qUznYzn8QtVaGOCMBBfjWXsqqivl8q1hs4wAYl03uNOXgFu7iZ7 +zFP6I6T3RB0+TR5fZqathfby47yOCZiAJI4go4IBdTCCAXEwHwYDVR0jBBgwFoAU +OuEJhtTPGcKWdnRJdtzgNcZjY5owHQYDVR0OBBYEFA9r5kvOOUeu9n6QHnnwMJGS +yF+jMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAiBgNVHSAEGzAZMA0GCysGAQQBsjEBAgJO +MAgGBmeBDAECATBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVz +dC5jb20vVVNFUlRydXN0RUNDQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYI +KwYBBQUHAQEEajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5j +b20vVVNFUlRydXN0RUNDQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6 +Ly9vY3NwLnVzZXJ0cnVzdC5jb20wCgYIKoZIzj0EAwMDZwAwZAIwJHBUDwHJQN3I +VNltVMrICMqYQ3TYP/TXqV9t8mG5cAomG2MwqIsxnL937Gewf6WIAjAlrauksO6N +UuDdDXyd330druJcZJx0+H5j5cFOYBaGsKdeGW7sCMaR2PsDFKGllas= +-----END CERTIFICATE----- diff --git a/script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL RSA Domain Secure Site CA.crt b/script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL RSA Domain Secure Site CA.crt new file mode 100644 index 0000000000..1d1739bccd --- /dev/null +++ b/script.plexmod/lib/_included_packages/plexnet/certs/ZeroSSL RSA Domain Secure Site CA.crt @@ -0,0 +1,39 @@ +-----BEGIN CERTIFICATE----- +MIIG1TCCBL2gAwIBAgIQbFWr29AHksedBwzYEZ7WvzANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMjAw +MTMwMDAwMDAwWhcNMzAwMTI5MjM1OTU5WjBLMQswCQYDVQQGEwJBVDEQMA4GA1UE +ChMHWmVyb1NTTDEqMCgGA1UEAxMhWmVyb1NTTCBSU0EgRG9tYWluIFNlY3VyZSBT +aXRlIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAhmlzfqO1Mdgj +4W3dpBPTVBX1AuvcAyG1fl0dUnw/MeueCWzRWTheZ35LVo91kLI3DDVaZKW+TBAs +JBjEbYmMwcWSTWYCg5334SF0+ctDAsFxsX+rTDh9kSrG/4mp6OShubLaEIUJiZo4 +t873TuSd0Wj5DWt3DtpAG8T35l/v+xrN8ub8PSSoX5Vkgw+jWf4KQtNvUFLDq8mF +WhUnPL6jHAADXpvs4lTNYwOtx9yQtbpxwSt7QJY1+ICrmRJB6BuKRt/jfDJF9Jsc +RQVlHIxQdKAJl7oaVnXgDkqtk2qddd3kCDXd74gv813G91z7CjsGyJ93oJIlNS3U +gFbD6V54JMgZ3rSmotYbz98oZxX7MKbtCm1aJ/q+hTv2YK1yMxrnfcieKmOYBbFD +hnW5O6RMA703dBK92j6XRN2EttLkQuujZgy+jXRKtaWMIlkNkWJmOiHmErQngHvt +iNkIcjJumq1ddFX4iaTI40a6zgvIBtxFeDs2RfcaH73er7ctNUUqgQT5rFgJhMmF +x76rQgB5OZUkodb5k2ex7P+Gu4J86bS15094UuYcV09hVeknmTh5Ex9CBKipLS2W +2wKBakf+aVYnNCU6S0nASqt2xrZpGC1v7v6DhuepyyJtn3qSV2PoBiU5Sql+aARp +wUibQMGm44gjyNDqDlVp+ShLQlUH9x8CAwEAAaOCAXUwggFxMB8GA1UdIwQYMBaA +FFN5v1qqK0rPVIDh2JvAnfKyA2bLMB0GA1UdDgQWBBTI2XhootkZaNU9ct5fCj7c +tYaGpjAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUE +FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwIgYDVR0gBBswGTANBgsrBgEEAbIxAQIC +TjAIBgZngQwBAgEwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1 +c3QuY29tL1VTRVJUcnVzdFJTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYG +CCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3Qu +Y29tL1VTRVJUcnVzdFJTQUFkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRw +Oi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBDAUAA4ICAQAVDwoIzQDV +ercT0eYqZjBNJ8VNWwVFlQOtZERqn5iWnEVaLZZdzxlbvz2Fx0ExUNuUEgYkIVM4 +YocKkCQ7hO5noicoq/DrEYH5IuNcuW1I8JJZ9DLuB1fYvIHlZ2JG46iNbVKA3ygA +Ez86RvDQlt2C494qqPVItRjrz9YlJEGT0DrttyApq0YLFDzf+Z1pkMhh7c+7fXeJ +qmIhfJpduKc8HEQkYQQShen426S3H0JrIAbKcBCiyYFuOhfyvuwVCFDfFvrjADjd +4jX1uQXd161IyFRbm89s2Oj5oU1wDYz5sx+hoCuh6lSs+/uPuWomIq3y1GDFNafW ++LsHBU16lQo5Q2yh25laQsKRgyPmMpHJ98edm6y2sHUabASmRHxvGiuwwE25aDU0 +2SAeepyImJ2CzB80YG7WxlynHqNhpE7xfC7PzQlLgmfEHdU+tHFeQazRQnrFkW2W +kqRGIq7cKRnyypvjPMkjeiV9lRdAM9fSJvsB3svUuu1coIG1xxI1yegoGM4r5QP4 +RGIVvYaiI76C0djoSbQ/dkIUUXQuB8AL5jyH34g3BZaaXyvpmnV4ilppMXVAnAYG +ON51WhJ6W0xNdNJwzYASZYH+tmCWI+N60Gv2NNMGHwMZ7e9bXgzUCZH5FaBFDGR5 +S9VWqHB73Q+OyIVvIbKYcSc2w/aSuFKGSA== +-----END CERTIFICATE----- diff --git a/script.plexmod/lib/_included_packages/plexnet/certs/acme.bundle.crt b/script.plexmod/lib/_included_packages/plexnet/certs/acme.bundle.crt new file mode 100644 index 0000000000..2cfc492df9 --- /dev/null +++ b/script.plexmod/lib/_included_packages/plexnet/certs/acme.bundle.crt @@ -0,0 +1,47 @@ +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/script.plexmod/lib/_included_packages/plexnet/certs/plex.direct.bundle.crt b/script.plexmod/lib/_included_packages/plexnet/certs/plex.direct.bundle.crt new file mode 100644 index 0000000000..e693fb3457 --- /dev/null +++ b/script.plexmod/lib/_included_packages/plexnet/certs/plex.direct.bundle.crt @@ -0,0 +1,61 @@ +-----BEGIN CERTIFICATE----- +MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw +WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP +R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx +sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm +NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg +Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG +/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB +Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA +FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw +Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB +gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W +PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl +ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz +CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm +lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 +avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 +yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O +yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids +hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ +HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv +MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX +nLRbwHOoq7hHwg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/script.plexmod/lib/_included_packages/plexnet/gdm.py b/script.plexmod/lib/_included_packages/plexnet/gdm.py index 507b290bcc..ccc540aed0 100644 --- a/script.plexmod/lib/_included_packages/plexnet/gdm.py +++ b/script.plexmod/lib/_included_packages/plexnet/gdm.py @@ -150,7 +150,7 @@ def _discover(self): for s, i in sockets: if self._close: return - util.DEBUG_LOG(' o-> Broadcasting to {0}: {1}'.format(i.name, i.broadcast)) + util.DEBUG_LOG(' o-> Broadcasting to {0}: {1}', i.name, i.broadcast) try: s.sendto(packet, (i.broadcast, DISCOVERY_PORT)) success = True @@ -216,7 +216,7 @@ def discoveryFinished(self, *args, **kwargs): self.close() if self.servers: - util.LOG("Finished GDM discovery, found {0} server(s)".format(len(self.servers))) + util.LOG("Finished GDM discovery, found {0} server(s)", len(self.servers)) from . import plexapp plexapp.SERVERMANAGER.updateFromConnectionType(self.servers, plexconnection.PlexConnection.SOURCE_DISCOVERED) self.servers = None diff --git a/script.plexmod/lib/_included_packages/plexnet/http.py b/script.plexmod/lib/_included_packages/plexnet/http.py index d79f8fbef2..e77d5adc5b 100644 --- a/script.plexmod/lib/_included_packages/plexnet/http.py +++ b/script.plexmod/lib/_included_packages/plexnet/http.py @@ -6,9 +6,11 @@ import requests import socket import urllib3 +import datetime from . import threadutils import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import mimetypes +import functools from . import plexobjects from xml.etree import ElementTree @@ -23,23 +25,26 @@ DEFAULT_TIMEOUT = asyncadapter.AsyncTimeout(util.TIMEOUT).setConnectTimeout(util.TIMEOUT) -KNOWN_HOSTS = {} +RESOLVED_PD_HOSTS = {} + +CURRENT_ACME_CRT_DATE = datetime.date(year=2035, month=6, day=3) +TODAY = datetime.date.today() _getaddrinfo = socket.getaddrinfo def pgetaddrinfo(host, port, *args, **kwargs): """ - "circumvent" DNS rebind protection + "circumvent" DNS rebind protection for our requests. this does not apply to Kodi requests (assets etc.) """ if host.endswith("plex.direct"): v6 = host.count("-") > 3 - if host in KNOWN_HOSTS: - ip = KNOWN_HOSTS[host] + if host in RESOLVED_PD_HOSTS: + ip = RESOLVED_PD_HOSTS[host] else: base = host.split(".", 1)[0] - ip = KNOWN_HOSTS[host] = v6 and base.replace("-", ":") or base.replace("-", ".") - util.DEBUG_LOG("Dynamically resolving {} to {}".format(host, ip)) + ip = RESOLVED_PD_HOSTS[host] = v6 and base.replace("-", ":") or base.replace("-", ".") + util.DEBUG_LOG("Dynamically resolving {} to {}", host, ip) fam = v6 and socket.AF_INET6 or socket.AF_INET stype = kwargs.get("type", kwargs.get("socktype", socket.SOCK_STREAM)) @@ -53,17 +58,17 @@ def pgetaddrinfo(host, port, *args, **kwargs): def GET(*args, **kwargs): - return requests.get(*args, headers=util.BASE_HEADERS.copy(), timeout=util.TIMEOUT, **kwargs) + return requests.get(*args, headers=util.BASE_HEADERS.copy(), timeout=DEFAULT_TIMEOUT, **kwargs) def POST(*args, **kwargs): - return requests.post(*args, headers=util.BASE_HEADERS.copy(), timeout=util.TIMEOUT, **kwargs) + return requests.post(*args, headers=util.BASE_HEADERS.copy(), timeout=DEFAULT_TIMEOUT, **kwargs) def Session(): s = asyncadapter.Session() + s.request = functools.partial(s.request, timeout=DEFAULT_TIMEOUT) s.headers = util.BASE_HEADERS.copy() - s.timeout = util.TIMEOUT return s @@ -77,9 +82,13 @@ def __setattr__(self, attr, value): class HttpRequest(object): + __slots__ = ("server", "path", "hasParams", "ignoreResponse", "session", "currentResponse", "method", "url", + "thread", "__dict__") _cancel = False - def __init__(self, url, method=None, forceCertificate=False): + USE_SYSTEM_CERT_BUNDLE = False + + def __init__(self, url, method=None): self.server = None self.path = None self.hasParams = '?' in url @@ -91,13 +100,18 @@ def __init__(self, url, method=None, forceCertificate=False): self.url = url self.thread = None - # Use our specific plex.direct CA cert if applicable to improve performance - # if forceCertificate or url[:5] == "https": # TODO: ---------------------------------------------------------------------------------IMPLEMENT - # certsPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'certs') - # if "plex.direct" in url: - # self.session.cert = os.path.join(certsPath, 'plex-bundle.crt') - # else: - # self.session.cert = os.path.join(certsPath, 'ca-bundle.crt') + # Use a specific CA cert bundle if applicable + if not self.USE_SYSTEM_CERT_BUNDLE and util.USE_CERT_BUNDLE != "system" and url[:5] == "https": + if util.USE_CERT_BUNDLE == "custom": + # noinspection PyTypeChecker + self.session.verify = os.path.join(util.translatePath(util.ADDON.getAddonInfo("profile")), + "custom_bundle.crt") + + elif util.USE_CERT_BUNDLE == "acme" and TODAY <= CURRENT_ACME_CRT_DATE: + self.session.verify = os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'certs', 'acme.bundle.crt') + #else: + # self.session.cert = os.path.join(certsPath, 'ca-bundle.crt') def removeAsPending(self): from . import plexapp @@ -120,6 +134,8 @@ def _startAsync(self, body=None, contentType=None, context=None): res = self.session.delete(self.url, timeout=timeout, stream=True) elif self.method == 'HEAD': res = self.session.head(self.url, timeout=timeout, stream=True) + elif self.method == 'OPTIONS': + res = self.session.options(self.url, timeout=timeout, stream=True) elif self.method == 'POST' or body is not None: if not contentType: self.session.headers["Content-Type"] = "application/x-www-form-urlencoded" @@ -153,49 +169,49 @@ def _startAsync(self, body=None, contentType=None, context=None): self.removeAsPending() - def getWithTimeout(self, seconds=DEFAULT_TIMEOUT): - return HttpObjectResponse(self.getPostWithTimeout(seconds), self.path, self.server) + def getWithTimeout(self, timeout=DEFAULT_TIMEOUT): + return HttpObjectResponse(self.getPostWithTimeout(timeout), self.path, self.server) - def postWithTimeout(self, seconds=DEFAULT_TIMEOUT, body=None): + def postWithTimeout(self, timeout=DEFAULT_TIMEOUT, body=None): self.method = 'POST' - return HttpObjectResponse(self.getPostWithTimeout(seconds, body), self.path, self.server) + return HttpObjectResponse(self.getPostWithTimeout(timeout, body), self.path, self.server) - def getToStringWithTimeout(self, seconds=DEFAULT_TIMEOUT): - res = self.getPostWithTimeout(seconds) + def getToStringWithTimeout(self, timeout=DEFAULT_TIMEOUT): + res = self.getPostWithTimeout(timeout) if not res: return '' return res.text.encode('utf8') - def postToStringWithTimeout(self, body=None, seconds=DEFAULT_TIMEOUT): + def postToStringWithTimeout(self, body=None, timeout=DEFAULT_TIMEOUT): self.method = 'POST' - res = self.getPostWithTimeout(seconds, body) + res = self.getPostWithTimeout(timeout, body) if not res: return '' return res.text.encode('utf8') - def getPostWithTimeout(self, seconds=DEFAULT_TIMEOUT, body=None): + def getPostWithTimeout(self, timeout=DEFAULT_TIMEOUT, body=None): if self._cancel: return - self.logRequest(body, seconds, False) + self.logRequest(body, timeout=timeout, _async=False) try: if self.method == 'PUT': - res = self.session.put(self.url, timeout=seconds, stream=True) + res = self.session.put(self.url, timeout=timeout, stream=True) elif self.method == 'DELETE': - res = self.session.delete(self.url, timeout=seconds, stream=True) + res = self.session.delete(self.url, timeout=timeout, stream=True) elif self.method == 'HEAD': - res = self.session.head(self.url, timeout=seconds, stream=True) + res = self.session.head(self.url, timeout=timeout, stream=True) elif self.method == 'POST' or body is not None: - res = self.session.post(self.url, data=body, timeout=seconds, stream=True) + res = self.session.post(self.url, data=body, timeout=timeout, stream=True) else: - res = self.session.get(self.url, timeout=seconds, stream=True) + res = self.session.get(self.url, timeout=timeout, stream=True) self.currentResponse = res if self._cancel: return None - util.LOG("Got a {0} from {1}".format(res.status_code, util.cleanToken(self.url))) + util.LOG("Got a {0} from {1}", res.status_code, util.cleanToken(self.url)) # self.event = msg return res except Exception as e: @@ -349,7 +365,7 @@ def addRequestHeaders(transferObj, headers=None): if isinstance(headers, dict): for header in headers: transferObj.addHeader(header, headers[header]) - util.DEBUG_LOG("Adding header to {0}: {1}: {2}".format(transferObj, header, headers[header])) + util.DEBUG_LOG("Adding header to {0}: {1}: {2}", transferObj, header, headers[header]) def addUrlParam(url, param): diff --git a/script.plexmod/lib/_included_packages/plexnet/locks.py b/script.plexmod/lib/_included_packages/plexnet/locks.py index 5e309f4ee4..b05c2a33ab 100644 --- a/script.plexmod/lib/_included_packages/plexnet/locks.py +++ b/script.plexmod/lib/_included_packages/plexnet/locks.py @@ -8,16 +8,18 @@ class Locks(object): + __slots__ = ("locks", "oneTimeLocks") + def __init__(self): self.locks = {} self.oneTimeLocks = {} def lock(self, name): self.locks[name] = (self.locks.get(name) or 0) + 1 - util.DEBUG_LOG("Lock {0}, total={0}".format(name, self.locks[name])) + util.DEBUG_LOG("Lock {0}, total={0}", name, self.locks[name]) def lockOnce(self, name): - util.DEBUG_LOG("Locking once {0}".format(name)) + util.DEBUG_LOG("Locking once {0}", name) self.oneTimeLocks[name] = True def unlock(self, name, forceUnlock=False): @@ -39,7 +41,7 @@ def unlock(self, name, forceUnlock=False): normal = False unlocked = (normal or oneTime) - util.DEBUG_LOG("Unlock {0}, total={1}, unlocked={2}".format(name, self.locks.get(name) or 0, unlocked)) + util.DEBUG_LOG("Unlock {0}, total={1}, unlocked={2}", name, self.locks.get(name) or 0, unlocked) return unlocked diff --git a/script.plexmod/lib/_included_packages/plexnet/media.py b/script.plexmod/lib/_included_packages/plexnet/media.py index 802da02c92..ec5a77c72a 100644 --- a/script.plexmod/lib/_included_packages/plexnet/media.py +++ b/script.plexmod/lib/_included_packages/plexnet/media.py @@ -19,6 +19,15 @@ class MediaItem(plexobjects.PlexObject): + def __eq__(self, other): + return self.ratingKey == other.ratingKey + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(self.ratingKey) + def getIdentifier(self): identifier = self.get('identifier') or None @@ -66,7 +75,7 @@ def exists(self, force_full_check=False): data = self.server.query('/library/metadata/{0}'.format(self.ratingKey)) except exceptions.BadRequest: # item does not exist anymore - util.DEBUG_LOG("Item {} doesn't exist.".format(self.ratingKey)) + util.DEBUG_LOG("Item {} doesn't exist.", self.ratingKey) return False return data is not None and data.attrib.get('size') != '0' @@ -176,10 +185,11 @@ class TranscodeSession(plexobjects.PlexObject): class MediaTag(plexobjects.PlexObject): TYPE = None ID = 'None' + virtual = False def __repr__(self): tag = self.tag.replace(' ', '.')[0:20] - return '<%s:%s:%s>' % (self.__class__.__name__, self.id, tag) + return '<%s:%s:%s:%s>' % (self.__class__.__name__, self.id, tag, self.virtual) def __eq__(self, other): if other.__class__ != self.__class__: @@ -196,6 +206,11 @@ class Collection(MediaTag): FILTER = 'collection' +class Location(MediaTag): + TYPE = 'Location' + FILTER = 'location' + + class Country(MediaTag): TYPE = 'Country' FILTER = 'country' @@ -255,6 +270,11 @@ class Writer(MediaTag): FILTER = 'writer' +class Guid(MediaTag): + TYPE = 'Guid' + FILTER = 'guid' + + class Chapter(MediaTag): TYPE = 'Chapter' @@ -270,6 +290,9 @@ class Marker(MediaTag): TYPE = 'Marker' FILTER = 'Marker' + def __repr__(self): + return '<%s:%s:%s:%s>' % (self.__class__.__name__, self.id, self.type, self.final and "final" or "") + class Review(MediaTag): TYPE = 'Review' @@ -307,5 +330,5 @@ def getRelated(self, offset=None, limit=None, _max=36): try: return plexobjects.listItems(self.server, path, offset=offset, limit=limit, params={"count": _max}) except exceptions.BadRequest: - util.DEBUG_LOG("Invalid related items response returned for %s" % self) + util.DEBUG_LOG("Invalid related items response returned for {}", self) return None diff --git a/script.plexmod/lib/_included_packages/plexnet/mediachoice.py b/script.plexmod/lib/_included_packages/plexnet/mediachoice.py index a41f5c7c89..4afb73b200 100644 --- a/script.plexmod/lib/_included_packages/plexnet/mediachoice.py +++ b/script.plexmod/lib/_included_packages/plexnet/mediachoice.py @@ -40,11 +40,11 @@ def __init__(self, media=None, partIndex=0): else: util.WARN_LOG("Media does not contain a valid part") - util.LOG("Choice media: {0} part:{1}".format(media, partIndex)) + util.LOG("Choice media: {0} part:{1}", media, partIndex) for streamType in ("videoStream", "audioStream", "subtitleStream"): attr = getattr(self, streamType) if attr: - util.LOG("Choice {0}: {1}".format(streamType, repr(attr))) + util.LOG("Choice {0}: {1}", streamType, repr(attr)) else: util.WARN_LOG("Could not create media choice for invalid media") diff --git a/script.plexmod/lib/_included_packages/plexnet/mediadecisionengine.py b/script.plexmod/lib/_included_packages/plexnet/mediadecisionengine.py index 9dea3e0860..9d5adcd4bf 100644 --- a/script.plexmod/lib/_included_packages/plexnet/mediadecisionengine.py +++ b/script.plexmod/lib/_included_packages/plexnet/mediadecisionengine.py @@ -24,7 +24,8 @@ def __init__(self): def chooseMedia(self, item, forceUpdate=False): # If we've already evaluated this item, use our previous choice. - if not forceUpdate and item.mediaChoice is not None and item.mediaChoice.media is not None and not item.mediaChoice.media.isIndirect(): + if not forceUpdate and item.mediaChoice is not None and item.mediaChoice.media is not None and \ + not item.mediaChoice.media.isIndirect(): return item.mediaChoice # See if we're missing media/stream details for this item. @@ -99,7 +100,7 @@ def sortChoices(self, choices): def evaluateMediaVideo(self, item, media, partIndex=0): # Resolve indirects before doing anything else. if media.isIndirect(): - util.LOG("Resolve indirect media for {0}".format(item)) + util.LOG("Resolve indirect media for {0}", item) media = media.resolveIndirect() choice = mediachoice.MediaChoice(media, partIndex) @@ -230,10 +231,10 @@ def evaluateMediaVideo(self, item, media, partIndex=0): allowed.append("dca") if AC3Cond == 'always' and choice.audioStream.codec not in allowed: - util.LOG("MDE: Codec {} can't be direct played due to user settings".format(choice.audioStream.codec)) + util.LOG("MDE: Codec {} can't be direct played due to user settings", choice.audioStream.codec) choice.isDirectPlayable = False - elif AC3Cond in ('2', '5'): + elif AC3Cond in ('2', '3', '5', '6'): ch = int(AC3Cond) ach = choice.sorts.audioChannels @@ -263,16 +264,18 @@ def evaluateMediaVideo(self, item, media, partIndex=0): def canDirectPlay(self, item, choice): maxResolution = item.settings.getMaxResolution(item.getQualityType(), self.isSupported4k(choice.media, choice.videoStream)) height = choice.media.getVideoResolution() + features = item.settings.getPlaybackFeatures() + video_codecs = item.settings.getAdditionalCodecs() if height > maxResolution: - util.LOG("MDE: (DP) Video height is greater than max allowed: {0} > {1}".format(height, maxResolution)) - if height > 1088 and item.settings.getPreference("allow_4k", True): + util.LOG("MDE: (DP) Video height is greater than max allowed: {0} > {1}", height, maxResolution) + if height > 1088 and "allow_4k" in features: util.LOG("MDE: (DP) Unsupported 4k media") return False maxBitrate = item.settings.getMaxBitrate(item.getQualityType()) bitrate = choice.media.bitrate.asInt() if bitrate > maxBitrate: - util.LOG("MDE: (DP) Video bitrate is greater than the allowed max: {0} > {1}".format(bitrate, maxBitrate)) + util.LOG("MDE: (DP) Video bitrate is greater than the allowed max: {0} > {1}", bitrate, maxBitrate) return False if choice.videoStream is None: @@ -282,18 +285,18 @@ def canDirectPlay(self, item, choice): if not item.settings.getGlobal("supports1080p60"): videoFrameRate = choice.videoStream.asInt() if videoFrameRate > 30 and height >= 1080: - util.LOG("MDE: (DP) Frame rate is not supported for resolution: {0}@{1}".format(height, videoFrameRate)) + util.LOG("MDE: (DP) Frame rate is not supported for resolution: {0}@{1}", height, videoFrameRate) return False - if choice.videoStream.codec == "hevc" and not item.settings.getPreference("allow_hevc", True): + if choice.videoStream.codec == "hevc" and "allow_hevc" not in video_codecs: util.LOG("MDE: (DP) Codec is HEVC, which is disabled") return False - if choice.videoStream.codec == "av1" and not item.settings.getPreference("allow_av1", False): + if choice.videoStream.codec == "av1" and "allow_av1" not in video_codecs: util.LOG("MDE: (DP) Codec is AV1, which is disabled") return False - if choice.videoStream.codec == "vc1" and not item.settings.getPreference("allow_vc1", True): + if choice.videoStream.codec == "vc1" and "allow_vc1" not in video_codecs: util.LOG("MDE: (DP) Codec is VC1, which is disabled") return False @@ -313,29 +316,29 @@ def canDirectPlay(self, item, choice): # Roku 4 only: H.265/HEVC (MKV, MP4, MOV); VP9 (.MKV) # if True: # container in ("mp4", "mov", "m4v", "mkv"): - # util.LOG("MDE: {0} container looks OK, checking streams".format(container)) + # util.LOG("MDE: {0} container looks OK, checking streams", container) # isHEVC = videoCodec == "hevc" and item.settings.getPreference("allow_hevc", False) # isVP9 = videoCodec == "vp9" and container == "mkv" and item.settings.getGlobal("vp9Support") # if videoCodec != "h264" and videoCodec != "mpeg4" and not isHEVC and not isVP9: - # util.LOG("MDE: Unsupported video codec: {0}".format(videoCodec)) + # util.LOG("MDE: Unsupported video codec: {0}", videoCodec) # return False # # TODO(schuyler): Fix ref frames check. It's more nuanced than this. # if choice.videoStream.refFrames.asInt() > 8: - # util.LOG("MDE: Too many ref frames: {0}".format(choice.videoStream.refFrames)) + # util.LOG("MDE: Too many ref frames: {0}", choice.videoStream.refFrames) # return False # # HEVC supports a bitDepth of 10, otherwise 8 is the limit # if choice.videoStream.bitDepth.asInt() > (isHEVC and 10 or 8): - # util.LOG("MDE: Bit depth too high: {0}".format(choice.videoStream.bitDepth)) + # util.LOG("MDE: Bit depth too high: {0}", choice.videoStream.bitDepth) # return False # # We shouldn't have to whitelist particular audio codecs, we can just # # check to see if the Roku can decode this codec with the number of channels. # if not item.settings.supportsAudioStream(audioCodec, numChannels): - # util.LOG("MDE: Unsupported audio track: {0} ({1} channels)".format(audioCodec, numChannels)) + # util.LOG("MDE: Unsupported audio track: {0} ({1} channels)", audioCodec, numChannels) # return False # # # TODO(schuyler): We've reported this to Roku, they may fix it. If/when @@ -347,7 +350,7 @@ def canDirectPlay(self, item, choice): # # Those were our problems, everything else should be OK. # return True # else: - # util.LOG("MDE: Unsupported container: {0}".format(container)) + # util.LOG("MDE: Unsupported container: {0}", container) # return False @@ -437,7 +440,7 @@ def evaluateSubtitles(self, stream): def evaluateMediaMusic(self, item, media): # Resolve indirects before doing anything else. if media.isIndirect(): - util.LOG("Resolve indirect media for {0}".format(item)) + util.LOG("Resolve indirect media for {0}", item) media = media.resolveIndirect() choice = mediachoice.MediaChoice(media) @@ -468,7 +471,9 @@ def evaluateMediaMusic(self, item, media): # Inspect the audio stream attributes if the codec/container can direct # play. For now we only need to verify the sample rate. - if choice.audioStream is not None and choice.audioStream.samplingRate.asInt() >= 192000: + maxSR = 384000 if item.settings.getPreference('audio_hires', True) else 191999 + + if choice.audioStream is not None and choice.audioStream.samplingRate.asInt() > maxSR: util.LOG("MDE: sampling rate is not compatible") choice.isDirectPlayable = False else: @@ -510,7 +515,7 @@ def cloudIfRemote(self, choice): return 0 def isSupported4k(self, media, videoStream): - if videoStream is None or not util.INTERFACE.getPreference("allow_4k", True): + if videoStream is None or "allow_4k" not in util.INTERFACE.getPlaybackFeatures(): return False # # Roku 4 only: H.265/HEVC (MKV, MP4, MOV); VP9 (.MKV) diff --git a/script.plexmod/lib/_included_packages/plexnet/myplexaccount.py b/script.plexmod/lib/_included_packages/plexnet/myplexaccount.py index d9add92d79..326be51353 100644 --- a/script.plexmod/lib/_included_packages/plexnet/myplexaccount.py +++ b/script.plexmod/lib/_included_packages/plexnet/myplexaccount.py @@ -16,7 +16,9 @@ class HomeUser(util.AttributeDict): - pass + def __repr__(self): + return '<{0}:{1}:{2} (admin: {3})>'.format(self.__class__.__name__, self.id, + self.get('title', 'None').encode('utf8'), self.get('admin', 0)) class MyPlexAccount(object): @@ -33,6 +35,7 @@ def __init__(self): # Booleans self.isAuthenticated = util.INTERFACE.getPreference('auto_signin', False) + self.cacheHomeUsers = util.INTERFACE.getPreference('cache_home_users', True) self.isSignedIn = False self.isOffline = False self.isExpired = False @@ -48,6 +51,7 @@ def __init__(self): self.adminHasPlexPass = False self.lastHomeUserUpdate = None + self.revalidatePlexPass = False self.homeUsers = [] def init(self): @@ -67,10 +71,12 @@ def saveState(self): 'isSecure': self.isSecure, 'adminHasPlexPass': self.adminHasPlexPass, 'thumb': self.thumb, - 'homeUsers': self.homeUsers, 'lastHomeUserUpdate': self.lastHomeUserUpdate } + if self.cacheHomeUsers: + obj["homeUsers"] = self.homeUsers + util.INTERFACE.setRegistry("MyPlexAccount", json.dumps(obj), "myplex") def loadState(self): @@ -103,30 +109,58 @@ def loadState(self): self.adminHasPlexPass = obj.get('adminHasPlexPass') or self.adminHasPlexPass self.thumb = obj.get('thumb') self.lastHomeUserUpdate = obj.get('lastHomeUserUpdate') - self.homeUsers = [HomeUser(data) for data in obj.get('homeUsers', [])] + if self.cacheHomeUsers: + self.homeUsers = [HomeUser(data) for data in obj.get('homeUsers', [])] + self.setAdminByCHU() if self.homeUsers: util.LOG("cached home users: {0} (last update: {1})".format(self.homeUsers, self.lastHomeUserUpdate)) + util.APP.trigger("loaded:cached_user", account=None) + + def setAdminByCHU(self): + for user in self.homeUsers: + if user.id == self.ID: + self.isAdmin = user.isAdmin def verifyAccount(self): if self.authToken: request = myplexrequest.MyPlexRequest("/users/account") context = request.createRequestContext("account", callback.Callable(self.onAccountResponse), - timeout=util.LONG_TIMEOUT) + timeout=util.PLEXTV_TIMEOUT) util.APP.startRequest(request, context) else: util.APP.clearInitializer("myplex") def logState(self): - util.LOG("Authenticated as {0}:{1}".format(self.ID, repr(self.title))) - util.LOG("SignedIn: {0}".format(self.isSignedIn)) - util.LOG("Offline: {0}".format(self.isOffline)) - util.LOG("Authenticated: {0}".format(self.isAuthenticated)) - util.LOG("PlexPass: {0}".format(self.isPlexPass)) - util.LOG("Managed: {0}".format(self.isManaged)) - util.LOG("Protected: {0}".format(self.isProtected)) - util.LOG("Admin: {0}".format(self.isAdmin)) - util.LOG("AdminPlexPass: {0}".format(self.adminHasPlexPass)) + util.LOG("Authenticated as {0}:{1}", self.ID, repr(self.title)) + util.LOG("SignedIn: {0}", self.isSignedIn) + util.LOG("Offline: {0}", self.isOffline) + util.LOG("Authenticated: {0}", self.isAuthenticated) + util.LOG("PlexPass: {0}", self.isPlexPass) + util.LOG("Managed: {0}", self.isManaged) + util.LOG("Protected: {0}", self.isProtected) + util.LOG("Admin: {0}", self.isAdmin) + util.LOG("AdminPlexPass: {0}", self.adminHasPlexPass) + + def getHomeSubscription(self): + """ + This gets the state of the plex home subscription, which is easier to determine than using a combination of + isAdmin and adminHasPlexPass, especially when caching home users. + """ + try: + req = myplexrequest.MyPlexRequest("/api/v2/home") + xml = req.getToStringWithTimeout(timeout=util.PLEXTV_TIMEOUT) + data = ElementTree.fromstring(xml) + return data.attrib.get('subscription') == '1' + except: + util.LOG("Couldn't get Plex Home info") + return + return False + + def refreshSubscription(self): + ret = self.getHomeSubscription() + if isinstance(ret, bool): + self.isPlexPass = ret def onAccountResponse(self, request, response, context): oldId = self.ID @@ -141,9 +175,11 @@ def onAccountResponse(self, request, response, context): self.title = data.attrib.get('title') self.username = data.attrib.get('username') self.email = data.attrib.get('email') - self.thumb = data.attrib.get('thumb') + self.thumb = data.attrib.get('thumb').split("?")[0] self.authToken = data.attrib.get('authenticationToken') - self.isPlexPass = (data.find('subscription') is not None and data.find('subscription').attrib.get('active') == '1') + self.isPlexPass = self.isPlexPass or \ + (data.find('subscription') is not None and + data.find('subscription').attrib.get('active') == '1') self.isManaged = data.attrib.get('restricted') == '1' self.isSecure = data.attrib.get('secure') == '1' self.hasQueue = bool(data.attrib.get('queueEmail')) @@ -159,12 +195,23 @@ def onAccountResponse(self, request, response, context): # Cache home users forever epoch = time.time() - if self.lastHomeUserUpdate: + # never automatically update home users if we have some. + # if we've never seen any, check once a week + if (self.lastHomeUserUpdate and self.homeUsers) or \ + (self.lastHomeUserUpdate and not self.homeUsers and epoch - self.lastHomeUserUpdate < 604800): util.DEBUG_LOG( "Skipping home user update (updated {0} seconds ago)".format(epoch - self.lastHomeUserUpdate)) else: self.updateHomeUsers(use_async=bool(self.homeUsers)) + if bool(self.homeUsers): + self.setAdminByCHU() + + # revalidate plex home subscription state after switching home user + if self.revalidatePlexPass and self.homeUsers: + self.refreshSubscription() + self.revalidatePlexPass = False + if self.isAdmin and self.isPlexPass: self.adminHasPlexPass = True @@ -221,8 +268,8 @@ def signOut(self, expired=False): # Booleans self.isSignedIn = False - self.isPlexPass = False - self.adminHasPlexPass = False + #self.isPlexPass = False + #self.adminHasPlexPass = False self.isManaged = False self.isSecure = False self.isExpired = expired @@ -250,7 +297,7 @@ def validateToken(self, token, switch_user=False, force_resource_refresh=False): request = myplexrequest.MyPlexRequest("/users/sign_in.xml") context = request.createRequestContext("sign_in", callback.Callable(self.onAccountResponse), - timeout=util.LONG_TIMEOUT) + timeout=util.PLEXTV_TIMEOUT) if self.isOffline: context.timeout = self.isOffline and asyncadapter.AsyncTimeout(1).setConnectTimeout(1) util.APP.startRequest(request, context, {}) @@ -260,7 +307,7 @@ def refreshAccount(self): return self.validateToken(self.authToken, False) - def updateHomeUsers(self, use_async=False): + def updateHomeUsers(self, use_async=False, refreshSubscription=False): # Ignore request and clear any home users we are not signed in if not self.isSignedIn: self.homeUsers = [] @@ -273,13 +320,18 @@ def updateHomeUsers(self, use_async=False): req = myplexrequest.MyPlexRequest("/api/home/users") if use_async: context = req.createRequestContext("home_users", callback.Callable(self.onHomeUsersUpdateResponse), - timeout=util.LONG_TIMEOUT) + timeout=util.PLEXTV_TIMEOUT) if self.isOffline: context.timeout = self.isOffline and asyncadapter.AsyncTimeout(1).setConnectTimeout(1) util.APP.startRequest(req, context) else: self.onHomeUsersUpdateResponse(req, None, None) + if refreshSubscription: + self.refreshSubscription() + self.logState() + self.saveState() + def onHomeUsersUpdateResponse(self, request, response, context): """ this can either be called with a given request, which will lead to a synchronous request, or as a @@ -288,7 +340,7 @@ def onHomeUsersUpdateResponse(self, request, response, context): if response: data = response.getBodyXml() else: - xml = request.getToStringWithTimeout(seconds=util.LONG_TIMEOUT) + xml = request.getToStringWithTimeout(timeout=util.PLEXTV_TIMEOUT) data = ElementTree.fromstring(xml) oldHU = self.homeUsers[:] @@ -310,7 +362,7 @@ def onHomeUsersUpdateResponse(self, request, response, context): break if oldHU != self.homeUsers: - util.LOG("home users: {0}".format(self.homeUsers)) + util.LOG("home users: {0}", self.homeUsers) self.lastHomeUserUpdate = time.time() self.saveState() @@ -331,10 +383,10 @@ def switchHomeUser(self, userId, pin=''): self.validateToken(self.authToken, True) return True else: - # build path and post to myplex to swith the user + # build path and post to myplex to switch the user path = '/api/home/users/{0}/switch'.format(userId) req = myplexrequest.MyPlexRequest(path) - xml = req.postToStringWithTimeout({'pin': pin}, seconds=util.LONG_TIMEOUT) + xml = req.postToStringWithTimeout({'pin': pin}, timeout=util.PLEXTV_TIMEOUT) try: data = ElementTree.fromstring(xml) except: @@ -344,6 +396,7 @@ def switchHomeUser(self, userId, pin=''): self.isAuthenticated = True # validate the token (trigger change:user) on user change or channel startup if userId != self.ID or not locks.LOCKS.isLocked("idleLock"): + self.revalidatePlexPass = True self.validateToken(data.attrib.get('authenticationToken'), True, force_resource_refresh=plexapp.SERVERMANAGER.reachabilityNeverTested) return True diff --git a/script.plexmod/lib/_included_packages/plexnet/myplexmanager.py b/script.plexmod/lib/_included_packages/plexnet/myplexmanager.py index 72c2ebb9ce..d96aa50a04 100644 --- a/script.plexmod/lib/_included_packages/plexnet/myplexmanager.py +++ b/script.plexmod/lib/_included_packages/plexnet/myplexmanager.py @@ -11,6 +11,11 @@ class MyPlexManager(object): + gotResources = False + + def __init__(self): + self.gotResources = False + def publish(self): util.LOG('MyPlexManager().publish() - NOT IMPLEMENTED') return # TODO: ----------------------------------------------------------------------------------------------------------------------------- IMPLEMENT? @@ -25,13 +30,13 @@ def publish(self): util.APP.startRequest(request, context, "_method=PUT") def refreshResources(self, force=False): - util.LOG('MyPlexManager().refreshResources() - Force: {}'.format(force)) + util.LOG('MyPlexManager().refreshResources() - Force: {}', force) if force: plexapp.SERVERMANAGER.resetLastTest() request = myplexrequest.MyPlexRequest("/pms/resources") context = request.createRequestContext("resources", callback.Callable(self.onResourcesResponse), - timeout=util.LONG_TIMEOUT) + timeout=util.PLEXTV_TIMEOUT) if plexapp.ACCOUNT.isSecure: request.addParam("includeHttps", "1") @@ -66,14 +71,16 @@ def onResourcesResponse(self, request, response, context): ) for conn in resource.connections: - util.DEBUG_LOG(' {0}'.format(conn)) + util.DEBUG_LOG(' {0}', conn) if 'server' in resource.provides: server = plexserver.createPlexServerForResource(resource) - util.DEBUG_LOG(' {0}'.format(server)) + util.DEBUG_LOG(' {0}', server) servers.append(server) + self.gotResources = True plexapp.SERVERMANAGER.updateFromConnectionType(servers, plexconnection.PlexConnection.SOURCE_MYPLEX) + util.APP.trigger("loaded:myplex_servers", servers=servers, source="myplex") MANAGER = MyPlexManager() diff --git a/script.plexmod/lib/_included_packages/plexnet/myplexrequest.py b/script.plexmod/lib/_included_packages/plexnet/myplexrequest.py index 5f560afe91..0cb567675b 100644 --- a/script.plexmod/lib/_included_packages/plexnet/myplexrequest.py +++ b/script.plexmod/lib/_included_packages/plexnet/myplexrequest.py @@ -5,6 +5,7 @@ class MyPlexRequest(plexrequest.PlexServerRequest): + USE_SYSTEM_CERT_BUNDLE = True def __init__(self, path): from . import myplexserver plexrequest.PlexServerRequest.__init__(self, myplexserver.MyPlexServer(), path) diff --git a/script.plexmod/lib/_included_packages/plexnet/nowplayingmanager.py b/script.plexmod/lib/_included_packages/plexnet/nowplayingmanager.py index 454516be7f..95f9ebdb8c 100644 --- a/script.plexmod/lib/_included_packages/plexnet/nowplayingmanager.py +++ b/script.plexmod/lib/_included_packages/plexnet/nowplayingmanager.py @@ -25,8 +25,7 @@ def __init__(self, timelineType, *args, **kwargs): util.AttributeDict.__init__(self, *args, **kwargs) self.type = timelineType self.state = "stopped" - self.item = None - self.choice = None + self.itemData = None self.playQueue = None self.controllable = util.AttributeDict() @@ -61,51 +60,6 @@ def updateControllableStr(self): prependComma = True self.controllableStr += name - def toXmlAttributes(self, elem): - self.updateControllableStr() - elem.attrib["type"] = self.type - elem.attrib["start"] = self.state - elem.attrib["controllable"] = self.controllableStr - - if self.item: - if self.item.duration: - elem.attrib['duration'] = self.item.duration - if self.item.ratingKey: - elem.attrib['ratingKey'] = self.item.ratingKey - if self.item.key: - elem.attrib['key'] = self.item.key - if self.item.container.address: - elem.attrib['containerKey'] = self.item.container.address - - # Send the audio, video and subtitle choice if it's available - if self.choice: - for stream in ("audioStream", "videoStream", "subtitleStream"): - if self.choice.get(stream) and self.choice[stream].id: - elem.attrib[stream + "ID"] = self.choice[stream].id - - server = self.item.getServer() - if server: - elem.attrib["machineIdentifier"] = server.uuid - - if server.activeConnection: - parts = six.moves.urllib.parse.uslparse(server.activeConnection.address) - elem.attrib["protocol"] = parts.scheme - elem.attrib["address"] = parts.netloc.split(':', 1)[0] - if ':' in parts.netloc: - elem.attrib["port"] = parts.netloc.split(':', 1)[-1] - elif parts.scheme == 'https': - elem.attrib["port"] = '443' - else: - elem.attrib["port"] = '80' - - if self.playQueue: - elem.attrib["playQueueID"] = str(self.playQueue.id) - elem.attrib["playQueueItemID"] = str(self.playQueue.selectedId) - elem.attrib["playQueueVersion"] = str(self.playQueue.version) - - for key, val in self.attrs.items(): - elem.attrib[key] = val - class NowPlayingManager(object): def __init__(self): @@ -131,43 +85,57 @@ def __init__(self): for timelineType in self.TIMELINE_TYPES: self.timelines[timelineType] = TimelineData(timelineType) - def updatePlaybackState(self, timelineType, playerObject, state, t, playQueue=None, duration=0, force=False): + def updatePlaybackState(self, timelineType, itemData, state, t, playQueue=None, duration=0, force=False, + force_time=False): timeline = self.timelines[timelineType] - timeline.state = state - timeline.item = playerObject.item - timeline.choice = playerObject.choice + timeline.itemData = itemData timeline.playQueue = playQueue - timeline.attrs["time"] = str(t) + old_time = timeline.attrs.get("time") + old_state = timeline.state + time_updated = False + if state != "stopped" or force_time: + timeline.attrs["time"] = str(t) + time_updated = True + elif old_time: + if old_state != "stopped": + # use old timeline state's time for stopped states + util.DEBUG_LOG("Using previous timeline state as we're stopped now: {}", old_time) + else: + util.DEBUG_LOG("Possibly using bad time for timeline state as we're stopped now but can't find a " + "non-stopped time: {}", old_time) + + # reuse old timestamp + t = int(timeline.attrs["time"]) + else: + util.DEBUG_LOG("Possibly using bad time for timeline state as we're stopped now but never seen a good time") + timeline.attrs["time"] = str(t) + time_updated = True + timeline.state = state timeline.duration = duration - # self.sendTimelineToAll() - self.sendTimelineToServer(timelineType, timeline, t, force=force) + return time_updated def sendTimelineToServer(self, timelineType, timeline, t, force=False): - if not hasattr(timeline.item, 'getServer') or not timeline.item.getServer(): + server = util.APP.serverManager.selectedServer + if not server: return serverTimeline = self.getServerTimeline(timelineType) # Only send timeline if it's the first, item changes, playstate changes or timer pops - itemsEqual = timeline.item and serverTimeline.item and timeline.item.ratingKey == serverTimeline.item.ratingKey + itemsEqual = timeline.itemData and serverTimeline.itemData \ + and timeline.itemData.ratingKey == serverTimeline.itemData.ratingKey if itemsEqual and timeline.state == serverTimeline.state and not serverTimeline.isExpired() and not force: return serverTimeline.reset() - serverTimeline.item = timeline.item + serverTimeline.itemData = timeline.itemData serverTimeline.state = timeline.state - # Ignore sending timelines for multi part media with no duration - obj = timeline.choice - if obj and obj.part and obj.part.duration.asInt() == 0 and obj.media.parts and len(obj.media.parts) > 1: - util.WARN_LOG("Timeline not supported: the current part doesn't have a valid duration") - return - # It's possible with timers and in player seeking for the time to be greater than the # duration, which causes a 400, so in that case we'll set the time to the duration. - duration = timeline.item.duration.asInt() or timeline.duration + duration = timeline.itemData.duration or timeline.duration if t > duration: t = duration @@ -175,11 +143,11 @@ def sendTimelineToServer(self, timelineType, timeline, t, force=False): params["time"] = t params["duration"] = duration params["state"] = timeline.state - params["guid"] = timeline.item.guid - params["ratingKey"] = timeline.item.ratingKey - params["url"] = timeline.item.url - params["key"] = timeline.item.key - params["containerKey"] = timeline.item.container.address + params["guid"] = timeline.itemData.guid + params["ratingKey"] = timeline.itemData.ratingKey + params["url"] = timeline.itemData.url + params["key"] = timeline.itemData.key + params["containerKey"] = timeline.itemData.containerKey if timeline.playQueue: params["playQueueItemID"] = timeline.playQueue.selectedId @@ -188,7 +156,7 @@ def sendTimelineToServer(self, timelineType, timeline, t, force=False): if params[paramKey]: path = http.addUrlParam(path, paramKey + "=" + six.moves.urllib.parse.quote(str(params[paramKey]))) - request = plexrequest.PlexRequest(timeline.item.getServer(), path) + request = plexrequest.PlexRequest(server, path) context = request.createRequestContext("timelineUpdate", callback.Callable(self.onTimelineResponse)) context.playQueue = timeline.playQueue diff --git a/script.plexmod/lib/_included_packages/plexnet/photo.py b/script.plexmod/lib/_included_packages/plexnet/photo.py index d3a66ca681..b611a0238d 100644 --- a/script.plexmod/lib/_included_packages/plexnet/photo.py +++ b/script.plexmod/lib/_included_packages/plexnet/photo.py @@ -46,7 +46,7 @@ def isPhotoOrDirectoryItem(self): class PhotoDirectory(media.MediaItem): TYPE = 'photodirectory' - def all(self): + def all(self, *args, **kwargs): path = self.key return plexobjects.listItems(self.server, path) diff --git a/script.plexmod/lib/_included_packages/plexnet/playqueue.py b/script.plexmod/lib/_included_packages/plexnet/playqueue.py index 63a9ba2284..5af80c5bc8 100644 --- a/script.plexmod/lib/_included_packages/plexnet/playqueue.py +++ b/script.plexmod/lib/_included_packages/plexnet/playqueue.py @@ -52,7 +52,8 @@ def allowSkipMessage(self): return "You can skip {0} songs an hour per mix.".format(self.skipsPerHour) def log(self, prefix): - util.DEBUG_LOG("AudioUsage {0}: total skips={1}, allowed skips={2}".format(prefix, len(self.skips), self.skipsPerHour)) + util.DEBUG_LOG("AudioUsage {0}: total skips={1}, allowed skips={2}", prefix, lambda: len(self.skips), + self.skipsPerHour) class UsageFactory(object): @@ -68,10 +69,18 @@ def createUsage(cls, playQueue): if obj.type: if obj.type == "audio": return obj.createAudioUsage() + elif obj.type == "photo": + return obj.createPhotoUsage() util.DEBUG_LOG("Don't know how to usage for " + str(obj.type)) return None + def createPhotoUsage(self): + if not self.usage or self.usage.playQueueId != self.playQueue.id: + self.usage = self.playQueue.usage + + return self.usage + def createAudioUsage(self): skips = self.playQueue.container.stationSkipsPerHour.asInt(-1) if skips == -1: @@ -230,7 +239,7 @@ def waitForInitialization(self): time.sleep(0.1) if self.initialized: - util.DEBUG_LOG('PlayQueue initialized in {0:.2f} secs: {1}'.format(time.time() - start, self)) + util.DEBUG_LOG('PlayQueue initialized in {0:.2f} secs: {1}', time.time() - start, self) else: util.DEBUG_LOG('PlayQueue failed to initialize') @@ -367,7 +376,7 @@ def onResponse(self, request, response, context): util.DEBUG_LOG('playQueue: Received response') self.responded = True if response.parseResponse(): - util.DEBUG_LOG('playQueue: {0} items'.format(len(response.items))) + util.DEBUG_LOG('playQueue: {0} items', lambda: len(response.items)) self.container = response.container # Handle an empty PQ if we have specified an pqEmptyCallable if self.options and self.options.pqEmptyCallable: @@ -384,6 +393,8 @@ def onResponse(self, request, response, context): self.version = response.container.playQueueVersion.asInt() itemsChanged = False + justAdded = False + if len(response.items) == len(self._items): for i in range(len(self._items)): if self._items[i] != response.items[i]: @@ -392,6 +403,9 @@ def onResponse(self, request, response, context): else: itemsChanged = True + if set(self._items).issubset(response.items): + justAdded = set(response.items) - set(self._items) + if itemsChanged: self._items = response.items @@ -464,7 +478,7 @@ def onResponse(self, request, response, context): self.trigger("change") if itemsChanged: - self.trigger("items.changed") + self.trigger("items.changed", just_added=justAdded) def isWindowed(self): return (not self.isLocal() and (self.totalSize > self.windowSize or self.forcedWindow)) diff --git a/script.plexmod/lib/_included_packages/plexnet/plexapp.py b/script.plexmod/lib/_included_packages/plexnet/plexapp.py index 931799be4d..8a6b23e410 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexapp.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexapp.py @@ -1,10 +1,7 @@ from __future__ import print_function, absolute_import -import threading import platform import uuid -import sys -from . import callback from . import signalsmixin from . import simpleobjects from . import util @@ -28,6 +25,8 @@ def init(): SERVERMANAGER = plexservermanager.MANAGER from . import myplexmanager util.MANAGER = MANAGER = myplexmanager.MANAGER + util.ACCOUNT = ACCOUNT + util.SERVERMANAGER = SERVERMANAGER util.DEBUG_LOG("Verifying account...") ACCOUNT.verifyAccount() @@ -44,6 +43,10 @@ def __init__(self): def addTimer(self, timer): self.timers.append(timer) + @property + def serverManager(self): + return SERVERMANAGER + def startRequest(self, request, context, body=None, contentType=None): context.request = request @@ -104,7 +107,7 @@ def preShutdown(self): from . import http http.HttpRequest._cancel = True if self.pendingRequests: - util.DEBUG_LOG('Closing down {0} App() requests...'.format(len(self.pendingRequests))) + util.DEBUG_LOG('Closing down {0} App() requests...', lambda: len(self.pendingRequests)) for k in list(self.pendingRequests.keys()): p = self.pendingRequests.get(k) if p: @@ -120,7 +123,7 @@ def preShutdown(self): def shutdown(self): if self.timers: - util.DEBUG_LOG('Waiting for {0} App() timers: Started'.format(len(self.timers))) + util.DEBUG_LOG('Waiting for {0} App() timers: Started', lambda: len(self.timers)) self.cancelAllTimers() @@ -286,6 +289,12 @@ def getPreference(self, key, default=None): else: return util.INTERFACE.getPreference(key, default) + def getPlaybackFeatures(self): + return util.INTERFACE.getPlaybackFeatures() + + def getAdditionalCodecs(self): + return util.INTERFACE.getAdditionalCodecs() + def getMaxResolution(self, quality_type, allow4k=False): qualityIndex = self.getQualityIndex(quality_type) diff --git a/script.plexmod/lib/_included_packages/plexnet/plexconnection.py b/script.plexmod/lib/_included_packages/plexnet/plexconnection.py index c9e9c41667..7fbcc437c8 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexconnection.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexconnection.py @@ -6,6 +6,11 @@ from . import callback from . import util +try: + from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network +except ImportError: + from _ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network + HAS_ICMPLIB = False try: from icmplib import ping, resolve, ICMPLibError @@ -14,16 +19,16 @@ else: HAS_ICMPLIB = True from urllib.parse import urlparse - from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network - # local networks - LOCAL_NETWORKS = { - 4: [IPv4Network('10.0.0.0/8'), IPv4Network('192.168.0.0/16'), IPv4Network('172.16.0.0/12'), - IPv4Network('127.0.0.0/8')], - 6: [IPv6Network('fd00::/8')] - } +# local networks +DOCKER_NETWORK = IPv4Network(u'172.16.0.0/12') +LOCAL_NETWORKS = { + 4: [IPv4Network(u'10.0.0.0/8'), IPv4Network(u'192.168.0.0/16'), DOCKER_NETWORK, + IPv4Network(u'127.0.0.0/8')], + 6: [IPv6Network(u'fd00::/8')] +} - LOCALS_SEEN = {} +LOCALS_SEEN = {} class ConnectionSource(int): @@ -70,6 +75,7 @@ def __init__(self, source, address, isLocal, token, isFallback=False, skipLocalC self.sources = source self.address = address self.isLocal = isLocal + self.localVerified = False self.isSecure = address[:5] == 'https' self.isFallback = isFallback self.token = token @@ -127,16 +133,14 @@ def checkLocal(self): hostname = pUrl.hostname if hostname.endswith("plex.direct"): - util.DEBUG_LOG("Using shortcut for hostname IP detection due to plex.direct host: {}".format(hostname)) - v6 = hostname.count("-") > 3 - base = hostname.split(".", 1)[0] - ips = [v6 and base.replace("-", ":") or base.replace("-", ".")] + util.DEBUG_LOG("Using shortcut for hostname IP detection due to plex.direct host: {}", hostname) + ips = [util.parsePlexDirectHost(hostname)] else: try: ips = resolve(hostname) except (socket.gaierror, ICMPLibError): - util.DEBUG_LOG("Couldn't resolve hostname: {}".format(hostname)) + util.DEBUG_LOG("Couldn't resolve hostname: {}", hostname) return False for ip in ips: @@ -144,9 +148,9 @@ def checkLocal(self): if ip in LOCALS_SEEN: local, network, host = LOCALS_SEEN[ip] if local: - util.DEBUG_LOG("We've already verified {} ({}) as local, skipping".format(hostname, ip)) + util.DEBUG_LOG("We've already verified {} ({}) as local, skipping", hostname, ip) else: - util.DEBUG_LOG("We've already verified {} ({}) as remote, skipping".format(hostname, ip)) + util.DEBUG_LOG("We've already verified {} ({}) as remote, skipping", hostname, ip) continue local_and_alive = True @@ -159,12 +163,13 @@ def checkLocal(self): try: host = ping(ip, count=1, interval=1, timeout=util.LAN_REACHABILITY_TIMEOUT, privileged=False) except: - util.DEBUG_LOG("IP {} didn't answer in time ({}s)".format(ip, util.LAN_REACHABILITY_TIMEOUT)) + util.DEBUG_LOG("IP {} didn't answer in time ({}s)", ip, util.LAN_REACHABILITY_TIMEOUT) LOCALS_SEEN[ip] = (False, network, None) continue if local_and_alive or host.is_alive: self.isLocal = True + self.localVerified = True if not local_and_alive: util.LOG("Found IP {0} in local network ({1}) when checking {2}. Ping: {3}ms (max: {4}s)" .format(ip, network, self.address, host.max_rtt, util.LAN_REACHABILITY_TIMEOUT)) @@ -215,7 +220,7 @@ def testReachability(self, server, allowFallback=False): ) ) else: - util.LOG("Insecure connections not allowed. Ignore insecure connection test for {0}".format(server)) + util.LOG("Insecure connections not allowed. Ignore insecure connection test for {0}", server) self.state = self.STATE_INSECURE callable = callback.Callable(server.onReachabilityResult, [self], random.randint(0, 256)) callable.deferCall() @@ -236,7 +241,7 @@ def testReachability(self, server, allowFallback=False): context.server = server util.addPlexHeaders(self.request, server.getToken()) self.hasPendingRequest = util.APP.startRequest(self.request, context) - util.DEBUG_LOG("Testing insecure connection for: {0}".format(server)) + util.DEBUG_LOG("Testing insecure connection for: {0}", server) return True return False diff --git a/script.plexmod/lib/_included_packages/plexnet/plexlibrary.py b/script.plexmod/lib/_included_packages/plexnet/plexlibrary.py index c9d0c4fc4b..9dce2276b0 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexlibrary.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexlibrary.py @@ -10,6 +10,8 @@ from . import exceptions from . import util from . import signalsmixin +from lib.path_mapping import pmm, norm_sep +from lib.exceptions import NoDataException from six.moves import map @@ -34,7 +36,7 @@ def section(self, title=None): return item raise exceptions.NotFound('Invalid library section: %s' % title) - def all(self): + def all(self, *args, **kwargs): return plexobjects.listItems(self.server, '/library/all') def onDeck(self): @@ -90,10 +92,21 @@ class LibrarySection(plexobjects.PlexObject): isLibraryPQ = True + def __init__(self, data, initpath=None, server=None, container=None): + self.locations = [] + self._isMapped = None + super(LibrarySection, self).__init__(data, initpath=initpath, server=server, container=container) + def __repr__(self): title = self.title.replace(' ', '.')[0:20] return '<%s:%s>' % (self.__class__.__name__, title.encode('utf8')) + def _setData(self, data): + super(LibrarySection, self)._setData(data) + for loc in plexobjects.PlexItemList(data, media.Location, media.Location.TYPE, server=self.server): + sep = norm_sep(loc.path) + self.locations.append(loc.path if loc.path.endswith(sep) else loc.path + sep) + @staticmethod def fromFilter(filter_): cls = SECTION_IDS.get(filter_.getLibrarySectionType()) @@ -127,6 +140,30 @@ def isDirectory(self): def isLibraryItem(self): return True + def getMappedPath(self, loc=None): + if not self.locations: + return None, None + + return pmm.getMappedPathFor(loc or self.locations[0], self.server) + + def deleteMapping(self, target): + pmm.deletePathMapping(target, server=self.getServer()) + self._isMapped = None + + @property + def isMapped(self): + if self._isMapped is not None: + return self._isMapped + elif self._isMapped is False: + return False + + for loc in self.locations: + if all(self.getMappedPath(loc)): + self._isMapped = True + return True + self._isMapped = False + return self._isMapped + def getAbsolutePath(self, key): if key == 'key': return '/library/sections/{0}/all'.format(self.key) @@ -215,10 +252,10 @@ def onDeck(self): return plexobjects.listItems(self.server, '/library/sections/%s/onDeck' % self.key) def analyze(self): - self.server.query('/library/sections/%s/analyze' % self.key) + self.server.query('/library/sections/%s/analyze' % self.key, method=self.server.session.put) def emptyTrash(self): - self.server.query('/library/sections/%s/emptyTrash' % self.key) + self.server.query('/library/sections/%s/emptyTrash' % self.key, method=self.server.session.put) def refresh(self): self.server.query('/library/sections/%s/refresh' % self.key) @@ -317,7 +354,7 @@ def _cleanSearchFilter(self, category, value, libtype=None): list(map(result.add, matches)) continue # nothing matched; use raw item value - util.LOG('Filter value not listed, using raw item value: {0}'.format(item)) + util.LOG('Filter value not listed, using raw item value: {0}', item) result.add(item) return ','.join(result) @@ -518,15 +555,19 @@ def reset(self): self.set('offset', 0) self.set('size', len(self.items)) totalSize = self.items[0].container.totalSize.asInt() - if totalSize: # Hubs from a list of hubs don't have this, so it it's not here this is intital and we can leave as is + if totalSize: + # Hubs from a list of hubs don't have this, so if it's not here this is intital, + # and we can leave as is self.set( 'more', (self.items[0].container.offset.asInt() + self.items[0].container.size.asInt() < totalSize) and '1' or '' ) - def getCleanHubIdentifier(self): + def getCleanHubIdentifier(self, is_home=False): if not self._identifier: self._identifier = re.sub(r'\.\d+$', '', re.sub(r'\.\d+$', '', self.hubIdentifier)) + if is_home and self._identifier == 'movie.recentlyreleased': + self._identifier = 'home.VIRTUAL.movies.recentlyreleased' return self._identifier @@ -535,9 +576,13 @@ class Hub(BaseHub): def init(self, data): self.items = [] + self._totalSize = None container = plexobjects.PlexContainer(data, self.key, self.server, self.key or '') + if container.totalSize: + self._totalSize = container.totalSize.asInt() + if self.type == 'genre': self.items = [media.Genre(elem, initpath='/hubs', server=self.server, container=container) for elem in data] elif self.type == 'director': @@ -549,7 +594,7 @@ def init(self, data): try: self.items.append(plexobjects.buildItem(self.server, elem, '/hubs', container=container, tag_fallback=True)) except exceptions.UnknownType: - util.DEBUG_LOG('Unkown hub item type({1}): {0}'.format(elem, elem.attrib.get('type'))) + util.DEBUG_LOG('Unkown hub item type({1}): {0}', elem, elem.attrib.get('type')) def __repr__(self): return '<{0}:{1}>'.format(self.__class__.__name__, self.hubIdentifier) @@ -566,10 +611,32 @@ def reload(self, **kwargs): return self.initpath = self.key - self._setData(data) + try: + self._setData(data) + except: + raise NoDataException self.init(data) - def extend(self, start=None, size=None): + @property + def totalSize(self): + """ + If we don't have seen the totalSize of the hub before, to a query on the hub's path with a limit of 0 items, + and cache the value for future access. + """ + if self._totalSize is None: + try: + data = self.server.query(self.key, limit=0) + except Exception as e: + return + ts = data.attrib.get('totalSize', None) + self._totalSize = int(ts) if ts is not None else None + return self._totalSize + + @totalSize.setter + def totalSize(self, value): + self._totalSize = value.asInt() + + def extend(self, start=None, size=None, **kwargs): path = self.key args = {} @@ -578,6 +645,9 @@ def extend(self, start=None, size=None): args['X-Plex-Container-Start'] = start args['X-Plex-Container-Size'] = size + if kwargs: + args.update(kwargs) + if args: path += util.joinArgs(args) if '?' not in path else '&' + util.joinArgs(args).lstrip('?') @@ -601,7 +671,7 @@ def init(self, data): try: self.items = self.extend(0, 10) except exceptions.BadRequest: - util.DEBUG_LOG('AudioPlaylistHub: Bad request: {0}'.format(self)) + util.DEBUG_LOG('AudioPlaylistHub: Bad request: {0}', self) self.items = [] def extend(self, start=None, size=None): diff --git a/script.plexmod/lib/_included_packages/plexnet/plexmedia.py b/script.plexmod/lib/_included_packages/plexnet/plexmedia.py index 76434d78a6..882dd2044c 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexmedia.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexmedia.py @@ -10,6 +10,8 @@ class PlexMedia(plexobjects.PlexObject): + __slots__ = ("_data", "container_", "container", "indirectHeaders", "parts") + def __init__(self, data, initpath=None, server=None, container=None): self._data = data.attrib plexobjects.PlexObject.__init__(self, data, initpath, server) diff --git a/script.plexmod/lib/_included_packages/plexnet/plexobjects.py b/script.plexmod/lib/_included_packages/plexnet/plexobjects.py index cba919e90e..1b34878cee 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexobjects.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexobjects.py @@ -34,6 +34,8 @@ def wrap(func): class PlexValue(six.text_type): + __slots__ = ("parent", "NA") + def __new__(cls, value, parent=None): self = super(PlexValue, cls).__new__(cls, value) self.parent = parent @@ -153,6 +155,8 @@ def isSettings(self): class PlexObject(Checks): + __slots__ = ("initpath", "key", "server", "container", "mediaChoice", "titleSort", "deleted", "_reloaded", "data") + def __init__(self, data, initpath=None, server=None, container=None): self.initpath = initpath self.key = None @@ -189,7 +193,7 @@ def __getattr__(self, attr): try: setattr(self, attr, a) except AttributeError: - util.LOG('Failed to set attribute: {0} ({1})'.format(attr, self.__class__)) + util.LOG('Failed to set attribute: {0} ({1})', attr, self.__class__) return a @@ -198,7 +202,7 @@ def exists(self, *args, **kwargs): return True def get(self, attr, default=''): - ret = self.__dict__.get(attr) + ret = self.__dict__.get(attr, getattr(self, attr) if attr in self.__slots__ else None) return ret is not None and ret or PlexValue(default, self) def set(self, attr, value): @@ -234,8 +238,6 @@ def reload(self, _soft=False, **kwargs): if _soft and self._reloaded: return self - kwargs["includeMarkers"] = 1 - try: if self.get('ratingKey'): data = self.server.query('/library/metadata/{0}'.format(self.ratingKey), params=kwargs) @@ -254,7 +256,7 @@ def reload(self, _soft=False, **kwargs): try: self._setData(data[0]) except (IndexError, TypeError, AttributeError): - util.DEBUG_LOG('No data on reload: {0}'.format(self)) + util.DEBUG_LOG('No data on reload: {0}', self) return self return self @@ -422,6 +424,8 @@ def serialize(self, full=False): class PlexContainer(PlexObject): + __slots__ = ("address",) + def __init__(self, data, initpath=None, server=None, address=None): PlexObject.__init__(self, data, initpath, server) self.setAddress(address) @@ -433,7 +437,7 @@ def setAddress(self, address): self.address = address # TODO(schuyler): Do we need to make sure that we only hang onto the path here and not a full URL? - if not self.address.startswith("/") and "node.plexapp.com" not in self.address: + if not self.address.startswith("/") and not self.upNext.asBool() and "node.plexapp.com" not in self.address: util.FATAL("Container address is not an expected path: {0}".format(address)) def getAbsolutePath(self, path): @@ -446,6 +450,8 @@ def getAbsolutePath(self, path): class PlexServerContainer(PlexContainer): + __slots__ = ("resources",) + def __init__(self, data, initpath=None, server=None, address=None): PlexContainer.__init__(self, data, initpath, server, address) from . import plexserver @@ -463,6 +469,8 @@ def __len__(self): class PlexItemList(object): + __slots__ = ("_data", "_itemClass", "_itemTag", "_server", "_container", "_items") + def __init__(self, data, item_cls, tag, server=None, container=None): self._data = data self._itemClass = item_cls @@ -502,6 +510,8 @@ def append(self, item): class PlexMediaItemList(PlexItemList): + __slots__ = ("_initpath", "_media", "_items") + def __init__(self, data, item_cls, tag, initpath=None, server=None, media=None): PlexItemList.__init__(self, data, item_cls, tag, server) self._initpath = initpath @@ -538,6 +548,8 @@ def buildItem(server, elem, initpath, bytag=False, container=None, tag_fallback= class ItemContainer(list): + __slots__ = ("container", "totalSize") + def __getattr__(self, attr): return getattr(self.container, attr) diff --git a/script.plexmod/lib/_included_packages/plexnet/plexpart.py b/script.plexmod/lib/_included_packages/plexnet/plexpart.py index 7fd0c138cd..8ded244f3d 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexpart.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexpart.py @@ -1,9 +1,13 @@ from __future__ import absolute_import +from kodi_six import xbmcvfs from . import plexobjects from . import plexstream from . import plexrequest from . import util +from lib.util import addonSettings +from lib.path_mapping import pmm, norm_sep + class PlexPart(plexobjects.PlexObject): def reload(self): @@ -101,7 +105,7 @@ def getSelectedStreamOfType(self, streamType): return default - def setSelectedStream(self, streamType, streamId, _async): + def setSelectedStream(self, streamType, streamId, _async, from_session=False, video=None): if streamType == plexstream.PlexStream.TYPE_AUDIO: typeString = "audio" elif streamType == plexstream.PlexStream.TYPE_SUBTITLE: @@ -115,12 +119,14 @@ def setSelectedStream(self, streamType, streamId, _async): if self.getServer().supportsFeature("allPartsStreamSelection"): path = path + "&allParts=1" +# + if from_session: + path = path + "&X-Plex-Session-Id=%s" % video.settings.getGlobal("clientIdentifier") request = plexrequest.PlexRequest(self.getServer(), path, "PUT") if _async: context = request.createRequestContext("ignored") - from . import plexapp util.APP.startRequest(request, context, "") else: request.postToStringWithTimeout() @@ -157,6 +163,40 @@ def getIndexPath(self, indexKey, interval=None): def hasStreams(self): return bool(self.streams) + def getPathMappedUrl(self, return_only_folder=False): + verify = addonSettings.verifyMappedFiles + + map_path, pms_path = pmm.getMappedPathFor(self.file, self.getServer()) + if map_path and pms_path: + if return_only_folder: + return map_path + + sep = norm_sep(map_path) + + # replace match and normalize path separator to separator style of map_path + url = self.file.replace(pms_path, map_path, 1).replace(sep == "/" and "\\" or "/", sep) + + if (verify and xbmcvfs.exists(url)) or not verify: + util.DEBUG_LOG("File {} found in path map, mapping to {}", self.file, pms_path) + return url + util.LOG("Mapped file {} doesn't exist", url) + return "" + + @property + def isPathMapped(self): + return bool(self.getPathMappedUrl()) + + def getPathMappedProto(self): + url = self.getPathMappedUrl() + if url: + prot = url.split("://")[0] + if prot == url: + ret = "mnt://" + else: + ret = "{}://".format(prot) + return ret + return "" + def __str__(self): return "PlexPart {0} {1}".format(self.id("NaN"), self.key) diff --git a/script.plexmod/lib/_included_packages/plexnet/plexplayer.py b/script.plexmod/lib/_included_packages/plexnet/plexplayer.py index 4c3b0c1c1b..0fbe5c6dd1 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexplayer.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexplayer.py @@ -6,14 +6,34 @@ from . import plexrequest from . import mediadecisionengine from . import serverdecision -from lib.util import CACHE_SIZE, advancedSettings, KODI_VERSION_MAJOR +from lib.util import KODI_VERSION_MAJOR +from lib.cache import CACHE_SIZE from six.moves import range DecisionFailure = serverdecision.DecisionFailure -class PlexPlayer(object): +class BasePlayer(object): + item = None + + def setupObj(self, obj, part, server, force_request_to_server=False): + # check for path mapping + url = part.getPathMappedUrl() + + if not url: + url = server.buildUrl(part.getAbsolutePath("key")) + # Check if we should include our token or not for this request + obj.isRequestToServer = force_request_to_server or server.isRequestToServer(url) + obj.streamUrls = [server.buildUrl(part.getAbsolutePath("key"), obj.isRequestToServer)] + obj.isMapped = False + else: + obj.isRequestToServer = False + obj.streamUrls = [url] + obj.isMapped = True + + +class PlexPlayer(BasePlayer): DECISION_ENDPOINT = "/video/:/transcode/universal/decision" def __init__(self, item, seekValue=0, forceUpdate=False): @@ -29,7 +49,7 @@ def init(self, item, forceUpdate=False): self.media = self.choice.media def terminate(self, code, reason): - util.LOG('TERMINATE PLAYER: ({0}, {1})'.format(code, reason)) + util.LOG('TERMINATE PLAYER: ({0}, {1})', code, reason) # TODO: Handle this? ---------------------------------------------------------------------------------------------------------- TODO @property @@ -45,12 +65,13 @@ def rebuild(self, item, decision=None): # item.settings = self.item.settings oldChoice = self.choice self.init(item, True) - util.LOG("Replacing '{0}' with '{1}' and rebuilding.".format(oldChoice, self.choice)) + util.LOG("Replacing '{0}' with '{1}' and rebuilding.", oldChoice, self.choice) self.build() self.decision = decision def build(self, forceTranscode=False): - if self.item.settings.getPreference("playback_directplay", True): + features = self.item.settings.getPlaybackFeatures() + if "playback_directplay" in features: directPlayPref = self.item.settings.getPreference("playback_directplay_force", False) and 'forced' or 'allow' else: directPlayPref = 'disabled' @@ -60,7 +81,7 @@ def build(self, forceTranscode=False): else: directPlay = directPlayPref == "forced" and True or None - return self._build(directPlay, self.item.settings.getPreference("playback_remux", True)) + return self._build(directPlay, "playback_remux" in features) def _build(self, directPlay=None, directStream=True, currentPartIndex=None): isForced = directPlay is not None @@ -171,7 +192,7 @@ def _build(self, directPlay=None, directStream=True, currentPartIndex=None): self.metadata = obj - util.LOG("Constructed video item for playback: {0}".format(util.cleanObjTokens(dict(obj)))) + util.LOG("Constructed video item for playback: {0}", util.cleanObjTokens(dict(obj))) return self.metadata @@ -218,19 +239,19 @@ def getServerDecision(self): if decisionPath: server = self.metadata.transcodeServer or self.item.getServer() request = plexrequest.PlexRequest(server, decisionPath) - response = request.getWithTimeout(10) + response = request.getWithTimeout(util.DEFAULT_TIMEOUT) if response.isSuccess() and response.container: decision = serverdecision.ServerDecision(self, response, self) if decision.isSuccess(): - util.LOG("MDE: Server was happy with client's original decision. {0}".format(decision)) + util.LOG("MDE: Server was happy with client's original decision. {0}", decision) return self elif decision.isDecision(True): util.WARN_LOG("MDE: Server was unhappy with client's original decision. {0}".format(decision)) return decision.getDecision() else: - util.LOG("MDE: Server was unbiased about the decision. {0}".format(decision)) + util.LOG("MDE: Server was unbiased about the decision. {0}", decision) # Check if the server has provided a new media item to use it. If # there is no item, then we'll continue along as if there was no @@ -271,10 +292,7 @@ def getDecisionPath(self, directPlay=False): "mediaBufferSize={}".format(str(CACHE_SIZE * 1024))) decisionPath = http.addUrlParam(decisionPath, "hasMDE=1") - if not advancedSettings.oldprofile: - decisionPath = http.addUrlParam(decisionPath, 'X-Plex-Client-Profile-Name=Generic') - else: - decisionPath = http.addUrlParam(decisionPath, 'X-Plex-Client-Profile-Name=Chrome') + decisionPath = http.addUrlParam(decisionPath, 'X-Plex-Client-Profile-Name=Generic') return decisionPath @@ -302,11 +320,7 @@ def buildTranscodeHls(self, obj): builder.extras = [] builder.addParam("protocol", "hls") - # TODO: This should be Generic, but will need to re-evaluate the augmentations with that change - if not advancedSettings.oldprofile: - builder.addParam("X-Plex-Client-Profile-Name", "Generic") - else: - builder.addParam("X-Plex-Client-Profile-Name", "Chrome") + builder.addParam("X-Plex-Client-Profile-Name", "Generic") if self.choice.subtitleDecision == self.choice.SUBTITLES_SOFT_ANY: builder.addParam("skipSubtitles", "1") @@ -318,11 +332,7 @@ def buildTranscodeHls(self, obj): # Augment the server's profile for things that depend on the Roku's configuration. if self.item.settings.supportsAudioStream("ac3", 6): builder.extras.append("append-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=hls&audioCodec=ac3)") - if not advancedSettings.oldprofile: - builder.extras.append("add-direct-play-profile(type=videoProfile&container=mkv&videoCodec=*&audioCodec=ac3)") - else: - builder.extras.append( - "add-direct-play-profile(type=videoProfile&container=matroska&videoCodec=*&audioCodec=ac3)") + builder.extras.append("add-direct-play-profile(type=videoProfile&container=mkv&videoCodec=*&audioCodec=ac3)") return builder @@ -336,13 +346,11 @@ def buildTranscodeMkv(self, obj, directStream=True): builder.extras = [] builder.addParam("protocol", "http") builder.addParam("copyts", "1") - if not advancedSettings.oldprofile: - builder.addParam("X-Plex-Client-Profile-Name", "Generic") - else: - builder.addParam("X-Plex-Client-Profile-Name", "Chrome") + builder.addParam("X-Plex-Client-Profile-Name", "Generic") obj.subtitleUrl = None + video_codecs = self.item.settings.getAdditionalCodecs() clampToOrig = self.item.settings.getPreference("audio_clamp_to_orig", True) useKodiAudio = self.item.settings.getPreference("audio_channels_kodi", False) AC3Cond = self.item.settings.getPreference("audio_force_ac3_cond", 'never') @@ -351,7 +359,7 @@ def buildTranscodeMkv(self, obj, directStream=True): forceAC3 = AC3Cond != 'never' ach = None - if AC3Cond in ('2', '5'): + if AC3Cond in ('2', '3', '5', '6'): ach = int(AC3Cond) # fixme: still necessary? @@ -391,7 +399,7 @@ def buildTranscodeMkv(self, obj, directStream=True): "eia_708_embedded,dvb_subtitle" + (",webvtt" if KODI_VERSION_MAJOR > 19 else '') - util.LOG('MDE-prep: enabling codecs: {}'.format(audioCodecs)) + util.LOG('MDE-prep: enabling codecs: {}', audioCodecs) # Allow virtually anything in Kodi playback. @@ -478,7 +486,7 @@ def buildTranscodeMkv(self, obj, directStream=True): # limit OPUS bitrate if hasAudioChoice and self.choice.audioStream.codec != "opus": - util.LOG('MDE-prep: limiting OPUS bitrate to {} kbit'.format(opusBitrate)) + util.LOG('MDE-prep: limiting OPUS bitrate to {} kbit', opusBitrate) builder.extras.append( "add-limitation(scope=videoAudioCodec&scopeName=opus&type=upperBound&name=audio.bitrate&" "value={}&isRequired=false)".format(opusBitrate) @@ -491,7 +499,7 @@ def buildTranscodeMkv(self, obj, directStream=True): "add-limitation(scope=videoAudioCodec&scopeName=ac3&type=upperBound&name=audio.bitrate&value=640)" ) - util.LOG('MDE-prep: limiting audio channels to {}'.format(maxAudioChannels)) + util.LOG('MDE-prep: limiting audio channels to {}', maxAudioChannels) builder.extras.append( "add-limitation(scope=videoAudioCodec&scopeName=*&type=upperBound&" "name=audio.channels&value={})".format(maxAudioChannels) @@ -504,7 +512,7 @@ def buildTranscodeMkv(self, obj, directStream=True): "name=audio.samplingRate&value=22050&isRequired=false)") # HEVC - if self.item.settings.getPreference("allow_hevc", True): + if "allow_hevc" in video_codecs: builder.extras.append( "append-transcode-target-codec(type=videoProfile&context=streaming&container=mkv&" "protocol=http&videoCodec=hevc)") @@ -520,7 +528,7 @@ def buildTranscodeMkv(self, obj, directStream=True): # "add-direct-play-profile(type=videoProfile&videoCodec=vp9&container=*&audioCodec=*)") # AV1 - if self.item.settings.getPreference("allow_av1", False): + if "allow_av1" in video_codecs: builder.extras.append( "append-transcode-target-codec(type=videoProfile&context=streaming&container=mkv&" "protocol=http&videoCodec=av1)") @@ -528,150 +536,7 @@ def buildTranscodeMkv(self, obj, directStream=True): # "add-direct-play-profile(type=videoProfile&videoCodec=av1&container=*&audioCodec=*)") # VC1 - if self.item.settings.getPreference("allow_vc1", True): - builder.extras.append( - "append-transcode-target-codec(type=videoProfile&context=streaming&container=mkv&" - "protocol=http&videoCodec=vc1)") - - return builder - - def buildTranscodeMkvLegacy(self, obj, directStream=True): - util.DEBUG_LOG('buildTranscodeMkvLegacy()') - obj.streamFormat = "mkv" - obj.streamBitrates = [0] - obj.transcodeEndpoint = "/video/:/transcode/universal/start.mkv" - - builder = http.HttpRequest(obj.transcodeServer.buildUrl(obj.transcodeEndpoint, True)) - builder.extras = [] - builder.addParam("protocol", "http") - builder.addParam("copyts", "1") - builder.addParam("X-Plex-Client-Profile-Name", "Generic") - - obj.subtitleUrl = None - - # fixme: still necessary? - if True: # if self.choice.subtitleDecision == self.choice.SUBTITLES_BURN: # Must burn transcoded because we can't set offset - builder.addParam("subtitles", "burn") - captionSize = captions.CAPTIONS.getBurnedSize() - if captionSize is not None: - builder.addParam("subtitleSize", captionSize) - - else: - # TODO(rob): can we safely assume the id will also be 3 (one based index). - # If not, we will have to get tricky and select the subtitle stream after - # video playback starts via roCaptionRenderer: GetSubtitleTracks() and - # ChangeSubtitleTrack() - - obj.subtitleConfig = {'TrackName': "mkv/3"} - - # Allow text conversion of subtitles if we only burn image formats - if self.item.settings.getPreference("burn_subtitles") == "image": - builder.addParam("advancedSubtitles", "text") - - builder.addParam("subtitles", "auto") - - if directStream: - audioCodecs = "eac3,ac3,dca,aac,mp3,mp2,pcm,flac,alac,wmav2,wmapro,wmavoice,opus,vorbis,truehd" - else: - audioCodecs = "mp3,ac3,aac,opus" - - # Allow virtually anything in Kodi playback. - - # DP might not do anything here - # builder.extras.append( - # "add-direct-play-profile(type=videoProfile&videoCodec=" - # "h264,mpeg1video,mpeg2video,mpeg4,msmpeg4v2,msmpeg4v3,vc1,wmv3&container=*&" - # "audioCodec="+audioCodecs+"&protocol=http)") - - builder.extras.append( - "add-transcode-target(type=videoProfile&videoCodec=" - "h264,mpeg1video,mpeg2video,mpeg4,msmpeg4v2,msmpeg4v3,wmv3&container=mkv&" - "audioCodec="+audioCodecs+"&protocol=http&context=streaming)") - - # builder.extras.append( - # "append-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=http&audioCodec=" + - # audioCodecs + ")") - - # if self.item.settings.supportsSurroundSound(): - # if self.choice.audioStream is not None: - # numChannels = self.choice.audioStream.channels.asInt(8) - # else: - # numChannels = 8 - # - # for codec in ("ac3", "eac3", "dca"): - # if self.item.settings.supportsAudioStream(codec, numChannels): - # builder.extras.append("append-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=http&audioCodec=" + codec + ")") - # builder.extras.append("add-direct-play-profile(type=videoProfile&videoCodec=*&container=mkv&audioCodec=" + codec + ")") - # if codec == "dca": - # builder.extras.append( - # "add-limitation(scope=videoAudioCodec&scopeName=dca&type=upperBound&name=audio.channels&value=8&isRequired=false)" - # ) - # - # for codec in ("ac3", "eac3", "dca"): - # builder.extras.append("append-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=http&audioCodec=" + codec + ")") - # builder.extras.append("add-direct-play-profile(type=videoProfile&videoCodec=*&container=mkv&audioCodec=" + codec + ")") - - # limit OPUS to 334kbit - numChannels = self.choice.audioStream.channels.asInt(8) if self.choice.audioStream else 8 - - if numChannels == 8: - # 7.1 - opusBitrate = 334 - elif numChannels >= 6: - # 5.1 - opusBitrate = 256 - else: - # 2 - opusBitrate = 128 - - builder.extras.append( - "add-limitation(scope=videoAudioCodec&scopeName=opus&type=upperBound&name=audio.bitrate&" - "value={}&isRequired=false)".format(opusBitrate) - ) - - # limit AC3 - builder.extras.append( - "add-limitation(scope=videoAudioCodec&scopeName=ac3&type=upperBound&name=audio.bitrate&value=640)" - ) - - # limit audio to Kodi audio channels - builder.extras.append( - "add-limitation(scope=videoAudioCodec&scopeName=*&type=upperBound&" - "name=audio.channels&value={})".format(self.audioChannels) - ) - - # AAC sample rate cannot be less than 22050hz (HLS is capable). - if self.choice.audioStream is not None and self.choice.audioStream.samplingRate.asInt(22050) < 22050: - builder.extras.append( - "add-limitation(scope=videoAudioCodec&scopeName=aac&type=lowerBound&" - "name=audio.samplingRate&value=22050&isRequired=false)") - - # HEVC - if self.item.settings.getPreference("allow_hevc", True): - builder.extras.append( - "append-transcode-target-codec(type=videoProfile&context=streaming&container=mkv&" - "protocol=http&videoCodec=hevc)") - # builder.extras.append( - # "add-direct-play-profile(type=videoProfile&videoCodec=hevc&container=*&audioCodec=*)") - - # VP9 - if self.item.settings.getGlobal("vp9Support"): - builder.extras.append( - "append-transcode-target-codec(type=videoProfile&context=streaming&container=mkv&" - "protocol=http&videoCodec=vp9)") - # builder.extras.append( - # "add-direct-play-profile(type=videoProfile&videoCodec=vp9&container=*&audioCodec=*)") - - # AV1 - if self.item.settings.getPreference("allow_av1", False): - builder.extras.append( - "append-transcode-target-codec(type=videoProfile&context=streaming&container=mkv&" - "protocol=http&videoCodec=av1)") - # builder.extras.append( - # "add-direct-play-profile(type=videoProfile&videoCodec=av1&container=*&audioCodec=*)") - - # VC1 - if self.item.settings.getPreference("allow_vc1", True): + if "allow_vc1" in video_codecs: builder.extras.append( "append-transcode-target-codec(type=videoProfile&context=streaming&container=mkv&" "protocol=http&videoCodec=vc1)") @@ -684,10 +549,9 @@ def buildDirectPlay(self, obj, partIndex): server = self.item.getServer() - # Check if we should include our token or not for this request - obj.isRequestToServer = server.isRequestToServer(server.buildUrl(part.getAbsolutePath("key"))) - obj.streamUrls = [server.buildUrl(part.getAbsolutePath("key"), obj.isRequestToServer)] + self.setupObj(obj, part, server) obj.token = obj.isRequestToServer and server.getToken() or None + if self.media.protocol == "hls": obj.streamFormat = "hls" obj.switchingStrategy = "full-adaptation" @@ -724,7 +588,7 @@ def goToNextPart(self): oldPart.nextPart = None self.metadata = newPart - util.LOG("Next part set for playback: {0}".format(self.metadata)) + util.LOG("Next part set for playback: {0}", self.metadata) def getBifUrl(self, offset=0): server = self.item.getServer() @@ -748,10 +612,7 @@ def buildTranscode(self, server, obj, partIndex, directStream, isCurrentPart): # if server.supportsFeature("mkvTranscode") and self.item.settings.getPreference("transcode_format", 'mkv') != "hls": if server.supportsFeature("mkvTranscode"): - if not advancedSettings.oldprofile: - builder = self.buildTranscodeMkv(obj, directStream=directStream) - else: - builder = self.buildTranscodeMkvLegacy(obj, directStream=directStream) + builder = self.buildTranscodeMkv(obj, directStream=directStream) else: builder = self.buildTranscodeHls(obj) @@ -840,38 +701,34 @@ def buildTranscode(self, server, obj, partIndex, directStream, isCurrentPart): return obj -class PlexAudioPlayer(object): - def __init__(self, item): +class PlexAudioPlayer(BasePlayer): + def __init__(self, item=None): + self.item = item + self.choice = None self.containerFormats = { 'aac': "es.aac-adts" } - self.item = item - self.choice = mediadecisionengine.MediaDecisionEngine().chooseMedia(item) - if self.choice: - self.media = self.choice.media self.lyrics = None # createLyrics(item, self.media) - def build(self, directPlay=None): - directPlay = directPlay or self.choice.isDirectPlayable + def build(self, item, directPlay=None): + item = item or self.item + self.choice = choice = mediadecisionengine.MediaDecisionEngine().chooseMedia(item) + directPlay = directPlay or choice.isDirectPlayable obj = util.AttributeDict() - # TODO(schuyler): Do we want/need to add anything generic here? Title? Duration? - if directPlay: - obj = self.buildDirectPlay(obj) + obj = self.buildDirectPlay(item, choice, obj) else: - obj = self.buildTranscode(obj) + obj = self.buildTranscode(item, choice, obj) - self.metadata = obj + util.LOG("Constructed audio item for playback: {0}", util.cleanObjTokens(dict(obj))) - util.LOG("Constructed audio item for playback: {0}".format(util.cleanObjTokens(dict(obj)))) - - return self.metadata + return obj - def buildTranscode(self, obj): - transcodeServer = self.item.getTranscodeServer(True, "audio") + def buildTranscode(self, item, choice, obj): + transcodeServer = item.getTranscodeServer(True, "audio") if not transcodeServer: return None @@ -881,36 +738,44 @@ def buildTranscode(self, obj): obj.transcodeEndpoint = "/music/:/transcode/universal/start.m3u8" builder = http.HttpRequest(transcodeServer.buildUrl(obj.transcodeEndpoint, True)) - # builder.addParam("protocol", "http") - builder.addParam("path", self.item.getAbsolutePath("key")) - builder.addParam("session", self.item.getGlobal("clientIdentifier")) + builder.addParam("protocol", "http") + builder.addParam("path", item.getAbsolutePath("key")) + builder.addParam("session", item.getGlobal("clientIdentifier")) builder.addParam("directPlay", "0") builder.addParam("directStream", "0") + # this works, but currently shows "Direct Play" in Plex Web, even though it's clearly transcoding + builder.addParam("X-Plex-Platform", "Generic") + builder.extras = ["add-transcode-target(type=musicProfile&audioCodec=mp3&container=mp3&" + "context=streaming&protocol=http)"] + + builder.addParam("X-Plex-Client-Profile-Extra", '+'.join(builder.extras)) + obj.url = builder.getUrl() return obj - def buildDirectPlay(self, obj): - if self.choice.part: - obj.url = self.item.getServer().buildUrl(self.choice.part.getAbsolutePath("key"), True) + def buildDirectPlay(self, item, choice, obj): + if choice.part: + self.setupObj(obj, choice.part, item.getServer(), force_request_to_server=True) + obj.url = obj.streamUrls[0] # Set and override the stream format if applicable - obj.streamFormat = self.choice.media.get('container', 'mp3') + obj.streamFormat = choice.media.get('container', 'mp3') if self.containerFormats.get(obj.streamFormat): obj.streamFormat = self.containerFormats[obj.streamFormat] # If we're direct playing a FLAC, bitrate can be required, and supposedly # this is the only way to do it. plexinc/roku-client#48 # - bitrate = self.choice.media.bitrate.asInt() + bitrate = choice.media.bitrate.asInt() if bitrate > 0: obj.streams = [{'url': obj.url, 'bitrate': bitrate}] return obj # We may as well fallback to transcoding if we could not direct play - return self.buildTranscode(obj) + return self.buildTranscode(item, choice, obj) def getLyrics(self): return self.lyrics @@ -940,7 +805,8 @@ def build(self, item=None): obj.url = server.buildUrl(path, True) obj.enableBlur = server.supportsPhotoTranscoding - util.DEBUG_LOG("Constructed photo item for playback: {0}".format(util.cleanObjTokens(dict(obj)))) + util.DEBUG_LOG("Constructed photo item for playback: {0}", + lambda: util.cleanObjTokens(dict(obj))) self.metadata = obj diff --git a/script.plexmod/lib/_included_packages/plexnet/plexresource.py b/script.plexmod/lib/_included_packages/plexnet/plexresource.py index b1c20ec021..419084daf1 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexresource.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexresource.py @@ -138,7 +138,7 @@ def URL(self): return self.http_url def connect(self): - util.LOG('Connecting: {0}'.format(util.cleanToken(self.URL))) + util.LOG('Connecting: {0}', util.cleanToken(self.URL)) try: self.data = self.query('/') self.reachable = True @@ -167,8 +167,8 @@ def headers(self, token=None): def query(self, path, method=None, token=None, **kwargs): method = method or http.requests.get url = self.getURL(path) - util.LOG('{0} {1}'.format(method.__name__.upper(), url)) - response = method(url, headers=self.headers(token), timeout=util.TIMEOUT, **kwargs) + util.LOG('{0} {1}', method.__name__.upper(), url) + response = method(url, headers=self.headers(token), timeout=util.DEFAULT_TIMEOUT, **kwargs) if response.status_code not in (200, 201): codename = http.status_codes.get(response.status_code)[0] raise exceptions.BadRequest('({0}) {1}'.format(response.status_code, codename)) @@ -201,34 +201,37 @@ def items(self): return self._items +# fixme: never called def fetchResources(token): headers = util.BASE_HEADERS.copy() headers['X-Plex-Token'] = token - util.LOG('GET {0}?X-Plex-Token={1}'.format(RESOURCES, util.hideToken(token))) + util.LOG('GET {0}?X-Plex-Token={1}', RESOURCES, util.hideToken(token)) response = http.GET(RESOURCES) data = ElementTree.fromstring(response.text.encode('utf8')) from . import plexserver return [plexserver.PlexServer(elem) for elem in data] +# fixme: never called def findResource(resources, search, port=32400): """ Searches server.name """ search = search.lower() - util.LOG('Looking for server: {0}'.format(search)) + util.LOG('Looking for server: {0}', search) for server in resources: if search == server.name.lower(): - util.LOG('Server found: {0}'.format(server)) + util.LOG('Server found: {0}', server) return server - util.LOG('Unable to find server: {0}'.format(search)) + util.LOG('Unable to find server: {0}', search) raise exceptions.NotFound('Unable to find server: {0}'.format(search)) +# fixme: never called def findResourceByID(resources, ID): """ Searches server.clientIdentifier """ - util.LOG('Looking for server by ID: {0}'.format(ID)) + util.LOG('Looking for server by ID: {0}', ID) for server in resources: if ID == server.clientIdentifier: - util.LOG('Server found by ID: {0}'.format(server)) + util.LOG('Server found by ID: {0}', server) return server - util.LOG('Unable to find server by ID: {0}'.format(ID)) + util.LOG('Unable to find server by ID: {0}', ID) raise exceptions.NotFound('Unable to find server by ID: {0}'.format(ID)) diff --git a/script.plexmod/lib/_included_packages/plexnet/plexserver.py b/script.plexmod/lib/_included_packages/plexnet/plexserver.py index 7857260a84..77bead34ea 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexserver.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexserver.py @@ -65,6 +65,8 @@ def __init__(self, data=None): self.versionNorm = None self.rawVersion = None self.transcodeSupport = False + self.currentHubs = None + self.dnsRebindingProtection = False if data is None: return @@ -79,6 +81,7 @@ def __init__(self, data=None): self.rawVersion = data.attrib.get('productVersion') self.versionNorm = util.normalizedVersion(self.rawVersion) self.transcodeSupport = data.attrib.get('transcodeSupport') == '1' + self.dnsRebindingProtection = data.attrib.get('dnsRebindingProtection') == '1' def __eq__(self, other): if not other: @@ -114,11 +117,15 @@ def isLocal(self): if self.activeConnection: return self.activeConnection.isLocal + @property + def anyLANConnection(self): + return any(c.localVerified for c in self.connections) + def getObject(self, key): data = self.query(key) return plexobjects.buildItem(self, data[0], key, container=self) - def hubs(self, section=None, count=None, search_query=None): + def hubs(self, section=None, count=None, search_query=None, section_ids=None, ignore_hubs=None): hubs = [] params = {"includeMarkers": 1} @@ -143,6 +150,10 @@ def hubs(self, section=None, count=None, search_query=None): return hubs else: q = '/hubs/sections/%s' % section + else: + # home hub + if section_ids: + params['pinnedContentDirectoryID'] = ",".join(section_ids) if count is not None: params['count'] = count @@ -150,8 +161,42 @@ def hubs(self, section=None, count=None, search_query=None): data = self.query(q, params=params) container = plexobjects.PlexContainer(data, initpath=q, server=self, address=q) + self.currentHubs = {} if self.currentHubs is None else self.currentHubs + + newCW = util.INTERFACE.getPreference('hubs_use_new_continue_watching', False) and not search_query \ + and not section + + if newCW: + # home, add continueWatching + cq = '/hubs/continueWatching' + if section_ids: + cq += util.joinArgs(params) + + cdata = self.query(cq, params=params) + ccontainer = plexobjects.PlexContainer(cdata, initpath=cq, server=self, address=cq) + self.currentHubs[cdata[0].attrib.get('hubIdentifier')] = cdata[0].attrib.get('title') + hubs.append(plexlibrary.Hub(cdata[0], server=self, container=ccontainer)) + for elem in data: + hubIdent = elem.attrib.get('hubIdentifier') + self.currentHubs["{}:{}".format(section, hubIdent)] = elem.attrib.get('title') + + # if we've added continueWatching, which combines continue and ondeck, skip those two hubs + if newCW and hubIdent and \ + (hubIdent.startswith('home.continue') or hubIdent.startswith('home.ondeck')): + continue + + if ignore_hubs and "{}:{}".format(section, hubIdent) in ignore_hubs: + continue + hubs.append(plexlibrary.Hub(elem, server=self, container=container)) + + if section_ids: + # when we have hidden sections, apply the filter to the hubs keys for subsequent queries + for hub in hubs: + if "pinnedContentDirectoryID" not in hub.key: + hub.key += util.joinArgs(params, '?' not in hub.key) + return hubs def playlists(self, start=0, size=10, hub=None): @@ -215,7 +260,7 @@ def query(self, path, method=None, **kwargs): url = http.addUrlParam(url, "X-Plex-Container-Start=%s" % offset) url = http.addUrlParam(url, "X-Plex-Container-Size=%s" % limit) - util.LOG('{0} {1}'.format(method.__name__.upper(), re.sub('X-Plex-Token=[^&]+', 'X-Plex-Token=****', url))) + util.LOG('{0} {1}', method.__name__.upper(), re.sub('X-Plex-Token=[^&]+', 'X-Plex-Token=****', url)) try: response = method(url, **kwargs) if response.status_code not in (200, 201): @@ -347,7 +392,7 @@ def collectDataFromRoot(self, data): appMinVer = util.INTERFACE.getGlobal('minServerVersionArr', '0.0.0.0') self.isSupported = self.isSecondary() or util.normalizedVersion(appMinVer) <= self.versionNorm - util.DEBUG_LOG("Server information updated from reachability check: {0}".format(self)) + util.DEBUG_LOG("Server information updated from reachability check: {0}", self) return True @@ -355,7 +400,7 @@ def updateReachability(self, force=True, allowFallback=False): if not force and self.activeConnection and self.activeConnection.state != plexresource.ResourceConnection.STATE_UNKNOWN: return - util.LOG('Updating reachability for {0}: conns={1}, allowFallback={2}'.format(repr(self.name), len(self.connections), allowFallback)) + util.LOG('Updating reachability for {0}: conns={1}, allowFallback={2}', repr(self.name), len(self.connections), allowFallback) epoch = time.time() retrySeconds = 60 @@ -364,10 +409,10 @@ def updateReachability(self, force=True, allowFallback=False): conn = self.connections[i] diff = epoch - (conn.lastTestedAt or 0) if conn.hasPendingRequest: - util.DEBUG_LOG("Skip reachability test for {0} (has pending request)".format(conn)) + util.DEBUG_LOG("Skip reachability test for {0} (has pending request)", conn) elif (diff < minSeconds or (not self.isSecondary() and self.isReachable() and diff < retrySeconds)) and \ not conn.state == "unauthorized": - util.DEBUG_LOG("Skip reachability test for {0} (checked {1} secs ago)".format(conn, diff)) + util.DEBUG_LOG("Skip reachability test for {0} (checked {1} secs ago)", conn, diff) elif conn.testReachability(self, allowFallback): self.pendingReachabilityRequests += 1 if conn.isSecure: @@ -391,7 +436,7 @@ def onReachabilityResult(self, connection): if connection.isSecure: self.pendingSecureRequests -= 1 - util.DEBUG_LOG("Reachability result for {0}: {1} is {2}".format(repr(self.name), connection.address, connection.state)) + util.DEBUG_LOG("Reachability result for {0}: {1} is {2}", repr(self.name), connection.address, connection.state) # Noneate active connection if the state is unreachable if self.activeConnection and self.activeConnection.state != plexresource.ResourceConnection.STATE_REACHABLE: @@ -407,17 +452,17 @@ def onReachabilityResult(self, connection): except IndexError: continue - util.DEBUG_LOG("Connection score: {0}, {1}".format(conn.address, conn.getScore(True))) + util.DEBUG_LOG("Connection score: {0}, {1}", conn.address, lambda: conn.getScore(True)) if not best or conn.getScore() > best.getScore(): best = conn if best and best.state == best.STATE_REACHABLE: if (best.isSecure or util.LOCAL_OVER_SECURE) or self.pendingSecureRequests <= 0: - util.DEBUG_LOG("Using connection for {0} for now: {1}".format(repr(self.name), best.address)) + util.DEBUG_LOG("Using connection for {0} for now: {1}", repr(self.name), best.address) self.activeConnection = best else: - util.DEBUG_LOG("Found a good connection for {0}, but holding out for better".format(repr(self.name))) + util.DEBUG_LOG("Found a good connection for {0}, but holding out for better", repr(self.name)) if self.pendingReachabilityRequests <= 0: # Retest the server with fallback enabled. hasFallback will only @@ -429,7 +474,7 @@ def onReachabilityResult(self, connection): else: self.trigger("completed:reachability") - util.LOG("Active connection for {0} is {1}".format(repr(self.name), self.activeConnection)) + util.LOG("Active connection for {0} is {1}", repr(self.name), self.activeConnection) from . import plexservermanager plexservermanager.MANAGER.updateReachabilityResult(self, bool(self.activeConnection)) @@ -463,7 +508,7 @@ def markUpdateFinished(self, source): hasSecureConn = True toKeep.append(conn) else: - util.DEBUG_LOG("Removed connection {0} for {1} after updating connections for {2}".format(conn, repr(self.name), source)) + util.DEBUG_LOG("Removed connection {0} for {1} after updating connections for {2}", conn, repr(self.name), source) if conn == self.activeConnection: util.DEBUG_LOG("Active connection lost") self.activeConnection = None diff --git a/script.plexmod/lib/_included_packages/plexnet/plexservermanager.py b/script.plexmod/lib/_included_packages/plexnet/plexservermanager.py index d6e968b364..e6f8b94daf 100644 --- a/script.plexmod/lib/_included_packages/plexnet/plexservermanager.py +++ b/script.plexmod/lib/_included_packages/plexnet/plexservermanager.py @@ -42,6 +42,10 @@ def __init__(self): def getSelectedServer(self): return self.selectedServer + @property + def allConnections(self): + return [c.address for s in list(self.serversByUuid.values()) for c in s.connections if s.connections] + def setSelectedServer(self, server, force=False): # Don't do anything if the server is already selected. if self.selectedServer and self.selectedServer == server: @@ -57,7 +61,7 @@ def setSelectedServer(self, server, force=False): return False if not self.selectedServer or force: - util.LOG("Setting selected server to {0}".format(server)) + util.LOG("Setting selected server to {0}", server) self.selectedServer = server # Update our saved state. @@ -143,11 +147,11 @@ def mergeServer(self, server): if server.uuid in self.serversByUuid: existing = self.serversByUuid[server.uuid] existing.merge(server) - util.DEBUG_LOG("Merged {0}".format(repr(server.name))) + util.DEBUG_LOG("Merged {0}", repr(server.name)) return existing else: self.serversByUuid[server.uuid] = server - util.DEBUG_LOG("Added new server {0}".format(repr(server.name))) + util.DEBUG_LOG("Added new server {0}", repr(server.name)) self.trigger("new:server", server=server) return server @@ -159,12 +163,12 @@ def deviceRefreshComplete(self, source): for uuid in toRemove: if uuid not in self.serversByUuid: - util.DEBUG_LOG("Server {} lost - removing".format(uuid)) + util.DEBUG_LOG("Server {} lost - removing", uuid) continue server = self.serversByUuid[uuid] - util.DEBUG_LOG("Server {0} has no more connections - removing".format(repr(server.name))) + util.DEBUG_LOG("Server {0} has no more connections - removing", repr(server.name)) # self.notifyAboutDevice(server, False) self.removeServer(server) @@ -184,7 +188,7 @@ def updateReachability(self, force=False, preferSearch=False, defer=False): if preferSearch and hasPreferredServer and preferredServerExists: # Update the preferred server immediately if requested and exits - util.LOG("Updating reachability for preferred server: force={0}".format(force)) + util.LOG("Updating reachability for preferred server: force={0}", force) self.serversByUuid[self.searchContext.preferredServer].updateReachability(force) self.deferUpdateReachability() elif defer: @@ -200,7 +204,7 @@ def updateReachability(self, force=False, preferSearch=False, defer=False): self.deferReachabilityTimer.cancel() self.deferReachabilityTimer = None - util.LOG("Updating reachability for all devices: force={0}".format(force)) + util.LOG("Updating reachability for all devices: force={0}", force) for uuid in list(self.serversByUuid.keys()): self.serversByUuid[uuid].updateReachability(force) @@ -295,7 +299,7 @@ def checkSelectedServerSearch(self, skip_preferred=False, skip_owned=False): elif waitingForOwned and (not self.searchContext.bestServer or not self.searchContext.bestServer.owned): util.LOG("Still waiting for an owned server: " + pendingString) elif waitingForAnything and not self.searchContext.bestServer: - util.LOG("Still waiting for any server: {0}".format(pendingString)) + util.LOG("Still waiting for any server: {0}", pendingString) else: # No hope for anything better, let's select what we found util.LOG("Settling for the best server we found") @@ -333,6 +337,7 @@ def loadState(self): server = plexserver.createPlexServerForName(serverObj['uuid'], serverObj['name']) server.owned = bool(serverObj.get('owned')) server.sameNetwork = serverObj.get('sameNetwork') + server.dnsRebindingProtection = serverObj.get('dnsRebindingProtection') hasSecureConn = False for i in range(len(serverObj.get('connections', []))): @@ -357,7 +362,8 @@ def loadState(self): self.serversByUuid[server.uuid] = server - util.LOG("Loaded {0} servers from registry".format(len(obj['servers']))) + util.LOG("Loaded {0} servers from registry", len(obj['servers'])) + util.APP.trigger("loaded:server_connections", servers=self.serversByUuid.values(), source="stored") self.updateReachability(False, True) def saveState(self, setPreferred=False): @@ -370,6 +376,8 @@ def saveState(self, setPreferred=False): servers = self.getServers() obj['servers'] = [] + hosts = [] + for server in servers: # Don't save secondary servers. They should be discovered through GDM or myPlex. if not server.isSecondary(): @@ -378,11 +386,13 @@ def saveState(self, setPreferred=False): 'uuid': server.uuid, 'owned': server.owned, 'sameNetwork': server.sameNetwork, + 'dnsRebindingProtection': server.dnsRebindingProtection, 'connections': [] } for i in range(len(server.connections)): conn = server.connections[i] + hosts.append(conn.address) serverObj['connections'].append({ 'sources': conn.sources, 'address': conn.address, @@ -397,6 +407,7 @@ def saveState(self, setPreferred=False): and setPreferred: util.INTERFACE.setPreference("lastServerId.{}".format(plexapp.ACCOUNT.ID), self.selectedServer.uuid) + util.APP.trigger("loaded:server_connections", servers=servers, source="myplex") util.INTERFACE.setRegistry("PlexServerManager", json.dumps(obj)) def clearState(self): @@ -421,7 +432,7 @@ def getChannelServer(self): self.channelServer = s if self.channelServer: - util.LOG("Setting channel server to {0}".format(self.channelServer)) + util.LOG("Setting channel server to {0}", self.channelServer) return self.channelServer @@ -449,7 +460,7 @@ def getTranscodeServer(self, transcodeType=None): if self.transcodeServer: transcodeTypeString = transcodeType or '' - util.LOG("Found a better {0} transcode server than {1}, using: {2}".format(transcodeTypeString, self.selectedserver, self.transcodeServer)) + util.LOG("Found a better {0} transcode server than {1}, using: {2}", transcodeTypeString, self.selectedserver, self.transcodeServer) return self.transcodeServer return self.selectedServer @@ -462,7 +473,7 @@ def startSelectedServerSearch(self, reset=False, ID=None): ID = ID is not None and ID or plexapp.ACCOUNT.ID pServ = util.INTERFACE.getPreference("lastServerId.{}".format(ID), '') - util.DEBUG_LOG("Preferred server for {0} is: {1}".format(ID, pServ)) + util.DEBUG_LOG("Preferred server for {0} is: {1}", ID, pServ) # Keep track of some information during our search waitFor = [] @@ -478,7 +489,7 @@ def startSelectedServerSearch(self, reset=False, ID=None): 'waitingForResources': waitFor }) - util.LOG("Starting selected server search, hoping for {0}".format(self.searchContext.preferredServer)) + util.LOG("Starting selected server search, hoping for {0}", self.searchContext.preferredServer) if util.LOCAL_OVER_SECURE: util.WARN_LOG("Preferring local server connections over secure ones!") @@ -530,7 +541,7 @@ def deferUpdateReachability(self, addTimer=True, logInfo=True): self.deferReachabilityTimer.reset() if self.deferReachabilityTimer and logInfo: - util.LOG('Defer update reachability for all devices a few seconds: GDMactive={0}'.format(gdm.DISCOVERY.isActive())) + util.LOG('Defer update reachability for all devices a few seconds: GDMactive={0}', gdm.DISCOVERY.isActive()) def onDeferUpdateReachabilityTimer(self): if not self.selectedServer and self.searchContext: @@ -592,7 +603,7 @@ def refreshManualConnections(self): util.DEBUG_LOG("No manual connections.") return - util.LOG("Refreshing {0} manual connections".format(len(manualConnections))) + util.LOG("Refreshing {0} manual connections", len(manualConnections)) for conn in manualConnections: # Default to http, as the server will need to be signed in for https to work, @@ -618,7 +629,7 @@ def onManualConnectionsResponse(self, request, response, context): data = response.getBodyXml() if data is not None: serverAddress = context.serverAddress - util.DEBUG_LOG("Received manual connection response for {0}".format(serverAddress)) + util.DEBUG_LOG("Received manual connection response for {0}", serverAddress) machineID = data.attrib.get('machineIdentifier') name = context.address diff --git a/script.plexmod/lib/_included_packages/plexnet/serverdecision.py b/script.plexmod/lib/_included_packages/plexnet/serverdecision.py index e1a5344c62..6c0c597064 100644 --- a/script.plexmod/lib/_included_packages/plexnet/serverdecision.py +++ b/script.plexmod/lib/_included_packages/plexnet/serverdecision.py @@ -38,7 +38,7 @@ def init(self): self.decisionsCodes[key] = self.response.container.get(key + "Code", "-1").asInt() self.decisionsTexts[key] = self.response.container.get(key + "Text") - util.DEBUG_LOG("Decision codes: {0}".format(self.decisionsCodes)) + util.DEBUG_LOG("Decision codes: {0}", self.decisionsCodes) def __str__(self): if self.isSupported: diff --git a/script.plexmod/lib/_included_packages/plexnet/signalsmixin.py b/script.plexmod/lib/_included_packages/plexnet/signalsmixin.py index 2efe9d6e63..6c96d32061 100644 --- a/script.plexmod/lib/_included_packages/plexnet/signalsmixin.py +++ b/script.plexmod/lib/_included_packages/plexnet/signalsmixin.py @@ -3,7 +3,7 @@ class SignalsMixin(object): - def __init__(self): + def __init__(self, *args, **kwargs): self._signals = {} def on(self, signalName, callback): @@ -14,6 +14,12 @@ def on(self, signalName, callback): signal.connect(callback) + def has_signal(self, signalName, callback): + if not self._signals: + return + + return signalName in self._signals and self._signals[signalName].is_connected(callback) + def off(self, signalName, callback): if not self._signals: return @@ -29,7 +35,8 @@ def off(self, signalName, callback): if signalName in self._signals: del self._signals[signalName] else: - self._signals[signalName].disconnect(callback) + if self.has_signal(signalName, callback): + self._signals[signalName].disconnect(callback) def trigger(self, signalName, **kwargs): if not self._signals: diff --git a/script.plexmod/lib/_included_packages/plexnet/util.py b/script.plexmod/lib/_included_packages/plexnet/util.py index d29232fb16..a9fdee9d46 100644 --- a/script.plexmod/lib/_included_packages/plexnet/util.py +++ b/script.plexmod/lib/_included_packages/plexnet/util.py @@ -2,8 +2,6 @@ from __future__ import absolute_import -from copy import copy - from . import simpleobjects import re import sys @@ -12,6 +10,8 @@ import uuid import threading import six +import math +from copy import copy from kodi_six import xbmcaddon from . import verlib @@ -22,11 +22,18 @@ else: Event = threading.Event +try: + from collections.abc import Iterable +except ImportError: + from collections import Iterable + BASE_HEADERS = '' # to maintain py2 compatibility, duplicate ADDON from lib.util to avoid circular import ADDON = xbmcaddon.Addon() +translatePath = None + def resetBaseHeaders(): return { @@ -47,7 +54,12 @@ def resetBaseHeaders(): PROJECT = 'PlexNet' # name provided to plex server VERSION = '0.0.0a1' # version of this api TIMEOUT = 10 # request timeout -LONG_TIMEOUT = 20 # s +TIMEOUT_CONNECT = 5 # connect timeout +DEFAULT_TIMEOUT = 10 +LONG_TIMEOUT = 20 +PLEXTV_TIMEOUT = None # set me later +PLEXTV_TIMEOUT_READ = 20 # s +PLEXTV_TIMEOUT_CONNECT = 5 CONN_CHECK_TIMEOUT = 2.5 # s LAN_REACHABILITY_TIMEOUT = 0.01 # s CHECK_LOCAL = False @@ -64,10 +76,14 @@ def resetBaseHeaders(): X_PLEX_VERSION = VERSION # Plex application version number USER_AGENT = '{0}/{1}'.format(PROJECT, VERSION) +USE_CERT_BUNDLE = False + INTERFACE = None TIMER = None APP = None MANAGER = None +ACCOUNT = None +SERVERMANAGER = None try: _platform = platform.system() @@ -78,7 +94,10 @@ def resetBaseHeaders(): _platform = sys.platform X_PLEX_DEVICE = _platform # Device name and model number, eg iPhone3,2, Motorola XOOM, LG5200TV -X_PLEX_IDENTIFIER = str(hex(uuid.getnode())) # UUID, serial number, or other number unique per device +X_PLEX_IDENTIFIER = ADDON.getSetting('client.ID') +if not X_PLEX_IDENTIFIER: + X_PLEX_IDENTIFIER = str(uuid.uuid4()) + ADDON.setSetting('client.ID', X_PLEX_IDENTIFIER) BASE_HEADERS = resetBaseHeaders() @@ -105,20 +124,20 @@ def setApp(app): APP = app -def LOG(msg): - INTERFACE.LOG(msg) +def LOG(msg, *args, **kwargs): + INTERFACE.LOG(msg, *args, **kwargs) -def DEBUG_LOG(msg): - INTERFACE.DEBUG_LOG(msg) +def DEBUG_LOG(msg, *args, **kwargs): + INTERFACE.DEBUG_LOG(msg, *args, **kwargs) -def ERROR_LOG(msg): - INTERFACE.ERROR_LOG(msg) +def ERROR_LOG(msg, *args, **kwargs): + INTERFACE.ERROR_LOG(msg, *args, **kwargs) -def WARN_LOG(msg): - INTERFACE.WARN_LOG(msg) +def WARN_LOG(msg, *args, **kwargs): + INTERFACE.WARN_LOG(msg, *args, **kwargs) def ERROR(msg=None, err=None): @@ -159,24 +178,50 @@ def cleanToken(url): return re.sub(r'X-Plex-Token=[^&]+', 'X-Plex-Token=****', url) -def cleanObjTokens(dorig, flistkeys=("streamUrls",), fstrkeys=("url", "token")): - d = {} - dcopy = copy(dorig) +def mask(v): + vlen = len(v) + return (v[:int(math.floor(vlen / 2))] + int(math.ceil(vlen / 2)) * "*") if vlen > 4 else "****" - # filter lists - for k in flistkeys: - if k not in d: - continue - d[k] = list(map(lambda x: cleanToken(x), d[k][:])) - # filter strings - for k in fstrkeys: - if k not in d: - continue - d[k] = "****" if k == "token" else cleanToken(d[k]) - - dcopy.update(d) - return dcopy +def cleanObjTokens(dorig, + flistkeys=("streamUrls", "streams",), + mask_keys=("token", "authToken"), + dict_cls=dict): + dcopy = copy(dorig) + if not isinstance(dcopy, dict): + if isinstance(dcopy, Iterable) and not isinstance(dcopy, six.string_types): + return [cleanObjTokens(a, flistkeys=flistkeys, mask_keys=mask_keys) for a in dcopy] + elif isinstance(dcopy, six.string_types): + return cleanToken(dcopy) + return dcopy + + d = dict_cls() + for k, v in dcopy.items(): + if isinstance(v, six.string_types): + if v: + d[k] = mask(v) if k in mask_keys else cleanToken(v) + continue + d[k] = v + + elif isinstance(v, dict): + d[k] = cleanObjTokens(v, flistkeys=flistkeys, mask_keys=mask_keys) + + elif isinstance(v, Iterable): + fv = [] + for iv in v: + if isinstance(iv, six.string_types): + if k in flistkeys: + fv.append(cleanToken(iv)) + continue + fv.append(iv) + else: + fv.append(cleanObjTokens(iv, flistkeys=flistkeys, mask_keys=mask_keys)) + d[k] = fv + + else: + d[k] = v + + return d def now(local=False): @@ -198,17 +243,24 @@ def joinArgs(args, includeQuestion=True): return '{0}{1}'.format(includeQuestion and '?' or '&', '&'.join(arglist)) +def getPlexHeaders(): + return {"X-Plex-Platform": INTERFACE.getGlobal("platform"), + "X-Plex-Version": INTERFACE.getGlobal("appVersionStr"), + "X-Plex-Client-Identifier": INTERFACE.getGlobal("clientIdentifier"), + "X-Plex-Platform-Version": INTERFACE.getGlobal("platformVersion", "unknown"), + "X-Plex-Product": INTERFACE.getGlobal("product"), + "X-Plex-Provides": not INTERFACE.getPreference("remotecontrol", False) and 'player' or '', + "X-Plex-Device": INTERFACE.getGlobal("device"), + "X-Plex-Model": INTERFACE.getGlobal("model"), + "X-Plex-Device-Name": INTERFACE.getGlobal("friendlyName"), + 'Accept-Encoding': 'gzip,deflate', + 'Accept-Language': ACCEPT_LANGUAGE, + 'User-Agent': '{0}/{1}'.format("PM4K", ADDON.getAddonInfo('version')) + } + + def addPlexHeaders(transferObj, token=None): - headers = {"X-Plex-Platform": INTERFACE.getGlobal("platform"), - "X-Plex-Version": INTERFACE.getGlobal("appVersionStr"), - "X-Plex-Client-Identifier": INTERFACE.getGlobal("clientIdentifier"), - "X-Plex-Platform-Version": INTERFACE.getGlobal("platformVersion", "unknown"), - "X-Plex-Product": INTERFACE.getGlobal("product"), - "X-Plex-Provides": not INTERFACE.getPreference("remotecontrol", False) and 'player' or '', - "X-Plex-Device": INTERFACE.getGlobal("device"), - "X-Plex-Model": INTERFACE.getGlobal("model"), - "X-Plex-Device-Name": INTERFACE.getGlobal("friendlyName"), - } + headers = getPlexHeaders() transferObj.session.headers.update(headers) @@ -255,6 +307,12 @@ def normalizedVersion(ver): return verlib.NormalizedVersion(verlib.suggest_normalized_version('0.0.0')) +def parsePlexDirectHost(hostname): + v6 = hostname.count("-") > 3 + base = hostname.split(".", 1)[0] + return v6 and base.replace("-", ":") or base.replace("-", ".") + + class CompatEvent(Event): def wait(self, timeout): Event.wait(self, timeout) @@ -315,9 +373,9 @@ def is_alive(self): def shouldAbort(self): return False - def join(self): + def join(self, timeout=None): if self.thread.is_alive(): - self.thread.join() + self.thread.join(timeout=timeout) def isExpired(self): return self.event.isSet() diff --git a/script.plexmod/lib/_included_packages/plexnet/video.py b/script.plexmod/lib/_included_packages/plexnet/video.py index 8fe100a503..81fd2be572 100644 --- a/script.plexmod/lib/_included_packages/plexnet/video.py +++ b/script.plexmod/lib/_included_packages/plexnet/video.py @@ -12,6 +12,9 @@ from . import mediachoice from .mixins import AudioCodecMixin +from lib.data_cache import dcm +from lib.util import T + class PlexVideoItemList(plexobjects.PlexItemList): def __init__(self, data, initpath=None, server=None, container=None): @@ -45,15 +48,19 @@ def _impl(self, *method_args, **method_kwargs): class Video(media.MediaItem, AudioCodecMixin): + __slots__ = ("_settings",) + TYPE = None manually_selected_sub_stream = False current_subtitle_is_embedded = False _current_subtitle_idx = None + _noSpoilers = False def __init__(self, *args, **kwargs): self._settings = None media.MediaItem.__init__(self, *args, **kwargs) AudioCodecMixin.__init__(self) + self._noSpoilers = False def __eq__(self, other): return other and self.ratingKey == other.ratingKey @@ -61,6 +68,12 @@ def __eq__(self, other): def __ne__(self, other): return not self.__eq__(other) + def __hash__(self): + return hash(self.ratingKey) + + def __repr__(self): + return '<%s:%s>' % (self.__class__.__name__, self.ratingKey) + @property def settings(self): if not self._settings: @@ -127,8 +140,7 @@ def selectedSubtitleStream(self, forced_subtitles_override=False, fallback=False if not possible_alt: possible_alt = alt_stream if possible_alt: - util.DEBUG_LOG("Selecting stream %s instead of %s" % - (possible_alt, stream)) + util.DEBUG_LOG("Selecting stream {} instead of {}", possible_alt, stream) stream.setSelected(False) possible_alt.setSelected(True) self.current_subtitle_is_embedded = possible_alt.embedded @@ -152,8 +164,9 @@ def setMediaChoice(self, media=None, partIndex=0): self.mediaChoice = mediachoice.MediaChoice(media, partIndex=partIndex) @forceMediaChoice - def selectStream(self, stream, _async=True): - self.mediaChoice.part.setSelectedStream(stream.streamType.asInt(), stream.id, _async) + def selectStream(self, stream, _async=True, from_session=False): + self.mediaChoice.part.setSelectedStream(stream.streamType.asInt(), stream.id, _async, from_session=from_session, + video=self) # Update any affected streams if stream.streamType.asInt() == plexstream.PlexStream.TYPE_AUDIO: for audioStream in self.audioStreams: @@ -194,7 +207,7 @@ def cycleSubtitles(self, forward=True): else: stream = self.subtitleStreams[-1] - util.DEBUG_LOG("Selecting subtitle stream: {} (was: {})".format(stream, cur)) + util.DEBUG_LOG("Selecting subtitle stream: {} (was: {})", stream, cur) self.selectStream(stream) return stream @@ -331,15 +344,23 @@ def audioChannelsString(self, translate_func=util.dummyTranslate): @property def remainingTime(self): - if not self.viewOffset.asInt(): + return self._remainingTime() + + def _remainingTime(self, view_offset=None): + view_offset = view_offset if view_offset is not None else self.viewOffset.asInt() + if not view_offset: return - return (self.duration.asInt() - self.viewOffset.asInt()) // 1000 + return (self.duration.asInt() - view_offset) // 1000 @property def remainingTimeString(self): - if not self.remainingTime: + return self._remainingTimeString() + + def _remainingTimeString(self, view_offset=None): + remt = self._remainingTime(view_offset=view_offset) + if not remt: return '' - seconds = self.remainingTime + seconds = remt hours = seconds // 3600 minutes = (seconds - hours * 3600) // 60 return (hours and "{}h ".format(hours) or '') + (minutes and "{}m".format(minutes) or "0m") @@ -364,6 +385,7 @@ def sectionOnDeckCount(self): class PlayableVideo(Video, media.RelatedMixin): + __slots__ = ("extras", "guids", "chapters") TYPE = None _videoStreams = None _audioStreams = None @@ -374,6 +396,7 @@ def _setData(self, data): Video._setData(self, data) if self.isFullObject(): self.extras = PlexVideoItemList(data.find('Extras'), initpath=self.initpath, server=self.server, container=self) + self.guids = plexobjects.PlexItemList(data, media.Guid, media.Guid.TYPE, server=self.server) # the PMS Extras API can return protocol=mp4 when it doesn't make sense, mark this as an extra so the MDE # knows what to do @@ -404,6 +427,8 @@ def reload(self, *args, **kwargs): fromMediaChoice = kwargs.get("fromMediaChoice", False) + kwargs["includeMarkers"] = 1 + # capture current IDs mediaID = None partID = None @@ -461,6 +486,8 @@ def postPlay(self, **params): @plexobjects.registerLibType class Movie(PlayableVideo): + __slots__ = ("collections", "countries", "directors", "genres", "media", "producers", "roles", "reviews", + "writers", "markers", "sessionKey", "user", "player", "session", "transcodeSession") TYPE = 'movie' def _setData(self, data): @@ -534,19 +561,25 @@ def actors(self): def isWatched(self): return self.get('viewCount').asInt() > 0 or self.get('viewOffset').asInt() > 0 + @property + def isFullyWatched(self): + return self.get('viewCount').asInt() > 0 and not self.get('viewOffset').asInt() + def getStreamURL(self, **params): return self._getStreamURL(**params) @plexobjects.registerLibType class Show(Video, media.RelatedMixin, SectionOnDeckMixin): + __slots__ = ("_genres", "guids", "onDeck") TYPE = 'show' def _setData(self, data): Video._setData(self, data) if self.isFullObject(): - self.genres = plexobjects.PlexItemList(data, media.Genre, media.Genre.TYPE, server=self.server) + self._genres = plexobjects.PlexItemList(data, media.Genre, media.Genre.TYPE, server=self.server) self.roles = plexobjects.PlexItemList(data, media.Role, media.Role.TYPE, server=self.server, container=self.container) + self.guids = plexobjects.PlexItemList(data, media.Guid, media.Guid.TYPE, server=self.server) #self.related = plexobjects.PlexItemList(data.find('Related'), plexlibrary.Hub, plexlibrary.Hub.TYPE, server=self.server, container=self) self.extras = PlexVideoItemList(data.find('Extras'), initpath=self.initpath, server=self.server, container=self) self.onDeck = PlexVideoItemList(data.find('OnDeck'), initpath=self.initpath, server=self.server, @@ -560,6 +593,10 @@ def unViewedLeafCount(self): def isWatched(self): return self.viewedLeafCount == self.leafCount + @property + def isFullyWatched(self): + return self.isWatched + @property def playbackSettings(self): return util.INTERFACE.playbackManager(self) @@ -580,7 +617,7 @@ def episode(self, title): path = '/library/metadata/%s/allLeaves' % self.ratingKey return plexobjects.findItem(self.server, path, title) - def all(self): + def all(self, *args, **kwargs): return self.episodes() def watched(self): @@ -592,6 +629,17 @@ def unwatched(self): def refresh(self): self.server.query('/library/metadata/%s/refresh' % self.ratingKey) + def genres(self): + genres = dcm.getCacheData("show_genres", self.ratingKey) + if genres: + return [media.Genre(util.AttributeDict(tag="genre", attrib={"tag": g}, virtual=True)) for g in genres] + + if not self.isFullObject(): + self.reload(soft=True) + + dcm.setCacheData("show_genres", self.ratingKey, [g.tag for g in self._genres]) + return self._genres + @plexobjects.registerLibType class Season(Video): @@ -604,7 +652,7 @@ def _setData(self, data): @property def defaultTitle(self): - return self.parentTitle or self.title + return T(32303, "Season {}").format(self.index) @property def unViewedLeafCount(self): @@ -614,6 +662,10 @@ def unViewedLeafCount(self): def isWatched(self): return self.viewedLeafCount == self.leafCount + @property + def isFullyWatched(self): + return self.isWatched + def episodes(self, watched=None, offset=None, limit=None): path = self.key return plexobjects.listItems(self.server, path, watched=watched, offset=offset, limit=limit) @@ -622,7 +674,7 @@ def episode(self, title): path = self.key return plexobjects.findItem(self.server, path, title) - def all(self): + def all(self, *args, **kwargs): return self.episodes() def show(self): @@ -637,6 +689,7 @@ def unwatched(self): @plexobjects.registerLibType class Episode(PlayableVideo, SectionOnDeckMixin): + __slots__ = ("_show", "_season") TYPE = 'episode' def init(self, data): @@ -692,6 +745,14 @@ def subtitleStreams(self): def isWatched(self): return self.get('viewCount').asInt() > 0 or self.get('viewOffset').asInt() > 0 + @property + def isFullyWatched(self): + return self.get('viewCount').asInt() > 0 and not self.get('viewOffset').asInt() + + @property + def inProgress(self): + return bool(self.get('viewOffset').asInt()) + @property def playbackSettings(self): return self.show().playbackSettings @@ -742,6 +803,10 @@ def _setData(self, data): def isWatched(self): return self.get('viewCount').asInt() > 0 or self.get('viewOffset').asInt() > 0 + @property + def isFullyWatched(self): + return self.get('viewCount').asInt() > 0 and not self.get('viewOffset').asInt() + def getStreamURL(self, **params): return self._getStreamURL(**params) diff --git a/script.plexmod/lib/_included_packages/plexnet/videosession.py b/script.plexmod/lib/_included_packages/plexnet/videosession.py index 933dac0edc..e77f993333 100644 --- a/script.plexmod/lib/_included_packages/plexnet/videosession.py +++ b/script.plexmod/lib/_included_packages/plexnet/videosession.py @@ -2,6 +2,7 @@ import six from collections import OrderedDict from plexnet import plexapp +from kodi_six import xbmc class MediaDetails: @@ -289,6 +290,24 @@ def value(self, obj): return self.resolve(self.retVal, obj) +class DPAttributeMapped(DPAttribute): + def __init__(self): + pass + + def value(self, obj): + p = xbmc.Player() + if p.isPlaying(): + f = p.getPlayingFile() + prot = f.split("://")[0] + if prot == f: + ret = "path mapped" + elif prot.startswith("http"): + ret = prot + else: + ret = "mapped ({})".format(prot) + return ret + + class ComputedPPIValue: """ Holds the final computed attribute data for display @@ -318,7 +337,8 @@ class ModePPI(ComputedPPIValue): name = "Mode" dataPoints = [ DPAttributeSession("partDecision"), - DPAttributeExists("local", source="session.player", returnValue="local") + DPAttributeExists("local", source="session.player", returnValue="local"), + DPAttributeMapped() ] diff --git a/script.plexmod/lib/_included_packages/tendo_singleton.py b/script.plexmod/lib/_included_packages/tendo_singleton.py new file mode 100644 index 0000000000..d825b93d26 --- /dev/null +++ b/script.plexmod/lib/_included_packages/tendo_singleton.py @@ -0,0 +1,102 @@ +#! /usr/bin/env python + +import logging +import os +import sys +import tempfile +from six import reraise + + +if sys.platform != "win32": + import fcntl + + +class SingleInstanceException(BaseException): + pass + + +class SingleInstance: + + """Class that can be instantiated only once per machine. + + If you want to prevent your script from running in parallel just instantiate SingleInstance() class. If is there another instance already running it will throw a `SingleInstanceException`. + + >>> import tendo + ... me = SingleInstance() + + This option is very useful if you have scripts executed by crontab at small amounts of time. + + Remember that this works by creating a lock file with a filename based on the full path to the script file. + + Providing a flavor_id will augment the filename with the provided flavor_id, allowing you to create multiple singleton instances from the same file. This is particularly useful if you want specific functions to have their own singleton instances. + """ + + def __init__(self, flavor_id="", lockfile=""): + self.initialized = False + if lockfile: + self.lockfile = lockfile + else: + basename = ( + os.path.splitext(os.path.abspath(sys.argv[0]))[0] + .replace("/", "-") + .replace(":", "") + .replace("\\", "-") + + "-%s" % flavor_id + + ".lock" + ) + self.lockfile = os.path.normpath(tempfile.gettempdir() + "/" + basename) + + logger.debug("SingleInstance lockfile: {}".format(self.lockfile)) + + def __enter__(self): + if sys.platform == "win32": + try: + # file already exists, we try to remove (in case previous + # execution was interrupted) + if os.path.exists(self.lockfile): + os.unlink(self.lockfile) + self.fd = os.open(self.lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR) + except OSError: + type, e, tb = sys.exc_info() + if e.errno == 13: + logger.error("Another instance is already running, quitting.") + raise SingleInstanceException() + print(e.errno) + raise + else: # non Windows + self.fp = open(self.lockfile, "w") + self.fp.flush() + try: + fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB) + except IOError: + logger.warning("Another instance is already running, quitting.") + raise SingleInstanceException() + self.initialized = True + return self + + def __exit__(self, exc_type, exc_value, exc_tb): + if not self.initialized: + return + if exc_value is not None: + logger.warning("Error: %s" % exc_value, exc_info=True) + try: + if sys.platform == "win32": + if hasattr(self, "fd"): + os.close(self.fd) + os.unlink(self.lockfile) + else: + fcntl.lockf(self.fp, fcntl.LOCK_UN) + # os.close(self.fp) + if os.path.isfile(self.lockfile): + os.unlink(self.lockfile) + except Exception as e: + if logger: + logger.warning(e) + else: + print("Unloggable error: {}".format(e)) + if exc_value is not None: + reraise(type(e), exc_value) + sys.exit(-1) + + +logger = logging.getLogger("tendo.singleton") diff --git a/script.plexmod/lib/actions.py b/script.plexmod/lib/actions.py new file mode 100644 index 0000000000..55f5b7fc57 --- /dev/null +++ b/script.plexmod/lib/actions.py @@ -0,0 +1,109 @@ +# coding=utf-8 +from kodi_six import xbmcgui + +KEY_VKEY = 0xF000 +KEY_UNICODE = 0xF200 + +ACTIONS = {} + +for action in dir(xbmcgui): + if action.startswith("ACTION_") or action.startswith("REMOTE_"): + ACTIONS[action] = getattr(xbmcgui, action) + +ACTIONS_REVERSED = {b: a for a, b in ACTIONS.items()} + + +# ref: https://github.com/kcsaff/getkey/blob/master/getkey/keynames.py +ASCII_NAMES = { + '\t': 'tab', + + ' ': 'space', # 0x20 + '!': 'exclamation', # 0x21 + '"': 'double quote', # 0x22 + '#': 'hash', # 0x23 + '$': 'dollar', # 0x24 + '%': 'percent', # 0x25 + '&': 'ampersand', # 0x26 + '\'': 'single quote', # 0x27 + '(': 'open paren', # 0x28 + ')': 'close paren', # 0x29 + '*': 'asterisk', # 0x2a + '+': 'plus', # 0x2b + ',': 'comma', # 0x2c + '-': 'minus', # 0x2d + '.': 'period', # 0x2e + '/': 'slash', # 0x2f + + ':': 'colon', # 0x3a + ';': 'semicolon', # 0x3b + '<': 'less than', # 0x3c + '=': 'equals', # 0x3d + '>': 'greater than', # 0x3e + '?': 'question', # 0x3f + '@': 'at', # 0x40 + + '[': 'left bracket', # 0x5b + '\\': 'backslash', # 0x5c + ']': 'right bracket', # 0x5d + '^': 'caret', # 0x5e + '_': 'underscore', # 0x5f + '`': 'backtick', # 0x60 + + '{': 'left brace', # 0x7b + '|': 'pipe', # 0x7c + '}': 'right brace', # 0x7d + '~': 'tilde', # 0x7e +} + + +# https://github.com/xbmc/xbmc/blob/master/xbmc/input/keyboard/Key.h#L64 +MODIFIERS = dict( + MODIFIER_CTRL=(0x00010000, "ctrl"), + MODIFIER_SHIFT=(0x00020000, "shift"), + MODIFIER_ALT=(0x00040000, "alt"), + MODIFIER_RALT=(0x00080000, "ralt"), + MODIFIER_SUPER=(0x00100000, "super"), + MODIFIER_META=(0X00200000, "meta"), + MODIFIER_LONG=(0X01000000, "long"), + MODIFIER_NUMLOCK=(0X02000000, "numlock"), + MODIFIER_CAPSLOCK=(0X04000000, "capslock"), + MODIFIER_SCROLLLOCK=(0X08000000, "scrolllock") +) + +MODIFIERS_REVERSED = {v[0]: k for k, v in MODIFIERS.items()} + +MODIFIER_MIN = MODIFIERS["MODIFIER_CTRL"][0] +MODIFIER_MAX = MODIFIERS["MODIFIER_SCROLLLOCK"][0] + + +class ActionKey(object): + key = None + code = None + + def __init__(self, code): + self.code = code + self.key = translate_key(code) + self.key_found = self.key != code + + @property + def name(self): + code = self.code + if KEY_VKEY < code < KEY_UNICODE: + return "Keyboard" + elif code in ACTIONS_REVERSED: + return ACTIONS_REVERSED[code] + return self.__class__.__name__ + + def __str__(self): + return "{0}: {1}".format(self.name, self.key) + + def __unicode__(self): + return str(self) + + +def translate_key(code): + if KEY_VKEY < code < KEY_UNICODE: + tcode = code - KEY_VKEY + c = chr(tcode) + return ASCII_NAMES.get(c, code) if tcode < 33 or tcode > 126 else c + return ACTIONS_REVERSED.get(code, code) diff --git a/script.plexmod/lib/advancedsettings.py b/script.plexmod/lib/advancedsettings.py new file mode 100644 index 0000000000..b4fdbd725c --- /dev/null +++ b/script.plexmod/lib/advancedsettings.py @@ -0,0 +1,42 @@ +# coding=utf-8 + +from kodi_six import xbmcvfs + +from lib.util import LOG, ERROR + + +class AdvancedSettings(object): + _data = None + + def __init__(self): + self.load() + + def __bool__(self): + return bool(self._data) + + def getData(self): + return self._data + + def load(self): + if xbmcvfs.exists("special://profile/advancedsettings.xml"): + try: + f = xbmcvfs.File("special://profile/advancedsettings.xml") + self._data = f.read() + f.close() + except: + LOG('script.plex: No advancedsettings.xml found') + + def write(self, data=None): + self._data = data = data or self._data + if not data: + return + + try: + f = xbmcvfs.File("special://profile/advancedsettings.xml", "w") + f.write(data) + f.close() + except: + ERROR("Couldn't write advancedsettings.xml") + + +adv = AdvancedSettings() diff --git a/script.plexmod/lib/aspectratio.py b/script.plexmod/lib/aspectratio.py new file mode 100644 index 0000000000..4de68c5c8f --- /dev/null +++ b/script.plexmod/lib/aspectratio.py @@ -0,0 +1,14 @@ +# coding=utf-8 + +V_AR_RATIO = None + + +def v_ar_ratio(w, h): + """ + get the vertical aspect ratio difference of w/h compared to our default resolution, 16:9/1920:1080 + """ + global V_AR_RATIO + hratio = 1080 / float(1920) + hratio2 = h / float(w) + V_AR_RATIO = hratio / hratio2 + return V_AR_RATIO diff --git a/script.plexmod/lib/backgroundthread.py b/script.plexmod/lib/backgroundthread.py index 7b69cd09d8..958d77ba57 100644 --- a/script.plexmod/lib/backgroundthread.py +++ b/script.plexmod/lib/backgroundthread.py @@ -42,6 +42,9 @@ def __le__(self, other): def __gt__(self, other): return self._priority > other._priority + def __bool__(self): + return self.isValid() + def start(self): BGThreader.addTask(self) @@ -114,7 +117,7 @@ def _queueLoop(self): if self._queue.empty(): return - util.DEBUG_LOG('BGThreader: ({0}): Active'.format(self.name)) + util.DEBUG_LOG('BGThreader: ({0}): Active', self.name) try: while not self.aborted(): self._task = self._queue.get_nowait() @@ -122,7 +125,7 @@ def _queueLoop(self): self._queue.task_done() self._task = None except six.moves.queue.Empty: - util.DEBUG_LOG('BGThreader ({0}): Idle'.format(self.name)) + util.DEBUG_LOG('BGThreader ({0}): Idle', self.name) def shutdown(self): self.abort() @@ -131,22 +134,22 @@ def shutdown(self): self._task.cancel() if self._thread and self._thread.is_alive(): - util.DEBUG_LOG('BGThreader: thread ({0}): Waiting...'.format(self.name)) + util.DEBUG_LOG('BGThreader: thread ({0}): Waiting...', self.name) self._thread.join() - util.DEBUG_LOG('BGThreader: thread ({0}): Done'.format(self.name)) + util.DEBUG_LOG('BGThreader: thread ({0}): Done', self.name) def working(self): return self._thread and self._thread.is_alive() def kill(self): if self._thread and self._thread.is_alive(): - util.DEBUG_LOG('BGThreader: thread ({0}): Waiting...'.format(self.name)) + util.DEBUG_LOG('BGThreader: thread ({0}): Waiting...', self.name) self._thread.join() - util.DEBUG_LOG('BGThreader: thread ({0}): Done'.format(self.name)) + util.DEBUG_LOG('BGThreader: thread ({0}): Done', self.name) class BackgroundThreader: - def __init__(self, name=None, worker_count=3): + def __init__(self, name=None, worker_count=5): self.name = name self._queue = MutablePriorityQueue() self._abort = False @@ -227,10 +230,10 @@ def kill(self): class ThreaderManager: - def __init__(self): + def __init__(self, worker_count=5): self.index = 0 self.abandoned = [] - self.threader = BackgroundThreader(str(self.index)) + self.threader = BackgroundThreader(str(self.index), worker_count=worker_count) def __getattr__(self, name): return getattr(self.threader, name) @@ -252,4 +255,4 @@ def kill(self): self.threader.kill() -BGThreader = ThreaderManager() +BGThreader = ThreaderManager(worker_count=util.getSetting('worker_count', 5)) diff --git a/script.plexmod/lib/cache.py b/script.plexmod/lib/cache.py new file mode 100644 index 0000000000..d488c88934 --- /dev/null +++ b/script.plexmod/lib/cache.py @@ -0,0 +1,176 @@ +# coding=utf-8 +import os +import re + +from kodi_six import xbmc +from kodi_six import xbmcvfs + +from plexnet import plexapp + +from lib.kodijsonrpc import rpc +from lib.util import ADDON, translatePath, KODI_BUILD_NUMBER, DEBUG_LOG, LOG, FROM_KODI_REPOSITORY +from lib.advancedsettings import adv + + +ADV_MSIZE_RE = re.compile(r'<memorysize>(\d+)</memorysize>') +ADV_RFACT_RE = re.compile(r'<readfactor>(\d+)</readfactor>') +ADV_CACHE_RE = re.compile(r'\s*<cache>.*</cache>', re.S | re.I) + + +class KodiCacheManager(object): + """ + A pretty cheap approach at managing the <cache> section of advancedsettings.xml + + Starting with build 20.90.821 (Kodi 21.0-BETA2) a lot of caching issues have been fixed and + readfactor behaves better. We need to adjust for that. + """ + useModernAPI = False + memorySize = 20 # in MB + readFactor = 4 + defRF = 4 + defRFSM = 20 + recRFRange = "4-10" + template = None + orig_tpl_path = os.path.join(ADDON.getAddonInfo('path'), "pm4k_cache_template.xml") + custom_tpl_path = "special://profile/pm4k_cache_template.xml" + translated_ctpl_path = translatePath(custom_tpl_path) + + # give Android a little more leeway with its sometimes weird memory management; otherwise stick with 23% of free mem + safeFactor = .20 if xbmc.getCondVisibility('System.Platform.Android') else .23 + + def __init__(self): + if KODI_BUILD_NUMBER >= 2090821: + self.memorySize = rpc.Settings.GetSettingValue(setting='filecache.memorysize')['value'] + self.readFactor = rpc.Settings.GetSettingValue(setting='filecache.readfactor')['value'] / 100.0 + if self.readFactor % 1 == 0: + self.readFactor = int(self.readFactor) + DEBUG_LOG("Not using advancedsettings.xml for cache/buffer management, we're at least Kodi 21 non-alpha") + self.useModernAPI = True + self.defRFSM = 7 + self.recRFRange = "1.5-4" + + if KODI_BUILD_NUMBER >= 2090830: + self.recRFRange = ADDON.getLocalizedString(32976) + + else: + self.load() + self.template = self.getTemplate() + + plexapp.util.APP.on('change:slow_connection', + lambda value=None, **kwargs: self.write(readFactor=value and self.defRFSM or self.defRF)) + + def getTemplate(self): + if xbmcvfs.exists(self.custom_tpl_path): + try: + f = xbmcvfs.File(self.custom_tpl_path) + data = f.read() + f.close() + if data: + return data + except: + pass + + DEBUG_LOG("Custom pm4k_cache_template.xml not found, using default") + f = xbmcvfs.File(self.orig_tpl_path) + data = f.read() + f.close() + return data + + def load(self): + data = adv.getData() + if not data: + return + + cachexml_match = ADV_CACHE_RE.search(data) + if cachexml_match: + cachexml = cachexml_match.group(0) + + try: + self.memorySize = int(ADV_MSIZE_RE.search(cachexml).group(1)) // 1024 // 1024 + except: + DEBUG_LOG("script.plex: invalid or not found memorysize in advancedsettings.xml") + + try: + self.readFactor = int(ADV_RFACT_RE.search(cachexml).group(1)) + except: + DEBUG_LOG("script.plex: invalid or not found readfactor in advancedsettings.xml") + + # self._cleanData = data.replace(cachexml, "") + #else: + # self._cleanData = data + + def write(self, memorySize=None, readFactor=None): + # never write to advancedSettings when we're installed from the Kodi repository and don't have the modern API + if FROM_KODI_REPOSITORY and not self.useModernAPI: + return + + memorySize = self.memorySize = memorySize if memorySize is not None else self.memorySize + readFactor = self.readFactor = readFactor if readFactor is not None else self.readFactor + + if self.useModernAPI: + # kodi cache settings have moved to Services>Caching + try: + rpc.Settings.SetSettingValue(setting='filecache.memorysize', value=self.memorySize) + rpc.Settings.SetSettingValue(setting='filecache.readfactor', value=int(self.readFactor * 100)) + except: + pass + return + + data = adv.getData() + cd = "<advancedsettings>\n</advancedsettings>" + if data: + cachexml_match = ADV_CACHE_RE.search(data) + if cachexml_match: + cachexml = cachexml_match.group(0) + cd = data.replace(cachexml, "") + else: + cd = data + + finalxml = "{}\n</advancedsettings>".format( + cd.replace("</advancedsettings>", self.template.format(memorysize=memorySize * 1024 * 1024, + readfactor=readFactor)) + ) + + adv.write(finalxml) + + def clamp16(self, x): + return x - x % 16 + + @property + def viableOptions(self): + default = list(filter(lambda x: x < self.recMax, + [16, 20, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024])) + + # add option to overcommit slightly + overcommit = [] + if xbmc.getCondVisibility('System.Platform.Android'): + overcommit.append(min(self.clamp16(int(self.free * 0.23)), 2048)) + + overcommit.append(min(self.clamp16(int(self.free * 0.26)), 2048)) + overcommit.append(min(self.clamp16(int(self.free * 0.3)), 2048)) + + # re-append current memorySize here, as recommended max might have changed + return list(sorted(list(set(default + [self.memorySize, self.recMax] + overcommit)))) + + @property + def readFactorOpts(self): + ret = list(sorted(list(set([1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5, 7, 10, 15, 20, 30, 50] + [self.readFactor])))) + if KODI_BUILD_NUMBER >= 2090830 and self.readFactor > 0: + # support for adaptive read factor from build 2090822 onwards + ret.insert(0, 0) + return ret + + @property + def free(self): + return float(xbmc.getInfoLabel('System.Memory(free)')[:-2]) + + @property + def recMax(self): + freeMem = self.free + recMem = min(int(freeMem * self.safeFactor), 2048) + LOG("Free memory: {} MB, recommended max: {} MB".format(freeMem, recMem)) + return recMem + + +kcm = KodiCacheManager() +CACHE_SIZE = kcm.memorySize diff --git a/script.plexmod/lib/data_cache.py b/script.plexmod/lib/data_cache.py new file mode 100644 index 0000000000..9766cbdea6 --- /dev/null +++ b/script.plexmod/lib/data_cache.py @@ -0,0 +1,121 @@ +# coding=utf-8 + +import os +import json +import time +import copy +import zlib + +from kodi_six import xbmcvfs + +from plexnet import plexapp + +from . util import translatePath, ADDON, ERROR, DEBUG_LOG, LOG + + +class DataCacheManager(object): + # store arbitrary data in JSON on disk + DATA_CACHES_VERSION = 2 + DATA_CACHES = { + "general": {}, + "cache": {} + } + DC_LAST_UPDATE = None + DC_PATH = os.path.join(translatePath(ADDON.getAddonInfo("profile")), "data_cache.json") + DC_LRU_TIMEOUT = 30 + DC_LRUP_TIMEOUT = 90 + USE_GZ = False + + def __init__(self): + self._currentServerUUID = None + plexapp.util.APP.on('change:selectedServer', self.setServerUUID) + if self.USE_GZ: + self.DC_PATH += "z" + if xbmcvfs.exists(self.DC_PATH): + try: + f = xbmcvfs.File(self.DC_PATH) + d = f.readBytes() if self.USE_GZ else f.read() + f.close() + + tdc = json.loads(zlib.decompress(d).decode("utf-8") if self.USE_GZ else d) + old_ver = tdc["general"].get("version", 0) + if old_ver < self.DATA_CACHES_VERSION: + # this is where we migrate + if old_ver == 1: + tdc = self.DATA_CACHES.copy() + tdc["general"]["version"] = self.DATA_CACHES_VERSION + tdc["general"]["updated"] = time.time() + self.DATA_CACHES = tdc + self.storeDataCache() + else: + tdc["general"]["version"] = self.DATA_CACHES_VERSION + self.DATA_CACHES.update(tdc) + self.dataCacheCleanup() + self.DC_LAST_UPDATE = self.DATA_CACHES["general"]["updated"] + except: + ERROR("Couldn't read data_cache.json") + self.DATA_CACHES["general"]["updated"] = time.time() + self.storeDataCache() + + def deinit(self): + plexapp.util.APP.off('change:selectedServer', self.setServerUUID) + + def getCacheData(self, context, identifier): + ret = self.DATA_CACHES["cache"].get(self._currentServerUUID, {}).get(context, {}).get(identifier, {}) + if "data" in ret and ret["data"]: + # purge old data (> X days last updated) + if ret["updated"] < time.time() - self.DC_LRUP_TIMEOUT * 3600 * 24: + del self.DATA_CACHES["cache"][self._currentServerUUID][context][identifier] + return None + + self.DATA_CACHES["cache"][self._currentServerUUID][context][identifier]["last_access"] = time.time() + return ret["data"] + + def setCacheData(self, context, identifier, value): + if self._currentServerUUID not in self.DATA_CACHES["cache"]: + self.DATA_CACHES["cache"][self._currentServerUUID] = {} + if context not in self.DATA_CACHES["cache"][self._currentServerUUID]: + self.DATA_CACHES["cache"][self._currentServerUUID][context] = {} + if identifier not in self.DATA_CACHES["cache"][self._currentServerUUID][context]: + self.DATA_CACHES["cache"][self._currentServerUUID][context][identifier] = {} + t = time.time() + self.DATA_CACHES["general"]["updated"] = t + self.DATA_CACHES["cache"][self._currentServerUUID][context][identifier] = { + "updated": t, + "last_access": t, + "data": value + } + + def setServerUUID(self, server=None, **kwargs): + if not server and not plexapp.SERVERMANAGER.selectedServer: + return + self._currentServerUUID = (server if server is not None else plexapp.SERVERMANAGER.selectedServer).uuid[-8:] + + def dataCacheCleanup(self): + d = copy.deepcopy(self.DATA_CACHES) + t = time.time() + for k, contexts in d["cache"].items(): + for context, identifiers in contexts.items(): + for identifier, iddata in identifiers.items(): + # clean up anything not accessed during the last X days + if iddata["last_access"] < t - self.DC_LRU_TIMEOUT * 3600 * 24: + DEBUG_LOG("Clearing cached data for: {}: {}".format(context, identifier)) + del self.DATA_CACHES["cache"][k][context][identifier] + + def storeDataCache(self): + lu = self.DATA_CACHES["general"].get("updated") + if self.DATA_CACHES and lu and self.DC_LAST_UPDATE != lu: + try: + dcf = xbmcvfs.File(self.DC_PATH, "w") + self.dataCacheCleanup() + d = json.dumps(self.DATA_CACHES) + if self.USE_GZ: + d = zlib.compress(d.encode("utf-8")) + dcf.write(d) + dcf.close() + LOG("Data cache written to: addon_data/script.plexmod/data_cache.json") + except: + ERROR("Couldn't write data_cache.json") + + +dcm = DataCacheManager() diff --git a/script.plexmod/lib/genres.py b/script.plexmod/lib/genres.py new file mode 100644 index 0000000000..ef1be9bf29 --- /dev/null +++ b/script.plexmod/lib/genres.py @@ -0,0 +1,41 @@ +# coding=utf-8 + +GENRES_TV = { + "Action": ["Action", "Action & Adventure"], + "Adventure": ["Adventure"], + "Animation": ["Animation"], + "Anime": ["Anime"], + "Awards Show": ["Awards Show"], + "Children": ["Children"], + "Comedy": ["Comedy"], + "Crime": ["Crime"], + "Documentary": ["Documentary"], + "Drama": ["Drama"], + "Family": ["Family"], + "Fantasy": ["Fantasy"], + "Food": ["Food"], + "Game Show": ["Game Show"], + "History": ["History"], + "Home and Garden": ["Home and Garden"], + "Horror": ["Horror"], + "Indie": ["Indie"], + "Martial Arts": ["Martial Arts"], + "Mini-Series": ["Mini-Series"], + "Musical": ["Musical"], + "Mystery": ["Mystery"], + "News": ["News"], + "Podcast": ["Podcast"], + "Reality": ["Reality"], + "Romance": ["Romance"], + "Science Fiction": ["Science Fiction", "Science-Fiction", "Sci-Fi", "Sci-Fi & Fantasy"], + "Soap": ["Soap"], + "Sport": ["Sport"], + "Suspense": ["Suspense"], + "Talk Show": ["Talk Show"], + "Thriller": ["Thriller"], + "Travel": ["Travel"], + "War": ["War", "War & Politics"], + "Western": ["Western"], +} + +GENRES_TV_BY_SYN = {v: k for k, values in GENRES_TV.items() for v in values} diff --git a/script.plexmod/lib/i18n.py b/script.plexmod/lib/i18n.py new file mode 100644 index 0000000000..ee7288b6d4 --- /dev/null +++ b/script.plexmod/lib/i18n.py @@ -0,0 +1,9 @@ +# coding=utf-8 +from kodi_six import xbmcaddon + + +ADDON = xbmcaddon.Addon() + + +def T(ID, eng=''): + return ADDON.getLocalizedString(ID) diff --git a/script.plexmod/lib/kodi_util.py b/script.plexmod/lib/kodi_util.py new file mode 100644 index 0000000000..1875f9fcb8 --- /dev/null +++ b/script.plexmod/lib/kodi_util.py @@ -0,0 +1,69 @@ +# coding=utf-8 + +from kodi_six import xbmc, xbmcgui, xbmcvfs + + +_build = None +# buildversion looks like: XX.X[-TAG] (a+.b+.c+) (.+); there are kodi builds that don't set the build version +sys_ver = xbmc.getInfoLabel('System.BuildVersion') +_ver = sys_ver + +try: + if ' ' in sys_ver and '(' in sys_ver: + _ver, _build = sys_ver.split()[:2] + + _splitver = _ver.split(".") + KODI_VERSION_MAJOR, KODI_VERSION_MINOR = int(_splitver[0].split("-")[0].strip()), \ + int(_splitver[1].split(" ")[0].split("-")[0].strip()) +except: + xbmc.log('script.plex: Couldn\'t determine Kodi version, assuming 19.4. Got: {}'.format(sys_ver)) + # assume something "old" + KODI_VERSION_MAJOR = 19 + KODI_VERSION_MINOR = 4 + +_bmajor, _bminor, _bpatch = (KODI_VERSION_MAJOR, KODI_VERSION_MINOR, 0) +parsedBuild = False +if _build: + try: + _bmajor, _bminor, _bpatch = _build[1:-1].split(".") + parsedBuild = True + except: + pass +if not parsedBuild: + xbmc.log('script.plex: Couldn\'t determine build version, falling back to Kodi version', xbmc.LOGINFO) + +# calculate a comparable build number +KODI_BUILD_NUMBER = int("{0}{1:02d}{2:03d}".format(_bmajor, int(_bminor), int(_bpatch))) + + +if KODI_VERSION_MAJOR > 18: + translatePath = xbmcvfs.translatePath +else: + translatePath = xbmc.translatePath + + +def setGlobalProperty(key, val, base='script.plex.{0}'): + xbmcgui.Window(10000).setProperty(base.format(key), val) + + +def setGlobalBoolProperty(key, boolean, base='script.plex.{0}'): + xbmcgui.Window(10000).setProperty(base.format(key), boolean and '1' or '') + + +def getGlobalProperty(key): + return xbmc.getInfoLabel('Window(10000).Property(script.plex.{0})'.format(key)) + + +def ensureHome(): + if xbmcgui.getCurrentWindowId() != 10000: + xbmc.log("Switching to home screen before starting addon: {}".format(xbmcgui.getCurrentWindowId()), + xbmc.LOGINFO) + xbmc.executebuiltin('Action(back)') + xbmc.executebuiltin('Dialog.Close(all,1)') + xbmc.executebuiltin('ActivateWindow(home)') + ct = 0 + while xbmcgui.getCurrentWindowId() != 10000 and ct <= 50: + xbmc.Monitor().waitForAbort(0.1) + ct += 1 + if ct > 50: + xbmc.log("Still active window: {}", xbmc.LOGINFO) diff --git a/script.plexmod/lib/logging.py b/script.plexmod/lib/logging.py new file mode 100644 index 0000000000..829f1436e3 --- /dev/null +++ b/script.plexmod/lib/logging.py @@ -0,0 +1,34 @@ +# coding=utf-8 +import sys +import traceback +import types + +from kodi_six import xbmc + + +def log(msg, *args, **kwargs): + if args: + # resolve dynamic args + msg = msg.format(*[arg() if isinstance(arg, types.FunctionType) else arg for arg in args]) + + level = kwargs.pop("level", xbmc.LOGINFO) + + if kwargs: + # resolve dynamic kwargs + msg = msg.format(**dict((k, v()) if isinstance(v, types.FunctionType) else v for k, v in kwargs.items())) + xbmc.log('script.plex: {0}'.format(msg), level) + + +def log_error(txt='', hide_tb=False): + short = str(sys.exc_info()[1]) + if hide_tb: + xbmc.log('script.plex: ERROR: {0} - {1}'.format(txt, short), xbmc.LOGERROR) + return short + + tb = traceback.format_exc() + xbmc.log("_________________________________________________________________________________", xbmc.LOGERROR) + xbmc.log('script.plex: ERROR: ' + txt, xbmc.LOGERROR) + for l in tb.splitlines(): + xbmc.log(' ' + l, xbmc.LOGERROR) + xbmc.log("_________________________________________________________________________________", xbmc.LOGERROR) + xbmc.log("`", xbmc.LOGERROR) diff --git a/script.plexmod/lib/main.py b/script.plexmod/lib/main.py index 88c347111f..9b0e10a503 100644 --- a/script.plexmod/lib/main.py +++ b/script.plexmod/lib/main.py @@ -1,27 +1,32 @@ +# coding=utf-8 from __future__ import absolute_import -from kodi_six import xbmc - -if xbmc.getInfoLabel('Window(10000).Property(script.plex.running)') == "1": - xbmc.executebuiltin('NotifyAll({0},{1},{2})'.format('script.plexmod', 'RESTORE', '{}')) - raise SystemExit import gc import atexit import threading import six import sys + +from kodi_six import xbmc + +#import cProfile, pstats, io +#from pstats import SortKey + sys.modules['_asyncio'] = None from . import plex from plexnet import plexapp -from .windows import background, userselect, home, windowutils +from .templating import render_templates +from .windows import background, userselect, home, windowutils, kodigui from . import player from . import backgroundthread from . import util +from .data_cache import dcm BACKGROUND = None quitKodi = False +restart = False if six.PY2: @@ -36,12 +41,12 @@ def waitForThreads(): for t in threading.enumerate(): if t != threading.currentThread(): if t.is_alive(): - util.DEBUG_LOG('Main: Waiting on: {0}...'.format(t.name)) + util.DEBUG_LOG('Main: Waiting on: {0}...', t.name) if isinstance(t, _Timer): t.cancel() try: - t.join() + t.join(.25) except: util.ERROR() @@ -53,6 +58,9 @@ def realExit(): xbmc.log('Main: script.plex: QUITTING KODI', xbmc.LOGINFO) xbmc.executebuiltin('Quit') + elif restart: + xbmc.executebuiltin('RunScript(script.plexmod)') + def signout(): util.setSetting('auth.token', '') @@ -60,46 +68,68 @@ def signout(): plexapp.ACCOUNT.signOut() -def main(): +def main(force_render=False): global BACKGROUND - util.ensureHome() try: - with util.Cron(0.1): + with kodigui.GlobalProperty('rendering'): + render_templates(force=force_render) + + with util.Cron(1 / util.addonSettings.tickrate): BACKGROUND = background.BackgroundWindow.create(function=_main) if BACKGROUND.waitForOpen(): - util.setGlobalProperty('running', '1') - BACKGROUND.modal() - del BACKGROUND + with kodigui.GlobalProperty('running'): + BACKGROUND.modal() + + # we've had an XMLError during modalizing, rebuild templates + if BACKGROUND._errored: + return main(force_render=True) + del BACKGROUND else: util.LOG("Couldn't start main loop, exiting.") finally: try: - util.setGlobalProperty('running', '') - util.setGlobalProperty('stop_running', '') + util.setGlobalProperty('ignore_spinner', '') + util.setGlobalProperty('is_active', '') except: pass def _main(): - global quitKodi - util.DEBUG_LOG('[ STARTED: {0} -------------------------------------------------------------------- ]'.format(util.ADDON.getAddonInfo('version'))) - util.DEBUG_LOG('USER-AGENT: {0}'.format(plex.defaultUserAgent())) + global quitKodi, restart + + # uncomment to profile code #1 + #pr = cProfile.Profile() + #pr.enable() + + util.DEBUG_LOG('[ STARTED: {0} -------------------------------------------------------------------- ]', util.ADDON.getAddonInfo('version')) + if util.KODI_VERSION_MAJOR > 19 and util.DEBUG and util.getSetting('dump_config', False): + lv = len(util.ADDON.getAddonInfo('version')) + util.DEBUG_LOG('[ SETTINGS DUMP {0}-------------------------------------------------------------------- ' + ']', (lv - 4)*'-') + util.dumpSettings() + util.DEBUG_LOG('[ /SETTINGS DUMP {0}------------------------------------------------------------------- ' + ']', (lv - 3) * '-') + + util.DEBUG_LOG('USER-AGENT: {0}', lambda: plex.defaultUserAgent()) + util.DEBUG_LOG('Aspect ratio: {:.2f} (default: {:.2f}), needs scaling: {}', util.CURRENT_AR, 1920 / 1080, + util.NEEDS_SCALING) background.setSplash() + util.setGlobalProperty('is_active', '1') try: - while not util.MONITOR.abortRequested() and not util.getGlobalProperty('stop_running'): + while not util.MONITOR.abortRequested(): if plex.init(): background.setSplash(False) fromSwitch = False - while not util.MONITOR.abortRequested() and not util.getGlobalProperty('stop_running'): + while not util.MONITOR.abortRequested(): if ( not plexapp.ACCOUNT.isOffline and not plexapp.ACCOUNT.isAuthenticated and (len(plexapp.ACCOUNT.homeUsers) > 1 or plexapp.ACCOUNT.isProtected) ): - result = userselect.start() + result = userselect.start(BACKGROUND._winID) if not result: return elif result == 'signout': @@ -110,7 +140,8 @@ def _main(): elif result == 'cancel' and fromSwitch: util.DEBUG_LOG('Main: User selection canceled, reusing previous user') plexapp.ACCOUNT.isAuthenticated = True - + elif result == 'cancel': + return if not fromSwitch: util.DEBUG_LOG('Main: User selected') @@ -124,7 +155,8 @@ def _main(): for timeout, skip_preferred, skip_owned in ((10, False, False), (10, True, True)): plex.CallbackEvent(plexapp.util.APP, 'change:selectedServer', timeout=timeout).wait() - selectedServer = plexapp.SERVERMANAGER.checkSelectedServerSearch(skip_preferred=skip_preferred, skip_owned=skip_owned) + selectedServer = plexapp.SERVERMANAGER.checkSelectedServerSearch( + skip_preferred=skip_preferred, skip_owned=skip_owned) if selectedServer: break else: @@ -132,10 +164,10 @@ def _main(): finally: background.setBusy(False) - util.DEBUG_LOG('Main: STARTING WITH SERVER: {0}'.format(selectedServer)) + util.DEBUG_LOG('Main: STARTING WITH SERVER: {0}', selectedServer) windowutils.HOME = home.HomeWindow.create() - if windowutils.HOME.waitForOpen(): + if windowutils.HOME.waitForOpen(base_win_id=BACKGROUND._winID): windowutils.HOME.modal() else: util.LOG("Couldn't open home window, exiting") @@ -157,6 +189,14 @@ def _main(): elif closeOption == 'switch': plexapp.ACCOUNT.isAuthenticated = False fromSwitch = True + elif closeOption == 'recompile': + render_templates(force=True) + util.LOG("Restarting Home") + continue + elif closeOption == 'restart': + util.LOG("Restarting Addon") + restart = True + return finally: windowutils.shutdownHome() BACKGROUND.activate() @@ -168,6 +208,9 @@ def _main(): util.ERROR() finally: util.DEBUG_LOG('Main: SHUTTING DOWN...') + dcm.storeDataCache() + dcm.deinit() + plexapp.util.INTERFACE.playbackManager.deinit() background.setShutdown() player.shutdown() plexapp.util.APP.preShutdown() @@ -179,11 +222,17 @@ def _main(): background.setSplash(False) background.killMonitor() + # uncomment to profile code #2 + #pr.disable() + #sortby = SortKey.CUMULATIVE + #s = io.StringIO() + #ps = pstats.Stats(pr, stream=s).sort_stats(sortby) + #ps.print_stats() + #util.DEBUG_LOG(s.getvalue()) + util.DEBUG_LOG('FINISHED') util.shutdown() - gc.collect(2) - if util.KODI_VERSION_MAJOR == 18 and quitKodi: - xbmc.log('Main: script.plex: QUITTING KODI', xbmc.LOGINFO) - xbmc.executebuiltin('Quit') + if util.KODI_VERSION_MAJOR == 18: + realExit() diff --git a/script.plexmod/lib/os_utils.py b/script.plexmod/lib/os_utils.py new file mode 100644 index 0000000000..3a582c3c9f --- /dev/null +++ b/script.plexmod/lib/os_utils.py @@ -0,0 +1,18 @@ +# coding=utf-8 +import os +import fnmatch + + +def fast_glob(pathname): + return list(fast_iglob(pathname)) + + +def fast_iglob(pathname): + """ + Minimal glob on Kodi>18 (os.walk now uses scandir on Python3.5+) + """ + dirname, basename = os.path.split(pathname) + for _, _, files in os.walk(dirname): + for f in files: + if fnmatch.fnmatch(f, basename): + yield f diff --git a/script.plexmod/lib/path_mapping.py b/script.plexmod/lib/path_mapping.py new file mode 100644 index 0000000000..e6fe30919a --- /dev/null +++ b/script.plexmod/lib/path_mapping.py @@ -0,0 +1,123 @@ +# coding=utf-8 + +import os +import copy +import re +import json + +import plexnet.util + +from kodi_six import xbmcvfs + +from .util import translatePath, ADDON, ERROR, LOG, getSetting + + +PM_MCMT_RE = re.compile(r'/\*.+\*/\s?', re.IGNORECASE | re.MULTILINE | re.DOTALL) +PM_CMT_RE = re.compile(r'[\t ]+//.+\n?') +PM_COMMA_RE = re.compile(r',\s*}\s*}') + + +def norm_sep(s): + return "\\" in s and "\\" or "/" + + +class PathMappingManager(object): + mapfile = os.path.join(translatePath(ADDON.getAddonInfo("profile")), "path_mapping.json") + PATH_MAP = {} + + def __init__(self): + self.load() + + def load(self): + if xbmcvfs.exists(self.mapfile): + try: + f = xbmcvfs.File(self.mapfile) + # sanitize json + + # remove multiline comments + data = PM_MCMT_RE.sub("", f.read()) + # remove comments + data = PM_CMT_RE.sub("", data) + # remove invalid trailing comma + + data = PM_COMMA_RE.sub("}}", data) + self.PATH_MAP = json.loads(data) + f.close() + except: + ERROR("Couldn't read path_mapping.json") + else: + LOG("Path mapping: {}".format(repr(self.PATH_MAP))) + + @property + def mapping(self): + return self.PATH_MAP and getSetting("path_mapping", True) + + def getMappedPathFor(self, path, server): + if self.mapping: + match = ("", "") + + for map_path, pms_path in self.PATH_MAP.get(server.name, {}).items(): + # the longest matching path wins + if path.startswith(pms_path) and len(pms_path) > len(match[1]): + match = (map_path, pms_path) + + if all(match): + map_path, pms_path = match + return map_path, pms_path + return None, None + + def deletePathMapping(self, target, server=None, save=True): + server = server or plexnet.util.SERVERMANAGER.selectedServer + if not server: + ERROR("Delete path mapping: Something went wrong") + return + + if server.name not in self.PATH_MAP: + return + + pm = copy.deepcopy(self.PATH_MAP) + + deleted = None + for s, t in pm[server.name].items(): + if target == t: + deleted = s + del self.PATH_MAP[server.name][s] + break + if save and deleted and self.save(): + LOG("Path mapping stored after deletion of {}:{}".format(deleted, target)) + + def addPathMapping(self, source, target, server=None, save=True): + server = server or plexnet.util.SERVERMANAGER.selectedServer + if not server: + ERROR("Add path mapping: Something went wrong") + return + + if server.name not in self.PATH_MAP: + self.PATH_MAP[server.name] = {} + + sep = norm_sep(source) + + if not source.endswith(sep): + source += sep + + sep = norm_sep(target) + + if not target.endswith(sep): + target += sep + + self.PATH_MAP[server.name][source] = target + if save and self.save(): + LOG("Path mapping stored for {}:{}".format(source, target)) + + def save(self): + try: + f = xbmcvfs.File(self.mapfile, "w") + f.write(json.dumps(self.PATH_MAP)) + f.close() + except: + ERROR("Couldn't write path_mapping.json") + else: + return True + + +pmm = PathMappingManager() diff --git a/script.plexmod/lib/playback_utils.py b/script.plexmod/lib/playback_utils.py index 86b20a4b33..34dd29052d 100644 --- a/script.plexmod/lib/playback_utils.py +++ b/script.plexmod/lib/playback_utils.py @@ -59,14 +59,21 @@ def __init__(self): plexapp.util.APP.on('change:{}'.format(v), lambda **kwargs: self.setGlob(**kwargs)) plexapp.util.APP.on('change:selectedServer', lambda **kwargs: self.setServerUUID(**kwargs)) + plexapp.util.APP.on("loaded:cached_user", lambda **kwargs: self.setUserID(**kwargs)) plexapp.util.APP.on("change:user", lambda **kwargs: self.setUserID(**kwargs)) plexapp.util.APP.on('init', lambda **kwargs: self.setUserID(**kwargs)) + def deinit(self): + plexapp.util.APP.off('change:selectedServer', lambda **kwargs: self.setServerUUID(**kwargs)) + plexapp.util.APP.off("loaded:cached_user", lambda **kwargs: self.setUserID(**kwargs)) + plexapp.util.APP.off("change:user", lambda **kwargs: self.setUserID(**kwargs)) + plexapp.util.APP.off('init', lambda **kwargs: self.setUserID(**kwargs)) + def __call__(self, obj, key=None, value=None, kv_dict=None): # shouldn't happen - if not self._currentServerUUID or not self._currentUserID: - util.DEBUG_LOG("APP.PlaybackManager, something's wrong: ServerUUID: %s, UserID: %s" % ( - self._currentServerUUID, self._currentUserID)) + if not self._currentServerUUID: + util.DEBUG_LOG("APP.PlaybackManager, something's wrong: ServerUUID: {}, UserID: {}", + self._currentServerUUID, self._currentUserID) return csid = self._currentServerUUID @@ -158,7 +165,7 @@ def load(self): if hasattr(self, migFunc): migResult, data = getattr(self, migFunc)(data) if migResult: - util.DEBUG_LOG("Migrated playback_settings.json to format v{}".format(v)) + util.DEBUG_LOG("Migrated playback_settings.json to format v{}", v) migratedAny = True if migratedAny: self.save(data=data) diff --git a/script.plexmod/lib/player.py b/script.plexmod/lib/player.py index b2dd54bb56..a4011fcd89 100644 --- a/script.plexmod/lib/player.py +++ b/script.plexmod/lib/player.py @@ -1,5 +1,6 @@ from __future__ import absolute_import import base64 +import json import threading import six import re @@ -11,7 +12,7 @@ from . import backgroundthread from . import kodijsonrpc from . import colors -from .windows import seekdialog +from .windows import seekdialog, windowutils from . import util from plexnet import plexplayer from plexnet import plexapp @@ -28,8 +29,8 @@ def __init__(self, player, session_id=None): self.media = None self.baseOffset = 0 self._lastDuration = 0 + self._progressHld = {} self.timelineType = None - self.lastTimelineState = None self.ignoreTimelines = False self.queuingNext = False self.playQueue = None @@ -117,10 +118,7 @@ def currentDuration(self): return self._lastDuration - def updateNowPlaying(self, force=False, refreshQueue=False, t=None, state=None, overrideChecks=False): - util.DEBUG_LOG("UpdateNowPlaying: force: {0} refreshQueue: " - "{1} state: {2} overrideChecks: {3} time: {4}".format(force, refreshQueue, state, overrideChecks, - t)) + def updateNowPlaying(self, refreshQueue=False, t=None, state=None, overrideChecks=False): if self.ignoreTimelines: util.DEBUG_LOG("UpdateNowPlaying: ignoring timeline as requested") return @@ -132,14 +130,27 @@ def updateNowPlaying(self, force=False, refreshQueue=False, t=None, state=None, if not self.shouldSendTimeline(item): return + util.DEBUG_LOG("UpdateNowPlaying: {0}, refreshQueue: {1} state: {2} (player: {5}) " + "overrideChecks: {3} time: {4} (player: {6})" + .format(item.ratingKey, + refreshQueue, + state, + overrideChecks, + t, + self.player.playState, + self.player.getTime() if self.player.isPlayingVideo() else "N/A")) + state = state or self.player.playState - # Avoid duplicates - if state == self.lastTimelineState and not force: - return - self.lastTimelineState = state - # self.timelineTimer.reset() + obj = item.choice + # Ignore sending timelines for multi part media with no duration + if obj and obj.part and obj.part.duration.asInt() == 0 and obj.media.parts and len(obj.media.parts) > 1: + util.LOG("Timeline not supported: the current part doesn't have a valid duration") + return + + # if we've been called explicitly with a time, honor + force_time = t is not None _time = t or int(self.trueTime * 1000) # self.trigger("progress", [m, item, time]) @@ -147,11 +158,25 @@ def updateNowPlaying(self, force=False, refreshQueue=False, t=None, state=None, if refreshQueue and self.playQueue: self.playQueue.refreshOnTimeline = True - plexapp.util.APP.nowplayingmanager.updatePlaybackState( - self.timelineType, self.player.playerObject, state, _time, self.playQueue, duration=self.currentDuration(), - force=overrideChecks + data = plexnetUtil.AttributeDict({ + "key": str(item.key), + "ratingKey": str(item.ratingKey), + "guid": str(item.guid), + "url": str(item.url), + "duration": item.duration.asInt(), + "containerKey": str(item.container.address) + }) + + new_time_stored = plexapp.util.APP.nowplayingmanager.updatePlaybackState( + self.timelineType, data, state, _time, self.playQueue, duration=self.currentDuration(), + force=overrideChecks, force_time=force_time ) + if new_time_stored: + # only update our immediate progress if we should (e.g. if updatePlaybackState reported a new time based + # on _time + self._progressHld[str(item.ratingKey)] = _time + def getVolume(self): return util.rpc.Application.GetProperties(properties=["volume"])["volume"] @@ -180,12 +205,14 @@ def __init__(self, player, session_id=None): self.title = '' self.title2 = '' self.seekOnStart = 0 + self.waitingForSOS = False self.chapters = None self.stoppedManually = False self.inBingeMode = False self.skipPostPlay = False self.prePlayWitnessed = False self.queuingNext = False + self.useAlternateSeek = util.isCoreELEC self.reset() def reset(self): @@ -194,7 +221,9 @@ def reset(self): self.baseOffset = 0 self.seeking = self.NO_SEEK self.seekOnStart = 0 + self.waitingForSOS = False self._lastDuration = 0 + self._progressHld = {} self.mode = self.MODE_RELATIVE self.ended = False self.stoppedManually = False @@ -207,6 +236,7 @@ def setup(self, duration, meta, offset, bif_url, title='', title2='', seeking=NO self.seeking = seeking self.duration = duration self._lastDuration = duration + self._progressHld = {} self.bifURL = bif_url self.title = title self.title2 = title2 @@ -249,14 +279,17 @@ def trueTime(self): return self.player.currentTime + self.player.playerObject.startOffset def shouldShowPostPlay(self): + if util.getUserSetting('post_play_never', False): + return False + if self.playlist and self.playlist.TYPE == 'playlist': return False if not self.stoppedManually and self.skipPostPlay: return False - if (not util.advancedSettings.postplayAlways and self._lastDuration <= FIVE_MINUTES_MILLIS)\ - or util.advancedSettings.postplayTimeout <= 0: + if (not util.addonSettings.postplayAlways and self._lastDuration <= FIVE_MINUTES_MILLIS)\ + or util.addonSettings.postplayTimeout <= 0: return False return True @@ -281,16 +314,21 @@ def getIntroOffset(self, offset=None, setSkipped=False): return self.getDialog().displayMarkers(onlyReturnIntroMD=True, offset=offset, setSkipped=setSkipped) def next(self, on_end=False): - if self.playlist and next(self.playlist): - self.seeking = self.SEEK_PLAYLIST + hasNext = False + if self.playlist: + hasNext = bool(next(self.playlist)) + if hasNext: + self.seeking = self.SEEK_PLAYLIST if on_end: if self.showPostPlay(): return True - if not self.playlist or self.stoppedManually: + if not self.playlist or self.stoppedManually or (self.playlist and not hasNext): return False + self.triggerProgressEvent() + self.player.playVideoPlaylist(self.playlist, handler=self, resume=False) return True @@ -299,6 +337,7 @@ def prev(self): if not self.playlist or not self.playlist.prev(): return False + self.triggerProgressEvent() self.seeking = self.SEEK_PLAYLIST self.player.playVideoPlaylist(self.playlist, handler=self, resume=False) @@ -347,7 +386,7 @@ def seek(self, offset, settings_changed=False, seeking=SEEK_IN_PROGRESS): self.offset = offset if self.isDirectPlay and not settings_changed: - util.DEBUG_LOG('New absolute player offset: {0}'.format(self.offset)) + util.DEBUG_LOG('New absolute player offset: {0}', self.offset) if self.player.playerObject.offsetIsValid(offset / 1000): if self.seekAbsolute(offset): @@ -360,7 +399,7 @@ def seek(self, offset, settings_changed=False, seeking=SEEK_IN_PROGRESS): if self.player.playState == self.player.STATE_PAUSED: self.player.pauseAfterPlaybackStarted = True - util.DEBUG_LOG('New player offset: {0}, state: {1}'.format(self.offset, self.player.playState)) + util.DEBUG_LOG('New player offset: {0}, state: {1}', self.offset, self.player.playState) self.player._playVideo(offset, seeking=self.seeking, force_update=settings_changed) def fastforward(self): @@ -378,26 +417,39 @@ def seekAbsolute(self, seek=None): seekSeconds = self.seekOnStart / 1000.0 try: if seekSeconds >= self.player.getTotalTime(): - util.DEBUG_LOG("SeekAbsolute: Bad offset: {0}".format(seekSeconds)) + util.DEBUG_LOG("SeekAbsolute: Bad offset: {0}", seekSeconds) return False except RuntimeError: # Not playing a file util.DEBUG_LOG("SeekAbsolute: runtime error") return False self.updateNowPlaying(state=self.player.STATE_PAUSED) # To for update after seek - util.DEBUG_LOG("SeekAbsolute: Seeking to {0}".format(self.seekOnStart)) - self.player.seekTime(self.seekOnStart / 1000.0) + # Some devices seem to have an issue with the self.player.seekTime function where after the seek the video + # will be playing, but the audio won't for a few seconds(I've seen up to 15 seconds). Using this alternate + # way to seek avoids that issue. + if self.useAlternateSeek: + currentTime = self.player.getTime() + relativeSeekSeconds = seekSeconds - currentTime + util.DEBUG_LOG("SeekAbsolute: Seeking to offset: {0}, current time: {1}, relative seek: {2}".format( + seekSeconds, currentTime, relativeSeekSeconds)) + xbmc.executebuiltin('Seek({})'.format(relativeSeekSeconds)) + else: + util.DEBUG_LOG("SeekAbsolute: Seeking to {0}", self.seekOnStart) + self.player.seekTime(seekSeconds) return True def onAVChange(self): util.DEBUG_LOG('SeekHandler: onAVChange') + self.player.trigger('changed.video') if self.dialog: self.dialog.onAVChange() def onAVStarted(self): util.DEBUG_LOG('SeekHandler: onAVStarted') + self.player.trigger('started.video') if self.isDirectPlay: + # handle seekOnStart/resume self.seekAbsolute() if self.dialog: @@ -419,14 +471,14 @@ def onAVStarted(self): util.ERROR("Exception when trying to check for embedded subtitles") def onPrePlayStarted(self): - util.DEBUG_LOG('SeekHandler: onPrePlayStarted, DP: {}'.format(self.isDirectPlay)) + util.DEBUG_LOG('SeekHandler: onPrePlayStarted, DP: {}', self.isDirectPlay) self.prePlayWitnessed = True if self.isDirectPlay: self.setSubtitles(do_sleep=False) def onPlayBackStarted(self): - util.DEBUG_LOG('SeekHandler: onPlayBackStarted, DP: {}'.format(self.isDirectPlay)) - self.updateNowPlaying(force=True, refreshQueue=True) + util.DEBUG_LOG('SeekHandler: onPlayBackStarted, DP: {}', self.isDirectPlay) + self.updateNowPlaying(refreshQueue=True) if self.dialog: self.dialog.onPlayBackStarted() @@ -443,6 +495,26 @@ def onPlayBackResumed(self): util.CRON.forceTick() # self.hideOSD() + @property + def videoPlayedFac(self): + return self.trueTime * 1000 / float(self.duration) + + @property + def videoWatched(self): + return self.videoPlayedFac >= self.playedThreshold or self.player.isExternal + + def triggerProgressEvent(self): + if not self.player.video: + return + + rk = str(self.player.video.ratingKey) + if rk not in self._progressHld: + # progress already consumed + return + + self.player.trigger('video.progress', data=(rk, self._progressHld[rk] if not self.videoWatched else True)) + self._progressHld = {} + def onPlayBackStopped(self): util.DEBUG_LOG('SeekHandler: onPlayBackStopped - ' 'Seeking={0}, QueueingNext={1}, BingeMode={2}, StoppedManually={3}, SkipPostPlay={4}' @@ -461,20 +533,23 @@ def onPlayBackStopped(self): if self.seeking not in (self.SEEK_IN_PROGRESS, self.SEEK_REWIND): self.updateNowPlaying() + self.triggerProgressEvent() # show post play if possible, if an item has been watched (90% by Plex standards) if self.seeking != self.SEEK_PLAYLIST and self.duration: - playedFac = self.trueTime * 1000 / float(self.duration) - util.DEBUG_LOG("Player - played-threshold: {}/{}".format(playedFac, self.playedThreshold)) + playedFac = self.videoPlayedFac + util.DEBUG_LOG("Player - played-threshold: {}/{}", playedFac, self.playedThreshold) if playedFac >= self.playedThreshold and self.next(on_end=True): return - if self.seeking not in (self.SEEK_IN_PROGRESS, self.SEEK_PLAYLIST): + if (self.seeking not in (self.SEEK_IN_PROGRESS, self.SEEK_PLAYLIST) or + (self.seeking == self.SEEK_PLAYLIST and self.stoppedManually)): self.hideOSD(delete=True) self.sessionEnded() def onPlayBackEnded(self): - util.DEBUG_LOG('SeekHandler: onPlayBackEnded - Seeking={0}'.format(self.seeking)) + util.DEBUG_LOG('SeekHandler: onPlayBackEnded - Seeking={0}, External={1}', + self.seeking, self.player.isExternal) if self.dialog: self.dialog.onPlayBackEnded() @@ -486,12 +561,13 @@ def onPlayBackEnded(self): return self.updateNowPlaying() + self.triggerProgressEvent() if self.queuingNext: util.DEBUG_LOG('SeekHandler: onPlayBackEnded - event ignored') return - self.stoppedManually = False + self.stoppedManually = False if not self.player.isExternal else True if self.playlist and self.playlist.hasNext(): self.queuingNext = True @@ -504,7 +580,7 @@ def onPlayBackEnded(self): if self.seeking != self.SEEK_PLAYLIST: self.hideOSD() - if self.seeking not in (self.SEEK_IN_PROGRESS, self.SEEK_PLAYLIST): + if self.seeking not in (self.SEEK_IN_PROGRESS, self.SEEK_PLAYLIST) or self.player.isExternal: self.sessionEnded() def onPlayBackPaused(self): @@ -513,19 +589,47 @@ def onPlayBackPaused(self): self.dialog.onPlayBackPaused() def onPlayBackSeek(self, stime, offset): - util.DEBUG_LOG('SeekHandler: onPlayBackSeek - {0}, {1}, {2}'.format(stime, offset, self.seekOnStart)) + if self.waitingForSOS: + return + util.DEBUG_LOG('SeekHandler: onPlayBackSeek - {0}, {1}, {2}', stime, offset, self.seekOnStart) if self.dialog: self.dialog.onPlayBackSeek(stime, offset) - if self.seekOnStart: - seeked = False - if self.dialog: - seeked = self.dialog.tick(stime) + if self.dialog and self.isDirectPlay and self.seekOnStart: + withinSOS = self.seekOnStart - 5000 - if seeked: - util.DEBUG_LOG("OnPlayBackSeek: Seeked on start to: {0}".format(stime)) - self.seekOnStart = 0 - return + tries = 0 + while not self.player.isPlayingVideo() and tries < 50: + xbmc.sleep(100) + tries += 1 + + if self.player.getTime() * 1000 < withinSOS: + self.waitingForSOS = True + # checking infoLabel Player.Seeking would be the better solution here, but we're dealing with stuff like + # CoreELEC, which doesn't necessarily properly honor this + xbmc.sleep(250) + self.seek(self.seekOnStart) + xbmc.sleep(util.addonSettings.coreelecResumeSeekWait) + + util.DEBUG_LOG("OnPlayBackSeek: SeekOnStart: " + "Expecting to be within 5 seconds of {}, currently at: {}", self.seekOnStart, + self.player.getTime()) + + tries = 0 + max_tries = int(5000 / util.addonSettings.coreelecResumeSeekWait) + while self.player.isPlayingVideo() and self.player.getTime() * 1000 < withinSOS and tries < max_tries: + util.DEBUG_LOG("OnPlayBackSeek: SeekOnStart: Not there, yet, " + "seeking again ({}, {})", self.seekOnStart, self.player.getTime()) + self.seek(self.seekOnStart) + tries += 1 + xbmc.sleep(util.addonSettings.coreelecResumeSeekWait) + if tries >= max_tries: + util.DEBUG_LOG("OnPlayBackSeek: SeekOnStart: Couldn't properly seek on start within ~5 seconds.") + else: + util.DEBUG_LOG("OnPlayBackSeek: Seeked on start to: {0}", self.seekOnStart) + self.waitingForSOS = False + self.dialog.offset = self.seekOnStart + self.seekOnStart = 0 self.updateOffset() # self.showOSD(from_seek=True) @@ -546,14 +650,14 @@ def setSubtitles(self, do_sleep=True, honor_forced_subtitles_override=True): if self.isDirectPlay: self.player.showSubtitles(False) if path: - util.DEBUG_LOG('Setting subtitle path: {0} ({1})'.format(path, subs)) + util.DEBUG_LOG('Setting subtitle path: {0} ({1})', path, subs) self.player.setSubtitles(path) self.player.showSubtitles(True) else: # u_til.TEST(subs.__dict__) # u_til.TEST(self.player.video.mediaChoice.__dict__) - util.DEBUG_LOG('Enabling embedded subtitles at: {0} ({1})'.format(subs.typeIndex, subs)) + util.DEBUG_LOG('Enabling embedded subtitles at: {0} ({1})', subs.typeIndex, subs) self.player.setSubtitleStream(subs.typeIndex) self.player.showSubtitles(True) @@ -573,13 +677,13 @@ def setAudioTrack(self): playerID = kodijsonrpc.rpc.Player.GetActivePlayers()[0]["playerid"] currIdx = kodijsonrpc.rpc.Player.GetProperties(playerid=playerID, properties=['currentaudiostream'])['currentaudiostream']['index'] if currIdx == track.typeIndex: - util.DEBUG_LOG('Audio track is correct index: {0}'.format(track.typeIndex)) + util.DEBUG_LOG('Audio track is correct index: {0}', track.typeIndex) return except: util.ERROR() - xbmc.sleep(100) - util.DEBUG_LOG('Switching audio track - index: {0}'.format(track.typeIndex)) + util.MONITOR.waitForAbort(0.1) + util.DEBUG_LOG('Switching audio track - index: {0}', track.typeIndex) self.player.setAudioStream(track.typeIndex) def updateOffset(self): @@ -604,7 +708,7 @@ def onPlayBackFailed(self): if self.dialog: self.dialog.onPlayBackFailed() - util.DEBUG_LOG('SeekHandler: onPlayBackFailed - Seeking={0}'.format(self.seeking)) + util.DEBUG_LOG('SeekHandler: onPlayBackFailed - Seeking={0}', self.seeking) if self.seeking not in (self.SEEK_IN_PROGRESS, self.SEEK_PLAYLIST): self.sessionEnded() @@ -619,17 +723,22 @@ def onPlayBackFailed(self): # self.dialog.activate() def onVideoWindowOpened(self): - util.DEBUG_LOG('SeekHandler: onVideoWindowOpened - Seeking={0}'.format(self.seeking)) + util.DEBUG_LOG('SeekHandler: onVideoWindowOpened - Seeking={0}', self.seeking) self.getDialog().show() self.initPlayback() def onVideoWindowClosed(self): self.hideOSD() - util.DEBUG_LOG('SeekHandler: onVideoWindowClosed - Seeking={0}'.format(self.seeking)) + util.DEBUG_LOG('SeekHandler: onVideoWindowClosed - Seeking={0}', self.seeking) if not self.seeking: + # send events as we might not have seen onPlayBackEnded and/or onPlayBackStopped in certain cases, + # especially when postplay isn't wanted and we're at the end of a show + #self.updateNowPlaying() + #if self._progressHld: + # self.triggerProgressEvent() if self.player.isPlaying(): - self.player.stop() + self.player.stopAndWait() if not self.playlist or not self.playlist.hasNext(): if not self.shouldShowPostPlay(): self.sessionEnded() @@ -639,8 +748,10 @@ def onVideoOSD(self): self.showOSD() def tick(self): - if self.seeking != self.SEEK_IN_PROGRESS: - self.updateNowPlaying(force=True) + if (self.seeking != self.SEEK_IN_PROGRESS and not self.ended and self.player.started and not self.seekOnStart + and not self.queuingNext and not self.stoppedManually and self.player.isPlayingVideo() and + self.player.playState != self.player.STATE_STOPPED): + self.updateNowPlaying() if self.dialog and getattr(self.dialog, "_ignoreTick", None) is not True: self.dialog.tick() @@ -681,7 +792,7 @@ def extractTrackInfo(self): if plexID: break - xbmc.sleep(100) + util.MONITOR.waitForAbort(0.1) if not plexID: return @@ -708,8 +819,18 @@ def setPlayQueue(self, pq): pq.on('items.changed', self.playQueueCallback) def playQueueCallback(self, **kwargs): + if windowutils.HOME._shuttingDown: + return + plist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC) + just_added = kwargs.get("just_added") # plist.clear() + + waited = 0 + while not kodijsonrpc.rpc.Player.GetActivePlayers() and not util.MONITOR.abortRequested() and waited < 10: + util.MONITOR.waitForAbort(0.5) + waited += 0.5 + try: citem = kodijsonrpc.rpc.Player.GetItem(playerid=0, properties=['comment'])['item'] plexID = citem['comment'].split(':', 1)[0] @@ -720,31 +841,45 @@ def playQueueCallback(self, **kwargs): current = plist.getposition() size = plist.size() - # Remove everything but the current track - for x in range(size - 1, current, -1): # First everything with a greater position - kodijsonrpc.rpc.Playlist.Remove(playlistid=xbmc.PLAYLIST_MUSIC, position=x) - for x in range(current): # Then anything with a lesser position - kodijsonrpc.rpc.Playlist.Remove(playlistid=xbmc.PLAYLIST_MUSIC, position=0) - - swap = None - for idx, track in enumerate(self.playQueue.items()): - tid = 'PLEX-{0}'.format(track.ratingKey) - if tid == plexID: - # Save the position of the current track in the pq - swap = idx - - url, li = self.player.createTrackListItem(track, index=idx + 1) - - plist.add(url, li) - - plist[0].setInfo('music', { - 'playcount': swap + 1, - }) + # if we've just added items to the playqueue, we don't need to do any swappery + if not just_added: + # Remove everything but the current track + for x in range(size - 1, current, -1): # First everything with a greater position + kodijsonrpc.rpc.Playlist.Remove(playlistid=xbmc.PLAYLIST_MUSIC, position=x) + for x in range(current): # Then anything with a lesser position + kodijsonrpc.rpc.Playlist.Remove(playlistid=xbmc.PLAYLIST_MUSIC, position=0) + + swap = None + for idx, track in enumerate(self.playQueue.items()): + tid = 'PLEX-{0}'.format(track.ratingKey) + if tid == plexID: + # Save the position of the current track in the pq + swap = idx + + url, li = self.player.createTrackListItem(track, index=idx + 1) + + plist.add(url, li) + + if swap is not None: + plist[0].setInfo('music', { + 'playcount': swap + 1, + }) + + # Now swap the track to the correct position. This seems to be the only way to update the kodi playlist position to the current track's new position + if swap is not None and swap != current: + kodijsonrpc.rpc.Playlist.Swap(playlistid=xbmc.PLAYLIST_MUSIC, position1=0, position2=swap + 1) + try: + kodijsonrpc.rpc.Playlist.Remove(playlistid=xbmc.PLAYLIST_MUSIC, position=0) + except: + pass + else: + # add added items + idx = plist.size() + 1 + for track in just_added: + url, li = self.player.createTrackListItem(track, index=idx) - # Now swap the track to the correct position. This seems to be the only way to update the kodi playlist position to the current track's new position - if swap is not None: - kodijsonrpc.rpc.Playlist.Swap(playlistid=xbmc.PLAYLIST_MUSIC, position1=0, position2=swap + 1) - kodijsonrpc.rpc.Playlist.Remove(playlistid=xbmc.PLAYLIST_MUSIC, position=0) + plist.add(url, li) + idx += 1 self.player.trigger('playlist.changed') @@ -775,14 +910,22 @@ def stampCurrentTime(self): def onMonitorInit(self): self.extractTrackInfo() + self.ignoreTimelines = False self.updateNowPlaying(state='playing') def onPlayBackStarted(self): self.player.lastPlayWasBGM = False self.updatePlayQueue(delay=True) self.extractTrackInfo() + self.ignoreTimelines = False self.updateNowPlaying(state='playing') + def onAVStarted(self): + self.player.trigger('started.audio') + + def onAVChange(self): + self.player.trigger('changed.audio') + def onPlayBackResumed(self): self.updateNowPlaying(state='playing') @@ -792,11 +935,14 @@ def onPlayBackPaused(self): def onPlayBackStopped(self): self.updatePlayQueue() self.updateNowPlaying(state='stopped') + self.ignoreTimelines = True + self.player.trigger('audio.stopped') self.finish() def onPlayBackEnded(self): self.updatePlayQueue() self.updateNowPlaying(state='stopped') + self.ignoreTimelines = True self.finish() def onPlayBackFailed(self): @@ -811,7 +957,7 @@ def tick(self): return self.stampCurrentTime() - self.updateNowPlaying(force=True) + self.updateNowPlaying() class BGMPlayerHandler(BasePlayerHandler): @@ -824,7 +970,9 @@ def __init__(self, player, rating_key): self.oldVolume = util.rpc.Application.GetProperties(properties=["volume"])["volume"] def onPlayBackStarted(self): - util.DEBUG_LOG("BGM: playing theme for %s" % self.currentlyPlaying) + self.player.bgmStarting = False + self.player.trigger('bgm.started') + util.DEBUG_LOG("BGM: playing theme for {}", self.currentlyPlaying) def _setVolume(self, vlm): xbmc.executebuiltin("SetVolume({})".format(vlm)) @@ -834,16 +982,16 @@ def setVolume(self, volume=None, reset=False): curVolume = self.getVolume() if curVolume != vlm: - util.DEBUG_LOG("BGM: {}setting volume to: {}".format("re-" if reset else "", vlm)) + util.DEBUG_LOG("BGM: {}setting volume to: {}", "re-" if reset else "", vlm) self._setVolume(vlm) else: - util.DEBUG_LOG("BGM: Volume already at {}".format(vlm)) + util.DEBUG_LOG("BGM: Volume already at {}", vlm) return waited = 0 waitMax = 5 while curVolume != vlm and waited < waitMax: - util.DEBUG_LOG("Waiting for volume to change from {} to {}".format(curVolume, vlm)) + util.DEBUG_LOG("Waiting for volume to change from {} to {}", curVolume, vlm) xbmc.sleep(100) waited += 1 curVolume = self.getVolume() @@ -856,7 +1004,7 @@ def resetVolume(self): self.setVolume(reset=True) def onPlayBackStopped(self): - util.DEBUG_LOG("BGM: stopped theme for {}".format(self.currentlyPlaying)) + util.DEBUG_LOG("BGM: stopped theme for {}", self.currentlyPlaying) util.setGlobalProperty('theme_playing', '') self.player.bgmPlaying = False self.resetVolume() @@ -910,12 +1058,14 @@ def __init__(self, *args, **kwargs): signalsmixin.SignalsMixin.__init__(self) self.sessionID = None self.handler = AudioPlayerHandler(self) + self.isExternal = False def init(self): self._closed = False self._nextItem = None self.started = False self.bgmPlaying = False + self.bgmStarting = False self.lastPlayWasBGM = False self.BGMTask = None self.pauseAfterPlaybackStarted = False @@ -928,7 +1078,8 @@ def init(self): self.currentTime = 0 self.thread = None self.ignoreStopEvents = False - if xbmc.getCondVisibility('Player.HasMedia'): + self.isExternal = False + if xbmc.getCondVisibility('Player.HasMedia') and self.isPlayingAudio() and not self.bgmPlaying: self.started = True self.resume = False self.open() @@ -1028,6 +1179,7 @@ def playBackgroundMusic(self, source, volume, rating_key, *args, **kwargs): self.BGMTask.cancel() self.started = False + self.bgmStarting = True self.handler = BGMPlayerHandler(self, rating_key) # store current volume if it's different from the BGM volume @@ -1086,25 +1238,23 @@ def _playVideo(self, offset=0, seeking=0, force_update=False, playerObject=None, return meta = self.playerObject.metadata - - # Kodi 19 will try to look for subtitles in the directory containing the file. '/' and `/file.mkv` both point - # to the file, and Kodi will happily try to read the whole file without recognizing it isn't a directory. - # To get around that, we omit the filename here since it is unnecessary. - url = meta.streamUrls[0].replace("file.mkv", "").replace("file.mp4", "") + url = meta.streamUrls[0] bifURL = self.playerObject.getBifUrl() - util.DEBUG_LOG('Playing URL(+{1}ms): {0}{2}'.format(plexnetUtil.cleanToken(url), offset, bifURL and ' - indexed' or '')) + util.DEBUG_LOG('Playing URL(+{1}ms): {0}{2}', plexnetUtil.cleanToken(url), offset, bifURL and ' - indexed' or '') self.ignoreStopEvents = True self.stopAndWait() # Stop before setting up the handler to prevent player events from causing havoc - if self.handler and self.handler.queuingNext and util.advancedSettings.consecutiveVideoPbWait: + if self.handler and self.handler.queuingNext and util.addonSettings.consecutiveVideoPbWait: util.DEBUG_LOG( - "Waiting for {}s until playing back next item".format(util.advancedSettings.consecutiveVideoPbWait)) - util.MONITOR.waitForAbort(util.advancedSettings.consecutiveVideoPbWait) + "Waiting for {}s until playing back next item".format(util.addonSettings.consecutiveVideoPbWait)) + util.MONITOR.waitForAbort(util.addonSettings.consecutiveVideoPbWait) self.ignoreStopEvents = False self.sessionID = session_id or self.sessionID + # fixme: this handler might be accessing a new playerObject, not the one it's expecting to access, + # especially when .next() is used self.handler.setup(self.video.duration.asInt(), meta, offset, bifURL, title=self.video.grandparentTitle, title2=self.video.title, seeking=seeking, chapters=self.video.chapters) @@ -1122,7 +1272,7 @@ def _playVideo(self, offset=0, seeking=0, force_update=False, playerObject=None, if introOffset: # cheat our way into an early intro skip by modifying the offset in the stream URL - util.DEBUG_LOG("Immediately seeking behind intro: {}".format(introOffset)) + util.DEBUG_LOG("Immediately seeking behind intro: {}", introOffset) url = self.OFFSET_RE.sub(r"\g<1>{}".format(introOffset // 1000), url) self.handler.dialog.baseOffset = introOffset @@ -1130,18 +1280,26 @@ def _playVideo(self, offset=0, seeking=0, force_update=False, playerObject=None, meta.playStart = introOffset // 1000 else: if offset: - util.DEBUG_LOG("Using as SeekOnStart: {0}; offset: {1}".format(meta.playStart, offset)) + util.DEBUG_LOG("Using as SeekOnStart: {0}; offset: {1}", meta.playStart, offset) self.handler.seekOnStart = meta.playStart * 1000 elif introOffset: - util.DEBUG_LOG("Seeking behind intro after playstart: {}".format(introOffset)) + util.DEBUG_LOG("Seeking behind intro after playstart: {}", introOffset) self.handler.seekOnStart = introOffset self.handler.mode = self.handler.MODE_ABSOLUTE - url = util.addURLParams(url, { - 'X-Plex-Client-Profile-Name': 'Generic', - 'X-Plex-Client-Identifier': plexapp.util.INTERFACE.getGlobal('clientIdentifier') - }) + if not meta.isMapped: + # Kodi 19 will try to look for subtitles in the directory containing the file. '/' and `/file.mkv` both + # point to the file, and Kodi will happily try to read the whole file without recognizing it isn't a + # directory. To get around that, we omit the filename here since it is unnecessary. + omit, fname = url.rsplit("/", 1) + if fname.startswith("file."): + url = "{}/{}".format(omit, "?" + fname.split("?")[1] if "?" in fname else "") + + url = util.addURLParams(url, { + 'X-Plex-Client-Profile-Name': 'Generic', + 'X-Plex-Client-Identifier': plexapp.util.INTERFACE.getGlobal('clientIdentifier') + }) li = xbmcgui.ListItem(self.video.title, path=url) vtype = self.video.type if self.video.type in ('movie', 'episode', 'musicvideo') else 'video' @@ -1149,28 +1307,86 @@ def _playVideo(self, offset=0, seeking=0, force_update=False, playerObject=None, util.setGlobalProperty("current_size", str(meta.size), base='videoinfo.{0}') imdbNum = None - if "com.plexapp.agents.imdb" in self.video.guid: - a = self.video.guid + + fill_trakt_ids = False + trakt_ids = {} + + # generate guids when script.trakt is installed + if "script.trakt" in util.USER_ADDONS: + fill_trakt_ids = True + + a = self.video.guid + if "com.plexapp.agents.imdb" in a: imdbNum = a.split("?lang=")[0][a.index("com.plexapp.agents.imdb://")+len("com.plexapp.agents.imdb://"):] - li.setInfo('video', { + if fill_trakt_ids: + if imdbNum: + trakt_ids["imdb"] = imdbNum + + elif fill_trakt_ids and "com.plexapp.agents.themoviedb" in a: + trakt_ids["tmdb"] = a.split("?lang=")[0][ + a.index("com.plexapp.agents.themoviedb://") + len("com.plexapp.agents.themoviedb://"):] + + elif fill_trakt_ids and "com.plexapp.agents.thetvdb" in a: + trakt_ids["tvdb"] = a.split("?lang=")[0][ + a.index("com.plexapp.agents.thetvdb://") + + len("com.plexapp.agents.thetvdb://"):].split("/", 1)[0] + + elif "plex://movie" in a or "plex://episode" in a: + ref = self.video + if fill_trakt_ids and "plex://episode" in a: + ref = self.video.show() + if not ref.isFullObject(): + ref.reload() + + for guid in ref.guids: + if not imdbNum and guid.id.startswith('imdb://'): + imdbNum = guid.id.split('imdb://')[1] + + if fill_trakt_ids: + sabbr, gid = guid.id.split("://") + try: + gid = int(gid) + except: + pass + + trakt_ids[sabbr] = gid + if fill_trakt_ids: + # generate trakt slug + if vtype == "movie": + year = self.video.year.asInt() + trakt_ids['slug'] = util.slugify("{}{}".format(self.video.title, year and " {}".format(year) or "")) + + util.DEBUG_LOG("Setting Trakt IDs: {}", trakt_ids) + # report IDs to trakt + xbmcgui.Window(10000).setProperty('script.trakt.ids', json.dumps(trakt_ids)) + + info = { 'mediatype': vtype, 'title': self.video.title, 'originaltitle': self.video.title, 'tvshowtitle': self.video.grandparentTitle, - 'episode': vtype == "episode" and self.video.index.asInt() or '', - 'season': vtype == "episode" and self.video.parentIndex.asInt() or '', - #'year': self.video.year.asInt(), + 'year': self.video.year.asInt(), 'plot': self.video.summary, 'path': meta.path, 'size': meta.size, 'imdbnumber': imdbNum - }) + } + if vtype == "episode": + info.update({ + 'episode': self.video.index.asInt(), + 'season': self.video.parentIndex.asInt(), + }) + util.DEBUG_LOG("Setting VideoInfo: {}".format( + plexnetUtil.cleanObjTokens(info, flistkeys=[]) + )) + li.setInfo('video', info) li.setArt({ 'poster': self.video.defaultThumb.asTranscodedImageURL(347, 518), 'fanart': self.video.defaultArt.asTranscodedImageURL(1920, 1080), 'thumb': self.video.defaultThumb.asTranscodedImageURL(256, 256), }) + self.trigger('starting.video') self.play(url, li) def playVideoPlaylist(self, playlist, resume=False, handler=None, session_id=None): @@ -1219,12 +1435,14 @@ def playAudio(self, track, fanart=None, **kwargs): self.ignoreStopEvents = True self.handler = AudioPlayerHandler(self) + self.playerObject = plexplayer.PlexAudioPlayer(track) url, li = self.createTrackListItem(track, fanart) self.stopAndWait() self.ignoreStopEvents = False # maybe fixme: once started, self.sessionID will never be None for Audio self.sessionID = "AUD%s" % track.ratingKey + self.trigger('starting.audio') self.play(url, li, **kwargs) def playAlbum(self, album, startpos=-1, fanart=None, **kwargs): @@ -1233,6 +1451,7 @@ def playAlbum(self, album, startpos=-1, fanart=None, **kwargs): self.ignoreStopEvents = True self.handler = AudioPlayerHandler(self) + self.playerObject = plexplayer.PlexAudioPlayer() plist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC) plist.clear() index = 1 @@ -1244,6 +1463,7 @@ def playAlbum(self, album, startpos=-1, fanart=None, **kwargs): self.stopAndWait() self.ignoreStopEvents = False self.sessionID = "ALB%s" % album.ratingKey + self.trigger('starting.audio') self.play(plist, startpos=startpos, **kwargs) def playAudioPlaylist(self, playlist, startpos=-1, fanart=None, **kwargs): @@ -1252,6 +1472,7 @@ def playAudioPlaylist(self, playlist, startpos=-1, fanart=None, **kwargs): self.ignoreStopEvents = True self.handler = AudioPlayerHandler(self) + self.playerObject = plexplayer.PlexAudioPlayer() plist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC) plist.clear() index = 1 @@ -1271,11 +1492,14 @@ def playAudioPlaylist(self, playlist, startpos=-1, fanart=None, **kwargs): self.stopAndWait() self.ignoreStopEvents = False self.sessionID = "PLS%s" % getattr(playlist, "ratingKey", getattr(playlist, "id", random.randint(0, 1000))) + self.trigger('starting.audio') self.play(plist, startpos=startpos, **kwargs) def createTrackListItem(self, track, fanart=None, index=0): data = base64.urlsafe_b64encode(track.serialize().encode("utf8")).decode("utf8") - url = 'plugin://script.plexmod/play?{0}'.format(data) + if not track.isFullObject(): + track = track.reload() + url = self.playerObject.build(track)['url'] li = xbmcgui.ListItem(track.title, path=url) li.setInfo('music', { 'artist': six.text_type(track.originalTitle or track.grandparentTitle), @@ -1285,6 +1509,8 @@ def createTrackListItem(self, track, fanart=None, index=0): 'tracknumber': track.get('index').asInt(), 'duration': int(track.duration.asInt() / 1000), 'playcount': index, + # fixme: this is not really necessary, as we don't go the plugin:// route anymore. + # changing the track identification style would mean a bigger rewrite, though, so let's keep it. 'comment': 'PLEX-{0}:{1}'.format(track.ratingKey, data) }) art = fanart or track.defaultArt @@ -1311,10 +1537,6 @@ def onPlayBackStarted(self): return util.DEBUG_LOG('Player - STARTED') self.trigger('playback.started') - self.started = True - if self.pauseAfterPlaybackStarted: - self.control('pause') - self.pauseAfterPlaybackStarted = False if not self.handler: return @@ -1323,7 +1545,7 @@ def onPlayBackStarted(self): def onAVChange(self): if not self.sessionID: return - util.DEBUG_LOG('Player - AVChange') + util.DEBUG_LOG('Player - AVChange: Time: {}', self.getTime() if self.isPlayingVideo() else "Not playing") if not self.handler: return self.handler.onAVChange() @@ -1331,8 +1553,15 @@ def onAVChange(self): def onAVStarted(self): if not self.sessionID: return - util.DEBUG_LOG('Player - AVStarted: {}'.format(self.handler)) + util.DEBUG_LOG('Player - AVStarted: {}, Time: {}', self.handler, + self.getTime() if self.isPlayingVideo() else "Not playing") + if self.pauseAfterPlaybackStarted: + self.control('pause') + self.pauseAfterPlaybackStarted = False + + self.isExternal = self.isExternalPlayer() self.trigger('av.started') + self.started = True if not self.handler: return self.handler.onAVStarted() @@ -1385,15 +1614,28 @@ def onPlayBackEnded(self): def onPlayBackSeek(self, time, offset): if not self.sessionID: return - util.DEBUG_LOG('Player - SEEK: %i' % offset) + util.DEBUG_LOG('Player - SEEK: {} {:d}', time, offset) if not self.handler: return self.handler.onPlayBackSeek(time, offset) + def onPlayBackError(self): + if not self.sessionID: + return + util.DEBUG_LOG('Player - ERROR: {}', self.handler) + if not self.handler: + return + + if self.handler.onPlayBackFailed(): + self.ignoreStopEvents = True + util.showNotification('Playback Error!') + self.stopAndWait() + self.close() + def onPlayBackFailed(self): if not self.sessionID: return - util.DEBUG_LOG('Player - FAILED: {}'.format(self.handler)) + util.DEBUG_LOG('Player - FAILED: {}', self.handler) if not self.handler: return @@ -1444,9 +1686,10 @@ def stopAndWait(self): if self.isPlaying(): util.DEBUG_LOG('Player: Stopping and waiting...') self.stop() - while not util.MONITOR.waitForAbort(0.1) and self.isPlaying(): - pass - util.MONITOR.waitForAbort(0.2) + if not util.MONITOR.abortRequested(): + while not util.MONITOR.waitForAbort(0.05) and self.isPlaying(): + if util.MONITOR.abortRequested(): + break util.DEBUG_LOG('Player: Stopping and waiting...Done') def monitor(self): diff --git a/script.plexmod/lib/plex.py b/script.plexmod/lib/plex.py index 9a6506dcf2..7b2e1549f1 100644 --- a/script.plexmod/lib/plex.py +++ b/script.plexmod/lib/plex.py @@ -76,6 +76,13 @@ def defaultUserAgent(): '%s/%s' % (p_system, p_release)]) +def getFriendlyName(): + fn = util.rpc.Settings.GetSettingValue(setting='services.devicename').get('value', 'Kodi') + if fn: + fn = fn.strip() + return fn or 'Kodi' + + class PlexInterface(plexapp.AppInterface): _regs = { None: {}, @@ -89,7 +96,7 @@ class PlexInterface(plexapp.AppInterface): 'provides': 'player', 'device': util.getPlatform() or plexapp.PLATFORM, 'model': 'Unknown', - 'friendlyName': util.rpc.Settings.GetSettingValue(setting='services.devicename').get('value') or 'Kodi', + 'friendlyName': getFriendlyName(), 'supports1080p60': True, 'vp9Support': True, 'audioChannels': '2.0', @@ -122,6 +129,15 @@ def getPreference(self, pref, default=None): else: return util.getSetting(pref, default) + def getPlaybackFeatures(self): + return self.getPreference("playback_features", + ["playback_directplay", + "playback_remux", + "allow_4k"]) + + def getAdditionalCodecs(self): + return self.getPreference("allowed_codecs", ["allow_hevc", "allow_vc1"]) + def getManualConnections(self): conns = [] for i in range(2): @@ -158,14 +174,16 @@ def clearInitializer(self, sec): def getGlobal(self, glbl, default=None): if glbl == 'transcodeVideoResolutions': - maxres = self.getPreference('allow_4k', True) and plexapp.Res((3840, 2160)) or plexapp.Res((1920, 1080)) + allow_4k = "allow_4k" in self.getPlaybackFeatures() + maxres = allow_4k and plexapp.Res((3840, 2160)) or plexapp.Res((1920, 1080)) self._globals['transcodeVideoResolutions'][-5:] = [maxres] * 5 elif glbl == 'audioChannels': try: self._globals['audioChannels'] = \ util.CHANNELMAPPING[util.rpc.Settings.GetSettingValue(setting='audiooutput.channels').get('value')] except: - util.DEBUG_LOG("Limiting audio channel definition to 2.0 due to error: %s" % traceback.format_exc()) + util.DEBUG_LOG("Limiting audio channel definition to 2.0 due to error: {}", + lambda: traceback.format_exc()) self._globals['audioChannels'] = "2.0" return self._globals.get(glbl, default) @@ -173,17 +191,17 @@ def getGlobal(self, glbl, default=None): def getCapabilities(self): return '' - def LOG(self, msg): - util.DEBUG_LOG('API: {0}'.format(msg)) + def LOG(self, msg, *args, **kwargs): + util.DEBUG_LOG('API: {0}'.format(msg), *args, **kwargs) - def DEBUG_LOG(self, msg): - self.LOG('DEBUG: {0}'.format(msg)) + def DEBUG_LOG(self, msg, *args, **kwargs): + self.LOG('DEBUG: {0}'.format(msg), *args, **kwargs) - def WARN_LOG(self, msg): - self.LOG('WARNING: {0}'.format(msg)) + def WARN_LOG(self, msg, *args, **kwargs): + self.LOG('WARNING: {0}'.format(msg), *args, **kwargs) - def ERROR_LOG(self, msg): - self.LOG('ERROR: {0}'.format(msg)) + def ERROR_LOG(self, msg, *args, **kwargs): + self.LOG('ERROR: {0}'.format(msg), *args, **kwargs) def ERROR(self, msg=None, err=None): if err: @@ -230,7 +248,7 @@ def getMaxResolution(self, quality_type, allow4k=False): qualityIndex = self.getQualityIndex(quality_type) if qualityIndex >= 9: - if self.getPreference('allow_4k', True): + if "allow_4k" in self.getPlaybackFeatures(): return allow4k and 2160 or 1088 else: return 1088 @@ -284,15 +302,30 @@ def onManualIPChange(**kwargs): plexapp.util.LOCAL_OVER_SECURE = util.getSetting('prefer_local', False) # set requests timeout -TIMEOUT = float(util.advancedSettings.requestsTimeout) -CONNCHECK_TIMEOUT = float(util.advancedSettings.connCheckTimeout) -plexapp.util.TIMEOUT = TIMEOUT -plexapp.util.CONN_CHECK_TIMEOUT = asyncadapter.AsyncTimeout(CONNCHECK_TIMEOUT).setConnectTimeout(CONNCHECK_TIMEOUT) -plexapp.util.LAN_REACHABILITY_TIMEOUT = util.advancedSettings.localReachTimeout / 1000.0 -pnhttp.DEFAULT_TIMEOUT = asyncadapter.AsyncTimeout(TIMEOUT).setConnectTimeout(TIMEOUT) +TIMEOUT_READ = float(util.addonSettings.requestsTimeoutRead) +TIMEOUT_CONNECT = float(util.addonSettings.requestsTimeoutConnect) +PLEXTV_TIMEOUT_READ = float(util.addonSettings.plextvTimeoutRead) +PLEXTV_TIMEOUT_CONNECT = float(util.addonSettings.plextvTimeoutConnect) +CONNCHECK_TIMEOUT = float(util.addonSettings.connCheckTimeout) +plexapp.util.TIMEOUT = TIMEOUT_READ +plexapp.util.TIMEOUT_CONNECT = TIMEOUT_CONNECT +plexapp.util.PLEXTV_TIMEOUT_READ = PLEXTV_TIMEOUT_READ +plexapp.util.PLEXTV_TIMEOUT_CONNECT = PLEXTV_TIMEOUT_CONNECT +plexapp.util.PLEXTV_TIMEOUT = asyncadapter.AsyncTimeout(PLEXTV_TIMEOUT_READ).setConnectTimeout(PLEXTV_TIMEOUT_CONNECT) +plexapp.util.CONN_CHECK_TIMEOUT = asyncadapter.AsyncTimeout(TIMEOUT_READ).setConnectTimeout(CONNCHECK_TIMEOUT) +plexapp.util.LAN_REACHABILITY_TIMEOUT = util.addonSettings.localReachTimeout / 1000.0 +plexapp.util.DEFAULT_TIMEOUT = asyncadapter.AsyncTimeout(TIMEOUT_READ).setConnectTimeout(TIMEOUT_CONNECT) +pnhttp.DEFAULT_TIMEOUT = plexapp.util.DEFAULT_TIMEOUT +asyncadapter.DEFAULT_TIMEOUT = pnhttp.DEFAULT_TIMEOUT asyncadapter.DEFAULT_TIMEOUT = pnhttp.DEFAULT_TIMEOUT plexapp.util.ACCEPT_LANGUAGE = util.ACCEPT_LANGUAGE_CODE plexapp.setUserAgent(defaultUserAgent()) +plexnet_util.BASE_HEADERS = plexnet_util.getPlexHeaders() +asyncadapter.MAX_RETRIES = int(util.addonSettings.maxRetries1) +if util.addonSettings.useCertBundle != "system": + util.LOG("Using certificate bundle: {}".format(util.addonSettings.useCertBundle)) + plexnet_util.USE_CERT_BUNDLE = util.addonSettings.useCertBundle +plexnet_util.translatePath = util.translatePath class CallbackEvent(plexapp.util.CompatEvent): @@ -302,6 +335,7 @@ def __init__(self, context, signal, timeout=15, *args, **kwargs): self.context = context self.signal = signal self.timeout = timeout + self.timed_out = False self.context.on(self.signal, self.set) def __enter__(self): @@ -318,13 +352,14 @@ def set(self, **kwargs): def wait(self): if not plexnet_util.Event.wait(self, self.timeout): - util.DEBUG_LOG('{0}: TIMED-OUT'.format(self)) + util.DEBUG_LOG('{0}: TIMED-OUT', self) + self.timed_out = True self.close() def triggeredOrTimedOut(self, timeout=None): try: if time.time() - self.start > self.timeout: - util.DEBUG_LOG('{0}: TIMED-OUT'.format(self)) + util.DEBUG_LOG('{0}: TIMED-OUT', self) return True if timeout: @@ -340,11 +375,20 @@ def close(self): def init(): util.DEBUG_LOG('Initializing...') - with CallbackEvent(plexapp.util.APP, 'init'): - util.DEBUG_LOG('Waiting for plexapp initialization...') - plexapp.init() + timed_out = False + retries = 0 + while retries == 0 or (retries < asyncadapter.MAX_RETRIES and timed_out): + with CallbackEvent(plexapp.util.APP, 'init', timeout=plexapp.util.PLEXTV_TIMEOUT_READ) as cb: + util.DEBUG_LOG('Waiting for plexapp initialization... {}'.format(retries+1)) + plexapp.init() + + timed_out = cb.timed_out + retries += 1 + if timed_out: + util.DEBUG_LOG("plexapp initialization timed out, trying again") - util.DEBUG_LOG('Account initialized: {}'.format(plexapp.ACCOUNT.ID)) + if not timed_out: + util.DEBUG_LOG('Account initialized: {}', plexapp.ACCOUNT.ID) retry = True @@ -367,7 +411,7 @@ def init(): # util.DEBUG_LOG('SIGN IN: Failed to connect to any servers') # return False - # util.DEBUG_LOG('SIGN IN: Connected to server: {0} - {1}'.format(PLEX.friendlyName, PLEX.baseuri)) + # util.DEBUG_LOG('SIGN IN: Connected to server: {0} - {1}', PLEX.friendlyName, PLEX.baseuri) success = requirePlexPass() if success == 'RETRY': retry = True diff --git a/script.plexmod/lib/plex_hosts.py b/script.plexmod/lib/plex_hosts.py new file mode 100644 index 0000000000..b4793e1620 --- /dev/null +++ b/script.plexmod/lib/plex_hosts.py @@ -0,0 +1,112 @@ +# coding=utf-8 +import re +try: + from urllib.parse import urlparse +except ImportError: + from requests.compat import urlparse + +import plexnet.http + +from six import text_type + +from lib import util +from lib.advancedsettings import adv + +from plexnet.util import parsePlexDirectHost +from plexnet.plexconnection import DOCKER_NETWORK, IPv4Address + +HOSTS_RE = re.compile(r'\s*<hosts>.*</hosts>', re.S | re.I) +HOST_RE = re.compile(r'<entry name="(?P<hostname>.+)">(?P<ip>.+)</entry>') + + +class PlexHostsManager(object): + _hosts = None + _orig_hosts = None + + HOSTS_TPL = """\ + <hosts><!-- managed by PM4K --> +{} + </hosts>""" + ENTRY_TPL = ' <entry name="{}">{}</entry>' + + def __init__(self): + self.load() + + def __bool__(self): + return bool(self._hosts) + + def __len__(self): + return self and len(self._hosts) or 0 + + def getHosts(self): + return self._hosts or {} + + @property + def hadHosts(self): + return bool(self._orig_hosts) + + def newHosts(self, hosts, source="stored"): + """ + hosts should be a list of plex.direct connection uri's + """ + for address in hosts: + parsed = urlparse(address) + ip = parsePlexDirectHost(parsed.hostname) + # ignore docker V4 hosts + if util.addonSettings.ignoreDockerV4 and ":" not in ip and IPv4Address(text_type(ip)) in DOCKER_NETWORK: + util.DEBUG_LOG("Ignoring plex.direct local {} Docker IPv4 address: {}", source, parsed.hostname) + continue + + if parsed.hostname not in self._hosts: + self._hosts[parsed.hostname] = plexnet.http.RESOLVED_PD_HOSTS.get(parsed.hostname, ip) + util.LOG("Found new unmapped {} plex.direct host: {}", source, parsed.hostname) + + @property + def differs(self): + return self._hosts != self._orig_hosts + + @property + def diff(self): + return set(self._hosts) - set(self._orig_hosts) + + def load(self): + data = adv.getData() + self._hosts = {} + self._orig_hosts = {} + if not data: + return + + hosts_match = HOSTS_RE.search(data) + if hosts_match: + hosts_xml = hosts_match.group(0) + + hosts = HOST_RE.findall(hosts_xml) + if hosts: + self._hosts = dict(hosts) + self._orig_hosts = dict(hosts) + util.DEBUG_LOG("Found {} hosts in advancedsettings.xml", lambda: len(self._hosts)) + + def write(self, hosts=None): + self._hosts = hosts or self._hosts + if not self._hosts: + return + data = adv.getData() + cd = "<advancedsettings>\n</advancedsettings>" + if data: + hosts_match = HOSTS_RE.search(data) + if hosts_match: + hosts_xml = hosts_match.group(0) + cd = data.replace(hosts_xml, "") + else: + cd = data + + finalxml = "{}\n</advancedsettings>".format( + cd.replace("</advancedsettings>", self.HOSTS_TPL.format("\n".join(self.ENTRY_TPL.format(hostname, ip) + for hostname, ip in self._hosts.items()))) + ) + + adv.write(finalxml) + self._orig_hosts = dict(self._hosts) + + +pdm = PlexHostsManager() diff --git a/script.plexmod/lib/templating/__init__.py b/script.plexmod/lib/templating/__init__.py new file mode 100644 index 0000000000..857829ad13 --- /dev/null +++ b/script.plexmod/lib/templating/__init__.py @@ -0,0 +1,3 @@ +# coding=utf-8 + +from .render import render_templates diff --git a/script.plexmod/lib/templating/context.py b/script.plexmod/lib/templating/context.py new file mode 100644 index 0000000000..fdd6df8643 --- /dev/null +++ b/script.plexmod/lib/templating/context.py @@ -0,0 +1,213 @@ +# coding=utf-8 + +TEMPLATE_CONTEXTS = { + "core": { + "resolution": (1920, 1080), + "needs_scaling": False, + }, + "indicators": { + "base": { + "use_scaling": False, + "scale": { + + } + }, + "classic": { + "INHERIT": "base", + "use_unwatched": True, + "hide_aw_bg": None, + "watched_bg": None, + "unwatched_count_bg": "FFCC7B19", + "textcolor": "FF000000", + "assets": { + "unwatched": "unwatched.png" + } + }, + "modern": { + "INHERIT": "base", + "use_scaling": True, + "scale": { + "tiny": 0.75, + "small": 1.0, + "medium": 1.175, + "large": 1.3 + }, + "use_unwatched": False, + "hide_aw_bg": False, + "watched_bg": "CC000000", + "unwatched_count_bg": "CC000000", + "textcolor": "FFFFFFFF", + "assets": { + "watched": "watched.png" + } + }, + "modern_2024": { + "INHERIT": "modern", + "assets": { + "watched": "watched_2024.png" + } + } + }, + "themes": { + "base": { + # general config + "assets": { + "buttons": { + "base": "script.plex/buttons/", + "focusSuffix": "-focus", + } + }, + "buttons": { + "useFocusColor": True, + "useNoFocusColor": True, + "zoomPlayButton": False, + "focusColor": None, + "noFocusColor": None + }, + + # specific interface config + "episodes": { + "use_button_bg": False, + "button_bg_color": None, + "buttongroup": { + "posy": None, + "itemgap": -50, + }, + # this button group will only exist when multiple media files for an episode exist, it adds another button + "buttongroup_1300": { + "posy": None, + "itemgap": -50, + }, + # applies to the main buttons + "buttons": { + "width": None, + "height": None, + } + }, + "seasons": { + "buttongroup": { + "itemgap": -20 + }, + "buttons": { + "width": None, + "height": None, + } + }, + "pre_play": { + "buttongroup": { + "itemgap": -20 + }, + "buttons": { + "width": None, + "height": None, + } + } + }, + "classic": { + "INHERIT": "base", + "episodes": { + "buttongroup": { + "posy": 369 + }, + "buttongroup_1300": { + "posy": "388.5" + }, + "buttons": { + "width": 176, + "height": 140 + }, + "buttons_1300": { + "width": 161, + "height": 125 + } + }, + "seasons": { + "buttons": { + "width": 126, + "height": 100, + } + }, + "pre_play": { + "buttongroup": { + "itemgap": -50 + }, + "buttons": { + "width": 176, + "height": 140, + } + }, + }, + "modern": { + "INHERIT": "base", + "assets": { + "buttons": { + "base": "script.plex/buttons/player/modern/", + "focusSuffix": "", + } + }, + "buttons": { + "useFocusColor": False, + "zoomPlayButton": True, + "noFocusColor": "88FFFFFF" + }, + "episodes": { + "use_button_bg": True, + "button_bg_color": "66000000", + "buttongroup": { + "posy": 369, + "itemgap": -40, + }, + "buttongroup_1300": { + "posy": 369, + "itemgap": -40, + }, + "buttons": { + "width": 131, + "height": 104, + }, + "buttons_1300": { + "width": 131, + "height": 104 + } + }, + "seasons": { + "buttongroup": { + "itemgap": -40 + }, + "buttons": { + "width": 152, + "height": 121, + } + }, + "pre_play": { + "buttongroup": { + "itemgap": -40 + }, + "buttons": { + "width": 152, + "height": 121, + } + } + }, + "modern-colored": { + "INHERIT": "modern", + "buttons": { + "useFocusColor": True, + "zoomPlayButton": False, + } + }, + "modern-dotted": { + "INHERIT": "modern", + "assets": { + "buttons": { + "base": "script.plex/buttons/player/modern-dotted/", + "focusSuffix": "-focus", + } + }, + "buttons": { + "useFocusColor": False, + "zoomPlayButton": False, + } + } + } +} diff --git a/script.plexmod/lib/templating/core.py b/script.plexmod/lib/templating/core.py new file mode 100644 index 0000000000..30a533922d --- /dev/null +++ b/script.plexmod/lib/templating/core.py @@ -0,0 +1,159 @@ +# coding=utf-8 +import os +import glob + +from pprint import pformat +from kodi_six import xbmcvfs, xbmc +from ibis.context import ContextDict +from lib.logging import log as LOG, log_error as ERROR +from .util import deep_update +from lib.os_utils import fast_iglob +from .filters import * + + +def build_stack(inheritor, sources): + inherit_from = inheritor.pop("INHERIT", None) + data_stack = [inheritor] + while inherit_from: + inheritor = ContextDict(copy.deepcopy(sources[inherit_from])) + inherit_from = inheritor.pop("INHERIT", None) + data_stack.append(inheritor) + + return data_stack + + +def prepare_template_data(thm, context): + template_context = {"theme": {}} + + theme_data = {"INHERIT": thm} + + # data stack + data_stack = build_stack(theme_data, context.pop("themes")) + + # build inheritance stack + while data_stack: + deep_update(template_context["theme"], data_stack.pop()) + + for ctx in ("core", "indicators",): + # simple overrides + if "START" not in context[ctx]: + data_stack.append(context[ctx]) + else: + # overrides with inheritance + data_stack = build_stack(context[ctx]["START"], context[ctx]) + template_context[ctx] = ContextDict() + while data_stack: + deep_update(template_context[ctx], data_stack.pop()) + + return ContextDict(template_context) + + +class TemplateEngine(object): + loader = None + target_dir = None + template_dir = None + custom_template_dir = None + initialized = False + context = None + debug_log = None + TEMPLATES = None + + def init(self, target_dir, template_dir, custom_template_dir): + self.target_dir = target_dir + self.template_dir = template_dir + self.custom_template_dir = custom_template_dir + self.get_available_templates() + paths = [custom_template_dir, template_dir] + + LOG("Looking for templates in: {}", paths) + self.prepare_loader(paths) + self.initialized = True + + def get_available_templates(self): + tpls = [] + for f in fast_iglob(os.path.join(self.template_dir, "script-plex-*.xml.tpl")): + tpls.append(f.split("script-plex-")[1].split(".xml.tpl")[0]) + self.TEMPLATES = tpls + + def prepare_loader(self, fns): + self.loader = ibis.loaders.FileLoader(*fns) + ibis.loader = self.loader + + def compile(self, fn, data): + template = self.loader(fn) + return template.render(data) + + def write(self, template, data, retry=0): + def ensure_file_exists(file_name, expected_size): + if xbmcvfs.exists(file_name): + s = xbmcvfs.Stat(file_name) + size = s.st_size() + return size == expected_size + return False + + leeway = 50 + expected_len = len(data) + # write final file + count = 0 + fn = os.path.join(self.target_dir, "script-plex-{}.xml".format(template)) + f = xbmcvfs.File(fn, "w") + + try: + success = f.write(data) + + while not success and count < leeway: + success = f.write(data) + xbmc.sleep(100) + count += 1 + finally: + f.close() + + count = 0 + exists = ensure_file_exists(fn, expected_len) + while not exists and count < leeway: + xbmc.sleep(100) + exists = ensure_file_exists(fn, expected_len) + count += 1 + + if not exists: + if retry > 0: + raise OSError("Timed out while waiting for template {} to be saved to disk".format(fn)) + return self.write(template, data, retry=1) + return True + + def apply(self, theme, update_callback, templates=None): + templates = self.TEMPLATES if templates is None else templates + template_context = prepare_template_data(theme, self.context) + self.debug_log("Final template context: {}".format(pformat(template_context))) + + progress = {"at": 0, "steps": len(templates)} + + def step(message): + progress["at"] += 1 + update_callback(progress["at"], progress["steps"], message) + + custom_templates = [] + if theme == "custom": + progress["steps"] += 1 + step("custom_templates") + custom_templates = [f.split("script-plex-")[1].split(".custom.xml.tpl")[0] for f in + glob.iglob(os.path.join(self.custom_template_dir, "*.custom.xml.tpl"))] + if not custom_templates: + LOG("No custom templates found in: {}", self.custom_template_dir) + + applied = [] + for template in templates: + fn = "script-plex-{}{}.xml.tpl".format(template, ".custom" if theme == "custom" and + template in custom_templates else "") + compiled_template = self.compile(fn, template_context) + if self.write(template, compiled_template): + applied.append(template) + else: + raise Exception("Couldn't write script-plex-{}.xml", template) + step(template) + + update_callback(progress["steps"], progress["steps"], "complete") + LOG('Using theme {} for: {}', theme, applied) + + +engine = TemplateEngine() diff --git a/script.plexmod/lib/templating/filters.py b/script.plexmod/lib/templating/filters.py new file mode 100644 index 0000000000..b660871918 --- /dev/null +++ b/script.plexmod/lib/templating/filters.py @@ -0,0 +1,130 @@ +# coding=utf-8 + +import ibis +import copy +import operator +import six + +from .util import register_builtin +from lib.aspectratio import v_ar_ratio +from lib.logging import log as LOG +from ibis.context import Undefined + + +@ibis.filters.register('get') +def get_attr(obj, attr, fallback=None, default=None): + if isinstance(attr, Undefined): + return obj.get(fallback, default) + return obj.get(attr, default) + + +@ibis.filters.register('calc') +@register_builtin +def calc(a, b, op="add"): + if isinstance(a, six.string_types): + a = float(a) if "." in a else int(a) + elif isinstance(b, six.string_types): + b = float(b) if "." in b else int(b) + try: + return getattr(operator, op)(a, b) + except: + raise ValueError("Can't calculate {}({}:{}, {}:{})".format(op, type(a), repr(a), type(b), repr(b))) + + +@ibis.filters.register('vscale', with_context=True) +@register_builtin +def vscale(value, up=1, negpos=False, context=None): + """ + scale integer based on the aspect ratio difference between the current resolution and our default resolution + + up is there to optionally apply a factor on top of the scaled value. this is important for buttons without a set + width, as they tend to get crushed + + negpos is used when we use negative absolute window position animations to position controls greater than our + screen size, e.g. "scrolling" them. In this case we subtract the resulting scaled value from the original one, + shifting it further into negativeness + fixme: Not sure if this is universal + """ + if not context.core.needs_scaling: + return value + + cached_scale = context.get('cached_scale', None) + if cached_scale is None: + w, h = context.core.resolution + cached_scale = v_ar_ratio(w, h) + context.set_global("cached_scale", cached_scale) + + if negpos and value < 0: + return value + round(cached_scale * value, 2) * up + return round(cached_scale * value, 2) * up + + +@ibis.filters.register('vperc') +@register_builtin +def vperc(height, perc=50, ref=1080, rel=50, r=2): + """ + return vertical position based on percentage of ref, percentage of height + @param r: + @param rel: + @param perc: + @param height: + @param ref: + @return: float + """ + return round(perc * ref / 100.0 - height * rel / 100.0, r) + + +@ibis.filters.register('valign') +@register_builtin +def valign(height, align="middle"): + if align == "middle": + return vperc(height) + elif align == "bottom": + return vperc(height, perc=100, rel=100) + + +@ibis.filters.register('add') +@register_builtin +def add(a, b): + return calc(a, b) + + +@ibis.filters.register('sub') +@register_builtin +def sub(a, b): + return calc(a, b, op="sub") + + +@ibis.filters.register('div') +@register_builtin +def div(a, b): + return calc(a, b, op="truediv") + + +@ibis.filters.register('mul') +@register_builtin +def mul(a, b): + return calc(a, b, op="mul") + + +@ibis.filters.register('int') +@register_builtin +def cast_int(a): + return int(a) + + +@ibis.filters.register('resolve', with_context=True) +@register_builtin('resolve') +def resolve_variable(arg, context=None): + return ibis.nodes.ResolveContextVariable(arg) + + +@ibis.filters.register('merge_dict') +@ibis.filters.register('merge') +@register_builtin('merge') +def merge_dict(*args): + final_dict = {} + for arg in args: + final_dict.update(copy.deepcopy(arg)) + + return final_dict diff --git a/script.plexmod/lib/templating/render.py b/script.plexmod/lib/templating/render.py new file mode 100644 index 0000000000..c5e4440678 --- /dev/null +++ b/script.plexmod/lib/templating/render.py @@ -0,0 +1,100 @@ +# coding=utf-8 +import json +import os +import time +import copy + +from .core import engine +# noinspection PyUnresolvedReferences +from lib.util import (DEF_THEME, ADDON, PROFILE, getSetting, translatePath, THEME_VERSION, setSetting, DEBUG_LOG, LOG, + T, MONITOR, xbmcvfs, addonSettings, DISPLAY_RESOLUTION, NEEDS_SCALING) +from .context import TEMPLATE_CONTEXTS +from .util import deep_update +from lib.os_utils import fast_glob +from lib.windows.busy import ProgressDialog + + +STEP_MAP = { + "custom_templates": 33063, + "default": 33064, + "complete": 33065 +} + + +def render_templates(theme=None, templates=None, force=False): + # apply theme if version changed + theme = theme or getSetting('theme', DEF_THEME) + target_dir = os.path.join(translatePath(ADDON.getAddonInfo('path')), "resources", "skins", "Main", "1080i") + + # try to find custom theme_overrides.json in userdata + custom_context_data_fn = os.path.join(PROFILE, "context_overrides.json") + context = copy.deepcopy(TEMPLATE_CONTEXTS) + if xbmcvfs.exists(custom_context_data_fn): + try: + f = xbmcvfs.File(custom_context_data_fn) + data = f.read() + f.close() + if data: + js = json.loads(data) + deep_update(context, js) + LOG("Loaded context overrides definitions from: {}".format(custom_context_data_fn)) + except: + LOG("Couldn't load {}", custom_context_data_fn) + + if not engine.initialized: + engine.init(target_dir, os.path.join(target_dir, "templates"), + os.path.join(translatePath(PROFILE), "templates")) + + engine.context = context + engine.debug_log = DEBUG_LOG + + def apply(): + LOG("Rendering templates") + start = time.time() + + with ProgressDialog(T(33062, ''), "", raise_hard=True) as pd: + def update_progress(at, length, message): + pd.update(int(at * 100 / float(length)), + message=T(STEP_MAP.get(message, STEP_MAP["default"]), '').format(message)) + + # get template overrides + watch_state_type = getSetting('watched_indicators', 'modern_2024') + overrides = { + "core": { + "resolution": DISPLAY_RESOLUTION, + "needs_scaling": NEEDS_SCALING + }, + "indicators": { + "START": { + "INHERIT": watch_state_type, + "style": watch_state_type, + "hide_aw_bg": getSetting('hide_aw_bg', False), + "use_scaling": getSetting('scale_indicators', True) + } + }, + } + deep_update(context, overrides) + + engine.apply(theme, update_progress, templates=templates) + end = time.time() + MONITOR.waitForAbort(0.1) + + LOG("Rendered templates in: {:.2f}s".format(end - start)) + + curThemeVer = getSetting('theme_version', 0) + lastRes = getSetting('last_resolution', "1920x1080").split("x") + lastSeenRes = [int(lastRes[0]), int(lastRes[1])] + + if curThemeVer < THEME_VERSION or (force or + lastSeenRes != DISPLAY_RESOLUTION or + addonSettings.alwaysCompileTemplates or + len(fast_glob(os.path.join(engine.template_dir, "script-plex-*.xml.tpl"))) != + len(fast_glob(os.path.join(engine.target_dir, "script-plex-*.xml")))): + setSetting('theme_version', THEME_VERSION) + setSetting('last_resolution', "x".join(list(map(str, DISPLAY_RESOLUTION)))) + # apply seekdialog button theme + apply() + + # lose template cache for performance reasons + if not addonSettings.cacheTemplates: + engine.loader.cache = {} diff --git a/script.plexmod/lib/templating/templates.py b/script.plexmod/lib/templating/templates.py new file mode 100644 index 0000000000..ab06361e3e --- /dev/null +++ b/script.plexmod/lib/templating/templates.py @@ -0,0 +1,19 @@ +# coding=utf-8 + +# unused right now +TEMPLATES = { + "episodes": { + "controls": { + "buttons": [ + { + "visible": "String.IsEmpty(Window.Property(use_bg_fallback))", + "posx": 0, + "posy": 0, + "width": 1920, + "height": 1080, + "texture": "$INFO[Window.Property(background_static)]" + }, + ] + } + } +} diff --git a/script.plexmod/lib/templating/util.py b/script.plexmod/lib/templating/util.py new file mode 100644 index 0000000000..4777305f30 --- /dev/null +++ b/script.plexmod/lib/templating/util.py @@ -0,0 +1,31 @@ +# coding=utf-8 +import ibis.context + +from ibis.context import ContextDict +from six.moves import collections_abc as collections + + +def register_builtin(nameorfunc): + if callable(nameorfunc): + ibis.context.builtins[nameorfunc.__name__] = nameorfunc + return nameorfunc + + def register_filter_function(func): + ibis.context.builtins[nameorfunc or func.__name__] = func + return func + + return register_filter_function + + +def deep_update(source, overrides): + """ + Update a nested dictionary or similar mapping. + Modify ``source`` in place. + """ + for key, value in overrides.items(): + if isinstance(value, collections.Mapping) and value: + returned = deep_update(source.get(key, {}), ContextDict(value)) + source[key] = returned + else: + source[key] = overrides[key] + return source diff --git a/script.plexmod/lib/util.py b/script.plexmod/lib/util.py index 025ae4b734..c2e2e176f1 100644 --- a/script.plexmod/lib/util.py +++ b/script.plexmod/lib/util.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import + import gc +import os import sys import re import binascii @@ -10,22 +12,36 @@ import time import datetime import contextlib +import subprocess +import unicodedata +import pprint + import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import six -import os import struct import requests +import plexnet.util + from .kodijsonrpc import rpc +# noinspection PyUnresolvedReferences from kodi_six import xbmc +# noinspection PyUnresolvedReferences from kodi_six import xbmcgui +# noinspection PyUnresolvedReferences from kodi_six import xbmcaddon +# noinspection PyUnresolvedReferences from kodi_six import xbmcvfs from . import colors # noinspection PyUnresolvedReferences from .exceptions import NoDataException -from plexnet import signalsmixin, plexapp +from .logging import log, log_error +# noinspection PyUnresolvedReferences +from .i18n import T +from . import aspectratio +from .kodi_util import * +from plexnet import signalsmixin DEBUG = True _SHUTDOWN = False @@ -34,49 +50,18 @@ SETTINGS_LOCK = threading.Lock() -_build = None -# buildversion looks like: XX.X[-TAG] (a+.b+.c+) (.+); there are kodi builds that don't set the build version -sys_ver = xbmc.getInfoLabel('System.BuildVersion') -_ver = sys_ver +SKIN_PLEXTUARY = xbmc.getSkinDir() == "skin.plextuary" +FROM_KODI_REPOSITORY = ADDON.getAddonInfo('name') == "PM4K for Plex" +PROFILE = translatePath(ADDON.getAddonInfo('profile')) -try: - if ' ' in sys_ver and '(' in sys_ver: - _ver, _build = sys_ver.split()[:2] - _splitver = _ver.split(".") - KODI_VERSION_MAJOR, KODI_VERSION_MINOR = int(_splitver[0].split("-")[0].strip()), \ - int(_splitver[1].split(" ")[0].split("-")[0].strip()) -except: - xbmc.log('script.plex: Couldn\'t determine Kodi version, assuming 19.4. Got: {}'.format(sys_ver)) - # assume something "old" - KODI_VERSION_MAJOR = 19 - KODI_VERSION_MINOR = 4 - -_bmajor, _bminor, _bpatch = (KODI_VERSION_MAJOR, KODI_VERSION_MINOR, 0) -parsedBuild = False -if _build: - try: - _bmajor, _bminor, _bpatch = _build[1:-1].split(".") - parsedBuild = True - except: - pass -if not parsedBuild: - xbmc.log('script.plex: Couldn\'t determine build version, falling back to Kodi version', xbmc.LOGINFO) +DEF_THEME = "modern-colored" +THEME_VERSION = 27 -# calculate a comparable build number -KODI_BUILD_NUMBER = int("{0}{1:02d}{2:03d}".format(_bmajor, int(_bminor), int(_bpatch))) xbmc.log('script.plex: Kodi {0}.{1} (build {2})'.format(KODI_VERSION_MAJOR, KODI_VERSION_MINOR, KODI_BUILD_NUMBER), xbmc.LOGINFO) -if KODI_VERSION_MAJOR > 18: - translatePath = xbmcvfs.translatePath -else: - translatePath = xbmc.translatePath - -PROFILE = translatePath(ADDON.getAddonInfo('profile')) - - def getChannelMapping(): data = rpc.Settings.GetSettings(filter={"section": "system", "category": "audio"})["settings"] return list(filter(lambda i: i["id"] == "audiooutput.channels", data))[0]["options"] @@ -108,23 +93,43 @@ def getLanguageCode(add_def=None): ACCEPT_LANGUAGE_CODE = 'en-US,en' +try: + DISPLAY_RESOLUTION = [xbmcgui.getScreenWidth(), xbmcgui.getScreenHeight()] +except: + log('Couldn\'t determine display resolution') + DISPLAY_RESOLUTION = [1920, 1080] + + +CURRENT_AR = DISPLAY_RESOLUTION[0] / DISPLAY_RESOLUTION[1] + +# we currently only support vertical scaling for smaller ARs; change to != once we know how to scale horizontally +NEEDS_SCALING = round(CURRENT_AR, 2) < round(1920 / 1080, 2) + + def getSetting(key, default=None): with SETTINGS_LOCK: setting = ADDON.getSetting(key) - return _processSetting(setting, default) + is_json = key in JSON_SETTINGS + return _processSetting(setting, default, is_json=is_json) def getUserSetting(key, default=None): - if not plexapp.ACCOUNT: + if not plexnet.util.ACCOUNT: return default - key = '{}.{}'.format(key, plexapp.ACCOUNT.ID) + is_json = key in JSON_SETTINGS + + key = '{}.{}'.format(key, plexnet.util.ACCOUNT.ID) with SETTINGS_LOCK: setting = ADDON.getSetting(key) - return _processSetting(setting, default) + return _processSetting(setting, default, is_json=is_json) + + +JSON_SETTINGS = [] +USER_SETTINGS = [] -def _processSetting(setting, default): +def _processSetting(setting, default, is_json=False): if not setting: return default if isinstance(default, bool): @@ -133,7 +138,7 @@ def _processSetting(setting, default): return float(setting) elif isinstance(default, int): return int(float(setting or 0)) - elif isinstance(default, list): + elif isinstance(default, list) and not is_json: if setting: return json.loads(binascii.unhexlify(setting)) else: @@ -142,7 +147,19 @@ def _processSetting(setting, default): return setting -class AdvancedSettings(object): +HOME_BUTTON_MAPPED = None + + +def homeButtonMapped(*args, **kwargs): + global HOME_BUTTON_MAPPED + data = getSetting('map_button_home', None) + HOME_BUTTON_MAPPED = data if data != "None" else None + + +homeButtonMapped() + + +class AddonSettings(object): """ @DynamicAttrs """ @@ -162,14 +179,16 @@ class AdvancedSettings(object): ("postplay_timeout", 16), ("skip_intro_button_timeout", 10), ("skip_credits_button_timeout", 10), - ("playlist_visit_media", True), + ("playlist_visit_media", False), ("intro_skip_early", False), ("show_media_ends_info", True), ("show_media_ends_label", True), ("background_colour", None), - ("oldprofile", False), - ("skip_intro_button_show_early_threshold1", 60), - ("requests_timeout", 5.0), + ("skip_intro_button_show_early_threshold1", 70), + ("requests_timeout_connect", 5.0), + ("requests_timeout_read", 10.0), + ("plextv_timeout_connect", 1.0), + ("plextv_timeout_read", 2.0), ("local_reach_timeout", 10), ("auto_skip_offset", 2.5), ("conn_check_timeout", 2.5), @@ -188,6 +207,20 @@ class AdvancedSettings(object): ("consecutive_video_pb_wait", 0.0), ("retrieve_all_media_up_front", False), ("library_chunk_size", 240), + ("verify_mapped_files", True), + ("episode_no_spoiler_blur", 16), + ("ignore_docker_v4", True), + ("cache_home_users", True), + ("intro_marker_max_offset", 600), + ("hubs_rr_max", 250), + ("max_retries1", 3), + ("use_cert_bundle", "acme"), + ("cache_templates", True), + ("always_compile_templates", False), + ("tickrate", 1.0), + ("honor_plextv_dnsrebind", True), + ("honor_plextv_pam", True), + ("coreelec_resume_seek_wait", 350), ) def __init__(self): @@ -198,37 +231,27 @@ def __init__(self): getSetting(setting, default)) -advancedSettings = AdvancedSettings() +addonSettings = AddonSettings() + +DEBUG = addonSettings.debug -def LOG(msg, level=xbmc.LOGINFO): - xbmc.log('script.plex: {0}'.format(msg), level) +def LOG(msg, *args, **kwargs): + return log(msg, *args, **kwargs) -def DEBUG_LOG(msg): +def DEBUG_LOG(msg, *args, **kwargs): if _SHUTDOWN: return - if not advancedSettings.debug and not xbmc.getCondVisibility('System.GetBool(debug.showloginfo)'): + if not addonSettings.debug and not xbmc.getCondVisibility('System.GetBool(debug.showloginfo)'): return - LOG(msg) + return log(msg, *args, **kwargs) def ERROR(txt='', hide_tb=False, notify=False, time_ms=3000): - short = str(sys.exc_info()[1]) - if hide_tb: - xbmc.log('script.plex: ERROR: {0} - {1}'.format(txt, short), xbmc.LOGERROR) - return short - - import traceback - tb = traceback.format_exc() - xbmc.log("_________________________________________________________________________________", xbmc.LOGERROR) - xbmc.log('script.plex: ERROR: ' + txt, xbmc.LOGERROR) - for l in tb.splitlines(): - xbmc.log(' ' + l, xbmc.LOGERROR) - xbmc.log("_________________________________________________________________________________", xbmc.LOGERROR) - xbmc.log("`", xbmc.LOGERROR) + short = log_error(txt, hide_tb) if notify: showNotification('ERROR: {0}'.format(txt or short), time_ms=time_ms) return short @@ -280,21 +303,30 @@ def actionLogoff(self): def onNotification(self, sender, method, data): LOG("Notification: {} {} {}".format(sender, method, data)) if sender == 'script.plexmod' and method.endswith('RESTORE'): - from .windows import kodigui + from .windows import kodigui, windowutils + + def exit_mainloop(): + LOG("Addon never properly started, can't reactivate") + windowutils.HOME.doClose() + if not kodigui.BaseFunctions.lastWinID: - ERROR("Addon never properly started, can't reactivate") - setGlobalProperty('stop_running', '1') + exit_mainloop() return if kodigui.BaseFunctions.lastWinID > 13000: reInitAddon() + setGlobalProperty('is_active', '1') xbmc.executebuiltin('ActivateWindow({0})'.format(kodigui.BaseFunctions.lastWinID)) else: - ERROR("Addon never properly started, can't reactivate") - setGlobalProperty('stop_running', '1') + exit_mainloop() return - elif sender == "xbmc" and method == "System.OnSleep" and getSetting('action_on_sleep', "none") != "none": - getattr(self, "action{}".format(getSetting('action_on_sleep', "none").capitalize()))() + elif sender == "xbmc" and method == "System.OnSleep": + if getSetting('action_on_sleep', "none") != "none": + getattr(self, "action{}".format(getSetting('action_on_sleep', "none").capitalize()))() + self.trigger('system.sleep') + + elif sender == "xbmc" and method == "System.OnWake": + self.trigger('system.wakeup') def stopPlayback(self): LOG('Monitor: Stopping media playback') @@ -302,11 +334,22 @@ def stopPlayback(self): def onScreensaverActivated(self): DEBUG_LOG("Monitor: OnScreensaverActivated") - if getSetting('player_stop_on_screensaver', True) and xbmc.Player().isPlayingVideo(): + self.trigger('screensaver.activated') + if getSetting('player_stop_on_screensaver', False) and xbmc.Player().isPlayingVideo(): self.stopPlayback() + def onScreensaverDeactivated(self): + DEBUG_LOG("Monitor: OnScreensaverDeactivated") + self.trigger('screensaver.deactivated') + def onDPMSActivated(self): DEBUG_LOG("Monitor: OnDPMSActivated") + self.trigger('dpms.activated') + #self.stopPlayback() + + def onDPMSDeactivated(self): + DEBUG_LOG("Monitor: OnDPMSDeactivated") + self.trigger('dpms.deactivated') #self.stopPlayback() def onSettingsChanged(self): @@ -316,184 +359,17 @@ def onSettingsChanged(self): MONITOR = UtilityMonitor() -ADV_MSIZE_RE = re.compile(r'<memorysize>(\d+)</memorysize>') -ADV_RFACT_RE = re.compile(r'<readfactor>(\d+)</readfactor>') -ADV_CACHE_RE = re.compile(r'\s*<cache>.*</cache>', re.S | re.I) - - -class KodiCacheManager(object): - """ - A pretty cheap approach at managing the <cache> section of advancedsettings.xml - - Starting with build 20.90.821 (Kodi 21.0-BETA2) a lot of caching issues have been fixed and - readfactor behaves better. We need to adjust for that. - """ - _cleanData = None - useModernAPI = False - memorySize = 20 # in MB - readFactor = 4 - defRF = 4 - defRFSM = 20 - recRFRange = "4-10" - template = None - orig_tpl_path = os.path.join(ADDON.getAddonInfo('path'), "pm4k_cache_template.xml") - custom_tpl_path = "special://profile/pm4k_cache_template.xml" - translated_ctpl_path = translatePath(custom_tpl_path) - - # give Android a little more leeway with its sometimes weird memory management; otherwise stick with 23% of free mem - safeFactor = .20 if xbmc.getCondVisibility('System.Platform.Android') else .23 - - def __init__(self): - if KODI_BUILD_NUMBER >= 2090821: - self.memorySize = rpc.Settings.GetSettingValue(setting='filecache.memorysize')['value'] - self.readFactor = rpc.Settings.GetSettingValue(setting='filecache.readfactor')['value'] / 100.0 - if self.readFactor % 1 == 0: - self.readFactor = int(self.readFactor) - DEBUG_LOG("Not using advancedsettings.xml for cache/buffer management, we're at least Kodi 21 non-alpha") - self.useModernAPI = True - self.defRFSM = 7 - self.recRFRange = "1.5-4" - - if KODI_BUILD_NUMBER >= 2090830: - self.recRFRange = ADDON.getLocalizedString(32976) - - else: - self.load() - self.template = self.getTemplate() - - plexapp.util.APP.on('change:slow_connection', - lambda value=None, **kwargs: self.write(readFactor=value and self.defRFSM or self.defRF)) - - def getTemplate(self): - if xbmcvfs.exists(self.custom_tpl_path): - try: - f = xbmcvfs.File(self.custom_tpl_path) - data = f.read() - f.close() - if data: - return data - except: - pass - - DEBUG_LOG("Custom pm4k_cache_template.xml not found, using default") - f = xbmcvfs.File(self.orig_tpl_path) - data = f.read() - f.close() - return data - - def load(self): - try: - f = xbmcvfs.File("special://profile/advancedsettings.xml") - data = f.read() - f.close() - except: - LOG('script.plex: No advancedsettings.xml found') - else: - cachexml_match = ADV_CACHE_RE.search(data) - if cachexml_match: - cachexml = cachexml_match.group(0) - - try: - self.memorySize = int(ADV_MSIZE_RE.search(cachexml).group(1)) // 1024 // 1024 - except: - DEBUG_LOG("script.plex: invalid or not found memorysize in advancedsettings.xml") - - try: - self.readFactor = int(ADV_RFACT_RE.search(cachexml).group(1)) - except: - DEBUG_LOG("script.plex: invalid or not found readfactor in advancedsettings.xml") - - self._cleanData = data.replace(cachexml, "") - else: - self._cleanData = data - - def write(self, memorySize=None, readFactor=None): - memorySize = self.memorySize = memorySize if memorySize is not None else self.memorySize - readFactor = self.readFactor = readFactor if readFactor is not None else self.readFactor - - if self.useModernAPI: - # kodi cache settings have moved to Services>Caching - try: - rpc.Settings.SetSettingValue(setting='filecache.memorysize', value=self.memorySize) - rpc.Settings.SetSettingValue(setting='filecache.readfactor', value=int(self.readFactor * 100)) - except: - pass - return - - cd = self._cleanData - if not cd: - cd = "<advancedsettings>\n</advancedsettings>" - - finalxml = "{}\n</advancedsettings>".format( - cd.replace("</advancedsettings>", self.template.format(memorysize=memorySize * 1024 * 1024, - readfactor=readFactor)) - ) - - try: - f = xbmcvfs.File("special://profile/advancedsettings.xml", "w") - f.write(finalxml) - f.close() - except: - ERROR("Couldn't write advancedsettings.xml") - - def clamp16(self, x): - return x - x % 16 - - @property - def viableOptions(self): - default = list(filter(lambda x: x < self.recMax, - [16, 20, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024])) - - # add option to overcommit slightly - overcommit = [] - if xbmc.getCondVisibility('System.Platform.Android'): - overcommit.append(min(self.clamp16(int(self.free * 0.23)), 2048)) - - overcommit.append(min(self.clamp16(int(self.free * 0.26)), 2048)) - overcommit.append(min(self.clamp16(int(self.free * 0.3)), 2048)) - - # re-append current memorySize here, as recommended max might have changed - return list(sorted(list(set(default + [self.memorySize, self.recMax] + overcommit)))) - - @property - def readFactorOpts(self): - ret = list(sorted(list(set([1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5, 7, 10, 15, 20, 30, 50] + [self.readFactor])))) - if KODI_BUILD_NUMBER >= 2090830 and self.readFactor > 0: - # support for adaptive read factor from build 2090822 onwards - ret.insert(0, 0) - return ret - - @property - def free(self): - return float(xbmc.getInfoLabel('System.Memory(free)')[:-2]) - - @property - def recMax(self): - freeMem = self.free - recMem = min(int(freeMem * self.safeFactor), 2048) - LOG("Free memory: {} MB, recommended max: {} MB".format(freeMem, recMem)) - return recMem - - -kcm = KodiCacheManager() - -CACHE_SIZE = kcm.memorySize - - -def T(ID, eng=''): - return ADDON.getLocalizedString(ID) - hasCustomBGColour = False if KODI_VERSION_MAJOR > 18: - hasCustomBGColour = not advancedSettings.dynamicBackgrounds and advancedSettings.backgroundColour and \ - advancedSettings.backgroundColour != "-" + hasCustomBGColour = not addonSettings.dynamicBackgrounds and addonSettings.backgroundColour and \ + addonSettings.backgroundColour != "-" def getAdvancedSettings(): # yes, global, hang me! - global advancedSettings - advancedSettings = AdvancedSettings() + global addonSettings + addonSettings = AddonSettings() def reInitAddon(): @@ -518,18 +394,6 @@ def _processSettingForWrite(value): return str(value) -def setGlobalProperty(key, val, base='script.plex.{0}'): - xbmcgui.Window(10000).setProperty(base.format(key), val) - - -def setGlobalBoolProperty(key, boolean, base='script.plex.{0}'): - xbmcgui.Window(10000).setProperty(base.format(key), boolean and '1' or '') - - -def getGlobalProperty(key): - return xbmc.getInfoLabel('Window(10000).Property(script.plex.{0})'.format(key)) - - def showNotification(message, time_ms=3000, icon_path=None, header=ADDON.getAddonInfo('name')): try: icon_path = icon_path or translatePath(ADDON.getAddonInfo('icon')) @@ -665,7 +529,7 @@ def shortenText(text, size): def scaleResolution(w, h, by=None): if by is None: - by = advancedSettings.posterResolutionScalePerc + by = addonSettings.posterResolutionScalePerc if 0 < by != 100.0: px = w * h * (by / 100.0) @@ -675,6 +539,30 @@ def scaleResolution(w, h, by=None): return w, h +def vscale(h, r=2): + if not NEEDS_SCALING: + return h + ratio = aspectratio.V_AR_RATIO + if ratio is None: + ratio = aspectratio.v_ar_ratio(DISPLAY_RESOLUTION[0], DISPLAY_RESOLUTION[1]) + return round(ratio * h, r) if r > 0 else int(round(ratio * h, r)) + + +def vscalei(h): + return vscale(h, r=0) + + +def vperc(height, perc=50, ref=1080, rel=50, r=2): + ret = perc * ref / 100.0 - height * rel / 100 + if r > 0: + return round(ret, r) + return int(round(ret, r)) + + +def vperci(height, perc=50, ref=1080, rel=50): + return vperc(height, perc=perc, ref=ref, rel=rel, r=0) + + class TextBox: # constants WINDOW = 10147 @@ -791,7 +679,7 @@ def __init__(self, interval): def __enter__(self): self.start() - DEBUG_LOG('Cron started') + DEBUG_LOG('Cron started with interval: {}'.format(self.interval)) return self def __exit__(self, exc_type, exc_value, traceback): @@ -943,6 +831,8 @@ def getTimeFormat(): # Kodi Omega on Android seems to have borked the regional format returned separately # (not happening on Windows at least). Format returned can be "%H:mm:ss", which is incompatible with strftime; fix. adjustedFmt = adjustedFmt.replace("mm", "%M").replace("ss", "%S").replace("xx", "%p") + if "%M" not in adjustedFmt and "M" in adjustedFmt: + adjustedFmt = adjustedFmt.replace("M", "%M") adjustedFmtKN = adjustedFmt.replace("%M", "mm").replace("%H", "hh").replace("%I", "h").replace("%S", "ss").\ replace("%p", "xx").replace(nonPadIF, "h").replace(nonPadHF, "h") @@ -952,6 +842,38 @@ def getTimeFormat(): timeFormat, timeFormatKN, padHour = getTimeFormat() +def getShortDateFormat(): + try: + return (rpc.Settings.GetSettingValue(setting="locale.shortdateformat")["value"] + .replace("DD", "%d").replace("MM", "%m").replace("YYYY", "%Y")) + except: + DEBUG_LOG("Couldn't get locale.shortdateformat setting, falling back to MM/DD/YYYY") + return "%d/%m/%Y" + + +shortDF = getShortDateFormat() + +# get mounts +KODI_SOURCES = [] + + +def getKodiSources(): + try: + data = rpc.Files.GetSources(media="files")["sources"] + except: + LOG("Couldn't parse Kodi sources") + else: + for d in data: + f = d["file"] + if f.startswith("smb://") or f.startswith("nfs://") or f.startswith("/") or ':\\\\' in f: + KODI_SOURCES.append(d) + LOG("Parsed {} Kodi sources: {}".format(len(KODI_SOURCES), KODI_SOURCES)) + + +if getSetting('path_mapping', True): + getKodiSources() + + def populateTimeFormat(): global timeFormat, timeFormatKN, padHour timeFormat, timeFormatKN, padHour = getTimeFormat() @@ -972,14 +894,66 @@ def getPlatform(): return key.rsplit('.', 1)[-1] -def getProgressImage(obj, perc=None): +platform = getPlatform() + + +def getCoreELEC(): + try: + stdout = subprocess.check_output('lsb_release', shell=True).decode() + match = re.search(r'CoreELEC', stdout) + if match: + return True + + return False + except: + return False + + +isCoreELEC = getCoreELEC() if platform in ['Linux', 'RaspberryPi'] else False + + +def getRunningAddons(): + try: + return xbmcvfs.listdir('addons://running/')[1] + except: + return [] + + +def getUserAddons(): + try: + return xbmcvfs.listdir('addons://user/all')[1] + except: + return [] + + +USER_ADDONS = getUserAddons() + + +SLUGIFY_RE1 = re.compile(r'[^\w\s-]') +SLUGIFY_RE2 = re.compile(r'[-\s]+') + + +def slugify(value): + """ + Converts to lowercase, removes non-word characters (alphanumerics and + underscores) and converts spaces to hyphens. Also strips leading and + trailing whitespace. + """ + value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') + value = SLUGIFY_RE1.sub('', value).strip().lower() + return SLUGIFY_RE2.sub('-', value) + + +def getProgressImage(obj, perc=None, view_offset=None): if not obj and not perc: return '' if obj: - if not obj.get('viewOffset') or not obj.get('duration'): + if not view_offset: + view_offset = obj.get('viewOffset') and obj.viewOffset.asInt() + if not view_offset or not obj.get('duration'): return '' - pct = int((obj.viewOffset.asInt() / obj.duration.asFloat()) * 100) + pct = int((view_offset / obj.duration.asFloat()) * 100) else: pct = perc pct = pct - pct % 2 # Round to even number - we have even numbered progress only @@ -992,8 +966,8 @@ def backgroundFromArt(art, width=1920, height=1080, background=colors.noAlpha.Ba return return art.asTranscodedImageURL( width, height, - blur=advancedSettings.backgroundArtBlurAmount2, - opacity=advancedSettings.backgroundArtOpacityAmount2, + blur=addonSettings.backgroundArtBlurAmount2, + opacity=addonSettings.backgroundArtOpacityAmount2, background=background ) @@ -1037,17 +1011,73 @@ def getOpenSubtitlesHash(size, url): return format(hash_, "016x") +SETTING_RE = re.compile(r'<setting id="(?P<name>.+?)"[^>]*?>', re.MULTILINE | re.DOTALL) -def ensureHome(): - if xbmcgui.getCurrentWindowId() != 10000: - LOG("Switching to home screen before starting addon") - xbmc.executebuiltin('ActivateWindow(home)') - ct = 0 - while xbmcgui.getCurrentWindowId() != 10000 and ct <= 50: - xbmc.Monitor().waitForAbort(0.1) - ct += 1 - if ct > 50: - DEBUG_LOG("Still active window: %s" % xbmcgui.getCurrentWindowId()) + +def dumpSettings(): + from .windows import settings + from collections import OrderedDict + + sections = set(settings.Settings.SECTION_IDS) - {"about", "player_user"} + + main_settings_dict = OrderedDict([(k, + OrderedDict([(s.ID, (s.get(as_code=True), s.default)) + for s in settings.Settings.SETTINGS[k][1] + if not s.userAware])) for k in sections]) + main_revmap = {k: i for i in sections for k in main_settings_dict[i].keys()} + adv_settings_dict = OrderedDict([(s, (getSetting(s, d), d)) for s, d in AddonSettings._proxiedSettings]) + + try: + f = xbmcvfs.File(os.path.join(translatePath(ADDON.getAddonInfo("profile")), "settings.xml")) + data = f.read() + all_settings = SETTING_RE.findall(data) + f.close() + except: + LOG('script.plex: No settings.xml found') + return + + final = OrderedDict({"settings": OrderedDict((k, []) for k in sections), "addon_settings": [], "unspecified": []}) + + for s in all_settings[:]: + # get setting from main settings + sec = main_revmap.get(s) + + if sec: + ms = main_settings_dict[sec][s] + try: + v = json.loads(ms[0], default=ms[0]) + except: + v = ms[0] + final["settings"][sec].append({s: {"value": v, "default": ms[1], "changed": v != ms[1]}}) + all_settings.remove(s) + continue + advs = adv_settings_dict.get(s) + if advs: + try: + v = json.loads(advs[0], default=advs[0]) + except: + v = advs[0] + final["addon_settings"].append({s: {"value": v, "default": advs[1], "changed": v != advs[1]}}) + all_settings.remove(s) + continue + + remove_keys = ("xml_cache.mpaResources",) + for key in remove_keys: + all_settings.remove(key) + + def decode(v): + try: + return json.loads(v) + except: + return v + + final["unspecified"] += [{s: decode(getSetting(s))} for s in all_settings] + final = plexnet.util.cleanObjTokens(final, + mask_keys=("token", "authToken", "uuid", "name", "ID", "thumb", "email", "id", + "title", "username", "address"), + dict_cls=OrderedDict) + + DEBUG_LOG("Settings dump: {}", pprint.pformat(final, compact=True)) def garbageCollect(): diff --git a/script.plexmod/lib/windows/__init__.py b/script.plexmod/lib/windows/__init__.py index f96b690080..90112572d8 100644 --- a/script.plexmod/lib/windows/__init__.py +++ b/script.plexmod/lib/windows/__init__.py @@ -1,5 +1,6 @@ from __future__ import absolute_import -from . import kodigui + from lib import util +from . import kodigui kodigui.MONITOR = util.MONITOR diff --git a/script.plexmod/lib/windows/background.py b/script.plexmod/lib/windows/background.py index 8940d1c6bd..567ce03c7c 100644 --- a/script.plexmod/lib/windows/background.py +++ b/script.plexmod/lib/windows/background.py @@ -1,6 +1,7 @@ from __future__ import absolute_import -from . import kodigui + from lib import util +from . import kodigui util.setGlobalProperty('background.busy', '') util.setGlobalProperty('background.shutdown', '') @@ -20,6 +21,7 @@ def __init__(self, *args, **kwargs): self.function = kwargs.get('function') def onFirstInit(self): + # try accessing our dummy control to trigger an error if our XML is broken self.function() self.doClose() diff --git a/script.plexmod/lib/windows/busy.py b/script.plexmod/lib/windows/busy.py index dd8e3ef060..c3da82aa58 100644 --- a/script.plexmod/lib/windows/busy.py +++ b/script.plexmod/lib/windows/busy.py @@ -1,9 +1,12 @@ from __future__ import absolute_import -from . import kodigui -from lib import util -from kodi_six import xbmcgui + import threading +from kodi_six import xbmcgui + +from lib import util +from . import kodigui + class BusyWindow(kodigui.BaseDialog): xmlFile = 'script-plex-busy.xml' @@ -14,6 +17,12 @@ class BusyWindow(kodigui.BaseDialog): height = 1080 +class BlockingBusyWindow(BusyWindow): + def onAction(self, action): + if action in (xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_STOP): + return False + + class BusyClosableWindow(BusyWindow): ctx = None @@ -147,3 +156,47 @@ def __exit__(self, exc_type, exc_val, exc_tb): class BusyClosableMsgContext(BusyMsgContext): pass + + +class BusyBlockingContext(BusyContext): + window_cls = BlockingBusyWindow + + +class ProgressDialog(object): + dialog = None + header = None + message = None + + def __init__(self, header, message=None, bg=True, raise_hard=False): + self.header = header + self.message = message + self.bg = bg + self.raise_hard = raise_hard + + def __enter__(self): + self.dialog = xbmcgui.DialogProgressBG() if self.bg else xbmcgui.DialogProgress() + self.dialog.create(self.header, self.message) + return self + + def __exit__(self, exc_type, exc_value, tb): + if exc_type is not None: + util.ERROR() + + self.dialog.close() + del self.dialog + self.dialog = None + util.garbageCollect() + if exc_type is not None and self.raise_hard: + raise exc_value + return True + + def update(self, perc, header=None, message=None): + if self.bg: + self.dialog.update(perc, header or self.header, message or self.message) + else: + self.dialog.update(perc, message or self.message) + + def isCanceled(self): + if self.bg: + return False + return self.dialog.iscanceled() diff --git a/script.plexmod/lib/windows/currentplaylist.py b/script.plexmod/lib/windows/currentplaylist.py index 91dffd23a1..45621bd894 100644 --- a/script.plexmod/lib/windows/currentplaylist.py +++ b/script.plexmod/lib/windows/currentplaylist.py @@ -1,18 +1,17 @@ from __future__ import absolute_import + from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui +from lib import kodijsonrpc +from lib import player +from lib import util +from lib.util import T from . import busy -from . import windowutils from . import dropdown +from . import kodigui from . import opener - -from lib import util -from lib import player -from lib import kodijsonrpc - -from lib.util import T +from . import windowutils class CurrentPlaylistWindow(kodigui.ControlledWindow, windowutils.UtilMixin): @@ -61,12 +60,23 @@ def __init__(self, *args, **kwargs): self.musicPlayerWinID = kwargs.get('winID') def doClose(self, **kwargs): - player.PLAYER.off('playback.started', self.onPlayBackStarted) + player.PLAYER.off('av.started', self.onPlayBackStarted) player.PLAYER.off('playlist.changed', self.playQueueCallback) if player.PLAYER.handler.playQueue and player.PLAYER.handler.playQueue.isRemote: player.PLAYER.handler.playQueue.off('change', self.updateProperties) + self.commonDeinit() kodigui.ControlledWindow.doClose(self) + def commonInit(self): + player.PLAYER.on('starting.audio', self.onAudioStarting) + player.PLAYER.on('started.audio', self.onAudioStarted) + player.PLAYER.on('changed.audio', self.onAudioChanged) + + def commonDeinit(self): + player.PLAYER.off('starting.audio', self.onAudioStarting) + player.PLAYER.off('started.audio', self.onAudioStarted) + player.PLAYER.off('changed.audio', self.onAudioChanged) + def onFirstInit(self): self.playlistListControl = kodigui.ManagedControlList(self, self.PLAYLIST_LIST_ID, 9) self.setupSeekbar() @@ -74,7 +84,7 @@ def onFirstInit(self): self.fillPlaylist() self.selectPlayingItem() self.setFocusId(self.PLAYLIST_LIST_ID) - + self.commonInit() self.updateProperties() if player.PLAYER.handler.playQueue and player.PLAYER.handler.playQueue.isRemote: player.PLAYER.handler.playQueue.on('change', self.updateProperties) @@ -83,6 +93,9 @@ def onFirstInit(self): def onAction(self, action): try: controlID = self.getFocusId() + if action in (xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK): + self.doClose() + return if self.checkSeekActions(action, controlID): return except: @@ -123,7 +136,20 @@ def onFocus(self, controlID): self.updateSelectedProgress() def onPlayBackStarted(self, **kwargs): - xbmc.sleep(2000) + self.setDuration() + + def onAudioStarting(self, *args, **kwargs): + util.setGlobalProperty('ignore_spinner', '1') + self.ignoreStopCommands = True + + def onAudioStarted(self, *args, **kwargs): + util.setGlobalProperty('ignore_spinner', '') + self.ignoreStopCommands = False + self.setDuration() + + def onAudioChanged(self, *args, **kwargs): + util.setGlobalProperty('ignore_spinner', '') + self.ignoreStopCommands = False self.setDuration() def repeatButtonClicked(self): @@ -180,11 +206,13 @@ def optionsButtonClicked(self, pos=(670, 1060)): def stopButtonClicked(self): xbmc.executebuiltin('Action(Back, {})'.format(self.musicPlayerWinID)) - xbmc.sleep(500) + util.MONITOR.waitForAbort(0.5) + player.PLAYER.stopAndWait() + self.exitCommand = "STOP" self.doClose() def selectPlayingItem(self): - for mli in self.playlistListControl: + for mli in reversed(self.playlistListControl): if xbmc.getCondVisibility('String.StartsWith(MusicPlayer.Comment,{0})'.format(mli.dataSource['comment'].split(':', 1)[0])): self.playlistListControl.selectItem(mli.pos()) break @@ -217,6 +245,7 @@ def playlistListClicked(self): mli = self.playlistListControl.getSelectedItem() if not mli: return + self.onAudioStarting() player.PLAYER.playselected(mli.pos()) def createListItem(self, pi, idx): @@ -257,7 +286,7 @@ def setupSeekbar(self): self.selectionBox = self.getControl(self.SELECTION_BOX) self.selectionBoxHalf = self.SELECTION_BOX_WIDTH // 2 self.selectionBoxMax = self.SEEK_IMAGE_WIDTH - player.PLAYER.on('playback.started', self.onPlayBackStarted) + player.PLAYER.on('av.started', self.onPlayBackStarted) def checkSeekActions(self, action, controlID): if controlID == self.SEEK_BUTTON_ID: @@ -280,9 +309,10 @@ def checkSeekActions(self, action, controlID): def setDuration(self): try: - self.duration = player.PLAYER.getTotalTime() * 1000 + duration = player.PLAYER.getTotalTime() * 1000 + self.duration = duration if duration > 0 else self.duration except RuntimeError: # Not playing - self.duration = 0 + pass def seekForward(self, offset): self.selectedOffset += offset @@ -311,6 +341,9 @@ def seekMouse(self, action): self.updateSelectedProgress() def updateSelectedProgress(self): + if not self.duration: + return + ratio = self.selectedOffset / float(self.duration) w = int(ratio * self.SEEK_IMAGE_WIDTH) self.seekbarControl.setWidth(w or 1) diff --git a/script.plexmod/lib/windows/dropdown.py b/script.plexmod/lib/windows/dropdown.py index aefb7f0e1b..233a00459b 100644 --- a/script.plexmod/lib/windows/dropdown.py +++ b/script.plexmod/lib/windows/dropdown.py @@ -1,8 +1,9 @@ from __future__ import absolute_import -from kodi_six import xbmc, xbmcgui -from . import kodigui + +from kodi_six import xbmcgui from lib import util +from . import kodigui SEPARATOR = None @@ -14,6 +15,7 @@ class DropdownDialog(kodigui.BaseDialog): res = '1080i' width = 1920 height = 1080 + optionHeight = util.vscalei(66) dropWidth = 360 borderOff = -20 @@ -49,23 +51,39 @@ def x(self): def y(self): y = self.pos[1] if self.posIsBottom: - y -= (len(self.options) * 66) + 80 + y -= (len(self.options) * self.optionHeight) + 80 return y def onFirstInit(self): self.setProperty('dropdown', self.setDropdownProp and '1' or '') self.setProperty('header', self.header) - self.optionsList = kodigui.ManagedControlList(self, self.OPTIONS_LIST_ID, 8) + self.optionsList = kodigui.ManagedControlList(self, self.OPTIONS_LIST_ID, 14) self.showOptions() - height = min(66 * 14, (len(self.options) * 66)) + 80 - self.getControl(100).setPosition(self.x, self.y) + height = min(self.optionHeight * 14, len(self.options) * self.optionHeight) + 80 + ol_height = height - 80 + y = self.y + + if isinstance(y, int) and y + height > self.height: + while y + height > self.height and y > 0: + y -= self.optionHeight + y = max(0, y) + + ol_height = height - 80 + if self.header: + ol_height -= util.vscalei(86) shadowControl = self.getControl(110) if self.header: - shadowControl.setHeight(height + 86) + shadowControl.setHeight(height + util.vscalei(86)) self.getControl(111).setHeight(height + 6) else: shadowControl.setHeight(height) + self.optionsList.setHeight(ol_height) + + if y == "middle": + y = util.vperci(util.vscale(ol_height)) + + self.getControl(100).setPosition(self.x, y) self.setProperty('show', '1') self.setProperty('close.direction', self.closeDirection) diff --git a/script.plexmod/lib/windows/episodes.py b/script.plexmod/lib/windows/episodes.py index d6c6ed3913..db99a1d761 100644 --- a/script.plexmod/lib/windows/episodes.py +++ b/script.plexmod/lib/windows/episodes.py @@ -3,31 +3,26 @@ import requests.exceptions from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui +from plexnet import plexapp, playlist, plexplayer -from lib import util from lib import backgroundthread from lib import metadata from lib import player - -from plexnet import plexapp, playlist, plexplayer -from plexnet.util import INTERFACE - +from lib import util +from lib.util import T from . import busy -from . import videoplayer from . import dropdown -from . import windowutils -from . import opener -from . import search -from . import playersettings from . import info +from . import kodigui +from . import opener from . import optionsdialog -from . import preplayutils from . import pagination from . import playbacksettings - -from lib.util import T -from .mixins import SeasonsMixin, RatingsMixin +from . import playersettings +from . import search +from . import videoplayer +from . import windowutils +from .mixins import SeasonsMixin, RatingsMixin, SpoilersMixin, PlaybackBtnMixin VIDEO_RELOAD_KW = dict(includeExtras=1, includeExtrasCount=10, includeChapters=1) @@ -75,8 +70,10 @@ def createListItem(self, data): return mli def prepareListItem(self, data, mli): + mli.setBoolProperty('watched', mli.dataSource.isFullyWatched) if not mli.dataSource.isWatched: mli.setProperty('unwatched.count', str(mli.dataSource.unViewedLeafCount)) + mli.setProperty('unwatched', '1') mli.setProperty('progress', util.getProgressImage(mli.dataSource)) def setEpisode(self, ep): @@ -174,8 +171,22 @@ def getData(self, offset, amount): return self.parentWindow.show_.getRelated(offset=offset, limit=amount) -class EpisodesWindow(kodigui.ControlledWindow, windowutils.UtilMixin, SeasonsMixin, RatingsMixin, - playbacksettings.PlaybackSettingsMixin): +class RedirectToEpisode(Exception): + episode = None + season = None + select_episode = True + + def __init__(self, episode, season=None, select_episode=True): + self.episode = episode + self.season = season + self.select_episode = select_episode + + +VIDEO_PROGRESS = {} + + +class EpisodesWindow(kodigui.ControlledWindow, windowutils.UtilMixin, SeasonsMixin, RatingsMixin, SpoilersMixin, + PlaybackBtnMixin, playbacksettings.PlaybackSettingsMixin): xmlFile = 'script-plex-episodes.xml' path = util.ADDON.getAddonInfo('path') theme = 'Main' @@ -218,24 +229,17 @@ class EpisodesWindow(kodigui.ControlledWindow, windowutils.UtilMixin, SeasonsMix def __init__(self, *args, **kwargs): kodigui.ControlledWindow.__init__(self, *args, **kwargs) windowutils.UtilMixin.__init__(self) + SpoilersMixin.__init__(self, *args, **kwargs) + PlaybackBtnMixin.__init__(self, *args, **kwargs) self.episode = None self.reset(kwargs.get('episode'), kwargs.get('season'), kwargs.get('show')) - self.initialEpisode = kwargs.get('episode') self.parentList = kwargs.get('parentList') - self.lastItem = None - self.lastFocusID = None - self.lastNonOptionsFocusID = None - self.episodesPaginator = None - self.relatedPaginator = None self.cameFrom = kwargs.get('came_from') self.tasks = backgroundthread.Tasks() - self.initialized = False - self.currentItemLoaded = False - self.closing = False - self._reloadVideos = [] def reset(self, episode, season=None, show=None): self.episode = episode + self.initialEpisode = episode self.season = season if season is not None else self.episode.season() try: self.show_ = show or (self.episode or self.season).show().reload(includeExtras=1, includeExtrasCount=10, @@ -243,10 +247,21 @@ def reset(self, episode, season=None, show=None): except IndexError: raise util.NoDataException + self.initialized = False + self.closing = False self.parentList = None + self.episodesPaginator = None + self.relatedPaginator = None self.seasons = None - self._reloadVideos = [] - #self.initialized = False + self.manuallySelected = False + self.manuallySelectedSeason = False + self.currentItemLoaded = False + self.lastItem = None + self.lastFocusID = None + self.lastNonOptionsFocusID = None + self.openedWithAutoPlay = False + self.useBGM = False + PlaybackBtnMixin.reset(self) def doClose(self): self.closing = True @@ -258,6 +273,7 @@ def doClose(self): self.tasks = None try: player.PLAYER.off('new.video', self.onNewVideo) + player.PLAYER.off('video.progress', self.onVideoProgress) except KeyError: pass @@ -271,81 +287,132 @@ def _onFirstInit(self): self.extraListControl = kodigui.ManagedControlList(self, self.EXTRA_LIST_ID, 5) self.relatedListControl = kodigui.ManagedControlList(self, self.RELATED_LIST_ID, 5) + VIDEO_PROGRESS.clear() + + if not self.openedWithAutoPlay: + # we may have set up the hooks before + self._setup_hooks() self._setup() self.postSetup() def doAutoPlay(self): # First reload the video to get all the other info self.initialEpisode.reload(checkFiles=1, **VIDEO_RELOAD_KW) + + # We're not hitting onFirstInit when autoplaying from home, setup hooks here, so we can grab video progress + self._setup_hooks() + self.openedWithAutoPlay = True return self.playButtonClicked(force_episode=self.initialEpisode, from_auto_play=True) def onFirstInit(self): self._onFirstInit() if self.show_ and self.show_.theme and not util.getSetting("slow_connection", False) and \ - (not self.cameFrom or self.cameFrom != self.show_.ratingKey): + (not self.cameFrom or self.cameFrom not in (self.show_.ratingKey, "postplay")) and \ + not self.openedWithAutoPlay: volume = self.show_.settings.getThemeMusicValue() if volume > 0: player.PLAYER.playBackgroundMusic(self.show_.theme.asURL(True), volume, self.show_.ratingKey) + self.useBGM = True + + self.openedWithAutoPlay = False @busy.dialog() def onReInit(self): + self.playBtnClicked = False + self.useBGM = False if not self.tasks: self.tasks = backgroundthread.Tasks() + vp = VIDEO_PROGRESS.copy() + + if self.manuallySelected and not VIDEO_PROGRESS: + util.DEBUG_LOG("Episodes: ReInit: Not doing anything, as we've previously manually selected " + "this item and don't have progress") + return + + self.manuallySelected = False + util.DEBUG_LOG("Episodes: {}: Got progress info: {}, came from: {}".format( + self.episode and self.episode.ratingKey or None, VIDEO_PROGRESS, self.cameFrom)) try: - self.selectEpisode() + self.selectEpisode(from_reinit=True) + except RedirectToEpisode as redirect: + if redirect.select_episode: + util.DEBUG_LOG("Got episode progress for a different season, redirecting") + self.episodeListControl.reset() + self.relatedListControl.reset() + self.reset(episode=redirect.episode if redirect.select_episode else None, season=redirect.season) + self._setup() + self.postSetup() + return except AttributeError: raise util.NoDataException + # keep progress data if we've been opened from another view, as parent views might need the updates as well + if not self.cameFrom: + VIDEO_PROGRESS.clear() + mli = self.episodeListControl.getSelectedItem() if not mli or not self.episodesPaginator: return - reloadItems = [mli] - for v in self._reloadVideos: + reload_items = [mli] + skip_progress_for = None + if vp: + skip_progress_for = [] for m in self.episodeListControl: - if m.dataSource == v: - reloadItems.append(m) - self.episodesPaginator.prepareListItem(v, m) - - # re-set current item's progress to a loading state - if util.getSetting("slow_connection", False): - self.progressImageControl.setWidth(1) - mli.setProperty('remainingTime', T(32914, "Loading")) - - self.reloadItems(items=reloadItems, with_progress=True) - self.episodesPaginator.setEpisode(self._reloadVideos and self._reloadVideos[-1] or mli) - self._reloadVideos = [] + # pagination boundary + if not m.dataSource: + continue + + if m.dataSource.ratingKey in vp: + reload_items.append(m) + skip_progress_for.append(m.dataSource.ratingKey) + del vp[m.dataSource.ratingKey] + if not vp: + break + + reload_items = list(set(reload_items)) + select_episode = reload_items and reload_items[-1] or mli + + self.episodesPaginator.setEpisode(select_episode.dataSource) + if not reload_items: + self.selectPlayButton() + self.reloadItems(items=reload_items, with_progress=True, skip_progress_for=skip_progress_for) + self.fillSeasons(self.show_, seasonsFilter=lambda x: len(x) > 1, selectSeason=self.season, update=True, + do_focus=not self.manuallySelectedSeason) self.fillRelated() - def postSetup(self, from_select_episode=False): - self.selectEpisode(from_select_episode=from_select_episode) - self.checkForHeaderFocus(xbmcgui.ACTION_MOVE_DOWN) + def postSetup(self): + self.checkForHeaderFocus(xbmcgui.ACTION_MOVE_DOWN, initial=True) + self.selectPlayButton() + self.initialized = True + def selectPlayButton(self): selected = self.episodeListControl.getSelectedItem() if selected: - self.setFocusId(self.getPlayButtonID(selected, base=not self.currentItemLoaded - and self.PLAY_BUTTON_DISABLED_ID or None) - ) - - self.initialized = True + set_focus = self.getPlayButtonID(selected, base=not self.currentItemLoaded + and self.PLAY_BUTTON_DISABLED_ID or None) + self.setCondFocusId(set_focus) @busy.dialog() def setup(self): self._setup() - def _setup(self, from_select_episode=False): + def _setup_hooks(self): player.PLAYER.on('new.video', self.onNewVideo) + player.PLAYER.on('video.progress', self.onVideoProgress) + + def _setup(self): (self.season or self.show_).reload(checkFiles=1, **VIDEO_RELOAD_KW) - if not from_select_episode or not self.episodesPaginator: + if not self.episodesPaginator: self.episodesPaginator = EpisodesPaginator(self.episodeListControl, leaf_count=int(self.season.leafCount) if self.season else 0, parent_window=self) - if not from_select_episode or not self.episodesPaginator: + if not self.relatedPaginator: self.relatedPaginator = RelatedPaginator(self.relatedListControl, leaf_count=int(self.show_.relatedCount), parent_window=self) @@ -361,20 +428,114 @@ def _setup(self, from_select_episode=False): hasPrev = self.fillRelated(hasPrev) self.fillRoles(hasPrev) - def selectEpisode(self, from_select_episode=False): - if not self.episode or not self.episodesPaginator: + def selectEpisode(self, from_reinit=False): + util.DEBUG_LOG("SelectEpisode called: {}, {}, {}, {}", from_reinit, self.episode, VIDEO_PROGRESS, self.cameFrom) + if not self.episodesPaginator: return + had_progress_data = bool(VIDEO_PROGRESS) + progress_data_left = None + if had_progress_data: + progress_data_left = VIDEO_PROGRESS.copy() + + set_main_progress_to = None + selected_new = False + + last_mli_seen = None + was_last_mli = False + for mli in self.episodeListControl: - if mli.dataSource == self.episode: - self.episodeListControl.selectItem(mli.pos()) - self.episodesPaginator.setEpisode(self.episode) + # pagination boundary + if not mli.dataSource: + continue + + is_last_mli = was_last_mli = self.episodeListControl.isLastItem(mli) + + just_fully_watched = False + + if progress_data_left and mli.dataSource: + progress = progress_data_left.pop(mli.dataSource.ratingKey, False) + # progress can be False (no entry), a number (progress), or True (fully watched just now) + # select it if it's not watched or in progress + if progress is True: + # ep was just watched + just_fully_watched = True + mli.setProperty('unwatched', '') + mli.setProperty('watched', '1') + mli.setProperty('progress', '') + mli.setProperty('unwatched.count', '') + mli.dataSource.set('viewCount', mli.dataSource.get('viewCount', 0).asInt() + 1) + mli.dataSource.set('viewOffset', 0) + self.setUserItemInfo(mli, fully_watched=True) + + elif progress and progress > 60000: + # ep has progress + mli.setProperty('watched', '') + mli.setProperty('progress', util.getProgressImage(mli.dataSource, view_offset=progress)) + mli.dataSource.set('viewOffset', progress) + self.setUserItemInfo(mli, watched=True) + set_main_progress_to = progress + + elif progress and progress <= 60000: + # reset progress as we might've had progress before + mli.setProperty('progress', '') + mli.dataSource.set('viewOffset', '') + self.setUserItemInfo(mli) + + # after immediately updating the watched state, if we still have data left, continue + if progress is True and progress_data_left: + continue + + last_mli_seen = mli + + # first condition: we select self.episode if we've got no progress data, or we haven't watched it just now. + # second condition: we've just come from playback with progress upon reinit. select the next available + # episode that's either unwatched or in progress. if we're at the last item in the list, select it as well. + # third condition: select the next unwatched episode if we don't have self.episode and didn't have any + # player progress, which happens when being called without an episode (season view, show view). + if (mli.dataSource == self.episode and not just_fully_watched and not progress_data_left) or \ + (had_progress_data and not progress_data_left and ((not just_fully_watched + and not mli.dataSource.isFullyWatched) or (just_fully_watched and is_last_mli))) or \ + ((not had_progress_data or not from_reinit) and not self.episode and not mli.dataSource.isFullyWatched): + if self.episodeListControl.getSelectedPosition() < mli.pos(): + self.episodeListControl.selectItem(mli.pos()) + self.episodesPaginator.setEpisode(self.episode or mli.dataSource) + self.lastItem = mli + selected_new = True + if just_fully_watched: + set_main_progress_to = 0 + + # this is a little counter-intuitive - None is actually valid here, and if set to None, setProgress will + # use the actual item progress, not ours + self.setProgress(mli, view_offset=set_main_progress_to) break else: - if not from_select_episode: - self.reset(self.episode) - self._setup(from_select_episode=True) - self.postSetup(from_select_episode=True) + # no matching episode found + mli = self.episodeListControl.getSelectedItem() + self.setProgress(mli, view_offset=0) + + if from_reinit and not self.cameFrom: + if progress_data_left: + # we've probably watched something in the next season + key = '/library/metadata/{0}'.format(list(progress_data_left.keys())[-1]) + ep = plexapp.SERVERMANAGER.selectedServer.getObject(key) + if ep.parentIndex != self.season.index and ep.grandparentRatingKey == self.show_.ratingKey: + raise RedirectToEpisode(ep) + elif was_last_mli and last_mli_seen.dataSource.isFullyWatched and self.getSeasons(): + # check if we need to go to the next season + remaining_seasons = self.seasons[self.seasons.index(self.season)+1:] + if remaining_seasons: + season = remaining_seasons[0] + VIDEO_PROGRESS.clear() + util.LOG("Season watched, going to next season: {}", season) + raise RedirectToEpisode(season.episodes()[0], season=season, select_episode=False) + + if selected_new: + #self.setProperty('hub.focus', "0") + #self.setProperty('on.extras', '') + self.lastFocusID = None + if not from_reinit: + self.currentItemLoaded = False self.episode = None @@ -383,7 +544,7 @@ def onAction(self, action): controlID = self.getFocusId() if not controlID and self.lastFocusID and not action == xbmcgui.ACTION_MOUSE_MOVE: - self.setFocusId(self.lastFocusID) + self.setCondFocusId(self.lastFocusID) if action == xbmcgui.ACTION_LAST_PAGE and xbmc.getCondVisibility('ControlGroup(300).HasFocus(0)'): next(self) @@ -397,7 +558,10 @@ def onAction(self, action): if action == xbmcgui.ACTION_MOVE_UP and controlID in (self.EPISODE_LIST_ID, self.SEASONS_LIST_ID): self.updateBackgroundFrom((self.show_ or self.season.show())) - if controlID == self.EPISODE_LIST_ID: + if controlID == self.SEASONS_LIST_ID and action in (xbmcgui.ACTION_MOVE_LEFT, xbmcgui.ACTION_MOVE_RIGHT): + self.manuallySelectedSeason = True + + elif controlID == self.EPISODE_LIST_ID: if self.checkForHeaderFocus(action): return elif action == xbmcgui.ACTION_CONTEXT_MENU: @@ -420,16 +584,16 @@ def onAction(self, action): return else: if self.lastNonOptionsFocusID: - self.setFocusId(self.lastNonOptionsFocusID) + self.setCondFocusId(self.lastNonOptionsFocusID) self.lastNonOptionsFocusID = None return elif action == xbmcgui.ACTION_NAV_BACK: if (not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format( self.OPTIONS_GROUP_ID)) or not controlID) and \ - not util.advancedSettings.fastBack: + not util.addonSettings.fastBack: if self.getProperty('on.extras'): - self.setFocusId(self.OPTIONS_GROUP_ID) + self.setCondFocusId(self.OPTIONS_GROUP_ID) return if action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): @@ -446,12 +610,21 @@ def onNewVideo(self, video=None, **kwargs): if not video.type == 'episode': return - util.DEBUG_LOG('Updating selected episode: {0}'.format(video)) + util.DEBUG_LOG('Updating selected episode: {0}', video) self.episode = video - self._reloadVideos.append(video) return True + def onVideoProgress(self, data=None, **kwargs): + if not data: + return + + util.DEBUG_LOG("Storing video progress data: {}", data) + VIDEO_PROGRESS[data[0]] = data[1] + + def onBGMStarted(self, **kwargs): + self.playBtnClicked = True + def checkOptionsAction(self, action): if action == xbmcgui.ACTION_MOVE_UP: mli = self.episodeListControl.getSelectedItem() @@ -459,7 +632,7 @@ def checkOptionsAction(self, action): return False pos = mli.pos() - 1 if self.episodeListControl.positionIsValid(pos): - self.setFocusId(self.EPISODE_LIST_ID) + self.setCondFocusId(self.EPISODE_LIST_ID) self.episodeListControl.selectItem(pos) return True elif action == xbmcgui.ACTION_MOVE_DOWN: @@ -468,7 +641,7 @@ def checkOptionsAction(self, action): return False pos = mli.pos() + 1 if self.episodeListControl.positionIsValid(pos): - self.setFocusId(self.EPISODE_LIST_ID) + self.setCondFocusId(self.EPISODE_LIST_ID) self.episodeListControl.selectItem(pos) return True @@ -503,7 +676,7 @@ def onClick(self, controlID): if item != self.season: self.openItem(self.seasonsListControl, came_from=self.season.parentRatingKey) else: - self.setFocusId(self.EPISODE_LIST_ID) + self.setCondFocusId(self.EPISODE_LIST_ID) elif controlID == self.ROLES_LIST_ID: self.roleClicked() elif controlID == self.EXTRA_LIST_ID: @@ -518,7 +691,7 @@ def onFocus(self, controlID): # correct play button after the hidden one has been focused if controlID == self.PLAY_BUTTON_ID and xbmc.getCondVisibility( '!String.IsEmpty(Container(400).ListItem.Property(media.multiple))'): - self.setFocusId(self.PLAY_BUTTON_ID + 1000) + self.setCondFocusId(self.PLAY_BUTTON_ID + 1000) return if 399 < controlID < 500: @@ -581,7 +754,14 @@ def getRoleItemDDPosition(self): if xbmc.getCondVisibility('Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)'): y -= 500 - focus = int(xbmc.getInfoLabel('Container(402).Position')) + tries = 0 + focus = xbmc.getInfoLabel('Container(402).Position') + while tries < 2 and focus == '': + focus = xbmc.getInfoLabel('Container(402).Position') + xbmc.sleep(250) + tries += 1 + + focus = int(focus) x = ((focus + 1) * 304) - 100 return x, y @@ -704,24 +884,31 @@ def infoButtonClicked(self): episode = mli.dataSource if episode.index: - subtitle = u'{0} {1} {2} {3}'.format(T(32303, 'Season'), episode.parentIndex, T(32304, 'Episode'), episode.index) + subtitle = u'{0} {1}'.format(T(32303, 'Season').format(episode.parentIndex), + T(32304, 'Episode').format(episode.index)) else: subtitle = episode.originallyAvailableAt.asDatetime('%B %d, %Y') + hide_spoilers = self.hideSpoilers(episode) + opener.handleOpen( info.InfoWindow, - title=episode.title, + title=hide_spoilers and self.noTitles and T(33008, '') or episode.title, sub_title=subtitle, thumb=episode.thumb, + thumb_opts=self.getThumbnailOpts(episode, hide_spoilers=hide_spoilers), thumb_fallback='script.plex/thumb_fallbacks/show.png', - info=episode.summary, + info=hide_spoilers and T(33008, '') or episode.summary, background=self.getProperty('background'), is_16x9=True, video=episode ) def episodeListClicked(self, force_episode=None, from_auto_play=False): - if not self.currentItemLoaded and not from_auto_play: + if (not self.currentItemLoaded or self.playBtnClicked) and not from_auto_play: + util.DEBUG_LOG("Not honoring play action: currentItemLoaded: {0}, " + "playBtnClicked: {1}, from_auto_play: {2}", + self.currentItemLoaded, self.playBtnClicked, from_auto_play) return if not force_episode: @@ -744,7 +931,7 @@ def episodeListClicked(self, force_episode=None, from_auto_play=False): {'key': 'resume', 'display': T(32429, 'Resume from {0}').format(util.timeDisplay(episode.viewOffset.asInt()).lstrip('0').lstrip(':'))}, {'key': 'play', 'display': T(32317, 'Play from beginning')} ], - pos=(660, 441), + pos=(660, "middle"), close_direction='none', set_dropdown_prop=False, header=T(32314, 'In Progress'), @@ -757,16 +944,22 @@ def episodeListClicked(self, force_episode=None, from_auto_play=False): if choice['key'] == 'resume': resume = True - self._reloadVideos.append(episode) + if not from_auto_play: + self.playBtnClicked = True pl = playlist.LocalPlaylist(self.show_.all(), self.show_.getServer()) try: - if len(pl): # Don't use playlist if it's only this video + # inject our show in case we need to access show metadata from the player + episode._show = self.show_ + if len(pl) > 1: # Don't use playlist if it's only this video + for ep in pl: + ep._show = self.show_ + pl.setCurrent(episode) - self.processCommand(videoplayer.play(play_queue=pl, resume=resume)) + self.processCommand(videoplayer.play(play_queue=pl, resume=resume, bgm=self.useBGM)) return True - self.processCommand(videoplayer.play(video=episode, resume=resume)) + self.processCommand(videoplayer.play(video=episode, resume=resume, bgm=self.useBGM)) return True except util.NoDataException: util.ERROR("No data - disconnected?", notify=True, time_ms=5000) @@ -816,13 +1009,15 @@ def optionsButtonClicked(self, from_item=False): options.append({'key': 'to_section', 'display': T(32324, u'Go to {0}').format( self.show_.getLibrarySectionTitle())}) - pos = (500, 620) + pos = (500, util.vscalei(620)) bottom = False if from_item: viewPos = self.episodeListControl.getViewPosition() optsLen = len(list(filter(None, options))) - # dropDown handles any overlap with the right window boundary so we don't need to care here - pos = ((((viewPos + 1) * 359) - 100), 649 if optsLen < 7 else 649 - 66 * (optsLen - 6)) + # dropDown handles any overlap with the right window boundary, so we don't need to care here + pos = ( + (((viewPos + 1) * 359) - 100), + util.vscalei(649) if optsLen < 7 else 649 - util.vscalei(66) * (optsLen - 6)) choice = dropdown.showDropdown(options, pos, pos_is_bottom=bottom, close_direction='left', set_dropdown_prop=False) @@ -855,7 +1050,7 @@ def optionsButtonClicked(self, from_item=False): elif choice['key'] == 'to_section': self.goHome(self.show_.getLibrarySectionId()) elif choice['key'] == 'delete': - self.delete() + self.delete(mli.dataSource) elif choice['key'] == 'playback_settings': self.playbackSettings(self.show_, pos, bottom) @@ -879,10 +1074,11 @@ def mediaButtonClicked(self): choice['key'].set('selected', 1) self.setPostReloadItemInfo(ds, mli) - def delete(self): + def delete(self, item): button = optionsdialog.show( T(32326, 'Really delete?'), - T(32327, 'Are you sure you really want to delete this media?'), + T(33036, "Delete episode S{0:02d}E{1:02d} from {2}?").format(item.parentIndex.asInt(), + item.index.asInt(), item.defaultTitle), T(32328, 'Yes'), T(32329, 'No') ) @@ -901,7 +1097,7 @@ def _delete(self): video = mli.dataSource success = video.delete() - util.LOG('Media DELETE: {0} - {1}'.format(video, success and 'SUCCESS' or 'FAILED')) + util.LOG('Media DELETE: {0} - {1}', video, success and 'SUCCESS' or 'FAILED') if success: self.episodeListControl.removeItem(mli.pos()) if not self.episodeListControl.size(): @@ -910,10 +1106,10 @@ def _delete(self): (self.season or self.show_).reload() return success - def checkForHeaderFocus(self, action): + def checkForHeaderFocus(self, action, initial=False): # don't continue if we're still waiting for tasks if self.tasks or not self.episodesPaginator: - if self.tasks: + if self.tasks and not initial: util.DEBUG_LOG("Episodes: Moving too fast through paginator, throttling.") return @@ -943,7 +1139,10 @@ def checkForHeaderFocus(self, action): if action in (xbmcgui.ACTION_MOVE_UP, xbmcgui.ACTION_PAGE_UP): if mli.getProperty('is.header'): xbmc.executebuiltin('Action(up)') - if action in (xbmcgui.ACTION_MOVE_DOWN, xbmcgui.ACTION_PAGE_DOWN, xbmcgui.ACTION_MOVE_LEFT, xbmcgui.ACTION_MOVE_RIGHT): + if action in (xbmcgui.ACTION_MOVE_DOWN, xbmcgui.ACTION_PAGE_DOWN, xbmcgui.ACTION_MOVE_LEFT, + xbmcgui.ACTION_MOVE_RIGHT): + if not initial and action in (xbmcgui.ACTION_MOVE_LEFT, xbmcgui.ACTION_MOVE_RIGHT): + self.manuallySelected = True if mli.getProperty('is.header'): xbmc.executebuiltin('Action(down)') @@ -957,8 +1156,10 @@ def updateProperties(self): self.setProperty('season.title', (self.season or self.show_).title) if self.season: - self.setProperty('episodes.header', u'{0} \u2022 {1} {2}'.format(showTitle, T(32303, 'Season'), self.season.index)) - self.setProperty('extras.header', u'{0} \u2022 {1} {2}'.format(T(32305, 'Extras'), T(32303, 'Season'), self.season.index)) + self.setProperty('episodes.header', u'{0} \u2022 {1}'.format(showTitle, + T(32303, 'Season').format(self.season.index))) + self.setProperty('extras.header', u'{0} \u2022 {1}'.format(T(32305, 'Extras'), + T(32303, 'Season').format(self.season.index))) else: self.setProperty('episodes.header', u'Episodes') self.setProperty('extras.header', u'Extras') @@ -972,27 +1173,75 @@ def updateProperties(self): def updateItems(self, item=None): if item: item.setProperty('unwatched', not item.dataSource.isWatched and '1' or '') + item.setProperty('watched', item.dataSource.isFullyWatched and '1' or '') self.setProgress(item) item.setProperty('progress', util.getProgressImage(item.dataSource)) (self.season or self.show_).reload() + + self.setUserItemInfo(item) else: self.fillEpisodes(update=True) + if not self.cameFrom: + VIDEO_PROGRESS.clear() if self.episode: self.episode.reload() + def setUserItemInfo(self, mli, video=None, types=("title", "thumbnail", "summary"), watched=None, + fully_watched=None, hide_spoilers=None): + video = video or mli.dataSource + + properties = {} + methods = [] + if self.noSpoilers == "off" and not hide_spoilers: + # no special handling + if "title" in types: + properties["title"] = video.title + methods.append(("setLabel", video.title)) + if "summary" in types: + properties["summary"] = video.summary.strip().replace('\t', ' ') + + if "thumbnail" in types: + methods.append(("setThumbnailImage", video.thumb.asTranscodedImageURL(*self.THUMB_AR16X9_DIM))) + + else: + hide_spoilers = hide_spoilers if hide_spoilers is not None else \ + self.hideSpoilers(video, fully_watched=fully_watched, watched=watched) + hide_title = hide_spoilers and self.noTitles + if "title" in types: + tit = hide_title and T(33008, '') or video.title + properties["title"] = tit + methods.append(("setLabel", tit)) + + if "summary" in types: + properties["summary"] = hide_spoilers and T(33008, '') or video.summary.strip().replace('\t', ' ') + + if "thumbnail" in types: + methods.append(("setThumbnailImage", + video.thumb.asTranscodedImageURL( + *self.THUMB_AR16X9_DIM, + **self.getThumbnailOpts(video, fully_watched=fully_watched, watched=watched, + hide_spoilers=hide_spoilers) + ) + )) + + for property, value in properties.items(): + mli.setProperty(property, value) + + for method, value in methods: + getattr(mli, method)(value) + def setItemInfo(self, video, mli): # video.reload(checkFiles=1) mli.setProperty('background', util.backgroundFromArt(video.art, width=self.width, height=self.height)) - mli.setProperty('title', video.title) mli.setProperty('show.title', video.grandparentTitle or (self.show_.title if self.show_ else '')) mli.setProperty('duration', util.durationToText(video.duration.asInt())) - mli.setProperty('summary', video.summary.strip().replace('\t', ' ')) mli.setProperty('video.rendering', video.videoCodecRendering) + self.setUserItemInfo(mli, video, types=("title", "summary")) if video.index: - mli.setProperty('season', u'{0} {1}'.format(T(32303, 'Season'), video.parentIndex)) - mli.setProperty('episode', u'{0} {1}'.format(T(32304, 'Episode'), video.index)) + mli.setProperty('season', T(32303, 'Season').format(video.parentIndex)) + mli.setProperty('episode', T(32304, 'Episode').format(video.index)) else: mli.setProperty('season', '') mli.setProperty('episode', '') @@ -1009,6 +1258,7 @@ def setItemInfo(self, video, mli): def setPostReloadItemInfo(self, video, mli): self.setItemAudioAndSubtitleInfo(video, mli) mli.setProperty('unwatched', not video.isWatched and '1' or '') + mli.setProperty('watched', video.isFullyWatched and '1' or '') mli.setProperty('video.res', video.resolutionString()) mli.setProperty('audio.codec', video.audioCodecString()) mli.setProperty('video.codec', video.videoCodecString()) @@ -1054,48 +1304,58 @@ def setItemAudioAndSubtitleInfo(self, video, mli): else: mli.setProperty('subtitles', T(32309, 'None')) - def setProgress(self, mli): + def setProgress(self, mli, view_offset=None): video = mli.dataSource - if video.viewOffset.asInt(): - width = video.viewOffset.asInt() and (1 + int((video.viewOffset.asInt() / video.duration.asFloat()) * self.width)) or 1 + view_offset = view_offset if view_offset is not None else video.viewOffset.asInt() + if view_offset: + width = view_offset and (1 + int((view_offset / video.duration.asFloat()) * self.width)) or 1 self.progressImageControl.setWidth(width) else: self.progressImageControl.setWidth(1) - if video.viewOffset.asInt(): - mli.setProperty('remainingTime', T(33615, "{time} left").format(time=video.remainingTimeString)) + if view_offset: + mli.setProperty('remainingTime', T(33615, + "{time} left").format(time=video._remainingTimeString(view_offset))) else: mli.setProperty('remainingTime', '') def createListItem(self, episode): if episode.index: - subtitle = u'{0}{1} \u2022 {2}{3}'.format(T(32310, 'S'), episode.parentIndex, T(32311, 'E'), episode.index) + subtitle = u'{0} \u2022 {1}'.format(T(32310, 'S').format(episode.parentIndex), + T(32311, 'E').format(episode.index)) else: subtitle = episode.originallyAvailableAt.asDatetime('%m/%d/%y') mli = kodigui.ManagedListItem( - episode.title, + '', subtitle, - thumbnailImage=episode.thumb.asTranscodedImageURL(*self.THUMB_AR16X9_DIM), data_source=episode ) + self.setUserItemInfo(mli, types=("title", "thumbnail")) mli.setProperty('episode.number', str(episode.index) or '') mli.setProperty('episode.duration', util.durationToText(episode.duration.asInt())) mli.setProperty('unwatched', not episode.isWatched and '1' or '') + mli.setProperty('watched', episode.isFullyWatched and '1' or '') # mli.setProperty('progress', util.getProgressImage(obj)) return mli def fillEpisodes(self, update=False): items = self.episodesPaginator.paginate() - self.reloadItems(items) + if not update: + self.selectEpisode() + self.reloadItems(items, with_progress=True) - def reloadItems(self, items, with_progress=False): + def reloadItems(self, items, with_progress=False, skip_progress_for=None): tasks = [] for mli in items: if not mli.dataSource: continue - task = EpisodeReloadTask().setup(mli.dataSource, self.reloadItemCallback, with_progress=with_progress) + item_progress = with_progress + if skip_progress_for: + item_progress = False if mli.dataSource.ratingKey in skip_progress_for else with_progress + + task = EpisodeReloadTask().setup(mli.dataSource, self.reloadItemCallback, with_progress=item_progress) self.tasks.add(task) tasks.append(task) @@ -1128,7 +1388,8 @@ def reloadItemCallback(self, task, episode, with_progress=False): self.episodesPaginator.prepareListItem(None, mli) if mli == selected: self.lastItem = mli - self.setProgress(mli) + if with_progress: + self.setProgress(mli) if not self.currentItemLoaded and ( mli == selected or (self.episode and self.episode == mli.dataSource)): @@ -1143,9 +1404,10 @@ def reloadItemCallback(self, task, episode, with_progress=False): and not util.MONITOR.abortRequested() and tries < 5: util.MONITOR.waitForAbort(0.1) tries += 1 - if xbmc.getCondVisibility('Control.IsVisible({})'.format(PBID)): + if xbmc.getCondVisibility('Control.IsVisible({})'.format(PBID)) and self.getFocusId() != PBID: self.setFocusId(PBID) - return + + break def fillExtras(self, has_prev=False): items = [] diff --git a/script.plexmod/lib/windows/home.py b/script.plexmod/lib/windows/home.py index 3777707c67..64db1538d3 100644 --- a/script.plexmod/lib/windows/home.py +++ b/script.plexmod/lib/windows/home.py @@ -1,27 +1,31 @@ from __future__ import absolute_import -import time + +import json import threading +import time +import math +import plexnet from kodi_six import xbmc from kodi_six import xbmcgui +from plexnet import plexapp, plexresource +from six.moves import range -from . import kodigui -from lib import util from lib import backgroundthread from lib import player - -import plexnet -from plexnet import plexapp - -from . import windowutils -from . import playlists +from lib import util +from lib.path_mapping import pmm +from lib.plex_hosts import pdm +from lib.util import T from . import busy +from . import dropdown +from . import kodigui from . import opener -from . import search from . import optionsdialog - -from lib.util import T -from six.moves import range +from . import playlists +from . import search +from . import windowutils +from .mixins import SpoilersMixin HUBS_REFRESH_INTERVAL = 300 # 5 Minutes HUB_PAGE_SIZE = 10 @@ -46,13 +50,17 @@ class HubsList(list): def init(self): self.lastUpdated = time.time() + self.invalid = False return self class SectionHubsTask(backgroundthread.Task): - def setup(self, section, callback): + def setup(self, section, callback, section_keys=None, ignore_hubs=None, reselect_pos_dict=None): self.section = section self.callback = callback + self.section_keys = section_keys + self.ignore_hubs = ignore_hubs + self.reselect_pos_dict = reselect_pos_dict return self def run(self): @@ -64,22 +72,30 @@ def run(self): return try: - hubs = HubsList(plexapp.SERVERMANAGER.selectedServer.hubs(self.section.key, count=HUB_PAGE_SIZE)).init() + hubs = HubsList(plexapp.SERVERMANAGER.selectedServer.hubs(self.section.key, count=HUB_PAGE_SIZE, + section_ids=self.section_keys, + ignore_hubs=self.ignore_hubs)).init() if self.isCanceled(): return - self.callback(self.section, hubs) + self.callback(self.section, hubs, reselect_pos_dict=self.reselect_pos_dict) except plexnet.exceptions.BadRequest: - util.DEBUG_LOG('404 on section: {0}'.format(repr(self.section.title))) - self.callback(self.section, False) - except TypeError: + util.DEBUG_LOG('404 on section: {0}', repr(self.section.title)) + hubs = HubsList().init() + hubs.invalid = True + self.callback(self.section, hubs) + except: util.ERROR("No data - disconnected?", notify=True, time_ms=5000) - self.cancel() + util.DEBUG_LOG('Generic exception when fetching section: {0}', repr(self.section.title)) + hubs = HubsList().init() + hubs.invalid = True + self.callback(self.section, hubs) class UpdateHubTask(backgroundthread.Task): - def setup(self, hub, callback): + def setup(self, hub, callback, reselect_pos=None): self.hub = hub self.callback = callback + self.reselect_pos = reselect_pos return self def run(self): @@ -94,16 +110,22 @@ def run(self): self.hub.reload(limit=HUB_PAGE_SIZE) if self.isCanceled(): return - self.callback(self.hub) + self.callback(self.hub, reselect_pos=self.reselect_pos) except plexnet.exceptions.BadRequest: - util.DEBUG_LOG('404 on section: {0}'.format(repr(self.section.title))) + util.DEBUG_LOG('404 on hub: {0}', repr(self.hub.hubIdentifier)) + except util.NoDataException: + util.ERROR("No data - disconnected?", notify=True, time_ms=5000) + except: + util.DEBUG_LOG('Something went wrong when updating hub: {0}', repr(self.hub.hubIdentifier)) class ExtendHubTask(backgroundthread.Task): - def setup(self, hub, callback, canceledCallback=None): + def setup(self, hub, callback, canceledCallback=None, size=HUB_PAGE_SIZE, reselect_pos=None): self.hub = hub self.callback = callback self.canceledCallback = canceledCallback + self.size = size + self.reselect_pos = reselect_pos return self def run(self): @@ -117,17 +139,27 @@ def run(self): return try: + size = self.size + if self.reselect_pos is not None: + rk, pos = self.reselect_pos + if pos == -1: + # we need the full hub if we want to round-robin + size = util.addonSettings.hubsRrMax start = self.hub.offset.asInt() + self.hub.size.asInt() - items = self.hub.extend(start=start, size=HUB_PAGE_SIZE) + items = self.hub.extend(start=start, size=size) if self.isCanceled(): if self.canceledCallback: self.canceledCallback(self.hub) return - self.callback(self.hub, items) + self.callback(self.hub, items, reselect_pos=self.reselect_pos) except plexnet.exceptions.BadRequest: - util.DEBUG_LOG('404 on hub: {0}'.format(repr(self.hub.hubIdentifier))) + util.DEBUG_LOG('404 on hub: {0}', repr(self.hub.hubIdentifier)) if self.canceledCallback: self.canceledCallback(self.hub) + except util.NoDataException: + util.ERROR("No data - disconnected?", notify=True, time_ms=5000) + except: + util.DEBUG_LOG('Something went wrong when extending hub: {0}', repr(self.hub.hubIdentifier)) class HomeSection(object): @@ -135,12 +167,24 @@ class HomeSection(object): type = 'home' title = T(32332, 'Home') + locations = [] + isMapped = False + + +home_section = HomeSection() + class PlaylistsSection(object): key = 'playlists' type = 'playlists' title = T(32333, 'Playlists') + locations = [] + isMapped = False + + +playlists_section = PlaylistsSection() + class ServerListItem(kodigui.ManagedListItem): uuid = None @@ -228,7 +272,7 @@ def onDestroy(self): self.unHookSignals() -class HomeWindow(kodigui.BaseWindow, util.CronReceiver): +class HomeWindow(kodigui.BaseWindow, util.CronReceiver, SpoilersMixin): xmlFile = 'script-plex-home.xml' path = util.ADDON.getAddonInfo('path') theme = 'Main' @@ -280,18 +324,24 @@ class HomeWindow(kodigui.BaseWindow, util.CronReceiver): HUBMAP = { # HOME 'home.continue': {'index': 0, 'with_progress': True, 'with_art': True, 'do_updates': True, 'text2lines': True}, + # This hub can be enabled in the settings so PM4K behaves like any other Plex client. + # It overrides home.continue and home.ondeck + 'continueWatching': {'index': 1, 'with_progress': True, 'do_updates': True, 'text2lines': True}, 'home.ondeck': {'index': 1, 'with_progress': True, 'do_updates': True, 'text2lines': True}, 'home.television.recent': {'index': 2, 'do_updates': True, 'with_progress': True, 'text2lines': True}, + # This is a virtual hub and it appears when the library recommendation is customized in Plex and + # Recently Released is checked. + 'home.VIRTUAL.movies.recentlyreleased': {'index': 3, 'do_updates': True, 'with_progress': True, 'text2lines': True}, 'home.movies.recent': {'index': 4, 'do_updates': True, 'with_progress': True, 'text2lines': True}, 'home.music.recent': {'index': 5, 'text2lines': True}, 'home.videos.recent': {'index': 6, 'with_progress': True, 'ar16x9': True}, #'home.playlists': {'index': 9}, # No other Plex home screen shows playlists so removing it from here 'home.photos.recent': {'index': 10, 'text2lines': True}, # SHOW - 'tv.ondeck': {'index': 1, 'with_progress': True, 'do_updates': True, 'text2lines': True}, - 'tv.recentlyaired': {'index': 2, 'do_updates': True, 'with_progress': True, 'text2lines': True}, - 'tv.recentlyadded': {'index': 3, 'do_updates': True, 'with_progress': True, 'text2lines': True}, - 'tv.inprogress': {'index': 4, 'with_progress': True, 'do_updates': True, 'text2lines': True}, + 'tv.inprogress': {'index': 1, 'with_progress': True, 'do_updates': True, 'text2lines': True}, + 'tv.ondeck': {'index': 2, 'with_progress': True, 'do_updates': True, 'text2lines': True}, + 'tv.recentlyaired': {'index': 3, 'do_updates': True, 'with_progress': True, 'text2lines': True}, + 'tv.recentlyadded': {'index': 4, 'do_updates': True, 'with_progress': True, 'text2lines': True}, 'tv.startwatching': {'index': 7, 'with_progress': True, 'do_updates': True}, 'tv.rediscover': {'index': 8, 'with_progress': True, 'do_updates': True}, 'tv.morefromnetwork': {'index': 13, 'with_progress': True, 'do_updates': True}, @@ -341,7 +391,8 @@ class HomeWindow(kodigui.BaseWindow, util.CronReceiver): def __init__(self, *args, **kwargs): kodigui.BaseWindow.__init__(self, *args, **kwargs) - self.lastSection = HomeSection + SpoilersMixin.__init__(self, *args, **kwargs) + self.lastSection = home_section self.tasks = [] self.closeOption = None self.hubControls = None @@ -350,12 +401,26 @@ def __init__(self, *args, **kwargs): self.sectionChangeTimeout = 0 self.lastFocusID = None self.lastNonOptionsFocusID = None - self._lastSelectedItem = None self.sectionHubs = {} self.updateHubs = {} self.changingServer = False self._shuttingDown = False self._skipNextAction = False + self._reloadOnReinit = False + self._applyTheme = False + self._ignoreTick = False + self._ignoreInput = False + self._ignoreReInit = False + self._restarting = False + self._anyItemAction = False + self._odHubsDirty = False + self.librarySettings = None + self.hubSettings = None + self.anyLibraryHidden = False + self.wantedSections = None + self.movingSection = False + self._initialMovingSectionPos = None + self.go_root = False windowutils.HOME = self self.lock = threading.Lock() @@ -364,7 +429,7 @@ def __init__(self, *args, **kwargs): def onFirstInit(self): # set last BG image if possible - if util.advancedSettings.dynamicBackgrounds: + if util.addonSettings.dynamicBackgrounds: bgUrl = util.getSetting("last_bg_url") if bgUrl: self.windowSetBackground(bgUrl) @@ -417,10 +482,38 @@ def onFirstInit(self): self.hookSignals() util.CRON.registerReceiver(self) self.updateProperties() + self.checkPlexDirectHosts(plexapp.SERVERMANAGER.serversByUuid.values(), source="stored") + + def closeWRecompileTpls(self): + self._applyTheme = False + self._shuttingDown = True + self.closeOption = "recompile" + self.doClose() def onReInit(self): + if self._ignoreReInit: + return + + self._anyItemAction = False + if self._applyTheme: + self.closeWRecompileTpls() + return + + if self.go_root: + self.setProperty('hub.focus', '') + self.setFocusId(self.SECTION_LIST_ID) + self.sectionList.setSelectedItemByPos(0) + # somehow we need to do this as well. + xbmc.executebuiltin('Control.SetFocus({0}, {1})'.format(self.SECTION_LIST_ID, 0)) + self.go_root = False + return + + if self._reloadOnReinit: + self.serverRefresh() + self._reloadOnReinit = False + if self.lastFocusID: - # try focusing the last focused ID. if that's a hub and it's empty (=not focusable), try focusing the + # try focusing the last focused ID. if that's a hub, and it's empty (=not focusable), try focusing the # next best hub if 399 < self.lastFocusID < 500: hubControlIndex = self.lastFocusID - 400 @@ -430,11 +523,127 @@ def onReInit(self): # fixme: declutter, separation of concerns self.checkHubItem(self.lastFocusID) else: - util.DEBUG_LOG("Focus requested on {}, which can't focus. Trying next hub".format(self.lastFocusID)) + util.DEBUG_LOG("Focus requested on {}, which can't focus. Trying next hub", self.lastFocusID) self.focusFirstValidHub(hubControlIndex) else: - self.setFocusId(self.lastFocusID) + if self.getFocusId() != self.lastFocusID: + self.setFocusId(self.lastFocusID) + + if self._odHubsDirty: + self._updateOnDeckHubs() + + def checkPlexDirectHosts(self, servers, source="stored", *args, **kwargs): + handlePD = util.getSetting('handle_plexdirect', 'ask') + if handlePD == "never": + return + + hosts = [] + for server in servers: + # only check stored or myplex servers + if server.sourceType not in (None, plexresource.ResourceConnection.SOURCE_MYPLEX): + continue + # if we're set to honor dnsRebindingProtection=1 and the server has this flag at 0 or + # if we're set to honor publicAddressMatches=1 and the server has this flag at 0, and we haven't seen the + # server locally, skip plex.direct handling + if ((util.addonSettings.honorPlextvDnsrebind and not server.dnsRebindingProtection) or + (util.addonSettings.honorPlextvPam and not server.sameNetwork and not server.anyLANConnection)): + util.DEBUG_LOG("Ignoring DNS handling for plex.direct connections of: {}", server) + continue + hosts += [c.address for c in server.connections] + + knownHosts = pdm.getHosts() + pdHosts = [host for host in hosts if ".plex.direct:" in host] + + util.DEBUG_LOG("Checking host mapping for {} {} connections: {}", len(pdHosts), source, ", ".join(pdHosts)) + + newHosts = set(pdHosts) - set(knownHosts) + if newHosts: + pdm.newHosts(newHosts, source=source) + diffLen = len(pdm.diff) + + # there are situations where the myPlexManager's resources are ready earlier than + # any other. In that case, force the check. + force = plexapp.MANAGER.gotResources + + if ((source == "stored" and plexapp.ACCOUNT.isOffline) or source == "myplex" or force) and pdm.differs: + if handlePD == 'ask': + button = optionsdialog.show( + T(32993, '').format(diffLen), + T(32994, '').format(diffLen), + T(32328, 'Yes'), + T(32035, 'Always'), + T(32033, 'Never'), + ) + if button not in (0, 1, 2): + return + + if button == 1: + util.setSetting('handle_plexdirect', 'always') + elif button == 2: + util.setSetting('handle_plexdirect', 'never') + return + + hadHosts = pdm.hadHosts + pdm.write() + + if not hadHosts and handlePD == "ask": + optionsdialog.show( + T(32995, ''), + T(32996, ''), + T(32997, 'OK'), + ) + else: + # be less intrusive + util.showNotification(T(32996, ''), header=T(32995, '')) + + def loadLibrarySettings(self): + setting_key = 'home.settings.{}.{}'.format(plexapp.SERVERMANAGER.selectedServer.uuid[-8:], plexapp.ACCOUNT.ID) + data = util.getSetting(setting_key, '') + self.librarySettings = {} + try: + self.librarySettings = json.loads(data) + except ValueError: + pass + except: + util.ERROR() + + def saveLibrarySettings(self): + if self.librarySettings: + setting_key = 'home.settings.{}.{}'.format(plexapp.SERVERMANAGER.selectedServer.uuid[-8:], + plexapp.ACCOUNT.ID) + util.setSetting(setting_key, json.dumps(self.librarySettings)) + + def loadHubSettings(self): + setting_key = 'hub.settings.{}.{}'.format(plexapp.SERVERMANAGER.selectedServer.uuid[-8:], plexapp.ACCOUNT.ID) + data = util.getSetting(setting_key, '') + self.hubSettings = {} + try: + self.hubSettings = json.loads(data) + except ValueError: + pass + except: + util.ERROR() + + def saveHubSettings(self): + if self.hubSettings: + setting_key = 'hub.settings.{}.{}'.format(plexapp.SERVERMANAGER.selectedServer.uuid[-8:], + plexapp.ACCOUNT.ID) + util.setSetting(setting_key, json.dumps(self.hubSettings)) + + @property + def currentHub(self): + hub_focus = int(self.getProperty('hub.focus')) + if len(self.hubControls) > hub_focus and self.hubControls[hub_focus]: + hub_control = self.hubControls[hub_focus] + hub = hub_control.dataSource + if not hub or hub.hubIdentifier == "home.continue": + return + return hub + + @property + def ignoredHubs(self): + return [combo for combo, data in self.hubSettings.items() if not data.get("show", True)] def updateProperties(self, *args, **kwargs): self.setBoolProperty('bifurcation_lines', util.getSetting('hubs_bifurcation_lines', False)) @@ -450,9 +659,10 @@ def focusFirstValidHub(self, startIndex=None): for index in indices: if self.hubControls[index]: - util.DEBUG_LOG("Focusing hub: %i" % (400 + index)) - self.setFocusId(400+index) - self.checkHubItem(400+index) + if self.lastFocusID != 400+index: + util.DEBUG_LOG("Focusing hub: %i" % (400 + index)) + self.setFocusId(400+index) + self.checkHubItem(400+index) return if startIndex is not None: @@ -471,12 +681,25 @@ def hookSignals(self): plexapp.SERVERMANAGER.on('reachable:server', self.displayServerAndUser) plexapp.util.APP.on('change:selectedServer', self.onSelectedServerChange) + plexapp.util.APP.on('change:map_button_home', util.homeButtonMapped) + plexapp.util.APP.on('loaded:server_connections', self.checkPlexDirectHosts) plexapp.util.APP.on('account:response', self.displayServerAndUser) plexapp.util.APP.on('sli:reachability:received', self.displayServerAndUser) plexapp.util.APP.on('change:hubs_bifurcation_lines', self.updateProperties) + plexapp.util.APP.on('change:no_episode_spoilers3', self.setDirty) + plexapp.util.APP.on('change:spoilers_allowed_genres2', self.setDirty) + plexapp.util.APP.on('change:hubs_use_new_continue_watching', self.setDirty) + plexapp.util.APP.on('change:path_mapping_indicators', self.setDirty) + plexapp.util.APP.on('change:debug', self.setDebugFlag) + plexapp.util.APP.on('theme_relevant_setting', self.setThemeDirty) player.PLAYER.on('session.ended', self.updateOnDeckHubs) util.MONITOR.on('changed.watchstatus', self.updateOnDeckHubs) + util.MONITOR.on('screensaver.activated', self.disableUpdates) + util.MONITOR.on('screensaver.deactivated', self.refreshLastSection) + util.MONITOR.on('dpms.deactivated', self.refreshLastSection) + util.MONITOR.on('system.sleep', self.disableUpdates) + util.MONITOR.on('system.wakeup', self.onWake) def unhookSignals(self): plexapp.SERVERMANAGER.off('new:server', self.onNewServer) @@ -485,24 +708,42 @@ def unhookSignals(self): plexapp.SERVERMANAGER.off('reachable:server', self.displayServerAndUser) plexapp.util.APP.off('change:selectedServer', self.onSelectedServerChange) + plexapp.util.APP.off('change:map_button_home', util.homeButtonMapped) + plexapp.util.APP.off('loaded:server_connections', self.checkPlexDirectHosts) plexapp.util.APP.off('account:response', self.displayServerAndUser) plexapp.util.APP.off('sli:reachability:received', self.displayServerAndUser) plexapp.util.APP.off('change:hubs_bifurcation_lines', self.updateProperties) + plexapp.util.APP.off('change:no_episode_spoilers3', self.setDirty) + plexapp.util.APP.off('change:spoilers_allowed_genres2', self.setDirty) + plexapp.util.APP.off('change:hubs_use_new_continue_watching', self.setDirty) + plexapp.util.APP.off('change:path_mapping_indicators', self.setDirty) + plexapp.util.APP.off('change:debug', self.setDebugFlag) + plexapp.util.APP.off('theme_relevant_setting', self.setThemeDirty) player.PLAYER.off('session.ended', self.updateOnDeckHubs) util.MONITOR.off('changed.watchstatus', self.updateOnDeckHubs) + util.MONITOR.off('screensaver.activated', self.disableUpdates) + util.MONITOR.off('screensaver.deactivated', self.refreshLastSection) + util.MONITOR.off('dpms.deactivated', self.refreshLastSection) + util.MONITOR.off('system.sleep', self.disableUpdates) + util.MONITOR.off('system.wakeup', self.onWake) def tick(self): - if not self.lastSection: + if not self.lastSection or self._ignoreTick: return hubs = self.sectionHubs.get(self.lastSection.key) - if not hubs: + if hubs is None: return - if time.time() - hubs.lastUpdated > HUBS_REFRESH_INTERVAL: + if (self.is_active and time.time() - hubs.lastUpdated > HUBS_REFRESH_INTERVAL and + not xbmc.Player().isPlayingVideo()): self.showHubs(self.lastSection, update=True) + def doClose(self): + plexapp.util.APP.trigger('close.windows') + super(HomeWindow, self).doClose() + def shutdown(self): self._shuttingDown = True try: @@ -514,7 +755,7 @@ def shutdown(self): self.storeLastBG() def storeLastBG(self): - if util.advancedSettings.dynamicBackgrounds: + if util.addonSettings.dynamicBackgrounds: oldbg = util.getSetting("last_bg_url", "") # store BG url of first hub, first item, as this is most likely to be the one we're focusing on the # next start @@ -545,6 +786,9 @@ def storeLastBG(self): def onAction(self, action): controlID = self.getFocusId() + if self._ignoreInput: + return + try: if self._skipNextAction: self._skipNextAction = False @@ -555,6 +799,17 @@ def onAction(self, action): self.setFocusId(self.lastFocusID) if controlID == self.SECTION_LIST_ID: + if self.movingSection: + self.sectionMover(self.movingSection, action) + return + + if action == xbmcgui.ACTION_CONTEXT_MENU: + show_section = self.sectionMenu() + if not show_section: + return + else: + self.serverRefresh(section=show_section) + return self.checkSectionItem(action=action) if controlID == self.SERVER_BUTTON_ID: @@ -590,12 +845,20 @@ def onAction(self, action): elif controlID == self.PLAYER_STATUS_BUTTON_ID and action == xbmcgui.ACTION_MOVE_RIGHT: self.setFocusId(self.SERVER_BUTTON_ID) elif 399 < controlID < 500: - if action.getId() in MOVE_SET: - self.checkHubItem(controlID, actionID=action.getId()) - return - elif action.getId() == xbmcgui.ACTION_PLAYER_PLAY: + if action.getId() in MOVE_SET or action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): + _continue = self.checkHubItem(controlID, action=action) + if not _continue: + return + elif action == xbmcgui.ACTION_PLAYER_PLAY: self.hubItemClicked(controlID, auto_play=True) return + elif action == xbmcgui.ACTION_CONTEXT_MENU: + show_section = self.hubMenu() + if not show_section: + return + else: + self.serverRefresh(section=show_section) + return if action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_CONTEXT_MENU): optionsFocused = xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format(self.OPTIONS_GROUP_ID)) @@ -614,10 +877,13 @@ def onAction(self, action): if controlID == self.SECTION_LIST_ID and self.sectionList.control.getSelectedPosition() > 0: self.sectionList.setSelectedItemByPos(0) - self.showHubs(HomeSection) + # set lastSection here already, otherwise tick() might interfere + # fixme: Might still happen in a race condition, check later + self.lastSection = home_section + self.showHubs(home_section) return - if util.advancedSettings.fastBack and not optionsFocused and offSections \ + if util.addonSettings.fastBack and not optionsFocused and offSections \ and self.lastFocusID not in (self.USER_BUTTON_ID, self.SERVER_BUTTON_ID, self.SEARCH_BUTTON_ID, self.SECTION_LIST_ID): self.setProperty('hub.focus', '0') @@ -626,7 +892,7 @@ def onAction(self, action): if action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_CONTEXT_MENU): if not optionsFocused and offSections \ - and (not util.advancedSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU): + and (not util.addonSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU): self.lastNonOptionsFocusID = self.lastFocusID self.setFocusId(self.OPTIONS_GROUP_ID) return @@ -643,6 +909,7 @@ def onAction(self, action): return elif ex.button == 1: self.storeLastBG() + util.setGlobalProperty('is_active', '') xbmc.executebuiltin('ActivateWindow(10000)') return elif ex.button == 0: @@ -657,8 +924,12 @@ def onAction(self, action): kodigui.BaseWindow.onAction(self, action) def onClick(self, controlID): + if self._ignoreInput: + return + if controlID == self.SECTION_LIST_ID: - self.sectionClicked() + if not self.movingSection: + self.sectionClicked() # elif controlID == self.SERVER_BUTTON_ID: # self.showServers() elif controlID == self.SERVER_LIST_ID: @@ -730,23 +1001,96 @@ def searchButtonClicked(self): self.processCommand(search.dialog(self)) def updateOnDeckHubs(self, **kwargs): + self._odHubsDirty = True + + def _updateOnDeckHubs(self, **kwargs): + util.DEBUG_LOG('UpdateOnDeckHubs called') + self._odHubsDirty = False if util.getSetting("speedy_home_hubs2", False): util.DEBUG_LOG("Using alternative home hub refresh") sections = set() for mli in self.sectionList: if mli.dataSource is not None and mli.dataSource != self.lastSection: sections.add(mli.dataSource) - tasks = [SectionHubsTask().setup(s, self.sectionHubsCallback) for s in [self.lastSection] + list(sections)] + tasks = [SectionHubsTask().setup(s, self.sectionHubsCallback, self.wantedSections, self.ignoredHubs) + for s in [self.lastSection] + list(sections)] else: - tasks = [UpdateHubTask().setup(hub, self.updateHubCallback) for hub in self.updateHubs.values()] + # fetch hubs we need to update + rp = self.getCurrentHubsPositions(self.lastSection) + tasks = [UpdateHubTask().setup(hub, self.updateHubCallback, + reselect_pos=rp.get(hub.getCleanHubIdentifier(self.lastSection.key is None))) + for hub in self.updateHubs.values()] self.tasks += tasks backgroundthread.BGThreader.addTasks(tasks) def showBusy(self, on=True): self.setProperty('busy', on and '1' or '') + def setDirty(self, *args, **kwargs): + self._reloadOnReinit = True + self.cacheSpoilerSettings() + + def setThemeDirty(self, *args, **kwargs): + self._applyTheme = util.getSetting("theme", "modern-colored") + + def setDebugFlag(self, *args, **kwargs): + util.DEBUG = util.getSetting("debug", False) + util.addonSettings.debug = util.DEBUG + + def fullyRefreshHome(self, *args, **kwargs): + section = kwargs.pop("section", None) + self.showSections(focus_section=section or home_section) + self.backgroundSet = False + self.showHubs(section if section else home_section) + + def disableUpdates(self, *args, **kwargs): + util.LOG("Sleep event, stopping updates") + self._ignoreTick = True + + def enableUpdates(self, *args, **kwargs): + util.LOG("Wake event, resuming updates") + self._ignoreTick = False + + def refreshLastSection(self, *args, **kwargs): + self.enableUpdates() + if not xbmc.Player().isPlayingVideo(): + util.LOG("Refreshing last section after wake events") + self.showHubs(self.lastSection, force=True) + + def onWake(self, *args, **kwargs): + wakeAction = util.getSetting('action_on_wake', util.isCoreELEC and 'wait_5' or 'wait_1') + if wakeAction == "restart": + self._ignoreReInit = True + self._restarting = True + if not self.is_active: + plexapp.util.APP.trigger('close.dialogs') + plexapp.util.APP.trigger('close.windows') + + self.closeOption = "restart" + self.doClose() + return + elif wakeAction.startswith("wait_"): + seconds = int(wakeAction.split("_")[1]) + established = 0 + self._ignoreInput = True + try: + with busy.BusyBlockingContext(): + with busy.ProgressDialog(T(33073, ''), T(33074, '').format(seconds)) as pd: + while established < seconds: + util.MONITOR.waitForAbort(0.5) + established += 0.5 + pd.update(int(established * 100 / float(seconds))) + if pd.isCanceled(): + break + self.refreshLastSection(*args, **kwargs) + return + finally: + self._ignoreInput = False + + self.refreshLastSection(*args, **kwargs) + @busy.dialog() - def serverRefresh(self): + def serverRefresh(self, section=None): backgroundthread.BGThreader.reset() if self.tasks: for task in self.tasks: @@ -755,13 +1099,18 @@ def serverRefresh(self): with self.lock: self.setProperty('hub.focus', '') self.displayServerAndUser() + self.loadLibrarySettings() + self.loadHubSettings() if not plexapp.SERVERMANAGER.selectedServer: self.setFocusId(self.USER_BUTTON_ID) return False - self.showSections() - self.backgroundSet = False - self.showHubs(HomeSection) + self.fullyRefreshHome(section=section) + if section is not None: + for mli in self.sectionList: + if mli.dataSource and mli.dataSource.key == section.key: + self.sectionList.selectItem(mli.pos()) + self.lastSection = mli.dataSource return True def hubItemClicked(self, hubControlID, auto_play=False): @@ -774,13 +1123,8 @@ def hubItemClicked(self, hubControlID, auto_play=False): return carryProps = None - if auto_play and self.hubControls: - # carry over some props to the new window as we might end up showing a resume dialog not rendering the - # underlying window. the new window class will invalidate the old one temporarily, though, as it seems - # and the properties vanish, resulting in all text2lines enabled hubs to lose their title2 labels - carryProps = dict( - ('hub.text2lines.4{0:02d}'.format(i), '1') for i, hubCtrl in enumerate(self.hubControls) if - hubCtrl.dataSource and self.HUBMAP[hubCtrl.dataSource.getCleanHubIdentifier()].get("text2lines")) + if auto_play: + carryProps = self.carriedProps try: command = opener.open(mli.dataSource, auto_play=auto_play, dialog_props=carryProps) @@ -790,6 +1134,9 @@ def hubItemClicked(self, hubControlID, auto_play=False): util.ERROR("No data - disconnected?", notify=True, time_ms=5000) return + if self._restarting: + return + self.updateListItem(mli) if not mli: @@ -825,7 +1172,280 @@ def processCommand(self, command): if mli.dataSource and mli.dataSource.key == sectionID: self.sectionList.selectItem(mli.pos()) self.lastSection = mli.dataSource - self.sectionChanged() + self.setProperty('hub.focus', '') + self.setFocusId(self.SECTION_LIST_ID) + self._sectionReallyChanged(self.lastSection) + + @property + def carriedProps(self): + # carry over some props to the new window as we might end up showing a dialog not rendering the + # underlying window. the new window class will invalidate the old one temporarily, though, as it seems + # and the properties vanish, resulting in all text2lines enabled hubs to lose their title2 labels + if self.hubControls: + return dict( + ('hub.text2lines.4{0:02d}'.format(i), '1') for i, hubCtrl in enumerate(self.hubControls) if + hubCtrl.dataSource and self.HUBMAP[hubCtrl.dataSource.getCleanHubIdentifier()].get("text2lines")) + + def sectionMenu(self): + item = self.sectionList.getSelectedItem() + if not item or not item.getProperty('item'): + return + + section = item.dataSource + choice = None + if not section.key: + # home section + sections = [playlists_section] + plexapp.SERVERMANAGER.selectedServer.library.sections() + options = [] + + if "order" in self.librarySettings and self.librarySettings["order"]: + options.append({'key': 'reset_order', 'display': T(33040, "Reset library order")}) + options.append(dropdown.SEPARATOR) + + had_section = False + for s in sections: + section_settings = self.librarySettings.get(s.key) + if section_settings and not section_settings.get("show", True): + options.append({'key': 'show', + 'section_id': s.key, + 'display': T(33029, "Show library: {}").format(s.title) + } + ) + had_section = True + if self.hubSettings: + had_hidden_hub = False + hidden_hubs_opts = [] + for section_hub_key in self.ignoredHubs: + if not section_hub_key.startswith("None:"): + continue + + hub_title = section_hub_key + if plexapp.SERVERMANAGER.selectedServer.currentHubs: + hub_title = plexapp.SERVERMANAGER.selectedServer.currentHubs.get(section_hub_key, + section_hub_key) + hidden_hubs_opts.append({'key': 'show', + 'hub_ident': section_hub_key, + 'display': T(33041, "Show hub: {}").format(hub_title) + } + ) + had_hidden_hub = True + + if had_section and had_hidden_hub: + options.append(dropdown.SEPARATOR) + options += hidden_hubs_opts + + if options: + choice = dropdown.showDropdown( + options, + pos=(660, 441), + close_direction='none', + set_dropdown_prop=False, + header=T(33034, "Library settings"), + select_index=0, + align_items="left", + dialog_props=self.carriedProps + ) + + else: + options = [] + if plexapp.ACCOUNT.isAdmin and section != playlists_section: + options = [{'key': 'refresh', 'display': T(33082, "Scan Library Files")}, + {'key': 'emptyTrash', 'display': T(33083, "Empty Trash")}, + {'key': 'analyze', 'display': T(33084, "Analyze")}, + dropdown.SEPARATOR] + + if section.locations: + for loc in section.locations: + source, target = section.getMappedPath(loc) + loc_is_mapped = source and target + options.append( + {'key': 'map', 'mapped': loc_is_mapped, 'path': loc, 'display': T(33026, + "Map path: {}").format(loc) + if not loc_is_mapped else T(33027, "Remove mapping: {}").format(target) + } + ) + + options.append(dropdown.SEPARATOR) + + options.append({'key': 'hide', 'display': T(33028, "Hide library")}) + options.append({'key': 'move', 'display': T(33039, "Move")}) + options.append(dropdown.SEPARATOR) + + if self.hubSettings: + for section_hub_key in self.ignoredHubs: + if not section_hub_key.startswith("{}:".format(section.key)): + continue + + hub_title = section_hub_key + if plexapp.SERVERMANAGER.selectedServer.currentHubs: + hub_title = plexapp.SERVERMANAGER.selectedServer.currentHubs.get(section_hub_key, + section_hub_key) + options.append({'key': 'show', + 'hub_ident': section_hub_key, + 'display': T(33041, "Show hub: {}").format(hub_title) + } + ) + + choice = dropdown.showDropdown( + options, + pos=(660, 441), + close_direction='none', + set_dropdown_prop=False, + header=T(33030, 'Choose action for: {}').format(section.title), + select_index=0, + align_items="left", + dialog_props=self.carriedProps + ) + + if not choice: + return + + if choice["key"] == "map": + is_mapped = choice.get("mapped") + if is_mapped: + # show deletion + source, target = section.getMappedPath(choice["path"]) + section.deleteMapping(target) + return self.lastSection + + else: + # show fb + # select loc to map + d = xbmcgui.Dialog().browse(0, T(33031, "Select Kodi source for {}").format(choice["path"]), "files") + if not d: + return + pmm.addPathMapping(d, choice["path"]) + return self.lastSection + elif choice["key"] == "hide": + if section.key not in self.librarySettings: + self.librarySettings[section.key] = {} + self.librarySettings[section.key]['show'] = False + self.saveLibrarySettings() + return self.sectionList[self.sectionList.prev()].dataSource + elif choice["key"] == "show": + if "hub_ident" in choice: + if choice["hub_ident"] in self.hubSettings: + self.hubSettings[choice["hub_ident"]]['show'] = True + self.saveHubSettings() + return self.lastSection + elif "section_id" in choice: + if choice["section_id"] in self.librarySettings: + self.librarySettings[choice["section_id"]]['show'] = True + self.saveLibrarySettings() + return self.lastSection + elif choice["key"] == "move": + self.sectionMover(item, "init") + elif choice["key"] == "reset_order": + if "order" in self.librarySettings: + del self.librarySettings["order"] + self.saveLibrarySettings() + return self.lastSection + elif choice["key"] == "refresh": + with busy.BusyContext(delay=True, delay_time=0.2): + section.refresh() + return self.lastSection + elif choice["key"] == "emptyTrash": + button = optionsdialog.show( + T(33083, 'Empty Trash'), + section.title, + T(32328, 'Yes'), + T(32329, 'No') + ) + if button == 0: + with busy.BusyContext(delay=True, delay_time=0.2): + section.emptyTrash() + return self.lastSection + elif choice["key"] == "analyze": + with busy.BusyContext(delay=True, delay_time=0.2): + section.analyze() + return + + def hubMenu(self): + hub = self.currentHub + if not hub: + return + + section_hub_key = "{}:{}".format(self.lastSection.key, hub.hubIdentifier) + + hub_title = section_hub_key + if plexapp.SERVERMANAGER.selectedServer.currentHubs: + hub_title = plexapp.SERVERMANAGER.selectedServer.currentHubs.get(section_hub_key, + section_hub_key) + + options = [{'key': 'hide', 'display': "Hide Hub: {}".format(hub_title)}] + + choice = dropdown.showDropdown( + options, + pos=(660, 441), + close_direction='none', + set_dropdown_prop=False, + header=T(33030, 'Choose action for: {}').format(hub.title), + select_index=0, + align_items="left", + dialog_props=self.carriedProps + ) + + if not choice: + return + + elif choice["key"] == "hide": + if section_hub_key not in self.hubSettings: + self.hubSettings[section_hub_key] = {} + self.hubSettings[section_hub_key]['show'] = False + self.saveHubSettings() + return self.lastSection + + def sectionMover(self, item, action): + def stop_moving(reset=False): + # set everything to non-moving and re-insert home item + self.movingSection = False + self.setBoolProperty("moving", False) + item.setBoolProperty("moving", False) + homemli = kodigui.ManagedListItem(T(32332, 'Home'), data_source=home_section) + homemli.setProperty('is.home', '1') + homemli.setProperty('item', '1') + if reset: + if self._initialMovingSectionPos is not None: + self.sectionList.moveItem(item, self._initialMovingSectionPos) + self._initialMovingSectionPos = None + self.sectionList.insertItem(0, homemli) + if reset: + self.sectionList.selectItem(0) + self.sectionChanged() + + if action == "init": + self.movingSection = item + self.setBoolProperty("moving", True) + self._initialMovingSectionPos = self.sectionList.getSelectedPos() - 1 + + # remove home item + self.sectionList.removeItem(0) + self.sectionList.setSelectedItem(item) + + item.setBoolProperty("moving", True) + + elif action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): + stop_moving(reset=True) + + elif action in (xbmcgui.ACTION_MOVE_LEFT, xbmcgui.ACTION_MOVE_RIGHT): + direction = "left" if action == xbmcgui.ACTION_MOVE_LEFT else "right" + index = self.sectionList.getManagedItemPosition(item) + last_index = len(self.sectionList) - 1 + next_index = min(max(0, index - 1 if direction == "left" else index + 1), last_index) + if index == 0 and direction == "left": + next_index = last_index + self.sectionList.selectItem(last_index) + elif index == last_index and direction == "right": + next_index = 0 + self.sectionList.selectItem(0) + + self.sectionList.moveItem(item, next_index) + + elif action == xbmcgui.ACTION_SELECT_ITEM: + stop_moving() + # store section order + self.librarySettings["order"] = [i.dataSource.key for i in self.sectionList.items if i.dataSource] + self.saveLibrarySettings() def checkSectionItem(self, force=False, action=None): item = self.sectionList.getSelectedItem() @@ -843,29 +1463,59 @@ def checkSectionItem(self, force=False, action=None): if item.getProperty('is.home'): self.storeLastBG() - if item.dataSource != self.lastSection: - self.sectionChanged(force) + if item.dataSource != self.lastSection or force: + self.sectionChanged(force=force) - def checkHubItem(self, controlID, actionID=None): + def checkHubItem(self, controlID, action=None): control = self.hubControls[controlID - 400] mli = control.getSelectedItem() is_valid_mli = mli and mli.getProperty('is.end') != '1' is_last_item = is_valid_mli and control.isLastItem(mli) - if util.advancedSettings.dynamicBackgrounds and is_valid_mli: + if action: + self._anyItemAction = True + + if action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): + pos = control.getSelectedPos() + if pos is not None and pos > 0: + control.selectItem(0) + self.updateBackgroundFrom(control[0].dataSource) + return + return True + + if util.addonSettings.dynamicBackgrounds and is_valid_mli: self.updateBackgroundFrom(mli.dataSource) if not mli or not mli.getProperty('is.end') or mli.getProperty('is.updating') == '1': - mlipos = control.getManagedItemPosition(mli) - - # in order to not round robin when the next chunk is loading, implement our own cheap round robining - # by storing the last selected item of the current control. if we've seen it twice, we need to wrap around - if mli and not mli.getProperty('is.end') and is_last_item and actionID == xbmcgui.ACTION_MOVE_RIGHT: - if (controlID, mlipos) == self._lastSelectedItem: - control.selectItem(0) - self._lastSelectedItem = None - else: - self._lastSelectedItem = (controlID, mlipos) + # round robining + if mli and util.getSetting("hubs_round_robin", False): + mlipos = control.getManagedItemPosition(mli) + + # in order to not round-robin when the next chunk is loading, implement our own cheap round-robining + # by storing the last selected item of the current control. if we've seen it twice, we need to wrap + # around + if not mli.getProperty('is.end') and is_last_item and action == xbmcgui.ACTION_MOVE_RIGHT: + if (controlID, mlipos) == self._lastSelectedItem: + control.selectItem(0) + self._lastSelectedItem = (controlID, 0) + self.updateBackgroundFrom(control[0].dataSource) + return + elif (action == xbmcgui.ACTION_MOVE_LEFT and mlipos == 0 + and (controlID, mlipos) == self._lastSelectedItem): + if not control.dataSource.more.asInt(): + last_item_index = len(control) - 1 + control.selectItem(last_item_index) + self._lastSelectedItem = (controlID, last_item_index) + self.updateBackgroundFrom(control[last_item_index].dataSource) + else: + task = ExtendHubTask().setup(control.dataSource, self.extendHubCallback, + canceledCallback=lambda hub: mli.setBoolProperty('is.updating', + False), + reselect_pos=(None, -1)) + self.tasks.append(task) + backgroundthread.BGThreader.addTask(task) + return + self._lastSelectedItem = (controlID, mlipos) return mli.setBoolProperty('is.updating', True) @@ -897,50 +1547,70 @@ def displayServerAndUser(self, **kwargs): self.setProperty('server.iconmod2', '') def cleanTasks(self): - self.tasks = [t for t in self.tasks if t.isValid()] + self.tasks = [t for t in self.tasks if t] def sectionChanged(self, force=False): self.sectionChangeTimeout = time.time() + 0.5 - if not self.sectionChangeThread or not self.sectionChangeThread.is_alive() or force: - if self.sectionChangeThread and self.sectionChangeThread.is_alive(): - self.sectionChangeThread.join() + # wait 2s at max if we're currently awaiting any hubs to reload + # fixme: this can be done in a better way, probably + waited = 0 + while any(self.tasks) and waited < 20: + self.showBusy(True) + util.MONITOR.waitForAbort(0.1) + waited += 1 + self.showBusy(False) + + if force: + self.sectionChangeTimeout = None + self._sectionChanged(immediate=True) + return + + if not self.sectionChangeThread or (self.sectionChangeThread and not self.sectionChangeThread.is_alive()): self.sectionChangeThread = threading.Thread(target=self._sectionChanged, name="sectionchanged") self.sectionChangeThread.start() - def _sectionChanged(self): - while not util.MONITOR.waitForAbort(0.1): - if time.time() >= self.sectionChangeTimeout: - break + def _sectionChanged(self, immediate=False): + if not immediate: + if not self.sectionChangeTimeout: + return + while not util.MONITOR.waitForAbort(0.1): + if time.time() >= self.sectionChangeTimeout: + break ds = self.sectionList.getSelectedItem().dataSource if self.lastSection == ds: return - self.lastSection = ds - - self._sectionReallyChanged() + self._sectionReallyChanged(ds) - def _sectionReallyChanged(self): + def _sectionReallyChanged(self, section): with self.lock: - section = self.lastSection self.setProperty('hub.focus', '') - if util.advancedSettings.dynamicBackgrounds: + if util.addonSettings.dynamicBackgrounds: self.backgroundSet = False - util.DEBUG_LOG('Section changed ({0}): {1}'.format(section.key, repr(section.title))) - self.showHubs(section) + util.DEBUG_LOG('Section changed ({0}): {1}', section.key, repr(section.title)) self.lastSection = section + self.showHubs(section) + + # timing issue + cur_sel_ds = self.sectionList.getSelectedItem().dataSource + if self.lastSection != cur_sel_ds: + util.DEBUG_LOG("Section changed in the " + "meantime from {} to {}, re-running the section change".format( + section.key, + cur_sel_ds.key)) self.checkSectionItem(force=True) - def sectionHubsCallback(self, section, hubs): + def sectionHubsCallback(self, section, hubs, reselect_pos_dict=None): with self.lock: update = bool(self.sectionHubs.get(section.key)) self.sectionHubs[section.key] = hubs if self.lastSection == section: - self.showHubs(section, update=update) + self.showHubs(section, update=update, reselect_pos_dict=reselect_pos_dict) - def updateHubCallback(self, hub, items=None): + def updateHubCallback(self, hub, items=None, reselect_pos=None): with self.lock: for mli in self.sectionList: section = mli.dataSource @@ -949,51 +1619,80 @@ def updateHubCallback(self, hub, items=None): hubs = self.sectionHubs.get(section.key, ()) if not hubs: - util.LOG("Hubs for {} not found/no data".format(section.key)) + util.LOG("Hubs for {} not found/no data", section.key) continue for idx, ihub in enumerate(hubs): if ihub == hub: if self.lastSection == section: - util.DEBUG_LOG('Hub {0} updated - refreshing section: {1}'.format(hub.hubIdentifier, repr(section.title))) + util.DEBUG_LOG('Hub {0} updated - refreshing section: {1}'.format(hub.hubIdentifier, + repr(section.title))) hubs[idx] = hub - self.showHub(hub, items=items) + self.showHub(hub, items=items, reselect_pos=reselect_pos) return - def extendHubCallback(self, hub, items): - util.DEBUG_LOG('ExtendHub called: {0} [{1}]'.format(hub.hubIdentifier, len(hub.items))) - self.updateHubCallback(hub, items) + def extendHubCallback(self, hub, items, reselect_pos=None): + util.DEBUG_LOG('ExtendHub called: {0} [{1}] (reselect: {2})'.format(hub.hubIdentifier, len(hub.items), + reselect_pos)) + self.updateHubCallback(hub, items, reselect_pos=reselect_pos) - def showSections(self): + def showSections(self, focus_section=None): self.sectionHubs = {} items = [] - homemli = kodigui.ManagedListItem(T(32332, 'Home'), data_source=HomeSection) + homemli = kodigui.ManagedListItem(T(32332, 'Home'), data_source=home_section) homemli.setProperty('is.home', '1') homemli.setProperty('item', '1') items.append(homemli) - pl = plexapp.SERVERMANAGER.selectedServer.playlists() - if pl: - plli = kodigui.ManagedListItem('Playlists', thumbnailImage='script.plex/home/type/playlists.png', data_source=PlaylistsSection) - plli.setProperty('is.playlists', '1') - plli.setProperty('item', '1') - items.append(plli) + sections = [] + + if "playlists" not in self.librarySettings \ + or ("playlists" in self.librarySettings and self.librarySettings["playlists"].get("show", True)): + pl = plexapp.SERVERMANAGER.selectedServer.playlists() + if pl: + sections.append(playlists_section) try: - sections = plexapp.SERVERMANAGER.selectedServer.library.sections() + _sections = plexapp.SERVERMANAGER.selectedServer.library.sections() except plexnet.exceptions.BadRequest: self.setFocusId(self.SERVER_BUTTON_ID) util.messageDialog("Error", "Bad request") return + self.wantedSections = [] + for section in _sections: + if section.key in self.librarySettings and not self.librarySettings[section.key].get("show", True): + self.anyLibraryHidden = True + continue + sections.append(section) + self.wantedSections.append(section.key) + + # sort libraries + if "order" in self.librarySettings: + sections = sorted(sections, key=lambda s: self.librarySettings["order"].index(s.key) + if s.key in self.librarySettings["order"] else -1) + + # speedup if we don't have any hidden libraries + if not self.anyLibraryHidden: + self.wantedSections = None + if plexapp.SERVERMANAGER.selectedServer.hasHubs(): - self.tasks = [SectionHubsTask().setup(s, self.sectionHubsCallback) for s in [HomeSection, PlaylistsSection] + sections] + self.tasks = [SectionHubsTask().setup(s, self.sectionHubsCallback, self.wantedSections, self.ignoredHubs) + for s in [home_section] + sections] backgroundthread.BGThreader.addTasks(self.tasks) + show_pm_indicator = util.getSetting('path_mapping_indicators', True) for section in sections: - mli = kodigui.ManagedListItem(section.title, thumbnailImage='script.plex/home/type/{0}.png'.format(section.type), data_source=section) + mli = kodigui.ManagedListItem(section.title, + thumbnailImage='script.plex/home/type/{0}.png'.format(section.type), + data_source=section) mli.setProperty('item', '1') + if section == playlists_section: + mli.setProperty('is.playlists', '1') + mli.setThumbnailImage('script.plex/home/type/playlists.png') + if pmm.mapping and show_pm_indicator: + mli.setBoolProperty('is.mapped', section.isMapped) items.append(mli) self.bottomItem = len(items) - 1 @@ -1002,25 +1701,50 @@ def showSections(self): mli = kodigui.ManagedListItem() items.append(mli) - self.lastSection = HomeSection + self.lastSection = focus_section or home_section self.sectionList.reset() self.sectionList.addItems(items) - if items: - self.setFocusId(self.SECTION_LIST_ID) + if not focus_section: + if items: + self.setFocusId(self.SECTION_LIST_ID) + else: + self.setFocusId(self.SERVER_BUTTON_ID) else: - self.setFocusId(self.SERVER_BUTTON_ID) + self.setFocusId(self.SECTION_LIST_ID) - def showHubs(self, section=None, update=False): + def showHubs(self, section=None, update=False, force=False, reselect_pos_dict=None): self.setBoolProperty('no.content', False) if not update: self.setProperty('drawing', '1') try: - self._showHubs(section=section, update=update) + self._showHubs(section=section, update=update, force=force, reselect_pos_dict=reselect_pos_dict) finally: self.setProperty('drawing', '') - def _showHubs(self, section=None, update=False): + def getCurrentHubsPositions(self, section): + is_home = section.key is None + rp = {} + # self.sectionHubs[section.key] might be None + if not self.sectionHubs.get(section.key, []): + return rp + + for hub in self.sectionHubs.get(section.key, []): + identifier = hub.getCleanHubIdentifier(is_home=is_home) + if identifier in self.HUBMAP: + pos = self.hubControls[self.HUBMAP[identifier]['index']].getSelectedPos() + if pos is not None: + mli = self.hubControls[self.HUBMAP[identifier]['index']].getItemByPos(pos) + if mli.dataSource: + # continue/inprogress hubs update their order after items have changed their state, skip those + if (identifier in ('home.continue', 'home.ondeck', 'continueWatching') + or identifier.endswith('.inprogress')): + rp[identifier] = (str(mli.dataSource.ratingKey), 0) + continue + rp[identifier] = (str(mli.dataSource.ratingKey), pos) + return rp + + def _showHubs(self, section=None, update=False, force=False, reselect_pos_dict=None): if not update: self.clearHubs() @@ -1034,47 +1758,65 @@ def _showHubs(self, section=None, update=False): self.showBusy(True) hubs = self.sectionHubs.get(section.key) - if hubs is False: - self.showBusy(False) - self.setBoolProperty('no.content', True) - return + section_stale = False - if not hubs: - for task in self.tasks: - if task.section == section: - backgroundthread.BGThreader.moveToFront(task) - break + if not force: + if hubs is not None: + section_stale = time.time() - hubs.lastUpdated > HUBS_REFRESH_INTERVAL - if section.type != "home": + # hubs.invalid is True when the last hub update errored. if the hub is stale, refresh it, though + if hubs is not None and hubs.invalid and not section_stale: + util.DEBUG_LOG("Section fetch has failed: {}", section.key) self.showBusy(False) self.setBoolProperty('no.content', True) - return + return + + if not hubs and not section_stale: + for task in self.tasks: + if task.section == section: + backgroundthread.BGThreader.moveToFront(task) + break - if time.time() - hubs.lastUpdated > HUBS_REFRESH_INTERVAL: - util.DEBUG_LOG('Section is stale: REFRESHING - update: {0}'.format(update)) + if section.type != "home": + self.showBusy(False) + self.setBoolProperty('no.content', True) + return + + if section_stale or force: + util.DEBUG_LOG('Section is stale: {0} REFRESHING - update: {1}, failed before: {2}'.format( + "Home" if section.key is None else section.key, update, "Unknown" if not hubs else hubs.invalid)) hubs.lastUpdated = time.time() self.cleanTasks() + + rpd = self.getCurrentHubsPositions(section) + if not update: if section.key in self.sectionHubs: self.sectionHubs[section.key] = None - self.tasks.append(SectionHubsTask().setup(section, self.sectionHubsCallback)) - backgroundthread.BGThreader.addTask(self.tasks[-1]) + task = SectionHubsTask().setup(section, self.sectionHubsCallback, self.wantedSections, + reselect_pos_dict=rpd, + ignore_hubs=self.ignoredHubs) + self.tasks.append(task) + backgroundthread.BGThreader.addTask(task) return - util.DEBUG_LOG('Showing hubs - Section: {0} - Update: {1}'.format(section.key, update)) + util.DEBUG_LOG('Showing hubs - Section: {0} - Update: {1}', section.key, update) try: hasContent = False skip = {} + for hub in hubs: - identifier = hub.getCleanHubIdentifier() + identifier = hub.getCleanHubIdentifier(is_home=not section.key) if identifier not in self.HUBMAP: - util.DEBUG_LOG('UNHANDLED - Hub: {0} [{1}]({2})'.format(hub.hubIdentifier, identifier, len(hub.items))) + util.DEBUG_LOG('UNHANDLED - Hub: {0} [{1}]({2})'.format(hub.hubIdentifier, identifier, + len(hub.items))) continue skip[self.HUBMAP[identifier]['index']] = 1 - if self.showHub(hub): + if self.showHub(hub, is_home=not section.key, + reselect_pos=reselect_pos_dict.get(identifier) if reselect_pos_dict else None): if hub.items: hasContent = True if self.HUBMAP[identifier].get('do_updates'): @@ -1103,18 +1845,22 @@ def _showHubs(self, section=None, update=False): finally: self.showBusy(False) - def showHub(self, hub, items=None): - identifier = hub.getCleanHubIdentifier() + def showHub(self, hub, items=None, is_home=False, reselect_pos=None): + identifier = hub.getCleanHubIdentifier(is_home=is_home) if identifier in self.HUBMAP: - util.DEBUG_LOG('HUB: {0} [{1}]({2}, {3})'.format(hub.hubIdentifier, - identifier, - len(hub.items), - len(items) if items else None)) - self._showHub(hub, hubitems=items, **self.HUBMAP[identifier]) + util.DEBUG_LOG('HUB: {0} [{1}]({2}, {3}, reselect: {4})'.format(hub.hubIdentifier, + identifier, + len(hub.items), + len(items) if items else None, + reselect_pos), + ) + self._showHub(hub, hubitems=items, reselect_pos=reselect_pos, identifier=identifier, + **self.HUBMAP[identifier]) return True else: - util.DEBUG_LOG('UNHANDLED - Hub: {0} [{1}]({1})'.format(hub.hubIdentifier, identifier, len(hub.items))) + util.DEBUG_LOG('UNHANDLED - Hub: {0} [{1}]({1})', hub.hubIdentifier, identifier, + lambda: len(hub.items)) return def createGrandparentedListItem(self, obj, thumb_w, thumb_h, with_grandparent_title=False): @@ -1140,7 +1886,7 @@ def createSimpleListItem(self, obj, thumb_w, thumb_h): def createEpisodeListItem(self, obj, wide=False): mli = self.createGrandparentedListItem(obj, *self.THUMB_POSTER_DIM) if obj.index: - subtitle = u'{0}{1} \u2022 {2}{3}'.format(T(32310, 'S'), obj.parentIndex, T(32311, 'E'), obj.index) + subtitle = u'{0} \u2022 {1}'.format(T(32310, 'S').format(obj.parentIndex), T(32311, 'E').format(obj.index)) else: subtitle = obj.originallyAvailableAt.asDatetime('%m/%d/%y') @@ -1152,6 +1898,7 @@ def createEpisodeListItem(self, obj, wide=False): mli.setProperty('thumb.fallback', 'script.plex/thumb_fallbacks/show.png') if not obj.isWatched: mli.setProperty('unwatched', '1') + mli.setBoolProperty('watched', obj.isFullyWatched) return mli def createSeasonListItem(self, obj, wide=False): @@ -1160,6 +1907,7 @@ def createSeasonListItem(self, obj, wide=False): mli.setProperty('thumb.fallback', 'script.plex/thumb_fallbacks/show.png') if not obj.isWatched: mli.setProperty('unwatched.count', str(obj.unViewedLeafCount)) + mli.setBoolProperty('watched', obj.isFullyWatched) return mli def createMovieListItem(self, obj, wide=False): @@ -1167,6 +1915,7 @@ def createMovieListItem(self, obj, wide=False): mli.setProperty('thumb.fallback', 'script.plex/thumb_fallbacks/movie.png') if not obj.isWatched: mli.setProperty('unwatched', '1') + mli.setBoolProperty('watched', obj.isFullyWatched) return mli def createShowListItem(self, obj, wide=False): @@ -1174,6 +1923,7 @@ def createShowListItem(self, obj, wide=False): mli.setProperty('thumb.fallback', 'script.plex/thumb_fallbacks/show.png') if not obj.isWatched: mli.setProperty('unwatched.count', str(obj.unViewedLeafCount)) + mli.setBoolProperty('watched', obj.isFullyWatched) return mli def createAlbumListItem(self, obj, wide=False): @@ -1224,7 +1974,7 @@ def createPlaylistListItem(self, obj, wide=False): return mli def unhandledHub(self, self2, obj, wide=False): - util.DEBUG_LOG('Unhandled Hub item: {0}'.format(obj.type)) + util.DEBUG_LOG('Unhandled Hub item: {0}', obj.type) CREATE_LI_MAP = { 'episode': createEpisodeListItem, @@ -1247,13 +1997,17 @@ def clearHubs(self): for control in self.hubControls: control.reset() - def _showHub(self, hub, hubitems=None, index=None, with_progress=False, with_art=False, ar16x9=False, - text2lines=False, **kwargs): + def _showHub(self, hub, hubitems=None, reselect_pos=None, identifier=None, index=None, with_progress=False, + with_art=False, ar16x9=False, text2lines=False, **kwargs): control = self.hubControls[index] control.dataSource = hub if not hub.items and not hubitems: control.reset() + if self.lastFocusID == index + 400: + util.DEBUG_LOG("Hub {} was focused but is gone.", identifier) + hubControlIndex = self.lastFocusID - 400 + self.focusFirstValidHub(hubControlIndex) return if not hubitems: @@ -1262,13 +2016,35 @@ def _showHub(self, hub, hubitems=None, index=None, with_progress=False, with_art self.setProperty('hub.4{0:02d}'.format(index), hub.title or kwargs.get('title')) self.setProperty('hub.text2lines.4{0:02d}'.format(index), text2lines and '1' or '') + use_reselect_pos = False + if reselect_pos is not None: + rk, pos = reselect_pos + use_reselect_pos = True if rk is not None else (reselect_pos > 0 or reselect_pos == -1) + + if pos == 0 and not use_reselect_pos: + # we might want to force the first position, check the hubs position + if control.getSelectedPos() > 0: + use_reselect_pos = True + items = [] + check_spoilers = False for obj in hubitems or hub.items: - if not self.backgroundSet: + if not self.backgroundSet and not use_reselect_pos: if self.updateBackgroundFrom(obj): self.backgroundSet = True - mli = self.createListItem(obj, wide=with_art) + + wide = with_art + no_spoilers = False + if obj.type == 'episode' and hub.hubIdentifier == "home.continue" and self.spoilerSetting != "off": + check_spoilers = True + obj._noSpoilers = no_spoilers = self.hideSpoilers(obj, use_cache=False) + + if obj.type == 'episode' and util.addonSettings.continueUseThumb and wide: + # with_art sets the wide parameter which includes the episode title + wide = no_spoilers in ("funwatched", "unwatched") and not self.noTitles + + mli = self.createListItem(obj, wide=wide) if mli: items.append(mli) @@ -1277,18 +2053,23 @@ def _showHub(self, hub, hubitems=None, index=None, with_progress=False, with_art mli.setProperty('progress', util.getProgressImage(mli.dataSource)) if with_art: for mli in items: - thumb = (util.advancedSettings.continueUseThumb - and mli.dataSource.type == 'episode' - and mli.dataSource.thumb - ) \ - or mli.dataSource.art - mli.setThumbnailImage(thumb.asTranscodedImageURL(*self.THUMB_AR16X9_DIM)) + extra_opts = {} + thumb = mli.dataSource.art + # use episode thumbnail for in progress episodes + if mli.dataSource.type == 'episode' and util.addonSettings.continueUseThumb and check_spoilers: + # blur them if we don't want any spoilers and the episode hasn't been fully watched + if mli.dataSource._noSpoilers: + extra_opts = {"blur": util.addonSettings.episodeNoSpoilerBlur} + thumb = mli.dataSource.thumb + + mli.setThumbnailImage(thumb.asTranscodedImageURL(*self.THUMB_AR16X9_DIM, **extra_opts)) mli.setProperty('thumb.fallback', 'script.plex/thumb_fallbacks/movie16x9.png') if ar16x9: for mli in items: mli.setProperty('thumb.fallback', 'script.plex/thumb_fallbacks/movie16x9.png') - if hub.more.asBool(): + more = hub.more.asBool() + if more: end = kodigui.ManagedListItem('') end.setBoolProperty('is.end', True) items.append(end) @@ -1297,10 +2078,78 @@ def _showHub(self, hub, hubitems=None, index=None, with_progress=False, with_art end = control.size() - 1 control.replaceItem(end, items[0]) control.addItems(items[1:]) - control.selectItem(end) + if reselect_pos is None: + control.selectItem(end) else: control.replaceItems(items) + # hub reselect logic after updating a hub + if use_reselect_pos: + rk, pos = reselect_pos + + # round-robin + if pos == -1: + last_pos = control.size() - 1 + if hub.more: + last_pos -= 1 + + control.selectItem(last_pos) + self._lastSelectedItem = (index + 400, last_pos) + if self.updateBackgroundFrom(control[last_pos].dataSource): + self.backgroundSet = True + return + + # during hub updates, if the user manually selects a different item, do nothing + if self._anyItemAction: + return + + cur_pos = control.getSelectedPos() + + if rk is not None: + rk_found = False + # try finding the ratingKey first + for idx, mli in enumerate(control): + if mli.dataSource and mli.dataSource.ratingKey and str(mli.dataSource.ratingKey) == rk: + if cur_pos != idx: + util.DEBUG_LOG("Hub {}: Reselect: Found {} in list, reselecting", identifier, rk) + control.selectItem(idx) + rk_found = True + else: + return + if rk_found: + if self.updateBackgroundFrom(control[pos].dataSource): + self.backgroundSet = True + return + + if cur_pos == pos: + util.DEBUG_LOG("Hub {}: Position was already correct ({})", identifier, pos) + return + + if pos < control.size() - (more and 1 or 0): + # we didn't find the ratingKey, try the position first, if it's smaller than our list size + util.DEBUG_LOG("Hub {}: Reselect: We didn't find {} in list, or no item given. " + "Reselecting position {}", identifier, rk, pos) + control.selectItem(pos) + if self.updateBackgroundFrom(control[pos].dataSource): + self.backgroundSet = True + else: + if more: + # re-extend the hub to its original size so we can reselect the ratingKey/position + # calculate how many pages we need to re-arrive at the last selected position + # fixme: someone check for an off-by-one please + size = max(math.ceil((pos + 2 - control.size()) / HUB_PAGE_SIZE), 1) * HUB_PAGE_SIZE + util.DEBUG_LOG("Hub {}: Reselect: Hub position for {} out of bounds ({}), " + "expanding hub ", identifier, rk, pos) + task = ExtendHubTask().setup(control.dataSource, self.extendHubCallback, + canceledCallback=lambda h: mli.setBoolProperty('is.updating', False), + size=size, reselect_pos=reselect_pos) + self.tasks.append(task) + backgroundthread.BGThreader.addTask(task) + else: + control.selectItem(control.size() - 1) + if self.updateBackgroundFrom(control[control.size() - 1].dataSource): + self.backgroundSet = True + def updateListItem(self, mli): if not mli or not mli.dataSource: # May have become invalid return @@ -1308,7 +2157,9 @@ def updateListItem(self, mli): obj = mli.dataSource if obj.type in ('episode', 'movie'): mli.setProperty('unwatched', not obj.isWatched and '1' or '') + mli.setProperty('watched', obj.isFullyWatched and '1' or '') elif obj.type in ('season', 'show', 'album'): + mli.setProperty('watched', obj.isFullyWatched and '1' or '') if obj.isWatched: mli.setProperty('unwatched.count', '') else: @@ -1375,8 +2226,9 @@ def showServers(self, from_refresh=False, mouse=False): items[0].setProperty('only', '1') self.serverList.replaceItems(items) + itemHeight = util.vscale(100, r=0) - self.getControl(800).setHeight((min(len(items), 9) * 100) + 80) + self.getControl(800).setHeight((min(len(items), 9) * itemHeight) + 80) for item in items: if item.dataSource != kodigui.DUMMY_DATA_SOURCE: @@ -1430,6 +2282,9 @@ def selectServer(self): def showUserMenu(self, mouse=False): items = [] if plexapp.ACCOUNT.isSignedIn: + if not len(plexapp.ACCOUNT.homeUsers) and not util.addonSettings.cacheHomeUsers: + plexapp.ACCOUNT.updateHomeUsers(refreshSubscription=True) + if len(plexapp.ACCOUNT.homeUsers) > 1: items.append(kodigui.ManagedListItem(T(32342, 'Switch User'), data_source='switch')) else: @@ -1450,8 +2305,9 @@ def showUserMenu(self, mouse=False): self.userList.reset() self.userList.addItems(items) + itemHeight = util.vscale(66, r=0) - self.getControl(801).setHeight((len(items) * 66) + 80) + self.getControl(801).setHeight((len(items) * itemHeight) + 80) if not mouse: self.setFocusId(self.USER_LIST_ID) @@ -1471,7 +2327,7 @@ def doUserOption(self): elif option == 'go_online': plexapp.ACCOUNT.refreshAccount() elif option == 'refresh_users': - plexapp.ACCOUNT.updateHomeUsers() + plexapp.ACCOUNT.updateHomeUsers(refreshSubscription=True) return True else: self.closeOption = option diff --git a/script.plexmod/lib/windows/info.py b/script.plexmod/lib/windows/info.py index 7c610b9ca3..e34c851c07 100644 --- a/script.plexmod/lib/windows/info.py +++ b/script.plexmod/lib/windows/info.py @@ -1,10 +1,13 @@ from __future__ import absolute_import -from . import kodigui -from . import windowutils -from lib import util -from plexnet.video import Episode, Movie, Clip import os +import datetime + +from plexnet.video import Episode, Movie, Clip + +from lib import util +from . import kodigui +from . import windowutils def split2len(s, n): @@ -33,6 +36,7 @@ def __init__(self, *args, **kwargs): self.title = kwargs.get('title') self.subTitle = kwargs.get('sub_title') self.thumb = kwargs.get('thumb') + self.thumb_opts = kwargs.get('thumb_opts', {}) self.thumbFallback = kwargs.get('thumb_fallback') self.info = kwargs.get('info') self.background = kwargs.get('background') @@ -72,6 +76,7 @@ def getVideoInfo(self): addMedia.append("Unavailable: {}".format(os.path.basename(part.file))) continue + pmFolder = part.getPathMappedUrl(return_only_folder=True) addMedia.append("File: ") splitFnAt = 74 fnLen = len(os.path.basename(part.file)) @@ -82,6 +87,10 @@ def getVideoInfo(self): appended = True continue addMedia.append("{}\n".format(s)) + if pmFolder: + addMedia.append("Mapped via: {}\n".format(pmFolder)) + addMedia.append("Added: {}\n".format(datetime.datetime.fromtimestamp( + self.video.addedAt.asFloat()).strftime("{} {}".format(util.shortDF, util.timeFormat)))) addMedia.append("Duration: {}, Size: {}\n".format(util.durationToShortText(int(part.duration)), util.simpleSize(int(part.size)))) @@ -152,7 +161,7 @@ def onFirstInit(self): self.setProperty('title.main', self.title) self.setProperty('title.sub', self.subTitle) self.setProperty('thumb.fallback', self.thumbFallback) - self.setProperty('thumb', self.thumb.asTranscodedImageURL(*self.thumbDim)) + self.setProperty('thumb', self.thumb.asTranscodedImageURL(*self.thumbDim, **self.thumb_opts)) self.setProperty('info', self.getVideoInfo()) self.setProperty('background', self.background) diff --git a/script.plexmod/lib/windows/kodigui.py b/script.plexmod/lib/windows/kodigui.py index 40f466b7db..be7ef15418 100644 --- a/script.plexmod/lib/windows/kodigui.py +++ b/script.plexmod/lib/windows/kodigui.py @@ -1,18 +1,23 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import -from kodi_six import xbmc -from kodi_six import xbmcgui -import time + import threading +import time import traceback + +from kodi_six import xbmc +from kodi_six import xbmcgui from six.moves import range from six.moves import zip + from .. import util +from plexnet import plexapp + MONITOR = None -class BaseFunctions: +class BaseFunctions(object): xmlFile = '' path = '' theme = '' @@ -99,10 +104,66 @@ def setBoolProperty(self, key, boolean): BG_NA = "script.plex/home/background-fallback_black.png" -class BaseWindow(xbmcgui.WindowXML, BaseFunctions): +class XMLBase(object): + def onInit(self, count=0): + try: + self.getControl(666) + except RuntimeError as e: + if e.args and "Non-Existent Control" in e.args[0]: + if count == 0: + # retry once + xbmc.sleep(250) + return self.onInit(count=1) + + util.ERROR("Possibly broken XML file: {}, triggering recompilation.".format(self.xmlFile)) + util.showNotification("Recompiling templates", time_ms=1000, + header="Possibly broken XML file(s)") + try: + xbmc.Player().stop() + except: + pass + xbmc.sleep(1000) + + if self.__class__.__name__ == "HomeWindow": + try: + self._errored = True + self.closeWRecompileTpls() + finally: + return + elif self.__class__.__name__ == "BackgroundWindow": + try: + self._errored = True + self.doClose() + finally: + return + + try: + self._errored = True + self.doClose() + finally: + from . import windowutils + windowutils.HOME.closeWRecompileTpls() + return + raise + self._onInit() + + def goHomeAction(self, action): + if (util.HOME_BUTTON_MAPPED is not None + and action.getButtonCode() == int(util.HOME_BUTTON_MAPPED) and hasattr(self, "goHome")): + self.goHome(with_root=True) + return True + return + + +class BaseWindow(XMLBase, xbmcgui.WindowXML, BaseFunctions): + __slots__ = ("_closing", "_winID", "started", "finishedInit", "dialogProps", "isOpen", "_errored", + "_closeSignalled") + def __init__(self, *args, **kwargs): BaseFunctions.__init__(self) self._closing = False + self._errored = False + self._closeSignalled = False self._winID = None self.started = False self.finishedInit = False @@ -111,55 +172,72 @@ def __init__(self, *args, **kwargs): carryProps = kwargs.get("window_props", None) if carryProps: self.setProperties(list(carryProps.keys()), list(carryProps.values())) + self.setBoolProperty('is_plextuary', util.SKIN_PLEXTUARY) - def onInit(self): + def onCloseSignal(self, *args, **kwargs): + self._closeSignalled = True + self.doClose() + + def _onInit(self): global LAST_BG_URL self._winID = xbmcgui.getCurrentWindowId() BaseFunctions.lastWinID = self._winID self.setProperty('use_solid_background', util.hasCustomBGColour and '1' or '') if util.hasCustomBGColour: - bgColour = util.advancedSettings.backgroundColour if util.advancedSettings.backgroundColour != "-" \ + bgColour = util.addonSettings.backgroundColour if util.addonSettings.backgroundColour != "-" \ else "ff000000" self.setProperty('background_colour', "0x%s" % bgColour.lower()) self.setProperty('background_colour_opaque', "0x%s" % bgColour.lower()) else: # set background color to 0 to avoid kodi UI BG clearing, improves performance - if util.advancedSettings.dbgCrossfade: + if util.addonSettings.dbgCrossfade: self.setProperty('background_colour', "0x00000000") else: self.setProperty('background_colour', "0xff111111") self.setProperty('background_colour_opaque', "0xff111111") - self.setBoolProperty('use_bg_fallback', util.advancedSettings.useBgFallback) + self.setBoolProperty('use_bg_fallback', util.addonSettings.useBgFallback) + self.setBoolProperty('dynamic_backgrounds', util.addonSettings.dynamicBackgrounds) try: if self.started: - self.onReInit() + if hasattr(self, "onReInit"): + self.onReInit() else: self.started = True if LAST_BG_URL: self.windowSetBackground(LAST_BG_URL) - self.onFirstInit() + + if self.__class__.__name__ not in ("HomeWindow", "BackgroundWindow"): + plexapp.util.APP.on('close.windows', self.onCloseSignal) + + if hasattr(self, "onFirstInit"): + self.onFirstInit() self.finishedInit = True + except util.NoDataException: self.exitCommand = "NODATA" self.doClose() - def onFirstInit(self): - pass + def onAction(self, action): + if XMLBase.goHomeAction(self, action): + return + xbmcgui.WindowXML.onAction(self, action) def onReInit(self): pass - def waitForOpen(self): + def waitForOpen(self, base_win_id=None): tries = 0 - while not self.isOpen and not util.MONITOR.waitForAbort(2) and tries < 60: + while ((not base_win_id and not self.isOpen) or + (base_win_id and xbmcgui.getCurrentWindowId() <= base_win_id)) \ + and not util.MONITOR.waitForAbort(1) and tries < 120: if tries == 0: - util.LOG("Couldn't open window {}, other dialog open? Retrying for 120s.".format(self)) + util.LOG("Couldn't open window {}, other dialog open? Retrying for 120s.", self) self.show() tries += 1 - util.DEBUG_LOG("Window {} opened: {}".format(self, self.isOpen)) + util.DEBUG_LOG("Window {} opened: {}", self, self.isOpen) return self.isOpen @@ -176,13 +254,17 @@ def setProperty(self, key, value): except RuntimeError: xbmc.log('kodigui.BaseWindow.setProperty: Missing window', xbmc.LOGDEBUG) + def setCondFocusId(self, focus): + if self.getFocusId() != focus: + self.setFocusId(focus) + def updateBackgroundFrom(self, ds): - if util.advancedSettings.dynamicBackgrounds: + if util.addonSettings.dynamicBackgrounds: return self.windowSetBackground(util.backgroundFromArt(ds.art, width=self.width, height=self.height)) def windowSetBackground(self, value): - if not util.advancedSettings.dbgCrossfade: + if not util.addonSettings.dbgCrossfade: if not value: return self.setProperty("background_static", value) @@ -210,6 +292,7 @@ def windowSetBackground(self, value): return value def doClose(self): + plexapp.util.APP.off('close.windows', self.onCloseSignal) if not self.isOpen: return self._closing = True @@ -222,30 +305,53 @@ def show(self): xbmcgui.WindowXML.show(self) self.isOpen = xbmcgui.getCurrentWindowId() >= 13000 + @property + def is_active(self): + return self._winID and BaseFunctions.lastWinID == self._winID + + @property + def is_current_window(self): + return self._winID and xbmcgui.getCurrentWindowId() == self._winID + def onClosed(self): pass -class BaseDialog(xbmcgui.WindowXMLDialog, BaseFunctions): +class BaseDialog(XMLBase, xbmcgui.WindowXMLDialog, BaseFunctions): + __slots__ = ("_closing", "_winID", "started", "isOpen", "_errored", "_closeSignalled") + def __init__(self, *args, **kwargs): BaseFunctions.__init__(self) self._closing = False + self._errored = False + self._closeSignalled = False self._winID = '' self.started = False carryProps = kwargs.get("dialog_props", None) if carryProps: self.setProperties(list(carryProps.keys()), list(carryProps.values())) + self.setBoolProperty('is_plextuary', util.SKIN_PLEXTUARY) - def onInit(self): + def onCloseSignal(self, *args, **kwargs): + self._closeSignalled = True + self.doClose() + + def _onInit(self): self._winID = xbmcgui.getCurrentWindowDialogId() BaseFunctions.lastDialogID = self._winID if self.started: self.onReInit() else: self.started = True + plexapp.util.APP.on('close.dialogs', self.onCloseSignal) self.onFirstInit() + def onAction(self, action): + if XMLBase.goHomeAction(self, action): + return + xbmcgui.WindowXMLDialog.onAction(self, action) + def onFirstInit(self): pass @@ -266,6 +372,7 @@ def setProperty(self, key, value): xbmc.log('kodigui.BaseDialog.setProperty: Missing window', xbmc.LOGDEBUG) def doClose(self): + plexapp.util.APP.off('close.dialogs', self.onCloseSignal) self._closing = True self.close() self.isOpen = False @@ -341,7 +448,11 @@ def __setattr__(self, key, value): class ManagedListItem(object): - def __init__(self, label='', label2='', iconImage='', thumbnailImage='', path='', data_source=None, properties=None): + __slots__ = ("_listItem", "dataSource", "properties", "label", "label2", "iconImage", "thumbnailImage", "path", + "_ID", "_manager", "_valid") + + def __init__(self, label='', label2='', iconImage='', thumbnailImage='', path='', data_source=None, + properties=None): self._listItem = xbmcgui.ListItem(label, label2, path=path) self._listItem.setArt({"thumb": thumbnailImage, "icon": iconImage}) self.dataSource = data_source @@ -354,6 +465,7 @@ def __init__(self, label='', label2='', iconImage='', thumbnailImage='', path='' self._ID = None self._manager = None self._valid = True + if properties: for k, v in properties.items(): self.setProperty(k, v) @@ -498,6 +610,9 @@ def onDestroy(self): class ManagedControlList(object): + __slots__ = ("controlID", "control", "items", "_sortKey", "_idCounter", "_maxViewIndex", "_properties", + "dataSource") + def __init__(self, window, control_id, max_view_index, data_source=None): self.controlID = control_id self.control = window.getControl(control_id) @@ -524,6 +639,12 @@ def __iter__(self): def __len__(self): return self.size() + def prev(self): + pos = self.getSelectedPos()-1 + if self.positionIsValid(pos): + return pos + return 0 + def _updateItems(self, bottom=None, top=None): if bottom is None: bottom = 0 @@ -633,10 +754,31 @@ def getSelectedItem(self): return None return self.getListItem(pos) + def getSelectedPos(self): + pos = self.control.getSelectedPosition() + if not self.positionIsValid(pos): + pos = self.size() - 1 + + if pos < 0: + return None + return pos + + def getItemByPos(self, pos): + if self.positionIsValid(pos): + return self.getListItem(pos) + def setSelectedItemByPos(self, pos): if self.positionIsValid(pos): self.control.selectItem(pos) + def setSelectedItem(self, item): + pos = self.getManagedItemPosition(item) + if self.positionIsValid(pos): + self.control.selectItem(pos) + + def setSelectedItemByDataSource(self, data_source): + self.setSelectedItem(self.getListItemByDataSource(data_source)) + def removeItem(self, index): old = self.items.pop(index) old.onDestroy() @@ -791,6 +933,8 @@ def newControl(self, window=None, control_id=None): class _MWBackground(ControlledWindow): + __slots__ = ("_multiWindow", "started") + def __init__(self, *args, **kwargs): self._multiWindow = kwargs.get('multi_window') self.started = False @@ -805,17 +949,25 @@ def onInit(self): class MultiWindow(object): + __slots__ = ("_windows", "_next", "_properties", "_current", "_allClosed", "exitCommand", "_currentOnAction", + "_closeSignalled") + def __init__(self, windows=None, default_window=None, **kwargs): self._windows = windows self._next = default_window or self._windows[0] self._properties = {} self._current = None self._allClosed = False + self._closeSignalled = False self.exitCommand = None def __getattr__(self, name): return getattr(self._current, name) + def onCloseSignal(self, *args, **kwargs): + self._closeSignalled = True + self.doClose() + def setWindows(self, windows): self._windows = windows @@ -886,9 +1038,12 @@ def setProperty(self, key, value): def _onFirstInit(self): for k, v in self._properties.items(): self._current.setProperty(k, v) + + plexapp.util.APP.on('close.windows', self.onCloseSignal) self.onFirstInit() def doClose(self): + plexapp.util.APP.off('close.windows', self.onCloseSignal) self._allClosed = True self._current.doClose() @@ -1113,7 +1268,9 @@ def reset(self, close_win=None, init=None): class WindowProperty(): - def __init__(self, win, prop, val='1', end=None): + __slots__ = ("win", "prop", "val", "end", "old") + + def __init__(self, win, prop, val='1', end=''): self.win = win self.prop = prop self.val = val @@ -1129,17 +1286,17 @@ def __exit__(self, exc_type, exc_value, traceback): class GlobalProperty(): - def __init__(self, prop, val='1', end=None): - from kodi_six import xbmcaddon - self._addonID = xbmcaddon.Addon().getAddonInfo('id') + __slots__ = ("_addonID", "prop", "val", "end", "old") + + def __init__(self, prop, val='1', end=''): self.prop = prop self.val = val self.end = end - self.old = xbmc.getInfoLabel('Window(10000).Property({0}}.{1})'.format(self._addonID, prop)) + self.old = xbmc.getInfoLabel('Window(10000).Property(script.plex.{})'.format(prop)) def __enter__(self): - xbmcgui.Window(10000).setProperty('{0}.{1}'.format(self._addonID, self.prop), self.val) + xbmcgui.Window(10000).setProperty('script.plex.{}'.format(self.prop), self.val) return self def __exit__(self, exc_type, exc_value, traceback): - xbmcgui.Window(10000).setProperty('{0}.{1}'.format(self._addonID, self.prop), self.end or self.old) + xbmcgui.Window(10000).setProperty('script.plex.{}'.format(self.prop), self.end or self.old) diff --git a/script.plexmod/lib/windows/library.py b/script.plexmod/lib/windows/library.py index 1ef8812dac..bf807a367f 100644 --- a/script.plexmod/lib/windows/library.py +++ b/script.plexmod/lib/windows/library.py @@ -1,33 +1,34 @@ from __future__ import absolute_import + +import json import os import random -import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error -import json -import time import threading +import plexnet +import six +import six.moves.urllib.error +import six.moves.urllib.parse +import six.moves.urllib.request from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui +from plexnet import playqueue +from six.moves import range -from lib import util from lib import backgroundthread from lib import player - +from lib import util +from lib.util import T from . import busy -from . import subitems -from . import preplay -from . import search -import plexnet from . import dropdown +from . import kodigui from . import opener +from . import preplay +from . import search +from . import subitems from . import windowutils - -from plexnet import playqueue - -from lib.util import T -import six -from six.moves import range +from . import mixins +from .mixins import PlaybackBtnMixin KEYS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -107,11 +108,12 @@ 'episode': T(32458, 'Episodes'), 'collection': T(32490, 'Collections'), 'folder': T(32491, 'Folders'), + 'track': T(33644, 'Tracks'), } SORT_KEYS = { 'movie': { - 'titleSort': {'title': T(32357, 'By Name'), 'display': T(32358, 'Name'), 'defSortDesc': False}, + 'titleSort': {'title': T(32357, 'By Title'), 'display': T(32358, 'Title'), 'defSortDesc': False}, 'addedAt': {'title': T(32351, 'By Date Added'), 'display': T(32352, 'Date Added'), 'defSortDesc': True}, 'originallyAvailableAt': {'title': T(32353, 'By Release Date'), 'display': T(32354, 'Release Date'), 'defSortDesc': True}, @@ -129,8 +131,10 @@ 'viewCount': {'title': T(32371, 'By Play Count'), 'display': T(32372, 'Play Count'), 'defSortDesc': True} }, 'show': { - 'titleSort': {'title': T(32357, 'By Name'), 'display': T(32358, 'Name'), 'defSortDesc': False}, + 'titleSort': {'title': T(32357, 'By Title'), 'display': T(32358, 'Title'), 'defSortDesc': False}, + 'year': {'title': T(32377, "Year"), 'display': T(32377, "Year"), 'defSortDesc': True}, 'show.titleSort': {'title': T(32457, 'By Show'), 'display': T(32456, 'Show'), 'defSortDesc': False}, + 'episode.addedAt': {'title': T(33042, 'Episode Date Added'), 'display': T(33042, 'Episode Date Added'), 'defSortDesc': True}, 'originallyAvailableAt': {'title': T(32365, 'By First Aired'), 'display': T(32366, 'First Aired'), 'defSortDesc': False}, 'unviewedLeafCount': {'title': T(32367, 'By Unplayed'), 'display': T(32368, 'Unplayed'), 'defSortDesc': True}, @@ -143,12 +147,18 @@ 'defSortDesc': True}, }, 'artist': { - 'titleSort': {'title': T(32357, 'By Name'), 'display': T(32358, 'Name'), 'defSortDesc': False}, + 'titleSort': {'title': T(32357, 'By Title'), 'display': T(32358, 'Title'), 'defSortDesc': False}, + 'artist.titleSort': {'title': T(32463, 'By Artist'), 'display': T(32462, 'Artist'), 'defSortDesc': False}, + 'lastViewedAt': {'title': T(32369, 'By Date Played'), 'display': T(32370, 'Date Played'), 'defSortDesc': False}, + }, + 'track': { + 'titleSort': {'title': T(32357, 'By Title'), 'display': T(32358, 'Title'), 'defSortDesc': False}, 'artist.titleSort': {'title': T(32463, 'By Artist'), 'display': T(32462, 'Artist'), 'defSortDesc': False}, 'lastViewedAt': {'title': T(32369, 'By Date Played'), 'display': T(32370, 'Date Played'), 'defSortDesc': False}, + 'viewCount': {'title': T(32371, 'By Play Count'), 'display': T(32372, 'Play Count'), 'defSortDesc': True} }, 'photo': { - 'titleSort': {'title': T(32357, 'By Name'), 'display': T(32358, 'Name'), 'defSortDesc': False}, + 'titleSort': {'title': T(32357, 'By Title'), 'display': T(32358, 'Title'), 'defSortDesc': False}, 'originallyAvailableAt': {'title': T(32373, 'By Date Taken'), 'display': T(32374, 'Date Taken'), 'defSortDesc': True} }, @@ -193,6 +203,8 @@ def run(self): type_ = 9 elif ITEM_TYPE == 'collection': type_ = 18 + elif ITEM_TYPE == 'track': + type_ = 10 if ITEM_TYPE == 'folder': items = self.section.folder(self.start, self.size, self.subDir) @@ -203,7 +215,7 @@ def run(self): return self.callback(items, self.start) except plexnet.exceptions.BadRequest: - util.DEBUG_LOG('404 on section: {0}'.format(repr(self.section.title))) + util.DEBUG_LOG('404 on section: {0}', repr(self.section.title)) class PhotoPropertiesTask(backgroundthread.Task): @@ -220,7 +232,7 @@ def run(self): self.photo.reload() self.callback(self.photo) except plexnet.exceptions.BadRequest: - util.DEBUG_LOG('404 on photo reload: {0}'.format(self.photo)) + util.DEBUG_LOG('404 on photo reload: {0}', self.photo) class LibrarySettings(object): @@ -298,7 +310,7 @@ def setSetting(self, setting, value): self._saveSettings() -class LibraryWindow(kodigui.MultiWindow, windowutils.UtilMixin): +class LibraryWindow(mixins.PlaybackBtnMixin, kodigui.MultiWindow, windowutils.UtilMixin): bgXML = 'script-plex-blank.xml' path = util.ADDON.getAddonInfo('path') theme = 'Main' @@ -310,6 +322,7 @@ class LibraryWindow(kodigui.MultiWindow, windowutils.UtilMixin): CHUNK_OVERCOMMIT = 6 def __init__(self, *args, **kwargs): + PlaybackBtnMixin.__init__(self) kodigui.MultiWindow.__init__(self, *args, **kwargs) windowutils.UtilMixin.__init__(self) self.section = kwargs.get('section') @@ -340,6 +353,7 @@ def __init__(self, *args, **kwargs): self.lock = threading.Lock() def reset(self): + PlaybackBtnMixin.reset(self) util.setGlobalProperty('sort', '') self.filterUnwatched = self.librarySettings.getSetting('filter.unwatched', False) self.sort = self.librarySettings.getSetting('sort', 'titleSort') @@ -348,7 +362,7 @@ def reset(self): self.alreadyFetchedChunkList = set() self.finalChunkPosition = 0 - self.CHUNK_SIZE = util.advancedSettings.libraryChunkSize + self.CHUNK_SIZE = util.addonSettings.libraryChunkSize key = self.section.key if not key.isdigit(): @@ -412,7 +426,7 @@ def onAction(self, action): if mli: self.requestChunk(mli.pos()) - if util.advancedSettings.dynamicBackgrounds: + if util.addonSettings.dynamicBackgrounds: if mli and mli.dataSource: self.updateBackgroundFrom(mli.dataSource) @@ -434,7 +448,7 @@ def onAction(self, action): elif action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_CONTEXT_MENU): if not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format(self.OPTIONS_GROUP_ID)) and \ - (not util.advancedSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU): + (not util.addonSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU): if xbmc.getCondVisibility('Integer.IsGreater(Container(101).ListItem.Property(index),5)'): self.showPanelControl.selectItem(0) return @@ -545,6 +559,10 @@ def keyClicked(self): util.setGlobalProperty('key', li.dataSource) def playButtonClicked(self, shuffle=False): + if self.playBtnClicked: + return + + self.playBtnClicked = True filter_ = self.getFilterOpts() sort = self.getSortOpts() args = {} @@ -566,7 +584,7 @@ def playButtonClicked(self, shuffle=False): args['unwatched'] = '1' pq = playqueue.createPlayQueueForItem(self.section, options={'shuffle': shuffle}, args=args) - opener.open(pq) + opener.open(pq, auto_play=True) def shuffleButtonClicked(self): self.playButtonClicked(shuffle=True) @@ -600,7 +618,7 @@ def itemTypeButtonClicked(self): for t in ('movie', 'collection', 'folder'): options.append({'type': t, 'display': TYPE_PLURAL.get(t, t)}) elif self.section.TYPE == 'artist': - for t in ('artist', 'album', 'collection'): + for t in ('artist', 'album', 'collection', 'track'): options.append({'type': t, 'display': TYPE_PLURAL.get(t, t)}) else: return @@ -667,16 +685,19 @@ def sortButtonClicked(self): defSortByOption[stype] = option.get('defSortDesc') options.append(option) elif self.section.TYPE == 'show': - searchTypes = ['titleSort', 'addedAt', 'lastViewedAt', 'originallyAvailableAt', 'rating', - 'audienceRating', 'userRating', 'contentRating', 'unviewedLeafCount'] + searchTypes = ['titleSort', 'year', 'originallyAvailableAt', 'rating', 'audienceRating', 'userRating', + 'contentRating', 'unviewedLeafCount', 'episode.addedAt', + 'addedAt', 'lastViewedAt'] if ITEM_TYPE == 'episode': - searchTypes = ['titleSort', 'show.titleSort', 'addedAt', 'originallyAvailableAt', 'lastViewedAt', 'rating', - 'audienceRating', 'userRating'] + searchTypes = ['titleSort', 'show.titleSort', 'addedAt', 'originallyAvailableAt', 'lastViewedAt', + 'rating', 'audienceRating', 'userRating'] elif ITEM_TYPE == 'collection': searchTypes = ['titleSort', 'addedAt'] for stype in searchTypes: - option = SORT_KEYS['show'].get(stype, SORT_KEYS['movie'].get(stype)).copy() + option = SORT_KEYS['show'].get(stype, SORT_KEYS['movie'].get(stype, {})).copy() + if not option: + continue option['type'] = stype option['indicator'] = self.sort == stype and ind or '' defSortByOption[stype] = option.get('defSortDesc') @@ -687,6 +708,8 @@ def sortButtonClicked(self): searchTypes = ['titleSort', 'artist.titleSort', 'addedAt', 'lastViewedAt', 'viewCount', 'originallyAvailableAt', 'rating'] elif ITEM_TYPE == 'collection': searchTypes = ['titleSort', 'addedAt'] + elif ITEM_TYPE == 'track': + searchTypes = ['titleSort', 'addedAt', 'lastViewedAt', 'viewCount'] for stype in searchTypes: option = SORT_KEYS['artist'].get(stype, SORT_KEYS['movie'].get(stype)).copy() @@ -786,7 +809,8 @@ def sortShowPanel(self, choice, force_refresh=False): self.showPanelControl.selectItem(0) self.setFocusId(self.POSTERS_PANEL_ID) self.backgroundSet = False - self.setBackground([item.dataSource for item in self.showPanelControl], 0, randomize=not util.advancedSettings.dynamicBackgrounds) + self.setBackground([item.dataSource for item in self.showPanelControl], 0, + randomize=not util.addonSettings.dynamicBackgrounds) def subOptionCallback(self, option): check = 'script.plex/home/device/check.png' @@ -963,6 +987,9 @@ def showPanelClicked(self): elif self.section.TYPE in ('photo', 'photodirectory'): self.showPhoto(mli.dataSource) + if self._closeSignalled: + return + if not mli: return @@ -983,6 +1010,7 @@ def updateUnwatchedAndProgress(self, mli): mli.dataSource.reload() if mli.dataSource.isWatched: mli.setProperty('unwatched', '') + mli.setBoolProperty('watched', mli.dataSource.isFullyWatched) mli.setProperty('unwatched.count', '') else: if self.section.TYPE == 'show' or mli.dataSource.TYPE == 'show' or mli.dataSource.TYPE == 'season': @@ -1010,7 +1038,7 @@ def updateItem(self, mli=None): for task in self.tasks: if task.contains(mli.pos()): - util.DEBUG_LOG('Moving task to front: {0}'.format(task)) + util.DEBUG_LOG('Moving task to front: {0}', task) backgroundthread.BGThreader.moveToFront(task) break @@ -1072,6 +1100,8 @@ def fillShows(self): type_ = 9 elif ITEM_TYPE == 'collection': type_ = 18 + elif ITEM_TYPE == 'track': + type_ = 10 idx = 0 fallback = 'script.plex/thumb_fallbacks/{0}.png'.format(TYPE_KEYS.get(self.section.type, TYPE_KEYS['movie'])['fallback']) @@ -1156,7 +1186,7 @@ def fillShows(self): # If we're retrieving media as we navigate then we just want to request the first # chunk of media and stop. We'll fetch the rest as the user navigates to those items - if not util.advancedSettings.retrieveAllMediaUpFront: + if not util.addonSettings.retrieveAllMediaUpFront: # Calculate the end chunk's starting position based on the totalSize of items self.finalChunkPosition = (totalSize // self.CHUNK_SIZE) * self.CHUNK_SIZE # Keep track of the chunks we've already fetched by storing the chunk's starting position @@ -1290,15 +1320,11 @@ def _chunkCallback(self, items, start): with self.lock: pos = start - self.setBackground(items, pos, randomize=not util.advancedSettings.dynamicBackgrounds) + self.setBackground(items, pos, randomize=not util.addonSettings.dynamicBackgrounds) thumbDim = TYPE_KEYS.get(self.section.type, TYPE_KEYS['movie'])['thumb_dim'] artDim = TYPE_KEYS.get(self.section.type, TYPE_KEYS['movie']).get('art_dim', (256, 256)) - showUnwatched = False - if (self.section.TYPE in ('movie', 'show') and items[0].TYPE != 'collection') or (self.section.TYPE == 'collection' and items[0].TYPE in ('movie', 'show', 'episode')): # NOTE: A collection with Seasons doesn't have the leafCount/viewedLeafCount until you actually go into the season so we can't update the unwatched count here - showUnwatched = True - if ITEM_TYPE == 'episode': for offset, obj in enumerate(items): if not self.showPanelControl: @@ -1309,7 +1335,8 @@ def _chunkCallback(self, items, start): mli.dataSource = obj mli.setProperty('index', str(pos)) if obj.index: - subtitle = u'{0}{1} \u2022 {2}{3}'.format(T(32310, 'S'), obj.parentIndex, T(32311, 'E'), obj.index) + subtitle = u'{0} \u2022 {1}'.format(T(32310, 'S').format(obj.parentIndex), + T(32311, 'E').format(obj.index)) mli.setProperty('subtitle', subtitle) subtitle = "\n" + subtitle else: @@ -1324,6 +1351,8 @@ def _chunkCallback(self, items, start): mli.setProperty('art', obj.defaultArt.asTranscodedImageURL(*artDim)) if not obj.isWatched: mli.setProperty('unwatched', '1') + mli.setBoolProperty('watched', obj.isFullyWatched) + mli.setProperty('initialized', '1') else: mli.clear() if obj is False: @@ -1365,19 +1394,26 @@ def _chunkCallback(self, items, start): mli = self.showPanelControl[pos] if obj: mli.setProperty('index', str(pos)) - mli.setLabel(obj.defaultTitle or '') + if obj.TYPE == 'track': + mli.setLabel("{} - {}: {}".format(obj.grandparentTitle, obj.parentTitle, obj.title)) + else: + mli.setLabel(obj.defaultTitle or '') if obj.TYPE == 'collection': colArtDim = TYPE_KEYS.get('collection').get('art_dim', (256, 256)) mli.setProperty('art', obj.artCompositeURL(*colArtDim)) mli.setThumbnailImage(obj.artCompositeURL(*thumbDim)) else: - mli.setThumbnailImage(obj.defaultThumb.asTranscodedImageURL(*thumbDim)) + if obj.TYPE == 'photodirectory' and obj.composite: + mli.setThumbnailImage(obj.composite.asTranscodedImageURL(*thumbDim)) + else: + mli.setThumbnailImage(obj.defaultThumb.asTranscodedImageURL(*thumbDim)) mli.dataSource = obj mli.setProperty('summary', obj.get('summary')) + mli.setProperty('year', obj.get('year')) - if showUnwatched and obj.TYPE != 'collection': - if not obj.isDirectory(): + if obj.TYPE != 'collection': + if not obj.isDirectory() and obj.get('duration').asInt(): mli.setLabel2(util.durationToText(obj.fixedDuration())) mli.setProperty('art', obj.defaultArt.asTranscodedImageURL(*artDim)) if not obj.isWatched and obj.TYPE != "Directory": @@ -1385,6 +1421,9 @@ def _chunkCallback(self, items, start): mli.setProperty('unwatched.count', str(obj.unViewedLeafCount)) else: mli.setProperty('unwatched', '1') + elif obj.isFullyWatched and obj.TYPE != "Directory": + mli.setBoolProperty('watched', '1') + mli.setProperty('initialized', '1') mli.setProperty('progress', util.getProgressImage(obj)) else: @@ -1397,7 +1436,7 @@ def _chunkCallback(self, items, start): pos += 1 def requestChunk(self, start): - if util.advancedSettings.retrieveAllMediaUpFront: + if util.addonSettings.retrieveAllMediaUpFront: return # Calculate the correct starting chunk position for the item they passed in @@ -1408,7 +1447,7 @@ def requestChunk(self, start): # Check if the chunk has already been requested, if not then go fetch the data if startChunkPosition not in self.alreadyFetchedChunkList: - util.DEBUG_LOG('Position {0} so requesting chunk {1}'.format(start, startChunkPosition)) + util.DEBUG_LOG('Position {0} so requesting chunk {1}', start, startChunkPosition) # Keep track of the chunks we've already fetched by storing the chunk's starting position self.alreadyFetchedChunkList.add(startChunkPosition) task = ChunkRequestTask().setup(self.section, startChunkPosition, self.CHUNK_SIZE, diff --git a/script.plexmod/lib/windows/mixins.py b/script.plexmod/lib/windows/mixins.py index f35ac80fbb..83d7c1d5c5 100644 --- a/script.plexmod/lib/windows/mixins.py +++ b/script.plexmod/lib/windows/mixins.py @@ -2,12 +2,15 @@ import math -from lib import util +from plexnet import util as pnUtil +from lib import util +from lib.data_cache import dcm +from lib.util import T +from lib.genres import GENRES_TV_BY_SYN +from . import busy from . import kodigui from . import optionsdialog -from . import busy -from lib.util import T class SeasonsMixin: @@ -48,13 +51,14 @@ def getSeasonProgress(self, show, season): watchedPerc += vPerc / season.leafCount.asFloat() return watchedPerc > 0 and math.ceil(watchedPerc) or 0 - def fillSeasons(self, show, update=False, seasonsFilter=None, selectSeason=None): + def fillSeasons(self, show, update=False, seasonsFilter=None, selectSeason=None, do_focus=True): seasons = show.seasons() if not seasons or (seasonsFilter and not seasonsFilter(seasons)): return False items = [] idx = 0 + focus = None for season in seasons: if selectSeason and season == selectSeason: continue @@ -64,7 +68,9 @@ def fillSeasons(self, show, update=False, seasonsFilter=None, selectSeason=None) mli.setProperty('index', str(idx)) mli.setProperty('thumb.fallback', 'script.plex/thumb_fallbacks/show.png') mli.setProperty('unwatched.count', not season.isWatched and str(season.unViewedLeafCount) or '') - if not season.isWatched: + mli.setBoolProperty('watched', season.isFullyWatched) + if not season.isWatched and focus is None and season.index.asInt() > 0: + focus = idx mli.setProperty('progress', util.getProgressImage(None, self.getSeasonProgress(show, season))) items.append(mli) idx += 1 @@ -76,14 +82,18 @@ def fillSeasons(self, show, update=False, seasonsFilter=None, selectSeason=None) subItemListControl.reset() subItemListControl.addItems(items) + if focus is not None and do_focus: + subItemListControl.setSelectedItemByPos(focus) + return True class DeleteMediaMixin: def delete(self, item=None): + item = item or self.mediaItem button = optionsdialog.show( T(32326, 'Really delete?'), - T(32327, 'Are you sure you really want to delete this media?'), + T(33035, "Delete {}: {}?").format(type(item).__name__, item.defaultTitle), T(32328, 'Yes'), T(32329, 'No') ) @@ -91,16 +101,16 @@ def delete(self, item=None): if button != 0: return - if not self._delete(item=item or self.mediaItem): + if not self._delete(item=item): util.messageDialog(T(32330, 'Message'), T(32331, 'There was a problem while attempting to delete the media.')) return return True @busy.dialog() - def _delete(self, item): + def _delete(self, item, do_close=False): success = item.delete() - util.LOG('Media DELETE: {0} - {1}'.format(self.mediaItem, success and 'SUCCESS' or 'FAILED')) - if success: + util.LOG('Media DELETE: {0} - {1}', item, success and 'SUCCESS' or 'FAILED') + if success and do_close: self.doClose() return success @@ -137,3 +147,96 @@ def sanitize(src): 'script.plex/ratings/{0}.png'.format(sanitize(video.audienceRatingImage))) else: setProperty('rating', video.rating) + + +class SpoilersMixin(object): + def __init__(self, *args, **kwargs): + self._noSpoilers = None + self.spoilerSetting = ["unwatched"] + self.noTitles = False + self.spoilersAllowedFor = True + self.cacheSpoilerSettings() + + def cacheSpoilerSettings(self): + self.spoilerSetting = util.getSetting('no_episode_spoilers3', ["unwatched"]) + self.noTitles = 'no_unwatched_episode_titles' in self.spoilerSetting + self.spoilersAllowedFor = util.getSetting('spoilers_allowed_genres2', ["Reality", "Game Show", "Documentary", + "Sport"]) + + @property + def noSpoilers(self): + return self.getNoSpoilers() + + def getCachedGenres(self, rating_key): + genres = dcm.getCacheData("show_genres", rating_key) + if genres: + return [pnUtil.AttributeDict(tag=g) for g in genres] + + def getNoSpoilers(self, item=None, show=None): + """ + when called without item or show, retains a global noSpoilers value, otherwise return dynamically based on item + or show + returns: "off" if spoilers unnecessary, otherwise "unwatched" or "funwatched" + """ + if not item and not show and self._noSpoilers is not None: + return self._noSpoilers + + if item and item.type != "episode": + return "off" + + nope = "funwatched" if "in_progress" in self.spoilerSetting else "unwatched" \ + if "unwatched" in self.spoilerSetting else "off" + + if nope != "off" and self.spoilersAllowedFor: + # instead of making possibly multiple separate API calls to find genres for episode's shows, try to get + # a cached value instead + genres = [] + if item or show: + genres = self.getCachedGenres(item and item.grandparentRatingKey or show.ratingKey) + + if not genres: + show = getattr(self, "show_", show or (item and item.show()) or None) + if not show: + return "off" + + if not genres and show: + genres = show.genres() + + for g in genres: + main_tag = GENRES_TV_BY_SYN.get(g.tag) + if main_tag and main_tag in self.spoilersAllowedFor: + nope = "off" + break + + if item or show: + self._noSpoilers = nope + return self._noSpoilers + return nope + + def hideSpoilers(self, ep, fully_watched=None, watched=None, use_cache=True): + """ + returns boolean on whether we should hide spoilers for the given episode + """ + watched = watched if watched is not None else ep.isWatched + fullyWatched = fully_watched if fully_watched is not None else ep.isFullyWatched + nspoil = self.getNoSpoilers(item=ep if not use_cache else None) + return ((nspoil == 'funwatched' and not fullyWatched) or + (nspoil == 'unwatched' and not watched)) + + def getThumbnailOpts(self, ep, fully_watched=None, watched=None, hide_spoilers=None): + if self.getNoSpoilers(item=ep) == "off": + return {} + return (hide_spoilers if hide_spoilers is not None else + self.hideSpoilers(ep, fully_watched=fully_watched, watched=watched)) \ + and {"blur": util.addonSettings.episodeNoSpoilerBlur} or {} + + +class PlaybackBtnMixin(object): + def __init__(self, *args, **kwargs): + self.playBtnClicked = False + + def reset(self, *args, **kwargs): + self.playBtnClicked = False + + def onReInit(self): + self.playBtnClicked = False diff --git a/script.plexmod/lib/windows/musicplayer.py b/script.plexmod/lib/windows/musicplayer.py index d2277eb5ee..d9d63a484c 100644 --- a/script.plexmod/lib/windows/musicplayer.py +++ b/script.plexmod/lib/windows/musicplayer.py @@ -1,12 +1,13 @@ from __future__ import absolute_import + from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui -from . import currentplaylist -from . import opener from lib import player from lib import util +from . import currentplaylist +from . import kodigui +from . import opener def timeDisplay(ms): @@ -49,6 +50,7 @@ def __init__(self, *args, **kwargs): self.album = kwargs.get('album') self.selectedOffset = 0 self.exitCommand = None + self.ignoreStopCommands = False if self.track: self.duration = self.track.duration.asInt() @@ -61,17 +63,33 @@ def onFirstInit(self): self.setupSeekbar() self.selectionBoxMax = self.SEEK_IMAGE_WIDTH - (self.selectionBoxHalf - 3) + self.commonInit() self.updateProperties() self.play() self.setFocusId(406) def doClose(self, **kwargs): - player.PLAYER.off('playback.started', self.onPlayBackStarted) + player.PLAYER.off('av.started', self.onPlayBackStarted) if self.playlist and self.playlist.isRemote: self.playlist.off('change', self.updateProperties) + + self.commonDeinit() kodigui.ControlledWindow.doClose(self) + def processCommand(self, command): + if command == "STOP": + self.doClose() + return + super(MusicPlayerWindow, self).processCommand(command) + def onAction(self, action): + if self.ignoreStopCommands and action in (xbmcgui.ACTION_PREVIOUS_MENU, + xbmcgui.ACTION_NAV_BACK): + if not self.is_current_window: + return + elif not self.ignoreStopCommands: + if not self.is_current_window and action != xbmcgui.ACTION_STOP: + return try: if action == xbmcgui.ACTION_STOP: self.stopButtonClicked() @@ -79,7 +97,7 @@ def onAction(self, action): except: util.ERROR() - super().onAction(action) + super(MusicPlayerWindow, self).onAction(action) def onClick(self, controlID): if controlID == self.PLAYLIST_BUTTON_ID: @@ -119,6 +137,7 @@ def skipPrevButtonClicked(self): if not self.playlist.refresh(force=True, wait=True): return + self.onAudioStarting() xbmc.executebuiltin('PlayerControl(Previous)') def skipNextButtonClicked(self): @@ -127,12 +146,14 @@ def skipNextButtonClicked(self): if not self.playlist.refresh(force=True, wait=True): return + self.onAudioStarting() xbmc.executebuiltin('PlayerControl(Next)') def showPlaylist(self): self.processCommand(opener.handleOpen(currentplaylist.CurrentPlaylistWindow, winID=xbmcgui.getCurrentWindowId())) def stopButtonClicked(self): + player.PLAYER.stopAndWait() self.doClose() def updateProperties(self, **kwargs): @@ -153,6 +174,8 @@ def play(self): if util.trackIsPlaying(self.track): return + self.onAudioStarting() + fanart = None if self.playlist: fanart = self.playlist.get('composite') or self.playlist.defaultArt diff --git a/script.plexmod/lib/windows/opener.py b/script.plexmod/lib/windows/opener.py index 591163d2a1..37ba37f328 100644 --- a/script.plexmod/lib/windows/opener.py +++ b/script.plexmod/lib/windows/opener.py @@ -1,9 +1,10 @@ from __future__ import absolute_import -from . import busy +import six from plexnet import playqueue, plexapp, plexlibrary + from lib import util -import six +from . import busy def open(obj, **kwargs): @@ -14,10 +15,10 @@ def open(obj, **kwargs): return handleOpen(musicplayer.MusicPlayerWindow, track=obj.current(), playlist=obj) elif obj.type == 'photo': from . import photos - return handleOpen(photos.PhotoWindow, play_queue=obj) + return handleOpen(photos.PhotoWindow, play_queue=obj, **kwargs) else: from . import videoplayer - videoplayer.play(play_queue=obj) + videoplayer.play(play_queue=obj, **kwargs) return '' elif isinstance(obj, six.string_types): key = obj diff --git a/script.plexmod/lib/windows/optionsdialog.py b/script.plexmod/lib/windows/optionsdialog.py index 317ee6eb40..21bd82bf43 100644 --- a/script.plexmod/lib/windows/optionsdialog.py +++ b/script.plexmod/lib/windows/optionsdialog.py @@ -1,7 +1,7 @@ from __future__ import absolute_import -from . import kodigui from lib import util +from . import kodigui class OptionsDialog(kodigui.BaseDialog): @@ -51,7 +51,7 @@ def onAction(self, action): if res: return - return kodigui.BaseDialog.onAction(self, action) + kodigui.BaseDialog.onAction(self, action) def onClick(self, controlID): if controlID in self.BUTTON_IDS: diff --git a/script.plexmod/lib/windows/pagination.py b/script.plexmod/lib/windows/pagination.py index 474be481c7..4d6a2df552 100644 --- a/script.plexmod/lib/windows/pagination.py +++ b/script.plexmod/lib/windows/pagination.py @@ -1,7 +1,9 @@ from __future__ import absolute_import -from . import kodigui + from kodi_six import xbmcgui + from lib import util +from . import kodigui class MCLPaginator(object): @@ -268,7 +270,10 @@ def createListItem(self, rel): def prepareListItem(self, data, mli): if data.type in ('season', 'show'): if not mli.dataSource.isWatched: - mli.setProperty('unwatched.count', str(mli.dataSource.unViewedLeafCount)) + mli.setProperty('unwatched.count', str(mli.dataSource.unViewedLeafCount) or '') + else: + mli.setBoolProperty('watched', mli.dataSource.isWatched) else: mli.setProperty('unwatched', not mli.dataSource.isWatched and '1' or '') + mli.setBoolProperty('watched', mli.dataSource.isFullyWatched) mli.setProperty('progress', util.getProgressImage(mli.dataSource)) diff --git a/script.plexmod/lib/windows/photos.py b/script.plexmod/lib/windows/photos.py index 7595ba7f5c..0bc159742b 100644 --- a/script.plexmod/lib/windows/photos.py +++ b/script.plexmod/lib/windows/photos.py @@ -1,20 +1,20 @@ from __future__ import absolute_import -import threading -import time + +import hashlib import os -import tempfile import shutil -import hashlib -import requests +import threading +import time -from kodi_six import xbmc, xbmcvfs +import requests +from kodi_six import xbmc from kodi_six import xbmcgui - -from . import kodigui -from . import busy +from plexnet import plexapp, plexplayer, playqueue +from plexnet import util as plexnetUtil from lib import util, colors -from plexnet import plexapp, plexplayer, playqueue +from . import busy +from . import kodigui class PhotoWindow(kodigui.BaseWindow): @@ -49,6 +49,7 @@ class PhotoWindow(kodigui.BaseWindow): def __init__(self, *args, **kwargs): kodigui.BaseWindow.__init__(self, *args, **kwargs) self.photo = kwargs.get('photo') + self.autoPlay = False self.playQueue = kwargs.get('play_queue') self.playerObject = None self.timelineType = 'photo' @@ -87,6 +88,13 @@ def onFirstInit(self): self.osdTimer = kodigui.PropertyTimer(self._winID, 4, 'OSD', '', init_value=False, callback=self.osdTimerCallback) self.imageControl = self.getControl(600) + if self.autoPlay: + self.play() + + def doAutoPlay(self): + self.autoPlay = True + return True + def osdTimerCallback(self): self.setFocusId(self.OVERLAY_BUTTON_ID) @@ -219,9 +227,9 @@ def getPlayQueue(self, shuffle=False): util.DEBUG_LOG('waiting for playQueue to initialize') if busy.widthDialog(self.playQueue.waitForInitialization, None, delay=True): - util.DEBUG_LOG('playQueue initialized: {0}'.format(self.playQueue)) + util.DEBUG_LOG('playQueue initialized: {0}', self.playQueue) else: - util.DEBUG_LOG('playQueue timed out wating for initialization') + util.DEBUG_LOG('playQueue timed out waiting for initialization') self.showPhoto() @@ -259,7 +267,7 @@ def showPhoto(self, trigger=None, **kwargs): # bad temporary fix for videos in photo playqueues if photo.type != "photo": self.next() - util.DEBUG_LOG("SKIPPING PHOTO: %s" % photo) + util.DEBUG_LOG("SKIPPING PHOTO: {}", photo) return self.updatePqueueListSelection(photo) @@ -522,7 +530,16 @@ def updateNowPlaying(self, force=False, refreshQueue=False, state=None): if refreshQueue and self.playQueue: self.playQueue.refreshOnTimeline = True - plexapp.util.APP.nowplayingmanager.updatePlaybackState(self.timelineType, self.playerObject, state, time, self.playQueue) + data = plexnetUtil.AttributeDict({ + "key": str(item.key), + "ratingKey": str(item.ratingKey), + "guid": str(item.guid), + "url": str(item.url), + "duration": item.duration.asInt(), + "containerKey": str(item.container.address) + }) + + plexapp.util.APP.nowplayingmanager.updatePlaybackState(self.timelineType, data, state, time, self.playQueue) def showOSD(self): self.osdTimer.reset(init=False) diff --git a/script.plexmod/lib/windows/playbacksettings.py b/script.plexmod/lib/windows/playbacksettings.py index 5e614e1aec..b870608515 100644 --- a/script.plexmod/lib/windows/playbacksettings.py +++ b/script.plexmod/lib/windows/playbacksettings.py @@ -1,9 +1,8 @@ # coding=utf-8 -from lib import util -from lib.util import T - from plexnet.util import INTERFACE +from lib import util +from lib.util import T from . import dropdown diff --git a/script.plexmod/lib/windows/playerbackground.py b/script.plexmod/lib/windows/playerbackground.py index e34073b15e..31ce2bfaad 100644 --- a/script.plexmod/lib/windows/playerbackground.py +++ b/script.plexmod/lib/windows/playerbackground.py @@ -1,7 +1,9 @@ from __future__ import absolute_import + import contextlib -from . import kodigui + from lib import util +from . import kodigui class PlayerBackground(kodigui.BaseWindow): diff --git a/script.plexmod/lib/windows/playersettings.py b/script.plexmod/lib/windows/playersettings.py index 51fbb5c1b2..1d6f6a7b74 100644 --- a/script.plexmod/lib/windows/playersettings.py +++ b/script.plexmod/lib/windows/playersettings.py @@ -1,13 +1,13 @@ from __future__ import absolute_import + +import plexnet from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui -from lib import util from lib import metadata +from lib import util from lib.util import T - -import plexnet +from . import kodigui class VideoSettingsDialog(kodigui.BaseDialog, util.CronReceiver): @@ -136,6 +136,10 @@ def showSettings(self, init=False): else: self.settingsList.replaceItems(items) + if self.nonPlayback: + # we don't have enough items for a scrollbar, increase width + self.settingsList.setWidth(1000) + self.setFocusId(self.SETTINGS_LIST_ID) def getAudioAndSubtitleInfo(self): @@ -321,7 +325,7 @@ def showAudioDialog(video, non_playback=False): if choice is None: return - video.selectStream(choice) + video.selectStream(choice, from_session=not non_playback) def showSubtitlesDialog(video, non_playback=False): @@ -336,7 +340,7 @@ def showSubtitlesDialog(video, non_playback=False): if choice is None: return - video.selectStream(choice) + video.selectStream(choice, from_session=not non_playback) video.manually_selected_sub_stream = choice.id diff --git a/script.plexmod/lib/windows/playlist.py b/script.plexmod/lib/windows/playlist.py index 705fed3725..160ccffc79 100644 --- a/script.plexmod/lib/windows/playlist.py +++ b/script.plexmod/lib/windows/playlist.py @@ -1,25 +1,23 @@ from __future__ import absolute_import + import threading +import plexnet from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui +from six.moves import range +from lib import backgroundthread +from lib import player +from lib import util +from lib.util import T from . import busy -from . import videoplayer -from . import windowutils from . import dropdown -from . import search -import plexnet +from . import kodigui from . import opener - -from lib import colors -from lib import util -from lib import player -from lib import backgroundthread - -from lib.util import T -from six.moves import range +from . import search +from . import videoplayer +from . import windowutils PLAYLIST_PAGE_SIZE = 500 PLAYLIST_INITIAL_SIZE = 100 @@ -55,9 +53,9 @@ def run(self): self.WINDOW.chunkCallback(items, self.start) except AttributeError: - util.DEBUG_LOG('Playlist window closed, ignoring chunk at index {0}'.format(self.start)) + util.DEBUG_LOG('Playlist window closed, ignoring chunk at index {0}', self.start) except plexnet.exceptions.BadRequest: - util.DEBUG_LOG('404 on playlist: {0}'.format(repr(self.WINDOW.playlist.title))) + util.DEBUG_LOG('404 on playlist: {0}', lambda: repr(self.WINDOW.playlist.title)) class PlaylistWindow(kodigui.ControlledWindow, windowutils.UtilMixin): @@ -95,10 +93,14 @@ def __init__(self, *args, **kwargs): def onFirstInit(self): self.playlistListControl = kodigui.ManagedControlList(self, self.PLAYLIST_LIST_ID, 5) self.setProperties() + player.PLAYER.on('new.video', self.onNewVideo) self.fillPlaylist() self.setFocusId(self.PLAYLIST_LIST_ID) + def onReInit(self): + self.playlistListControl.setSelectedItemByDataSource(self.playlist.current()) + # def onAction(self, action): # try: # if action in(xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_CONTEXT_MENU): @@ -108,12 +110,18 @@ def onFirstInit(self): # except: # util.ERROR() - # kodigui.ControlledWindow.onAction(self, action) + # self.defOnAction(action) + + def onNewVideo(self, *args, **kwargs): + video = kwargs.get("video") + self.playlist.setCurrent(self.playlist.getPosFromItem(video)) def onAction(self, action): try: if action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): self.doClose() + elif self.playlist.playlistType == 'video' and action == xbmcgui.ACTION_CONTEXT_MENU: + return self.plItemPlaybackMenu() except: util.ERROR() @@ -127,23 +135,58 @@ def onClick(self, controlID): elif controlID == self.PLAYER_STATUS_BUTTON_ID: self.showAudioPlayer() elif controlID == self.PLAY_BUTTON_ID: - self.playlistListClicked(no_item=True, shuffle=False) + self.playlistListClicked(no_item=True, shuffle=False, play=True) elif controlID == self.SHUFFLE_BUTTON_ID: - self.playlistListClicked(no_item=True, shuffle=True) + self.playlistListClicked(no_item=True, shuffle=True, play=True) elif controlID == self.OPTIONS_BUTTON_ID: self.optionsButtonClicked() elif controlID == self.SEARCH_BUTTON_ID: self.searchButtonClicked() def doClose(self): + player.PLAYER.off('new.video', self.onNewVideo) kodigui.ControlledWindow.doClose(self) self.tasks.cancel() ChunkRequestTask.reset() + def plItemPlaybackMenu(self, select_choice='visit'): + mli = self.playlistListControl.getSelectedItem() + if not mli or not mli.dataSource: + return + + can_resume = mli.dataSource.viewOffset.asInt() + + options = [ + {'key': 'visit', 'display': T(33019, 'Visit Media Item')}, + {'key': 'play', 'display': T(33020, 'Play') if not can_resume else T(32317, 'Play from beginning')}, + ] + if can_resume: + options.append({'key': 'resume', 'display': T(32429, 'Resume from {0}').format( + util.timeDisplay(mli.dataSource.viewOffset.asInt()).lstrip('0').lstrip(':'))}) + + choice = dropdown.showDropdown( + options, + pos=(660, 441), + close_direction='none', + set_dropdown_prop=False, + header=T(33021, 'Choose action'), + select_index=2 if select_choice == 'resume' else 1 if util.addonSettings.playlistVisitMedia else 0 + ) + + if not choice: + return + + if choice['key'] == 'visit': + self.openItem(mli.dataSource) + elif choice['key'] == 'play': + self.playlistListClicked(resume=False, play=True) + elif choice['key'] == 'resume': + self.playlistListClicked(resume=True, play=True) + def searchButtonClicked(self): self.processCommand(search.dialog(self)) - def playlistListClicked(self, no_item=False, shuffle=False): + def playlistListClicked(self, no_item=False, shuffle=False, resume=None, play=False): if no_item: mli = None else: @@ -167,17 +210,20 @@ def playlistListClicked(self, no_item=False, shuffle=False): pq = plexnet.playqueue.createPlayQueueForItem(self.playlist, options=args) opener.open(pq) elif self.playlist.playlistType == 'video': - if not util.advancedSettings.playlistVisitMedia: + if not util.addonSettings.playlistVisitMedia or play: + if resume is None and mli and bool(mli.dataSource.viewOffset.asInt()): + return self.plItemPlaybackMenu(select_choice='resume') + if self.playlist.leafCount.asInt() <= PLAYLIST_INITIAL_SIZE: self.playlist.setShuffle(shuffle) self.playlist.setCurrent(mli and mli.pos() or 0) - videoplayer.play(play_queue=self.playlist) + videoplayer.play(play_queue=self.playlist, resume=resume) else: args = {'shuffle': shuffle} if mli: args['key'] = mli.dataSource.key pq = plexnet.playqueue.createPlayQueueForItem(self.playlist, options=args) - opener.open(pq) + opener.open(pq, resume=resume) else: if not mli: firstItem = 0 @@ -272,13 +318,15 @@ def createTrackListItem(self, mli, track): def createEpisodeListItem(self, mli, episode): label2 = u'{0} \u2022 {1}'.format( - episode.grandparentTitle, u'{0}{1} \u2022 {2}{3}'.format(T(32310, 'S'), episode.parentIndex, T(32311, 'E'), episode.index) + episode.grandparentTitle, u'{0} \u2022 {1}'.format(T(32310, 'S').format(episode.parentIndex), + T(32311, 'E').format(episode.index)) ) mli.setLabel2(label2) mli.setThumbnailImage(episode.thumb.asTranscodedImageURL(*self.LI_AR16X9_THUMB_DIM)) mli.setProperty('track.duration', util.durationToShortText(episode.duration.asInt())) mli.setProperty('video', '1') mli.setProperty('watched', episode.isWatched and '1' or '') + mli.setProperty('unwatched', episode.isWatched and '' or '1') def createMovieListItem(self, mli, movie): mli.setLabel(movie.defaultTitle) @@ -287,6 +335,7 @@ def createMovieListItem(self, mli, movie): mli.setProperty('track.duration', util.durationToShortText(movie.duration.asInt())) mli.setProperty('video', '1') mli.setProperty('watched', movie.isWatched and '1' or '') + mli.setProperty('unwatched', movie.isWatched and '' or '1') @busy.dialog() def fillPlaylist(self): @@ -306,6 +355,9 @@ def fillPlaylist(self): self.playlistListControl.reset() self.playlistListControl.addItems(items) + self.playlist.setCurrent(self.playlist.getPosFromItem(self.playlist.userCurrent())) + self.playlistListControl.setSelectedItemByDataSource(self.playlist.current()) + if total <= min(PLAYLIST_INITIAL_SIZE, PLAYLIST_PAGE_SIZE): return diff --git a/script.plexmod/lib/windows/playlists.py b/script.plexmod/lib/windows/playlists.py index 12d22bb1fa..b2593a83d4 100644 --- a/script.plexmod/lib/windows/playlists.py +++ b/script.plexmod/lib/windows/playlists.py @@ -1,17 +1,15 @@ from __future__ import absolute_import + from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui +from plexnet import plexapp +from lib import util from . import busy +from . import kodigui from . import playlist -from . import windowutils from . import search - -from lib import util -from lib import colors - -from plexnet import plexapp +from . import windowutils class PlaylistsWindow(kodigui.ControlledWindow, windowutils.UtilMixin): diff --git a/script.plexmod/lib/windows/preplay.py b/script.plexmod/lib/windows/preplay.py index e72bae1097..3ace7d6c9f 100644 --- a/script.plexmod/lib/windows/preplay.py +++ b/script.plexmod/lib/windows/preplay.py @@ -2,28 +2,23 @@ from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui +from plexnet import plexplayer, media +from lib import metadata +from lib import util +from lib.util import T from . import busy -from . import opener +from . import dropdown from . import info -from . import videoplayer +from . import kodigui +from . import opener +from . import optionsdialog +from . import pagination from . import playersettings from . import search -from . import dropdown +from . import videoplayer from . import windowutils -from . import optionsdialog -from . import preplayutils -from . import pagination -from .mixins import RatingsMixin - -from plexnet import plexplayer, media - -from lib import util -from lib import metadata - -from lib.util import T - +from .mixins import RatingsMixin, PlaybackBtnMixin VIDEO_RELOAD_KW = dict(includeExtras=1, includeExtrasCount=10, includeChapters=1, includeReviews=1) @@ -33,7 +28,7 @@ def getData(self, offset, amount): return self.parentWindow.video.getRelated(offset=offset, limit=amount) -class PrePlayWindow(kodigui.ControlledWindow, windowutils.UtilMixin, RatingsMixin): +class PrePlayWindow(kodigui.ControlledWindow, windowutils.UtilMixin, RatingsMixin, PlaybackBtnMixin): xmlFile = 'script-plex-pre_play.xml' path = util.ADDON.getAddonInfo('path') theme = 'Main' @@ -69,6 +64,7 @@ class PrePlayWindow(kodigui.ControlledWindow, windowutils.UtilMixin, RatingsMixi def __init__(self, *args, **kwargs): kodigui.ControlledWindow.__init__(self, *args, **kwargs) + PlaybackBtnMixin.__init__(self) self.video = kwargs.get('video') self.parentList = kwargs.get('parent_list') self.videos = None @@ -100,6 +96,7 @@ def doAutoPlay(self): @busy.dialog() def onReInit(self): + PlaybackBtnMixin.onReInit(self) self.initialized = False if util.getSetting("slow_connection", False): self.progressImageControl.setWidth(1) @@ -141,7 +138,7 @@ def onAction(self, action): elif action == xbmcgui.ACTION_NAV_BACK: if (not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format( self.OPTIONS_GROUP_ID)) or not controlID) and \ - not util.advancedSettings.fastBack: + not util.addonSettings.fastBack: if self.getProperty('on.extras'): self.setFocusId(self.OPTIONS_GROUP_ID) return @@ -310,7 +307,7 @@ def mediaButtonClicked(self): def delete(self): button = optionsdialog.show( T(32326, 'Really delete?'), - T(32327, 'Are you sure you really want to delete this media?'), + T(33035, "Delete {}: {}?").format(type(self.video).__name__, self.video.defaultTitle), T(32328, 'Yes'), T(32329, 'No') ) @@ -326,7 +323,7 @@ def delete(self): @busy.dialog() def _delete(self): success = self.video.delete() - util.LOG('Media DELETE: {0} - {1}'.format(self.video, success and 'SUCCESS' or 'FAILED')) + util.LOG('Media DELETE: {0} - {1}', self.video, success and 'SUCCESS' or 'FAILED') return success def roleClicked(self): @@ -448,12 +445,22 @@ def getRoleItemDDPosition(self): if xbmc.getCondVisibility('Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)'): y -= 500 - focus = int(xbmc.getInfoLabel('Container(400).Position')) + tries = 0 + focus = xbmc.getInfoLabel('Container(400).Position') + while tries < 2 and focus == '': + focus = xbmc.getInfoLabel('Container(400).Position') + xbmc.sleep(250) + tries += 1 + + focus = int(focus) x = ((focus + 1) * 304) - 100 return x, y def playVideo(self, from_auto_play=False): + if self.playBtnClicked: + return + if not self.video.available(): util.messageDialog(T(32312, 'Unavailable'), T(32313, 'This item is currently unavailable.')) return @@ -478,6 +485,9 @@ def playVideo(self, from_auto_play=False): if choice['key'] == 'resume': resume = True + if not from_auto_play: + self.playBtnClicked = True + self.processCommand(videoplayer.play(video=self.video, resume=resume)) return True @@ -501,7 +511,7 @@ def focusPlayButton(self): def setup(self): self.focusPlayButton() - util.DEBUG_LOG('PrePlay: Showing video info: {0}'.format(self.video)) + util.DEBUG_LOG('PrePlay: Showing video info: {0}', self.video) if self.video.type == 'episode': self.setProperty('preview.yes', '1') elif self.video.type == 'movie': @@ -528,6 +538,7 @@ def setInfo(self, skip_bg=False): self.setProperty('duration', util.durationToText(self.video.duration.asInt())) self.setProperty('summary', self.video.summary.strip().replace('\t', ' ')) self.setProperty('unwatched', not self.video.isWatched and '1' or '') + self.setBoolProperty('watched', self.video.isFullyWatched) directors = u' / '.join([d.tag for d in self.video.directors()][:3]) directorsLabel = len(self.video.directors) > 1 and T(32401, u'DIRECTORS').upper() or T(32383, u'DIRECTOR').upper() @@ -542,7 +553,7 @@ def setInfo(self, skip_bg=False): self.setProperty('content.rating', '') self.setProperty('thumb', self.video.defaultThumb.asTranscodedImageURL(*self.THUMB_POSTER_DIM)) self.setProperty('preview', self.video.thumb.asTranscodedImageURL(*self.PREVIEW_DIM)) - self.setProperty('info', u'{0} {1} {2} {3}'.format(T(32303, 'Season'), self.video.parentIndex, T(32304, 'Episode'), self.video.index)) + self.setProperty('info', u'{0} {1}'.format(T(32303, 'Season').format(self.video.parentIndex), T(32304, 'Episode').format(self.video.index))) self.setProperty('date', util.cleanLeadingZeros(self.video.originallyAvailableAt.asDatetime('%B %d, %Y'))) self.setProperty('related.header', T(32306, 'Related Shows')) elif self.video.type == 'movie': diff --git a/script.plexmod/lib/windows/preplayutils.py b/script.plexmod/lib/windows/preplayutils.py index 7d000622fe..03ea300a6d 100644 --- a/script.plexmod/lib/windows/preplayutils.py +++ b/script.plexmod/lib/windows/preplayutils.py @@ -1,7 +1,7 @@ from __future__ import absolute_import -from . import dropdown from lib.util import T +from . import dropdown def chooseVersion(video): diff --git a/script.plexmod/lib/windows/search.py b/script.plexmod/lib/windows/search.py index 2b4e2998c7..d84a77890c 100644 --- a/script.plexmod/lib/windows/search.py +++ b/script.plexmod/lib/windows/search.py @@ -1,17 +1,17 @@ from __future__ import absolute_import -import time + import threading +import time from kodi_six import xbmcgui, xbmc +from plexnet import plexapp +from lib import util +from lib.kodijsonrpc import rpc from . import kodigui from . import opener from . import windowutils -from lib import util -from lib.kodijsonrpc import rpc - -from plexnet import plexapp class SearchDialog(kodigui.BaseDialog, windowutils.UtilMixin): xmlFile = 'script-plex-search.xml' @@ -382,10 +382,10 @@ def showHubs(self, hubs): self.setProperty('no.results', '1') def showHub(self, hub, idx): - util.DEBUG_LOG('Showing search hub: {0} at {1}'.format(hub.type, idx)) + util.DEBUG_LOG('Showing search hub: {0} at {1}', hub.type, idx) info = self.HUBMAP.get(hub.type) if not info: - util.DEBUG_LOG('Unhandled hub type: {0}'.format(hub.type)) + util.DEBUG_LOG('Unhandled hub type: {0}', hub.type) return itemListControl = self.hubControls[idx][info['type']] diff --git a/script.plexmod/lib/windows/seekdialog.py b/script.plexmod/lib/windows/seekdialog.py index 1be1fd0f7e..2aff52733f 100644 --- a/script.plexmod/lib/windows/seekdialog.py +++ b/script.plexmod/lib/windows/seekdialog.py @@ -1,28 +1,27 @@ from __future__ import absolute_import + import re -import time import threading -import math +import time +from collections import OrderedDict from kodi_six import xbmc from kodi_six import xbmcgui -from collections import OrderedDict - -from . import kodigui -from . import playersettings -from . import dropdown -from . import busy from plexnet import plexapp - -from lib import util -from plexnet.videosession import VideoSessionInfo, ATTRIBUTE_TYPES as SESSION_ATTRIBUTE_TYPES +from plexnet.util import AttributeDict from plexnet.exceptions import ServerNotOwned, NotFound -from plexnet.signalsmixin import SignalsMixin +from plexnet.videosession import VideoSessionInfo, ATTRIBUTE_TYPES as SESSION_ATTRIBUTE_TYPES +from six.moves import range +import lib.cache +from lib import util from lib.kodijsonrpc import builtin - from lib.util import T -from six.moves import range +from . import busy +from . import dropdown +from . import kodigui +from . import playersettings +from .mixins import SpoilersMixin KEY_MOVE_SET = frozenset( ( @@ -74,6 +73,11 @@ }) ]) + +class Marker(AttributeDict): + pass + + FINAL_MARKER_NEGOFF = 3000 MARKER_SHOW_NEGOFF = 3000 MARKER_OFF = 500 @@ -135,7 +139,7 @@ class SeekDialog(kodigui.BaseDialog): SKIP_STEPS = {"negative": [-10000], "positive": [30000]} def __init__(self, *args, **kwargs): - kodigui.BaseDialog.__init__(self, *args, **kwargs) + super(SeekDialog, self).__init__(*args, **kwargs) # fixme: heyo, there's a lot of disorder in here. self.handler = kwargs.get('handler') @@ -171,7 +175,7 @@ def __init__(self, *args, **kwargs): self._delayedSeekTimeout = 0 self._osdHideAnimationTimeout = 0 self._hideDelay = self.HIDE_DELAY - self._autoSeekDelay = util.advancedSettings.autoSeek and util.advancedSettings.autoSeekDelay or 0 + self._autoSeekDelay = util.addonSettings.autoSeek and util.addonSettings.autoSeekDelay or 0 self._atSkipStep = -1 self._lastSkipDirection = None self._forcedLastSkipAmount = None @@ -181,6 +185,9 @@ def __init__(self, *args, **kwargs): self._ignoreInput = False self._ignoreTick = False self._abortBufferWait = False + self.no_spoilers = util.getSetting('no_episode_spoilers3', ["unwatched"]) + self.no_time_no_osd_spoilers = util.getSetting('no_osd_time_spoilers', False) + self.clientLikePlex = util.getSetting('player_official', True) self._videoBelowOneHour = False self.timeFmtKodi = util.timeFormatKN @@ -192,6 +199,11 @@ def __init__(self, *args, **kwargs): self.timeKeeperTime = None self.idleTime = None self.stopPlaybackOnIdle = util.getSetting('player_stop_on_idle', 0) + self.resumeSeekBehind = util.getSetting('resume_seek_behind', 0) + self.resumeSeekBehindPause = util.getSetting('resume_seek_behind_pause', False) + self.resumeSeekBehindAfter = util.getSetting('resume_seek_behind_after', 0) / 1000.0 + self.resumeSeekBehindOnlyDP = util.getSetting('resume_seek_behind_onlydp', True) + self.pausedAt = None self.isDirectPlay = True self.isTranscoded = False @@ -203,23 +215,26 @@ def __init__(self, *args, **kwargs): self._creditsSkipShownStarted = None self._currentMarker = None self.skipSteps = self.SKIP_STEPS - self.useAutoSeek = util.advancedSettings.autoSeek - self.useDynamicStepsForTimeline = util.advancedSettings.dynamicTimelineSeek + self.useAutoSeek = util.addonSettings.autoSeek + self.useDynamicStepsForTimeline = util.addonSettings.dynamicTimelineSeek + self.showSkipIntro = False + self.showSkipCredits = False self.bingeMode = False self.autoSkipIntro = False self.autoSkipCredits = False self.showIntroSkipEarly = False self.skipPostPlay = False + self.videoPausedForAudioStreamChange = False - self.skipIntroButtonTimeout = util.advancedSettings.skipIntroButtonTimeout - self.skipCreditsButtonTimeout = util.advancedSettings.skipCreditsButtonTimeout - self.showItemEndsInfo = util.advancedSettings.showMediaEndsInfo - self.showItemEndsLabel = util.advancedSettings.showMediaEndsLabel + self.skipIntroButtonTimeout = util.addonSettings.skipIntroButtonTimeout + self.skipCreditsButtonTimeout = util.addonSettings.skipCreditsButtonTimeout + self.showItemEndsInfo = util.addonSettings.showMediaEndsInfo + self.showItemEndsLabel = util.addonSettings.showMediaEndsLabel self.player.video.server.on("np:timelineResponse", self.timelineResponseCallback) - if util.kodiSkipSteps and util.advancedSettings.kodiSkipStepping: + if util.kodiSkipSteps and util.addonSettings.kodiSkipStepping: self.skipSteps = {"negative": [], "positive": []} for step in util.kodiSkipSteps: key = "negative" if step < 0 else "positive" @@ -290,21 +305,44 @@ def trueOffset(self): @property def markers(self): - # fixme: fix transcoded marker skip if not self._enableMarkerSkip: return None - if not self._markers and hasattr(self.handler.player.video, "markers"): + if self._markers is None and hasattr(self.handler.player.video, "markers"): markers = [] - for marker in self.handler.player.video.markers: - if marker.type in MARKERS: + for m in self.handler.player.video.markers: + if m.type in MARKERS: + # normalize markers and properties as we modify them later on + final = m.final.asBool() + sto = m.startTimeOffset.asInt() + marker = Marker({ + "id": m.id.asInt(), + "final": final, + "type": str(m.type), + "title": "{}@{}{}".format(m.type, m.startTimeOffset.asInt(), final and ",final" or ""), + "startTimeOffset": sto, + "endTimeOffset": m.endTimeOffset.asInt() + }) + + # skip completely bad markers + if marker.startTimeOffset > self.duration: + continue + + # skip intro markers that are too late + if (marker.type == "intro" + and marker.startTimeOffset > util.addonSettings.introMarkerMaxOffset * 1000): + util.DEBUG_LOG("Throwing away intro marker {}, as its start time offset is bigger than the" + " configured maximum", marker) + continue + m = MARKERS[marker.type].copy() m["marker"] = marker m["marker_type"] = marker.type markers.append(m) self._markers = markers + util.DEBUG_LOG("Got markers: {}", lambda: list(_m["marker"] for _m in markers)) return self._markers @@ -312,6 +350,43 @@ def markers(self): def markers(self, val): self._markers = val + def getCurrentMarkerDef(self, offset=None): + """ + Show intro/credits skip button at current time + """ + + if not self.markers: + return + + off = offset if offset is not None else self.trueOffset() + + for markerDef in self.markers: + marker = markerDef["marker"] + if marker: + startTimeOffset = marker.startTimeOffset + + # marker display wanted? + if (not self.showSkipIntro and markerDef["marker_type"] == "intro") or \ + (not self.showSkipCredits and markerDef["marker_type"] == "credits"): + continue + + # show intro skip early? (only if intro is during the first X minutes) + if self.showIntroSkipEarly and markerDef["marker_type"] == "intro" and \ + startTimeOffset <= util.addonSettings.skipIntroButtonShowEarlyThreshold1 * 1000: + startTimeOffset = 0 + markerDef["overrideStartOff"] = 0 + + # fix markers with a bad endTimeOffset + if marker.endTimeOffset > self.duration: + marker.endTimeOffset = self.duration + util.DEBUG_LOG("Fixing marker endTimeOffset for: {}", marker) + + markerEndNegoff = FINAL_MARKER_NEGOFF if getattr(markerDef["marker"], "final", False) else 0 + + if startTimeOffset - MARKER_SHOW_NEGOFF <= off < marker.endTimeOffset - markerEndNegoff: + + return markerDef + def onFirstInit(self): try: self._onFirstInit() @@ -341,14 +416,29 @@ def _onFirstInit(self): self.bigSeekGroupControl = self.getControl(self.BIG_SEEK_GROUP_ID) self.initialized = True - showQuickSubs = util.getSetting('subtitle_downloads', False) - showRepeat = util.getSetting('video_show_repeat', False) - showFfwdRwd = util.getSetting('video_show_ffwdrwd', False) - showShuffle = util.getSetting('video_show_shuffle', False) + button_settings = util.getUserSetting('player_show_buttons', ['subtitle_downloads', 'skip_intro', 'skip_credits']) + showQuickSubs = 'subtitle_downloads' in button_settings + showRepeat = 'video_show_repeat' in button_settings + showFfwdRwd = 'video_show_ffwdrwd' in button_settings + showShuffle = 'video_show_shuffle' in button_settings + self.showSkipIntro = 'skip_intro' in button_settings + self.showSkipCredits = 'skip_credits' in button_settings self.setBoolProperty('nav.quick_subtitles', showQuickSubs) self.setBoolProperty('nav.repeat', showRepeat) self.setBoolProperty('nav.ffwdrwd', showFfwdRwd) self.setBoolProperty('nav.shuffle', showShuffle) + navPlaylist = util.getSetting('video_show_playlist', 'eponly') + self.setBoolProperty('nav.playlist', (navPlaylist == "eponly" and + (self.player.video.type == 'episode' or self.handler.playlist)) or + navPlaylist == "always") + + if not self.getProperty('nav.playlist'): + self.subtitleButtonLeft += self.NAVBAR_BTN_SIZE + + navPrevNext = util.getSetting('video_show_prevnext', 'eponly') + self.setBoolProperty('nav.prevnext', (navPrevNext == "eponly" and + (self.player.video.type == 'episode' or self.handler.playlist)) or + navPrevNext == "always") if showQuickSubs: self.subtitleButtonLeft += self.NAVBAR_BTN_SIZE * len( @@ -378,42 +468,33 @@ def setup(self, duration, meta, offset=0, bif_url=None, title='', title2='', cha """ this is called by our handler and occurs earlier than onFirstInit. """ - util.DEBUG_LOG("SeekDialog: setup, keepMarkerDef={}".format(keepMarkerDef)) + util.DEBUG_LOG("SeekDialog: setup, keepMarkerDef={}", keepMarkerDef) + self._duration = duration self.title = title self.title2 = title2 self.chapters = chapters or [] self.isDirectPlay = not meta.isTranscoded self.isTranscoded = not self.isDirectPlay - self.showChapters = util.getUserSetting('show_chapters', True) and ( - bool(chapters) or (util.getUserSetting('virtual_chapters', True) and bool(self.markers))) self.setProperty('video.title', title) self.setProperty('is.show', (self.player.video.type == 'episode') and '1' or '') self.setProperty('ep.year', (self.player.video.type == 'episode') and self.player.video.year or '') self.setProperty('has.playlist', self.handler.playlist and '1' or '') self.setProperty('shuffled', (self.handler.playlist and self.handler.playlist.isShuffled) and '1' or '') - self.setProperty('has.chapters', self.showChapters and '1' or '') - self.setProperty('show.buffer', (util.advancedSettings.playerShowBuffer and self.isDirectPlay) and '1' or '') + self.setProperty('show.buffer', (util.addonSettings.playerShowBuffer and self.isDirectPlay) and '1' or '') + self.setProperty('theme', 'modern') self.killTimeKeeper() - navPlaylist = util.getSetting('video_show_playlist', 'eponly') - self.setBoolProperty('nav.playlist', (navPlaylist == "eponly" and self.player.video.type == 'episode') or - navPlaylist == "always") - if not self.getProperty('nav.playlist'): self.subtitleButtonLeft += self.NAVBAR_BTN_SIZE - navPrevNext = util.getSetting('video_show_prevnext', 'eponly') - self.setBoolProperty('nav.prevnext', (navPrevNext == "eponly" and self.player.video.type == 'episode') or - navPrevNext == "always") - if not self.getProperty('nav.prevnext'): self.subtitleButtonLeft += self.NAVBAR_BTN_SIZE try: if self.player.video.type == 'episode': pbs = self.player.video.playbackSettings - util.DEBUG_LOG("Playback settings for {}: {}".format(self.player.video.ratingKey, pbs)) + util.DEBUG_LOG("Playback settings for {}: {}", self.player.video.ratingKey, pbs) self.bingeMode = pbs.binge_mode self.handler.inBingeMode = self.bingeMode @@ -434,11 +515,15 @@ def setup(self, duration, meta, offset=0, bif_url=None, title='', title2='', cha except IndexError: self.doClose(delete=True) raise util.NoDataException + + self.showChapters = util.getUserSetting('show_chapters', True) and ( + bool(chapters) or (util.getUserSetting('virtual_chapters', True) and bool(self.markers))) + self.setProperty('has.chapters', self.showChapters and '1' or '') + self.baseOffset = offset self.offset = 0 self.idleTime = None self.lastSubtitleNavAction = "forward" - self._duration = duration self._videoBelowOneHour = duration / 3600000 < 1 if self._videoBelowOneHour: self.timeFmtKodi = self.timeFmtKodi.replace("hh:", "") @@ -513,13 +598,15 @@ def onAction(self, action): if markerDef["marker"]: marker = markerDef["marker"] final = getattr(marker, "final", False) - markerOff = 0 if final else MARKER_END_JUMP_OFF + markerOff = -FINAL_MARKER_NEGOFF if final else MARKER_END_JUMP_OFF - util.DEBUG_LOG('MarkerSkip: Skipping marker {}'.format(markerDef["marker"])) + util.DEBUG_LOG('MarkerSkip: Skipping marker' + ' {} (final: {}, to: {}, offset: {})'.format(markerDef["marker"], + final, marker.endTimeOffset, markerOff)) self.setProperty('show.markerSkip', '') self.setProperty('show.markerSkip_OSDOnly', '') markerDef["skipped"] = True - self.doSeek(math.ceil(float(marker.endTimeOffset)) + markerOff) + self.doSeek(marker.endTimeOffset + markerOff) self.hideOSD(skipMarkerFocus=True) if marker.type == "credits" and not final: @@ -568,7 +655,13 @@ def onAction(self, action): self.setProperty('show.chapters', '1') elif action == xbmcgui.ACTION_MOVE_DOWN: - if self.previousFocusID == self.BIG_SEEK_LIST_ID and ( + # pressing down with the OSD open and chapters available + if (self.showChapters and self.clientLikePlex and + (self.previousFocusID not in (controlID, self.MAIN_BUTTON_ID, self.BIG_SEEK_LIST_ID))): + self.setProperty('show.chapters', '1') + self.setFocusId(self.BIG_SEEK_LIST_ID) + + elif self.previousFocusID == self.BIG_SEEK_LIST_ID and ( self.getProperty('show.markerSkip') or self.getProperty('show.markerSkip_OSDOnly')): self.setFocusId(self.SKIP_MARKER_BUTTON_ID) self.setProperty('show.chapters', '') @@ -596,14 +689,22 @@ def onAction(self, action): else: self.skipBack(without_osd=True) - if action in (xbmcgui.ACTION_MOVE_UP, xbmcgui.ACTION_MOVE_DOWN): - # we're seeking from the timeline, with the OSD closed; act as we're skipping - if not self._seeking: - self.selectedOffset = self.trueOffset() - - if self.skipChapter(forward=(action == xbmcgui.ACTION_MOVE_UP), without_osd=True): + elif action in (xbmcgui.ACTION_MOVE_UP, + xbmcgui.ACTION_MOVE_DOWN, + xbmcgui.ACTION_PAGE_UP, + xbmcgui.ACTION_PAGE_DOWN): + if self.clientLikePlex: + self.showOSD() return + if action in (xbmcgui.ACTION_MOVE_UP, xbmcgui.ACTION_MOVE_DOWN): + # we're seeking from the timeline, with the OSD closed; act as we're skipping + if not self._seeking: + self.selectedOffset = self.trueOffset() + + if self.skipChapter(forward=(action == xbmcgui.ACTION_MOVE_UP), without_osd=True): + return + if action in ( xbmcgui.ACTION_MOVE_UP, xbmcgui.ACTION_MOVE_DOWN, @@ -663,16 +764,16 @@ def onAction(self, action): # immediate marker timer actions if self.countingDownMarker: if controlID != self.BIG_SEEK_LIST_ID and \ - (util.advancedSettings.skipMarkerTimerCancel - or util.advancedSettings.skipMarkerTimerImmediate): - if util.advancedSettings.skipMarkerTimerCancel and \ + (util.addonSettings.skipMarkerTimerCancel + or util.addonSettings.skipMarkerTimerImmediate): + if util.addonSettings.skipMarkerTimerCancel and \ action in (xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK): self.displayMarkers(cancelTimer=True) return # skip the first second of a marker shown with countdown to avoid unexpected OK/SELECT # behaviour - elif util.advancedSettings.skipMarkerTimerImmediate \ + elif util.addonSettings.skipMarkerTimerImmediate \ and action == xbmcgui.ACTION_SELECT_ITEM and \ self._currentMarker["countdown"] is not None and \ self._currentMarker["countdown_initial"] is not None and \ @@ -695,17 +796,18 @@ def onAction(self, action): self.hideOSD() return - if action in (xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK): - if self._osdHideAnimationTimeout: + if action in (xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_STOP): + if action != xbmcgui.ACTION_STOP and self._osdHideAnimationTimeout: if self._osdHideAnimationTimeout >= time.time(): return else: self._osdHideAnimationTimeout = None - if self.osdVisible(): - self.hideOSD() + if action != xbmcgui.ACTION_STOP and self.osdVisible(): + if not self.playlistDialogVisible: + self.hideOSD() else: - self.sendTimeline(state=self.player.STATE_STOPPED) + self.sendTimeline(state=self.player.STATE_STOPPED, ensureFinalTimelineEvent=True) self.stop() return except: @@ -779,7 +881,7 @@ def onClick(self, controlID): if not self._seeking: # we might be reacting to an immediate marker skip while showing a marker with timeout; # in that case, don't show the OSD - if not self._currentMarker or not util.advancedSettings.skipMarkerTimerImmediate or \ + if not self._currentMarker or not util.addonSettings.skipMarkerTimerImmediate or \ self._currentMarker["countdown"] is None: self.showOSD() else: @@ -972,10 +1074,11 @@ def determineSkipStep(self, direction): def skipChapter(self, forward=True, without_osd=False): lastSelectedOffset = self.selectedOffset - util.DEBUG_LOG('chapter skipping from {0} with forward {1}'.format(lastSelectedOffset, forward)) + util.DEBUG_LOG('chapter skipping from {0} with forward {1}', lastSelectedOffset, forward) if forward: nextChapters = [c for c in self.chapters if c.startTime() > lastSelectedOffset] - util.DEBUG_LOG('Found {0} chapters among {1}'.format(len(nextChapters), len(self.chapters))) + util.DEBUG_LOG('Found {0} chapters among {1}', lambda: len(nextChapters), + lambda: len(self.chapters)) if len(nextChapters) == 0: return False chapter = nextChapters[0] @@ -984,16 +1087,17 @@ def skipChapter(self, forward=True, without_osd=False): if startTimeLimit < 0: startTimeLimit = 0 lastChapters = [c for c in self.chapters if c.startTime() <= startTimeLimit] - util.DEBUG_LOG('Found {0} chapters among {1}'.format(len(lastChapters), len(self.chapters))) + util.DEBUG_LOG('Found {0} chapters among {1}', lambda: len(lastChapters), + lambda: len(self.chapters)) if len(lastChapters) == 0: return False chapter = lastChapters[-1] if chapter.tag: - util.DEBUG_LOG('Skipping to chapter: {}'.format(chapter.tag)) + util.DEBUG_LOG('Skipping to chapter: {}', chapter.tag) self.forceNextTimeAsChapter = chapter.tag - util.DEBUG_LOG('New start time is {0}'.format(chapter.startTime())) + util.DEBUG_LOG('New start time is {0}', lambda: chapter.startTime()) self.skipByOffset(chapter.startTime() - lastSelectedOffset, without_osd=without_osd) return True @@ -1064,22 +1168,25 @@ def handleDialog(self, func): self.hasDialog = False def videoSettingsHaveChanged(self): - changed = False - if ( - self.player.video.settings.prefOverrides != self.initialVideoSettings or - self.player.video.selectedAudioStream() != self.initialAudioStream - ): + changed = AttributeDict(video=False, audio=False, subtitle=False, reload=False) + if self.player.video.settings.prefOverrides != self.initialVideoSettings: + changed.video = True + changed.reload = True + if self.player.video.selectedAudioStream() != self.initialAudioStream: + changed.audio = True + if not self.isDirectPlay: + changed.reload = True + + if changed.video or changed.audio: self.initialVideoSettings = dict(self.player.video.settings.prefOverrides) self.initialAudioStream = self.player.video.selectedAudioStream() - changed = True sss = self.player.video.selectedSubtitleStream() if sss != self.initialSubtitleStream: self.initialSubtitleStream = sss - if changed or self.isTranscoded: - return True - else: - return 'SUBTITLE' + changed.subtitle = True + if self.isTranscoded: + changed.reload = True return changed @@ -1123,7 +1230,8 @@ def optionsButtonClicked(self): # Button currently commented out. def subtitleButtonClicked(self): options = [] - options.append({'key': 'download', 'display': T(32405, 'Download Subtitles')}) + if self.isDirectPlay: + options.append({'key': 'download', 'display': T(32405, 'Download Subtitles')}) # select "enable" by default selectIndex = 1 @@ -1177,14 +1285,42 @@ def subtitleButtonClicked(self): if self.handler and self.handler.player and self.handler.player.playerObject \ and util.getSetting('calculate_oshash', False): meta = self.handler.player.playerObject.metadata - oss_hash = util.getOpenSubtitlesHash(meta.size, meta.streamUrls[0]) - if oss_hash: - util.DEBUG_LOG("OpenSubtitles hash: %s" % oss_hash) - util.setGlobalProperty("current_oshash", oss_hash, base='videoinfo.{0}') + if not meta.size: + util.LOG("Can't calculate OpenSubtitles hash because we're transcoding") + + else: + oss_hash = util.getOpenSubtitlesHash(meta.size, meta.streamUrls[0]) + if oss_hash: + util.DEBUG_LOG("OpenSubtitles hash: {}", oss_hash) + util.setGlobalProperty("current_oshash", oss_hash, base='videoinfo.{0}') else: util.setGlobalProperty("current_oshash", '', base='videoinfo.{0}') self.lastSubtitleNavAction = "download" + + # remove the Year info from the current video info tag for better OSS search results + t = self.player.getVideoInfoTag() + changed_info_tag = False + item = xbmcgui.ListItem() + item.setPath(self.player.getPlayingFile()) + if t: + year = t.getYear() + if year: + item.setInfo("video", {"year": 0}) + self.player.updateInfoTag(item) + changed_info_tag = year + builtin.ActivateWindow('SubtitleSearch') + # wait for the window to activate + while not xbmc.getCondVisibility('Window.IsActive(SubtitleSearch)'): + util.MONITOR.waitForAbort(0.1) + # wait for the window to close + while xbmc.getCondVisibility('Window.IsActive(SubtitleSearch)'): + util.MONITOR.waitForAbort(0.1) + + if changed_info_tag: + item.setInfo("video", {"year": changed_info_tag}) + self.player.updateInfoTag(item) + elif choice['key'] == 'delay': self.hideOSD() self.lastSubtitleNavAction = "delay" @@ -1213,6 +1349,8 @@ def toggleSubtitles(self): def disableSubtitles(self): self.player.video.disableSubtitles() self.setSubtitles() + if self.isTranscoded: + self.doSeek(self.trueOffset(), settings_changed=True) def cycleSubtitles(self, forward=True): """ @@ -1221,6 +1359,8 @@ def cycleSubtitles(self, forward=True): stream = self.player.video.cycleSubtitles(forward=forward) self.setSubtitles(honor_forced_subtitles_override=False) util.showNotification(str(stream), time_ms=1500, header=util.T(32396, "Subtitles")) + if self.isTranscoded: + self.doSeek(self.trueOffset(), settings_changed=True) def setSubtitles(self, do_sleep=False, honor_forced_subtitles_override=False): self.handler.setSubtitles(do_sleep=do_sleep, honor_forced_subtitles_override=honor_forced_subtitles_override) @@ -1230,23 +1370,59 @@ def setSubtitles(self, do_sleep=False, honor_forced_subtitles_override=False): util.DEBUG_LOG("Switching embedded subtitle stream, seeking due to Kodi issue #21086") # true offset can be 0, which might lead to an infinite loop, seek to 100ms at least. - self.doSeek(max(self.trueOffset() - 100, 100)) + if self.handler.seekOnStart: + util.DEBUG_LOG("Waiting for seekOnStart to apply: {}", self.handler.seekOnStart) + + waited = 0 + while self.handler.seekOnStart and waited < 20: + xbmc.sleep(100) + waited += 1 + + if waited < 20: + self.doSeek(max(self.trueOffset() - 100, 100)) + return + util.LOG("Tried switching embedded subtitle stream to the correct one, but we've waited too long for " + "seekOnStart.") def showSettings(self): with self.propertyContext('settings.visible'): playersettings.showDialog(self.player.video, via_osd=True, parent=self) changed = self.videoSettingsHaveChanged() + any_changes = any(changed.values()) + + if any_changes: + if not changed.reload: + if changed.subtitle: + self.setSubtitles(do_sleep=False) + self.lastSubtitleNavAction = "forward" + + if changed.audio: + self.handler.setAudioTrack() + + oldTranscoded = self.player.playerObject.metadata.isTranscoded + + # check if we need to restart + self.player.playerObject.rebuild(self.player.video) + + # ping server to update activity/session + self.player.playerObject.getServerDecision() + + if oldTranscoded == self.player.playerObject.metadata.isTranscoded: + # On CoreELEC changing the audio stream causes the audio to stutter or delay + # so this small seek helps sync things back up. But we also need to pause the + # video for a short time if it's playing or the seek doesn't work + if util.isCoreELEC and changed.audio: + if not xbmc.getCondVisibility('Player.Paused'): + self.videoPausedForAudioStreamChange = True + self.handler.player.control('pause') + self.doSeek(offset=((self.handler.player.getTime() * 1000) - 1000)) + return True - if changed == 'SUBTITLE': - self.setSubtitles(do_sleep=False) - self.lastSubtitleNavAction = "forward" - return True - - elif changed: + util.LOG("Media settings have changed and are not directly applicable, restarting video: {}", changed) self.doSeek(self.trueOffset(), settings_changed=True) - else: - return True + return False + return True def setBigSeekShift(self): closest = None @@ -1309,12 +1485,22 @@ def updateProperties(self, **kwargs): self.setFocusId(self.MAIN_BUTTON_ID) self.fromSeek = 0 + v = self.player.video + is_show = v.type == 'episode' + self.setProperty('has.bif', self.bifURL and '1' or '') self.setProperty('video.title', self.title) self.setProperty('video.title2', self.title2) - self.setProperty('is.show', (self.player.video.type == 'episode') and '1' or '') + self.setProperty('is.show', is_show and '1' or '') self.setProperty('media.show_ends', self.showItemEndsInfo and '1' or '') self.setProperty('time.ends_label', self.showItemEndsLabel and (util.T(32543, 'Ends at')) or '') + self.setBoolProperty('no.osd.hide_info', self.no_time_no_osd_spoilers) + + hide_title = False + if is_show and 'no_unwatched_episode_titles' in self.no_spoilers: + hide_title = True + + self.setBoolProperty('hide.title', hide_title) if self.isDirectPlay: self.setProperty('time.fmt', self.timeFmtKodi) @@ -1367,11 +1553,13 @@ def updateChapters(self): if self.showChapters: chaps = [] chapOffsets = [] + thumb_opts = ("blur_chapters" in self.no_spoilers + and {"blur": util.addonSettings.episodeNoSpoilerBlur} or {}) if self.chapters: self.setProperty('chapters.label', T(33605, 'Video Chapters').upper()) for index, chapter in enumerate(self.chapters): thumb = chapter.thumb and chapter.thumb.asTranscodedImageURL( - *PlaylistDialog.LI_AR16X9_THUMB_DIM) or None + *PlaylistDialog.LI_AR16X9_THUMB_DIM, **thumb_opts) or None # mli = kodigui.ManagedListItem(data_source=chapter.startTime(), # thumbnailImage=thumb, # label=chapter.tag or T(33607, 'Chapter {}').format(index + 1)) @@ -1392,8 +1580,8 @@ def updateChapters(self): marker = markerDef["marker"] if marker: if markerDef["marker_type"] == "intro": - preparedMarkers.append((int(marker.startTimeOffset), T(33608, "Intro"), False)) - preparedMarkers.append((int(marker.endTimeOffset), T(33610, "Main"), False)) + preparedMarkers.append((marker.startTimeOffset, T(33608, "Intro"), False)) + preparedMarkers.append((marker.endTimeOffset, T(33610, "Main"), False)) elif markerDef["marker_type"] == "credits": creditsCounter += 1 @@ -1401,7 +1589,7 @@ def updateChapters(self): label = T(33635, "Final Credits") else: label = T(33609, "Credits") + "{}" - preparedMarkers.append((int(marker.startTimeOffset), label, True)) + preparedMarkers.append((marker.startTimeOffset, label, True)) # add staggered virtual markers preparedMarkers.append((int(self.duration * 0.25), "25 %", False)) @@ -1421,7 +1609,12 @@ def updateChapters(self): if skipMarker: continue - chaps.append((offset, self.handler.player.playerObject.getBifUrl(offset), + bifUrl = self.handler.player.playerObject.getBifUrl(offset) + if "blur_chapters" in self.no_spoilers: + bifUrl = self.player.video.server.getImageTranscodeURL(bifUrl, + *PlaylistDialog.LI_AR16X9_THUMB_DIM, + **thumb_opts) + chaps.append((offset, bifUrl, label.format(" #{}".format(credCnt) if credits and creditsCounter > 1 else ""))) if credits: @@ -1458,7 +1651,7 @@ def updateCurrent(self, update_position_control=True, atOffset=None): self.positionControl.setWidth(w) # update cache/buffer bar - if util.advancedSettings.playerShowBuffer and self.isDirectPlay and util.KODI_VERSION_MAJOR > 18: + if util.addonSettings.playerShowBuffer and self.isDirectPlay and util.KODI_VERSION_MAJOR > 18: cache_w = int(xbmc.getInfoLabel("Player.ProgressCache")) * self.SEEK_IMAGE_WIDTH // 100 self.cacheControl.setWidth(cache_w) @@ -1554,33 +1747,6 @@ def seekMouse(self, action, without_osd=False, preview=False): self.updateProgress(set_to_current=False) self.setProperty('button.seek', '1') - def getCurrentMarkerDef(self, offset=None): - """ - Show intro/credits skip button at current time - """ - - if not self.markers: - return - - off = offset if offset is not None else self.trueOffset() - - for markerDef in self.markers: - marker = markerDef["marker"] - if marker: - startTimeOffset = int(marker.startTimeOffset) - - # show intro skip early? (only if intro is during the first X minutes) - if self.showIntroSkipEarly and markerDef["marker_type"] == "intro" and \ - startTimeOffset <= util.advancedSettings.skipIntroButtonShowEarlyThreshold1 * 1000: - startTimeOffset = 0 - markerDef["overrideStartOff"] = 0 - - markerEndNegoff = FINAL_MARKER_NEGOFF if getattr(markerDef["marker"], "final", False) else 0 - - if startTimeOffset - MARKER_SHOW_NEGOFF <= off < int(marker.endTimeOffset) - markerEndNegoff: - - return markerDef - @property def duration(self): @@ -1672,7 +1838,7 @@ def waitForBuffer(self): currentBufferPerc = int(xbmc.getInfoLabel("Player.ProgressCache")) - int(xbmc.getInfoLabel("Player.Progress")) # configured buffer size - bufferBytes = util.kcm.memorySize * 1024 * 1024 + bufferBytes = lib.cache.kcm.memorySize * 1024 * 1024 # wait for the full buffer or for 10% of the file at max # a full buffer is typically 30% of the configured cache value @@ -1693,7 +1859,7 @@ def waitForBuffer(self): wasPlaying = True waitedFor = 0 - waitMax = util.advancedSettings.bufferWaitMax + waitMax = util.addonSettings.bufferWaitMax waitExceeded = False self.waitingForBuffer = True self.showOSD(focusButton=False) @@ -1744,8 +1910,8 @@ def waitForBuffer(self): util.DEBUG_LOG("SeekDialog.buffer: Buffer already filled, not waiting for buffer") else: - wait = util.advancedSettings.bufferInsufficientWait - util.DEBUG_LOG("SeekDialog.buffer: Buffer is too small for us to see, waiting {} seconds".format(wait)) + wait = util.addonSettings.bufferInsufficientWait + util.DEBUG_LOG("SeekDialog.buffer: Buffer is too small for us to see, waiting {} seconds", wait) self.waitingForBuffer = True wasPlaying = False @@ -1761,6 +1927,13 @@ def waitForBuffer(self): self.player.pause() return True + def seekBehind(self): + to = self.trueOffset() + if ((not self.resumeSeekBehindOnlyDP or self.isDirectPlay) + and self.resumeSeekBehind and to > self.resumeSeekBehind): + util.DEBUG_LOG("SeekDialog: Seeking back from {} to {}", to, to - self.resumeSeekBehind) + self.doSeek(to - self.resumeSeekBehind) + def onPlayBackResumed(self): util.DEBUG_LOG("SeekDialog: OnPlaybackResumed") if self._ignoreInput: @@ -1769,8 +1942,15 @@ def onPlayBackResumed(self): self.idleTime = None self.ldTimer and self.syncTimeKeeper() + if self.resumeSeekBehind and not self.resumeSeekBehindPause and ( + not self.resumeSeekBehindAfter or + self.pausedAt and time.time() - self.pausedAt >= self.resumeSeekBehindAfter): + self.seekBehind() + + self.pausedAt = None + def onAVChange(self): - util.DEBUG_LOG("SeekDialog: OnAVChange: DPO: {0}, offset: {1}".format(self.DPPlayerOffset, self.offset)) + util.DEBUG_LOG("SeekDialog: OnAVChange: DPO: {0}, offset: {1}", self.DPPlayerOffset, self.offset) # wait for buffer if we're not expecting a seek if not self.handler.seekOnStart and util.getSetting("slow_connection", False) and not self.waitingForBuffer: @@ -1781,7 +1961,7 @@ def onAVChange(self): return def onAVStarted(self): - util.DEBUG_LOG("SeekDialog: OnAVStarted: DPO: {0}, offset: {1}".format(self.DPPlayerOffset, self.offset)) + util.DEBUG_LOG("SeekDialog: OnAVStarted: DPO: {0}, offset: {1}", self.DPPlayerOffset, self.offset) if self._ignoreInput: self._ignoreInput = False @@ -1796,10 +1976,22 @@ def onPlayBackStarted(self): def onPlayBackPaused(self): util.DEBUG_LOG("SeekDialog: OnPlaybackPaused") + + # Need to resume the video when changing streams on CoreELEC + if util.isCoreELEC and self.videoPausedForAudioStreamChange: + self.videoPausedForAudioStreamChange = False + self.handler.player.control('play') + return + self.idleTime = time.time() + if self.resumeSeekBehindPause and not self.resumeSeekBehindAfter: + self.seekBehind() + return + + self.pausedAt = time.time() def onPlayBackSeek(self, stime, offset): - util.DEBUG_LOG("SeekDialog: OnPlaybackSeek: {0}, {1}".format(stime, offset)) + util.DEBUG_LOG("SeekDialog: OnPlaybackSeek: {0}, {1}", stime, offset) self.idleTime = None self.ldTimer and self.syncTimeKeeper() @@ -1816,7 +2008,7 @@ def onPlayBackFailed(self): self.killTimeKeeper() def syncTimeKeeper(self): - if not not self.handler.player.playerObject: + if not self.handler.player.playerObject: return self.timeKeeperTime = self.trueOffset()#int(self.handler.player.getTime() * 1000) @@ -1844,7 +2036,7 @@ def onTimeKeeperCallback(self, tick=True): if self.stopPlaybackOnIdle: if self.idleTime and time.time() - self.idleTime >= self.stopPlaybackOnIdle: - util.LOG("Player has been idle for {}s, stopping.".format(int(time.time() - self.idleTime))) + util.LOG("Player has been idle for {}s, stopping.", int(time.time() - self.idleTime)) self.handler.player.stopAndWait() return @@ -1882,8 +2074,8 @@ def countingDownMarker(self, val): self._currentMarker["countdown"] = None self.setProperty('marker.countdown', '') - def sendTimeline(self, state=None, t=None, force=True, ensureFinalTimelineEvent=True): - self.handler.updateNowPlaying(force=force, state=state, t=t, overrideChecks=True) + def sendTimeline(self, state=None, t=None, ensureFinalTimelineEvent=True): + self.handler.updateNowPlaying(state=state, t=t, overrideChecks=True) if ensureFinalTimelineEvent: self.handler.ignoreTimelines = True @@ -1905,7 +2097,7 @@ def displayMarkers(self, cancelTimer=False, immediate=False, onlyReturnIntroMD=F # getCurrentMarkerDef might have overridden the startTimeOffset, use that startTimeOff = markerDef["overrideStartOff"] if markerDef["overrideStartOff"] is not None else \ - int(markerDef["marker"].startTimeOffset) + markerDef["marker"].startTimeOffset markerAutoSkip = getattr(self, markerDef["markerAutoSkip"]) @@ -1916,14 +2108,14 @@ def displayMarkers(self, cancelTimer=False, immediate=False, onlyReturnIntroMD=F markerAutoSkipped = markerDef["markerAutoSkipped"] - sTOffWThres = startTimeOff + util.advancedSettings.autoSkipOffset * 1000 + sTOffWThres = startTimeOff + util.addonSettings.autoSkipOffset * 1000 # we just want to return an early marker if we want to autoSkip it, so we can tell the handler to seekOnStart if onlyReturnIntroMD and markerDef["marker_type"] == "intro" and markerAutoSkip: if startTimeOff == 0 and not markerDef["markerAutoSkipped"]: if setSkipped: markerDef["markerAutoSkipped"] = True - return int(markerDef["marker"].endTimeOffset) + MARKER_END_JUMP_OFF + return markerDef["marker"].endTimeOffset + MARKER_END_JUMP_OFF return False if cancelTimer and self.countingDownMarker: @@ -1953,8 +2145,8 @@ def displayMarkers(self, cancelTimer=False, immediate=False, onlyReturnIntroMD=F if getattr(markerDef["marker"], "final", False): # final marker is _not_ at the end of video, seek and do nothing - if int(markerDef["marker"].endTimeOffset) < self.duration - FINAL_MARKER_NEGOFF: - target = int(markerDef["marker"].endTimeOffset) + if markerDef["marker"].endTimeOffset < self.duration - FINAL_MARKER_NEGOFF: + target = markerDef["marker"].endTimeOffset util.DEBUG_LOG( "MarkerAutoSkip: Skipping final marker, its endTime is too early, " "though, seeking and playing back") @@ -1981,8 +2173,8 @@ def displayMarkers(self, cancelTimer=False, immediate=False, onlyReturnIntroMD=F self.stop() return False - util.DEBUG_LOG('MarkerAutoSkip: Skipping marker {}'.format(markerDef["marker"])) - self.doSeek(int(markerDef["marker"].endTimeOffset) + MARKER_END_JUMP_OFF) + util.DEBUG_LOG('MarkerAutoSkip: Skipping marker {}', markerDef["marker"]) + self.doSeek(markerDef["marker"].endTimeOffset + MARKER_END_JUMP_OFF) return True # got a marker, display logic @@ -2014,20 +2206,29 @@ def displayMarkers(self, cancelTimer=False, immediate=False, onlyReturnIntroMD=F # reset countdown on new marker if not self._currentMarker or self._currentMarker != markerDef or markerDef["countdown"] is None: # fixme: round might not be right here, but who cares - markerDef["countdown"] = int(max(round((sTOffWThres - self.trueOffset()) / 1000.0) + 1, 1)) + to = self.trueOffset() + # set the countdown to either the auto skip offset, or, if we're already "inside" the marker time + # area through seeking, at max the difference between the current offset and the end of the + # video + markerDef["countdown"] = int( + max( + round((sTOffWThres - to) / 1000.0) + 1, + min(util.addonSettings.autoSkipOffset, int((self.duration - to) / 1000.0)) + ) + ) isNew = True if self.player.playState == self.player.STATE_PLAYING and not self.osdVisible(): markerDef["countdown"] -= 1 - if isNew: - markerDef["countdown_initial"] = markerDef["countdown"] + if isNew: + markerDef["countdown_initial"] = markerDef["countdown"] self.setProperty('marker.countdown', '1') if markerDef["countdown"] > 0: markerName = "{} ({})".format(markerDef["autoSkipName"], markerDef["countdown"]) else: - markerName = markerDef["autoSkipName"] + markerName = " {} ".format(markerDef["autoSkipName"]) else: markerName = markerDef["name"] self.setProperty('skipMarkerName', markerName) @@ -2057,6 +2258,12 @@ def tick(self, offset=None, waitForBuffer=False): if not cont: return + if (self.pausedAt and self.resumeSeekBehindPause and + time.time() - self.pausedAt >= self.resumeSeekBehindAfter): + self.seekBehind() + self.pausedAt = None + return + # invisibly sync low-drift timer to current playback every X seconds, as Player.getTime() can be wildly off if self.ldTimer and not self.osdVisible() and self.timeKeeper and self.timeKeeper.ticks >= 60: self.syncTimeKeeper() @@ -2115,6 +2322,7 @@ def showPlaylistDialog(self): self.playlistDialog.doModal() self.resetTimeout() self.playlistDialogVisible = False + self.setFocusId(self.PLAYLIST_BUTTON_ID) def osdVisible(self): return xbmc.getCondVisibility('Control.IsVisible(801)') @@ -2146,7 +2354,7 @@ def hideOSD(self, skipMarkerFocus=False, closing=False): self.playlistDialogVisible = False -class PlaylistDialog(kodigui.BaseDialog): +class PlaylistDialog(kodigui.BaseDialog, SpoilersMixin): xmlFile = 'script-plex-video_current_playlist.xml' path = util.ADDON.getAddonInfo('path') theme = 'Main' @@ -2161,6 +2369,7 @@ class PlaylistDialog(kodigui.BaseDialog): def __init__(self, *args, **kwargs): kodigui.BaseDialog.__init__(self, *args, **kwargs) + SpoilersMixin.__init__(self, *args, **kwargs) self.handler = kwargs.get('handler') self.playlist = self.handler.playlist @@ -2172,6 +2381,10 @@ def onFirstInit(self): self.updatePlayingItem() self.setFocusId(self.PLAYLIST_LIST_ID) + def onReInit(self): + self.updatePlayingItem() + self.setFocusId(self.PLAYLIST_LIST_ID) + def onClick(self, controlID): if controlID == self.PLAYLIST_LIST_ID: self.playlistListClicked() @@ -2196,14 +2409,26 @@ def createListItem(self, pi): def createEpisodeListItem(self, episode): label2 = u'{0} \u2022 {1}'.format( episode.grandparentTitle, - u'{0}{1} \u2022 {2}{3}'.format(T(32310, 'S'), episode.parentIndex, T(32311, 'E'), episode.index) + u'{0} \u2022 {1}'.format(T(32310, 'S').format(episode.parentIndex), T(32311, 'E').format(episode.index)) ) - mli = kodigui.ManagedListItem(episode.title, label2, - thumbnailImage=episode.thumb.asTranscodedImageURL(*self.LI_AR16X9_THUMB_DIM), + title = episode.title + thumbnail_opts = {} + no_spoilers = self.getNoSpoilers(episode) + if no_spoilers != "off": + hide_spoilers = self.hideSpoilers(episode) + if hide_spoilers: + if self.noTitles: + title = T(33008, '') + thumbnail_opts = self.getThumbnailOpts(episode, hide_spoilers=hide_spoilers) + + mli = kodigui.ManagedListItem(title, label2, + thumbnailImage=episode.thumb.asTranscodedImageURL(*self.LI_AR16X9_THUMB_DIM, + **thumbnail_opts), data_source=episode) mli.setProperty('track.duration', util.durationToShortText(episode.duration.asInt())) mli.setProperty('video', '1') - mli.setProperty('watched', episode.isWatched and '1' or '') + mli.setProperty('unwatched', not episode.isWatched and '1' or '') + mli.setProperty('watched', episode.isFullyWatched and '1' or '') return mli def createMovieListItem(self, movie): @@ -2212,7 +2437,8 @@ def createMovieListItem(self, movie): data_source=movie) mli.setProperty('track.duration', util.durationToShortText(movie.duration.asInt())) mli.setProperty('video', '1') - mli.setProperty('watched', movie.isWatched and '1' or '') + mli.setProperty('unwatched', not movie.isWatched and '1' or '') + mli.setProperty('watched', movie.isFullyWatched and '1' or '') return mli def playQueueCallback(self, **kwargs): @@ -2245,7 +2471,7 @@ def updatePlayingItem(self): selectIndex = index if selectIndex is not None: - xbmc.executebuiltin('Control.SetFocus({0}, {1})'.format(self.PLAYLIST_LIST_ID, selectIndex)) + self.playlistListControl.setSelectedItemByPos(selectIndex) def fillPlaylist(self): items = [] diff --git a/script.plexmod/lib/windows/settings.py b/script.plexmod/lib/windows/settings.py index 841cae9172..b02f17235b 100644 --- a/script.plexmod/lib/windows/settings.py +++ b/script.plexmod/lib/windows/settings.py @@ -1,15 +1,26 @@ +# coding=utf-8 from __future__ import absolute_import +from __future__ import unicode_literals + +import json +import sys + +import plexnet from kodi_six import xbmc from kodi_six import xbmcgui -from kodi_six import xbmcvfs -from . import kodigui -from . import windowutils +from kodi_six import xbmcaddon +from threading import Timer +import lib.cache from lib import util +from lib import genres +from lib import actions from lib.util import T +from . import kodigui +from . import windowutils -import plexnet -import sys + +UNDEF = "__UNDEF__" class Setting(object): @@ -19,19 +30,52 @@ class Setting(object): desc = None default = None userAware = False + isThemeRelevant = False + backport_from = None def translate(self, val): return str(val) - def get(self): - return util.getSetting(self.ID, self.default) - - def set(self, val): - old = self.get() - setRet = util.setSetting(self.ID, val) - if old != val: - util.DEBUG_LOG('Setting: {0} - changed from [{1}] to [{2}]'.format(self.ID, old, val)) - plexnet.util.APP.trigger('change:{0}'.format(self.ID), value=val) + def get(self, *args, **kwargs): + _id = kwargs.pop("_id", UNDEF) + use_id = _id if _id != UNDEF else self.ID + default = kwargs.pop("default", UNDEF) + use_default = default if default != UNDEF else self.default + + value = util.getSetting(use_id, use_default) + if value == use_default and self.backport_from: + # fallback set and we're on default + old_val = util.getSetting(self.backport_from, DEFAULT) + + # old setting was set + if old_val != DEFAULT: + # get correct old value + old_val_cast = util.getSetting(self.backport_from, use_default) + util.setSetting(self.backport_from, '') + + # old value is different from the new one, set + if old_val_cast != use_default: + self.set(old_val_cast, skip_get=True) + value = old_val_cast + return value + + def emit_events(self, id_, val, **kwargs): + plexnet.util.APP.trigger('change:{0}'.format(id_), value=val) + + def emit_tr_events(self, id_, val, **kwargs): + plexnet.util.APP.trigger('theme_relevant_setting', id=id_, value=val, **kwargs) + + def set(self, val, skip_get=False): + if not skip_get: + old = Setting.get(self) + setRet = util.setSetting(self.ID, val) + if old != val: + util.DEBUG_LOG('Setting: {0} - changed from [{1}] to [{2}]', self.ID, old, val) + self.emit_events(self.ID, val) + if self.isThemeRelevant: + self.emit_tr_events(self.ID, val) + else: + setRet = util.setSetting(self.ID, val) return setRet def valueLabel(self): @@ -42,11 +86,13 @@ def __repr__(self): class BasicSetting(Setting): - def __init__(self, ID, label, default, desc=''): + def __init__(self, ID, label, default, desc='', theme_relevant=False, backport_from=None): self.ID = ID self.label = label self.default = default self.desc = desc + self.isThemeRelevant = theme_relevant + self.backport_from = backport_from def description(self, desc): self.desc = desc @@ -66,8 +112,8 @@ def optionLabels(self): def optionIndex(self): return len(self.options) - 1 - self.get() - def set(self, val): - BasicSetting.set(self, len(self.options) - 1 - val) + def set(self, val, skip_get=False): + BasicSetting.set(self, len(self.options) - 1 - val, skip_get=skip_get) class QualitySetting(ListSetting): @@ -103,32 +149,52 @@ class BoolSetting(BasicSetting): type = 'BOOL' -class BoolUserSetting(BoolSetting): +class UserAwareSetting(BasicSetting): """ A user-aware BoolSetting """ userAware = True + def __init__(self, *args, **kwargs): + super(UserAwareSetting, self).__init__(*args, **kwargs) + util.USER_SETTINGS.append(self.ID) + @property def userAwareID(self): - return '{}.{}'.format(self.ID, plexnet.plexapp.ACCOUNT.ID) + if plexnet.plexapp.ACCOUNT and plexnet.plexapp.ACCOUNT.ID: + return '{}.{}'.format(self.ID, plexnet.plexapp.ACCOUNT.ID) + return 'USER_AWARE' + + def emit_events(self, id_, val, **kwargs): + plexnet.util.APP.trigger('change:{0}'.format(self.ID), key=self.userAwareID, value=val, skey=self.ID) + + def get(self, *args, **kwargs): + _id = kwargs.pop("_id", UNDEF) + default = kwargs.pop("default", UNDEF) + return super(UserAwareSetting, self).get(*args, + _id=_id if _id != UNDEF else self.userAwareID, default=default, + **kwargs) + + def set(self, val, skip_get=False): + if not skip_get: + old = self.get(_id=self.userAwareID) + if old != val: + util.DEBUG_LOG('Setting: {0} - changed from [{1}] to [{2}]', self.userAwareID, old, val) + self.emit_events(self.userAwareID, val) + if self.isThemeRelevant: + self.emit_tr_events(self.userAwareID, val) + return util.setSetting(self.userAwareID, val) - def get(self): - return util.getSetting(self.userAwareID, self.default) - def set(self, val): - old = self.get() - if old != val: - util.DEBUG_LOG('Setting: {0} - changed from [{1}] to [{2}]'.format(self.userAwareID, old, val)) - plexnet.util.APP.trigger('change:{0}'.format(self.ID), key=self.userAwareID, value=val, skey=self.ID) - return util.setSetting(self.userAwareID, val) +class BoolUserSetting(UserAwareSetting, BoolSetting): + pass class OptionsSetting(BasicSetting): type = 'OPTIONS' - def __init__(self, ID, label, default, options): - BasicSetting.__init__(self, ID, label, default) + def __init__(self, ID, label, default, options, **kwargs): + BasicSetting.__init__(self, ID, label, default, **kwargs) self.options = options def translate(self, val): @@ -148,30 +214,104 @@ def optionIndex(self): return 0 -class BufferSetting(OptionsSetting): - def get(self): - return util.kcm.memorySize +DEFAULT = "__DEFAULT__" - def set(self, val): - old = self.get() - if old != val: - util.DEBUG_LOG('Setting: {0} - changed from [{1}] to [{2}]'.format(self.ID, old, val)) - plexnet.util.APP.trigger('change:{0}'.format(self.ID), value=val) - util.kcm.write(memorySize=val) +class MultiOptionsSetting(OptionsSetting): + type = 'MULTI' + valueLabelDelim = ', ' + noneOption = None + def __init__(self, ID, label, default, options, none_option=None, **kwargs): + super(MultiOptionsSetting, self).__init__(ID, label, [], options, **kwargs) + self.default = default + self.noneOption = none_option + util.JSON_SETTINGS.append(self.ID) + + def get(self, *args, **kwargs): + with_default = kwargs.pop('with_default', True) + val = super(MultiOptionsSetting, self).get(*args, default=DEFAULT, **kwargs) + if val and val != DEFAULT: + try: + return json.loads(val) + except json.decoder.JSONDecodeError: + # fallback for legacy settings that weren't json + for o in self.options: + if o[0] == val: + return [val] + elif val == DEFAULT: + # backport old separated options + ret = self.default[:] + for o in self.options: + lval = util.getSetting(o[0], DEFAULT) + # we only support backporting booleans right now + if lval != DEFAULT: + if lval == "true" and o[0] not in self.default: + ret.append(o[0]) + elif lval == "false" and o[0] in self.default: + ret.remove(o[0]) + + if ret != self.default: + self.set(ret, skip_get=True) + return ret + return with_default and self.default or [] + + def set(self, val, skip_get=False): + super(MultiOptionsSetting, self).set(json.dumps(val), skip_get=skip_get) + + def translate(self, val, return_str=False, delim=", "): + if isinstance(val, (list, tuple, set)): + # keep options order + data = [super(MultiOptionsSetting, self).translate(o[0]) for o in self.options if o[0] in val] + if return_str: + return delim.join(data) + return data + return super(MultiOptionsSetting, self).translate(val) + + def valueLabel(self, values=None): + vals = values or self.get() + if vals: + return self.translate(vals, return_str=True, delim=self.valueLabelDelim) + return T(33056, "None") -class ReadFactorSetting(OptionsSetting): - def get(self): - return util.kcm.readFactor + def optionIndex(self): + val = self.get() + ret = [] + for i, o in enumerate(self.options): + if o[0] in val: + ret.append(i) + return ret - def set(self, val): - old = self.get() - if old != val: - util.DEBUG_LOG('Setting: {0} - changed from [{1}] to [{2}]'.format(self.ID, old, val)) - plexnet.util.APP.trigger('change:{0}'.format(self.ID), value=val) - util.kcm.write(readFactor=val) +class MultiUAOptionsSetting(MultiOptionsSetting, UserAwareSetting): + pass + + +class KCMSetting(OptionsSetting): + key = None + + def emit_events(self, id_, val, **kwargs): + plexnet.util.APP.trigger('change:{0}'.format(self.ID), value=val) + + def get(self, *args, **kwargs): + return getattr(lib.cache.kcm, self.key) + + def set(self, val, skip_get=False): + if not skip_get: + old = self.get() + if old != val: + util.DEBUG_LOG('Setting: {0} - changed from [{1}] to [{2}]', self.ID, old, val) + self.emit_events(self.ID, val) + + lib.cache.kcm.write(**{self.key: val}) + + +class BufferSetting(KCMSetting): + key = "memorySize" + + +class ReadFactorSetting(KCMSetting): + key = "readFactor" class InfoSetting(BasicSetting): @@ -245,29 +385,46 @@ class IntegerSetting(BasicSetting): type = 'INTEGER' +class KeySetting(BasicSetting): + type = 'STRING' + + def value_setter(self): + w = SchnorchelDialog() + timeout = Timer(w.timeout, w.close) + timeout.start() + w.doModal() + timeout.cancel() + choice = w.key + del w + return choice + + def get(self, as_code=False, *args, **kwargs): + code = super(KeySetting, self).get(default=None, *args, **kwargs) + if as_code: + return code + + if code is not None and code != "None": + ak = actions.ActionKey(int(code)) + return ak + + class Settings(object): SETTINGS = { 'main': ( T(32000, 'Main'), ( + BoolSetting('kiosk.mode', T(32043, 'Start Plex On Kodi Startup'), False), + OptionsSetting( + 'kiosk.delay', T(33651, 'Start Delay'), + 0, + [(0, T(32481))] + [ + (a, T(33091).format(sec_or_ms=a, unit_s_or_ms="s")) for a in + list(range(1, 11, 1)) + list(range(15, 125, 5))] + ), BoolSetting( 'auto_signin', T(32038, 'Automatically Sign In'), False ).description( T(32100, 'Skip user selection and pin entry on startup.') ), - BoolSetting( - 'speedy_home_hubs2', T(33503, 'Use alternative hubs refresh'), False - ).description( - T( - 33504, - "Refreshes all hubs for all libraries after an item's watch-state has changed, instead of " - "only those likely affected. Use this if you find a hub that doesn't update properly." - ) - ), - BoolSetting( - 'hubs_bifurcation_lines', T(32961, 'Show hub bifurcation lines'), False - ).description( - T(32962, "Visually separate hubs horizontally using a thin line.") - ), BoolSetting( 'search_use_kodi_kbd', T(32955, 'Use Kodi keyboard for searching'), False ), @@ -286,21 +443,27 @@ class Settings(object): QualitySetting('local_quality', T(32020, 'Local Quality'), 13), QualitySetting('remote_quality', T(32021, 'Remote Quality'), 13), QualitySetting('online_quality', T(32022, 'Online Quality'), 13), - BoolSetting('playback_directplay', T(32025, 'Allow Direct Play'), True), - BoolSetting('playback_remux', T(32026, 'Allow Direct Stream'), True).description( - T(32979, 'Allows the server to only transcode streams of a video that need transcoding,' - ' while streaming the others unaltered. If disabled, force the server to transcode ' - 'everything not direct playable.') - ), - BoolSetting('allow_4k', T(32036, 'Allow 4K'), True).description( - T(32102, 'Enable this if your hardware can handle 4K playback. Disable it to force transcoding.') - ), - BoolSetting('allow_hevc', T(32037, 'Allow HEVC (h265)'), True).description( - T(32103, 'Enable this if your hardware can handle HEVC/h265. Disable it to force transcoding.') - ), - BoolSetting('allow_vc1', T(32977, 'Allow VC1'), True).description( - T(32978, 'Enable this if your hardware can handle VC1. Disable it to force transcoding.') - ) + MultiOptionsSetting( + 'playback_features', T(33058, ''), + ["playback_directplay", "playback_remux", "allow_4k"], + ( + ('playback_directplay', T(32025, '')), + ('playback_remux', T(32026, '')), + ('allow_4k', T(32036, '')), + ) + ).description(T(33060, "").format( + feature_ds=T(32026, ''), + desc_ds=T(32979, ''), + feature_4k=T(32036, ''), + desc_4k=T(32102, ''))), + MultiOptionsSetting( + 'allowed_codecs', T(33059, ''), + ["allow_hevc", "allow_vc1"], + [ + ('allow_hevc', T(32037, '')), + ('allow_vc1', T(32977, '')), + ] + ([('allow_av1', T(32601, ''))] if util.KODI_VERSION_MAJOR >= 20 else []) + ).description(T(33061, "")), ) ), 'audio': ( @@ -320,8 +483,10 @@ class Settings(object): ( ('never', T(32033, 'Never')), ('always', T(32028, 'Always')), - ('2', '2.1+'), - ('5', '5.1+'), + ('2', '>2.0'), + ('3', '>2.1'), + ('5', '>5.0'), + ('6', '>5.1'), ) ).description( T(32063, 'Transcode audio to AC3 in certain conditions (useful for passthrough).') @@ -331,6 +496,10 @@ class Settings(object): T(32065, 'When force AC3 settings are enabled, treat DTS the same as AC3 ' '(useful for Optical passthrough)') ), + BoolSetting('audio_hires', T(33079, ''), + True).description( + T(33080, '') + ), OptionsSetting( 'burn_subtitles', T(32031, 'Burn-in Subtitles'), @@ -357,30 +526,142 @@ class Settings(object): ), ) ), + 'ui': ( + T(32467, 'User Interface'), ( + OptionsSetting( + 'theme', + T(32983, 'Theme'), + util.DEF_THEME, + ( + ('modern', T(32985, 'Modern')), + ('modern-dotted', T(32986, 'Modern (dotted)')), + ('modern-colored', T(32989, 'Modern (colored)')), + ('classic', T(32987, 'Classic')), + ('custom', T(32988, 'Custom')), + ), theme_relevant=True + ).description( + T(32984, 'stub') + ), + OptionsSetting( + 'watched_indicators', T(33022, ''), + "modern_2024", + ( + ('classic', T(32987, 'Classic')), + ('modern', T(32985, 'Modern')), + ('modern_2024', T(33076, 'Modern (2024)')), + ), + theme_relevant=True + ).description( + T(33023, "") + ), + BoolSetting( + 'hide_aw_bg', T(33024, ''), False, theme_relevant=True + ).description( + T(33025, "") + ), + BoolSetting( + 'scale_indicators', T(33077, ''), True, theme_relevant=True + ).description( + T(33078, "") + ), + MultiOptionsSetting( + 'no_episode_spoilers3', T(33006, ''), + ['unwatched'], + ( + ('unwatched', T(33010, '')), + ('in_progress', T(33011, '')), + ('no_unwatched_episode_titles', T(33012, '')), + ('blur_chapters', T(33081, '')), + ) + ).description(T(33007, "")), + MultiOptionsSetting( + 'spoilers_allowed_genres2', T(33016, ''), + ["Reality", "Game Show", "Documentary", "Sport"], + [(g, g) for g in genres.GENRES_TV] + ).description(T(33017, "")), + BoolSetting( + 'hubs_use_new_continue_watching', T(32998, ''), False + ).description( + T(32999, "") + ), + BoolSetting( + 'hubs_round_robin', T(33043, ''), False + ).description( + T(33044, "").format(util.addonSettings.hubsRrMax) + ), + BoolSetting( + 'hubs_bifurcation_lines', T(32961, 'Show hub bifurcation lines'), False + ).description( + T(32962, "Visually separate hubs horizontally using a thin line.") + ), + BoolSetting( + 'path_mapping_indicators', T(33032, 'Show path mapping indicators'), True + ).description( + T(33033, "When path mapping is active for a library, display an indicator.") + ), + KeySetting('map_button_home', T(33085), None).description(T(33087)) + ) + ), 'player': ( T(32940, 'Player UI'), ( - BoolSetting('subtitle_downloads', T(32932, 'Show subtitle quick-actions button'), False).description( - T(32939, 'Only applies to video player UI')), - BoolSetting('video_show_ffwdrwd', T(32933, 'Show FFWD/RWD buttons'), False).description( - T(32939, 'Only applies to video player UI')), - BoolSetting('video_show_repeat', T(32934, 'Show repeat button'), False).description( - T(32939, 'Only applies to video player UI')), - BoolSetting('video_show_shuffle', T(32935, 'Show shuffle button'), False).description( - T(32939, 'Only applies to video player UI')), + BoolSetting('player_official', T(33045, 'Behave like official Plex clients'), True).description( + T(33046, '')), + BoolSetting('no_osd_time_spoilers', T(33004, ''), False, backport_from="no_spoilers").description( + T(33005, '')), + MultiUAOptionsSetting( + 'player_show_buttons', T(33057, 'Show buttons'), + ['subtitle_downloads', 'skip_intro', 'skip_credits'], + ( + ('subtitle_downloads', T(32932, 'Show subtitle quick-actions button')), + ('video_show_ffwdrwd', T(32933, 'Show FFWD/RWD buttons')), + ('video_show_repeat', T(32934, 'Show repeat button')), + ('video_show_shuffle', T(32935, 'Show shuffle button')), + ('skip_intro', T(32495, 'Skip Intro')), + ('skip_credits', T(32496, 'Skip Credits')), + ) + ).description(T(32939, 'Only applies to video player UI')), OptionsSetting( 'video_show_playlist', T(32936, 'Show playlist button'), 'eponly', ( - ('always', T(32035, 'Always')), ('eponly', T(32938, 'Only for Episodes')), + ('always', T(32035, 'Always')), ('eponly', T(32938, 'Only for Episodes/Playlists')), ('never', T(32033, 'Never')) ) - ).description(T(32939, 'Only applies to video player UI')), + ).description(T(33088, 'Only applies to video player UI')), OptionsSetting( 'video_show_prevnext', T(32937, 'Show prev/next button'), 'eponly', ( - ('always', T(32035, 'Always')), ('eponly', T(32938, 'Only for Episodes')), + ('always', T(32035, 'Always')), ('eponly', T(32938, 'Only for Episodes/Playlists')), ('never', T(32033, 'Never')) ) - ).description(T(32939, 'Only applies to video player UI')), + ).description(T(33088, 'Only applies to video player UI')), + OptionsSetting( + 'resume_seek_behind', T(33089, ''), 0, + [(0, T(32481))] + [ + (a, T(33091).format(sec_or_ms=a if a < 1000 else int(a / 1000), + unit_s_or_ms="ms" if a < 1000 else "s")) for a in + [100] + list(range(250, 1000, 250)) + list(range(1000, 61000, 1000))] + ).description(T(33090, '')), + BoolSetting('resume_seek_behind_pause', T(33092, ''), False).description( + T(33095, '')), + OptionsSetting( + 'resume_seek_behind_after', T(33093, ''), 0, + [(0, T(32481))] + [ + (a, T(33091).format(sec_or_ms=a if a < 1000 else int(a / 1000), + unit_s_or_ms="ms" if a < 1000 else "s")) for a in + list(range(250, 1000, 250)) + list(range(1000, 61000, 1000))] + ).description(T(33094, '')), + BoolSetting('resume_seek_behind_onlydp', T(33096, ''), True).description( + T(33097, '')), + OptionsSetting( + 'player_stop_on_idle', + T(32946, 'Stop video playback on idle after'), + 0, + ((0, T(32033, 'Never')), (30, '30s'), (60, '1m'), (120, '2m'), (300, '5m'), (600, '10m'), + (900, '15m'), (1200, '20m'), (1800, '30m'), (2700, '45m'), (3600, '1h'),) + ), + BoolSetting( + 'player_stop_on_screensaver', T(32947, 'Stop video playback on screensaver'), False + ), ) ), 'player_user': ( @@ -408,8 +689,11 @@ class Settings(object): T( 32101, "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatical" - "ly be played after a 15 second delay." - ) + "ly be played after a {} second delay." + ).format(util.addonSettings.postplayTimeout) + ), + BoolUserSetting( + 'post_play_never', T(33652, 'Never show Post Play'), False ), BoolUserSetting( 'binge_mode', T(33618, 'TV binge-viewing mode'), False @@ -467,6 +751,12 @@ class Settings(object): ) ), BoolSetting('gdm_discovery', T(32042, 'Server Discovery (GDM)'), False), + OptionsSetting( + 'handle_plexdirect', T(32990), 'ask', + (('ask', T(32991)), ('always', T(32035)), ('never', T(32033))) + ).description( + T(32992, 'stub') + ), IPSetting('manual_ip_0', T(32044, 'Connection 1 IP'), ''), IntegerSetting('manual_port_0', T(32045, 'Connection 1 Port'), 32400), IPSetting('manual_ip_1', T(32046, 'Connection 2 IP'), ''), @@ -476,33 +766,35 @@ class Settings(object): 'system': ( T(33600, 'System'), ( - BoolSetting('kiosk.mode', T(32043, 'Start Plex On Kodi Startup'), False), BoolSetting('exit_default_is_quit', T(32965, 'Start Plex On Kodi Startup'), False) .description(T(32966, "stub")), + BoolSetting('path_mapping', T(33000, ''), True).description(T(33001, '')), BufferSetting('cache_size', T(33613, 'Kodi Buffer Size (MB)'), 20, - [(mem, '{} MB'.format(mem)) for mem in util.kcm.viableOptions]) + [(mem, '{} MB'.format(mem)) for mem in lib.cache.kcm.viableOptions]) .description( '{}{}'.format(T(33614, 'stub1').format( - util.kcm.free, util.kcm.recMax), - '' if util.kcm.useModernAPI else ' '+T(32954, 'stub2')) - ), + lib.cache.kcm.free, lib.cache.kcm.recMax), + '' if lib.cache.kcm.useModernAPI else ' ' + T(32954, 'stub2')) + ) if not util.FROM_KODI_REPOSITORY or lib.cache.kcm.useModernAPI else None, ReadFactorSetting('readfactor', T(32922, 'Kodi Cache Readfactor'), 4, - [(rf, str(rf) if rf > 0 else T(32976, 'stub')) for rf in util.kcm.readFactorOpts]) + [(rf, str(rf) if rf > 0 else T(32976, 'stub')) for rf in lib.cache.kcm.readFactorOpts]) .description( T(32923, 'Sets the Kodi cache readfactor value. Default: {0}, recommended: {1}.' 'With "Slow connection" enabled this will be set to {2}, as otherwise the cache doesn\'t' - 'fill fast/aggressively enough.').format(util.kcm.defRF, - util.kcm.recRFRange, - util.kcm.defRFSM) - ), + 'fill fast/aggressively enough.').format(lib.cache.kcm.defRF, + lib.cache.kcm.recRFRange, + lib.cache.kcm.defRFSM) + ) if not util.FROM_KODI_REPOSITORY or lib.cache.kcm.useModernAPI else None, BoolSetting( 'slow_connection', T(32915, 'Slow connection'), False - ).description("Use with a wonky/slow connection, e.g. in a hotel room. Adjusts the UI to visually " - "wait for item refreshes and waits for the buffer to fill when starting playback."), + ).description(T(32916, "Use with a wonky/slow connection, " + "e.g. in a hotel room. Adjusts the UI to visually " + "wait for item refreshes and waits for the buffer to fill when starting " + "playback.")), OptionsSetting( 'action_on_sleep', T(32700, 'Action on Sleep event'), @@ -514,16 +806,14 @@ class Settings(object): ('cecstandby', T(32705, 'CEC Standby')), ('logoff', T(32421, 'Sign Out'))) ).description(T(32701, 'When Kodi receives a sleep event from the system, run the following action.')), OptionsSetting( - 'player_stop_on_idle', - T(32946, 'Stop video playback on idle after'), - 0, - ((0, T(32033, 'Never')), (30, '30s'), (60, '1m'), (120, '2m'), (300, '5m'), (600, '10m'), - (900, '15m'), (1200, '20m'), (1800, '30m'), (2700, '45m'), (3600, '1h'),) - ), - BoolSetting( - 'player_stop_on_screensaver', T(32947, 'Stop video playback on screensaver'), True - ), + 'action_on_wake', + T(33070, 'Action on Wake event'), + util.isCoreELEC and 'wait_5' or 'wait_1', + [('none', T(32702, 'Nothing')), ('restart', T(33071, 'Restart PM4K'))] + + [('wait_{}'.format(s), T(33072, '').format(s)) for s in [1, 2, 3] + list(range(5, 65, 5))] + ).description(T(33075, '')), BoolSetting('debug', T(32024, 'Debug Logging'), False), + BoolSetting('dump_config', T(33642, 'Debug Logging'), False).description(T(33643)), ) ), 'privacy': ( @@ -545,24 +835,12 @@ class Settings(object): ), } - SECTION_IDS = ('main', 'video', 'audio', 'player', 'player_user', 'network', 'system', 'about') + SECTION_IDS = ('main', 'video', 'audio', 'ui', 'player', 'player_user', 'network', 'system', 'about') def __getitem__(self, key): return self.SETTINGS[key] -# enable AV1 setting if kodi nexus -if util.KODI_VERSION_MAJOR >= 20: - videoSettings = list(Settings.SETTINGS["video"]) - videoSettings[1] = tuple(list(videoSettings[1]) + [ - BoolSetting('allow_av1', T(32601, 'Allow AV1'), False).description( - T(32602, - 'Enable this if your hardware can handle AV1. Disable it to force transcoding.') - ) - ]) - Settings.SETTINGS["video"] = (videoSettings[0], videoSettings[1]) - - class SettingsWindow(kodigui.BaseWindow, windowutils.UtilMixin): xmlFile = 'script-plex-settings.xml' path = util.ADDON.getAddonInfo('path') @@ -595,10 +873,16 @@ def onAction(self, action): try: self.checkSection() controlID = self.getFocusId() - if action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): - if self.getFocusId() == self.OPTIONS_LIST_ID: + if action in (xbmcgui.ACTION_STOP, xbmcgui.ACTION_CONTEXT_MENU): + self.editSetting(clear=True) + return + elif action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): + if controlID == self.OPTIONS_LIST_ID: self.setFocusId(self.SETTINGS_LIST_ID) return + elif controlID == self.SETTINGS_LIST_ID: + self.setFocusId(self.SECTION_LIST_ID) + return # elif not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format(self.TOP_GROUP_ID)): # self.setFocusId(self.TOP_GROUP_ID) # return @@ -632,7 +916,7 @@ def checkSection(self): self.lastSection = mli.dataSource self.showSettings(self.lastSection) self.setProperty('section.about', self.lastSection == 'about' and '1' or '') - util.DEBUG_LOG('Settings: Changed section ({0})'.format(self.lastSection)) + util.DEBUG_LOG('Settings: Changed section ({0})', self.lastSection) def showSections(self): items = [] @@ -640,6 +924,7 @@ def showSections(self): label = self.settings[sectionID][0] item = kodigui.ManagedListItem(label, data_source=sectionID) items.append(item) + items[-1].setProperty('is.last', '1') self.sectionList.addItems(items) @@ -650,7 +935,11 @@ def showSettings(self, section): items = [] for setting in settings: - item = kodigui.ManagedListItem(setting.label, setting.type != 'BOOL' and setting.valueLabel() or '', data_source=setting) + if setting is None: + continue + + item = kodigui.ManagedListItem(setting.label, setting.type != 'BOOL' and setting.valueLabel() or '', + data_source=setting) item.setProperty('description', setting.desc) if setting.type == 'BOOL': item.setProperty('checkbox', '1') @@ -666,14 +955,17 @@ def showSettings(self, section): self.settingsList.reset() self.settingsList.addItems(items) - def editSetting(self, from_right=False): + def editSetting(self, from_right=False, clear=False): mli = self.settingsList.getSelectedItem() if not mli: return setting = mli.dataSource - if setting.type in ('LIST', 'OPTIONS'): + if clear and setting.type != 'STRING': + return + + if setting.type in ('LIST', 'OPTIONS', 'MULTI'): self.fillList(setting) elif setting.type == 'BOOL' and not from_right: self.toggleBool(mli, setting) @@ -681,6 +973,8 @@ def editSetting(self, from_right=False): self.editIP(mli, setting) elif setting.type == 'INTEGER' and not from_right: self.editInteger(mli, setting) + elif setting.type == 'STRING' and not from_right: + self.editString(mli, setting, clear=clear) elif setting.type == 'BUTTON': self.buttonDialog(mli, setting) @@ -701,21 +995,43 @@ def changeSetting(self): elif setting.type == 'OPTIONS': setting.set(optionItem.dataSource) mli.setLabel2(setting.valueLabel()) + elif setting.type == 'MULTI': + values = setting.get() + if optionItem.dataSource in values: + values.remove(optionItem.dataSource) + optionItem.setProperty('checkbox.checked', '') + else: + values.append(optionItem.dataSource) + optionItem.setProperty('checkbox.checked', '1') + setting.set(values) + mli.setLabel2(setting.valueLabel(values=values)) - self.setFocusId(self.SETTINGS_LIST_ID) + if setting.type != 'MULTI': + self.setFocusId(self.SETTINGS_LIST_ID) def fillList(self, setting): + mli = self.settingsList.getSelectedItem() + if not mli: + return + items = [] if setting.type == 'LIST': for label in setting.optionLabels(): items.append(kodigui.ManagedListItem(label)) - elif setting.type == 'OPTIONS': + elif setting.type in ('OPTIONS', 'MULTI'): for ID, label in setting.options: items.append(kodigui.ManagedListItem(label, data_source=ID)) self.optionsList.reset() self.optionsList.addItems(items) - self.optionsList.selectItem(setting.optionIndex()) + idx = setting.optionIndex() + if isinstance(idx, int): + idx = [idx] + for _idx in idx: + if setting.type == 'MULTI': + self.optionsList[_idx].setProperty('checkbox.checked', '1') + if idx: + self.optionsList.selectItem(idx[-1]) self.setFocusId(self.OPTIONS_LIST_ID) def toggleBool(self, mli, setting): @@ -750,6 +1066,80 @@ def editInteger(self, mli, setting): setting.set(int(result)) mli.setLabel2(result) + def editString(self, mli, setting, clear=False): + if clear: + setting.set(None) + mli.setLabel2(T(32447, "None")) + return + if hasattr(setting, "value_setter"): + result = setting.value_setter() + if result is not None: + setting.set(result.code) + mli.setLabel2(str(result)) + return + else: + result = xbmcgui.Dialog().input(T(32417, 'Enter Port Number'), str(setting.get()), xbmcgui.INPUT_STRING) + if result is None: + return + elif result == -1: + setting.set(None) + return + + setting.set(result) + mli.setLabel2(str(result)) + + +class SchnorchelDialog(xbmcgui.WindowXMLDialog): + """ + inspired by https://github.com/pkscout/script.keymap/blob/main/editor.py + """ + + def __new__(cls, *args, **kwargs): + gui_api = tuple(map(int, xbmcaddon.Addon('xbmc.gui').getAddonInfo('version').split('.'))) + file_name = "DialogNotification.xml" if gui_api >= (5, 11, 0) else "DialogKaiToast.xml" + return super(SchnorchelDialog, cls).__new__(cls, file_name, "") + + def __init__(self, timeout=10): + self.key = None + self.timeout = timeout + self._winID = None + + self.setProperty("no.image", "1") + + def onInit(self): + ctrl1, ctrl2 = 401, 402 + if util.SKIN_PLEXTUARY: + ctrl1, ctrl2 = 1401, 1402 + try: + self.getControl(ctrl1).addLabel(T(33085)) + self.getControl(ctrl2).addLabel(T(33086).format(self.timeout)) + except AttributeError: + self.getControl(ctrl1).setLabel(T(33085)) + self.getControl(ctrl2).setLabel(T(33086).format(self.timeout)) + + def setProperty(self, key, value): + if not self._winID: + self._winID = xbmcgui.getCurrentWindowId() + + try: + xbmcgui.Window(self._winID).setProperty(key, value) + xbmcgui.WindowXML.setProperty(self, key, value) + except RuntimeError: + xbmc.log('kodigui.BaseWindow.setProperty: Missing window', xbmc.LOGDEBUG) + + def onAction(self, action): + code = action.getButtonCode() + action_id = action.getId() + self.key = None + if action_id not in (xbmcgui.ACTION_SELECT_ITEM, xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): + self.key = None if code == 0 else actions.ActionKey(code) + elif action_id in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_PREVIOUS_MENU): + self.key = None + else: + self.key = -1 + self.close() + return + class SelectDialog(kodigui.BaseDialog, util.CronReceiver): xmlFile = 'script-plex-settings_select_dialog.xml' diff --git a/script.plexmod/lib/windows/signin.py b/script.plexmod/lib/windows/signin.py index 444933662d..d7a13eae49 100644 --- a/script.plexmod/lib/windows/signin.py +++ b/script.plexmod/lib/windows/signin.py @@ -1,7 +1,9 @@ from __future__ import absolute_import + from kodi_six import xbmcgui -from . import kodigui + from lib import util +from . import kodigui class Background(kodigui.BaseWindow): @@ -81,6 +83,8 @@ def onAction(self, action): if action == xbmcgui.ACTION_SELECT_ITEM: self.doSignin = True self.doClose() + elif action in (xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK): + self.doClose() def onClick(self, controlID): if controlID == self.SIGNIN_BUTTON_ID: diff --git a/script.plexmod/lib/windows/slidehshow.py b/script.plexmod/lib/windows/slidehshow.py index d25f8b670b..c4a2d51dad 100644 --- a/script.plexmod/lib/windows/slidehshow.py +++ b/script.plexmod/lib/windows/slidehshow.py @@ -1,10 +1,11 @@ -import time import random +import time -from . import kodigui +from plexnet import plexapp from lib import util -from plexnet import plexapp +from . import kodigui + class Slideshow(kodigui.BaseWindow, util.CronReceiver): xmlFile = 'script-plex-slideshow.xml' @@ -25,7 +26,7 @@ def __init__(self, *args, **kwargs): self.timeBetweenImages = self.TIME_BETWEEN_IMAGES self.timeBetweenDisplayMove = self.TIME_DISPLAY_MOVE self.timeTitleIsHidden = self.TIME_HIDE_TITLE_IN_QUIZ - self.quizMode = util.advancedSettings.screensaverQuiz + self.quizMode = util.addonSettings.screensaverQuiz self.initialized = False def onFirstInit(self): @@ -65,7 +66,7 @@ def tick(self): if nextIndex >= len(self.images): if self.selectedServer != None: self.images = self.selectedServer.library.randomArts(); - util.DEBUG_LOG('[SS] Fetched {0} items'.format(len(self.images))) + util.DEBUG_LOG('[SS] Fetched {0} items', lambda: len(self.images)) nextIndex = 0 if len(self.images) == 0: diff --git a/script.plexmod/lib/windows/subitems.py b/script.plexmod/lib/windows/subitems.py index 915ec15f11..d55064ada1 100644 --- a/script.plexmod/lib/windows/subitems.py +++ b/script.plexmod/lib/windows/subitems.py @@ -1,31 +1,29 @@ from __future__ import absolute_import + import gc from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui +from plexnet import playlist -from lib import util from lib import metadata from lib import player - -from plexnet import playlist - +from lib import util +from lib.util import T from . import busy +from . import dropdown from . import episodes -from . import tracks -from . import opener from . import info +from . import kodigui from . import musicplayer -from . import videoplayer -from . import dropdown -from . import windowutils -from . import search +from . import opener from . import pagination from . import playbacksettings - -from lib.util import T -from .mixins import SeasonsMixin, DeleteMediaMixin, RatingsMixin +from . import search +from . import tracks +from . import videoplayer +from . import windowutils +from .mixins import SeasonsMixin, DeleteMediaMixin, RatingsMixin, PlaybackBtnMixin class RelatedPaginator(pagination.BaseRelatedPaginator): @@ -34,7 +32,7 @@ def getData(self, offset, amount): class ShowWindow(kodigui.ControlledWindow, windowutils.UtilMixin, SeasonsMixin, DeleteMediaMixin, RatingsMixin, - playbacksettings.PlaybackSettingsMixin): + PlaybackBtnMixin, playbacksettings.PlaybackSettingsMixin): xmlFile = 'script-plex-seasons.xml' path = util.ADDON.getAddonInfo('path') theme = 'Main' @@ -69,6 +67,7 @@ def __init__(self, *args, **kwargs): kodigui.ControlledWindow.__init__(self, *args, **kwargs) SeasonsMixin.__init__(*args, **kwargs) DeleteMediaMixin.__init__(*args, **kwargs) + PlaybackBtnMixin.__init__(self, *args, **kwargs) self.mediaItem = kwargs.get('media_item') self.parentList = kwargs.get('parent_list') self.cameFrom = kwargs.get('came_from') @@ -76,6 +75,7 @@ def __init__(self, *args, **kwargs): self.exitCommand = None self.lastFocusID = None self.lastNonOptionsFocusID = None + self.manuallySelectedSeason = False self.initialized = False self.relatedPaginator = None @@ -106,6 +106,9 @@ def onInit(self): player.PLAYER.playBackgroundMusic(self.mediaItem.theme.asURL(True), volume, self.mediaItem.ratingKey) + def onReInit(self): + PlaybackBtnMixin.onReInit(self) + def setup(self): self.mediaItem.reload(includeExtras=1, includeExtrasCount=10, includeOnDeck=1) @@ -127,6 +130,10 @@ def updateProperties(self): self.setProperty('duration', util.durationToText(self.mediaItem.fixedDuration())) self.setProperty('info', '') self.setProperty('date', self.mediaItem.year) + if not self.mediaItem.isWatched: + self.setProperty('unwatched.count', str(self.mediaItem.unViewedLeafCount) or '') + else: + self.setBoolProperty('watched', self.mediaItem.isWatched) self.setProperty('extras.header', T(32305, 'Extras')) self.setProperty('related.header', T(32306, 'Related Shows')) @@ -136,7 +143,7 @@ def updateProperties(self): elif self.mediaItem.studio: self.setProperty('directors', u'{0} {1}'.format(T(32386, 'Studio').upper(), self.mediaItem.studio)) - cast = u' / '.join([r.tag for r in self.mediaItem.roles()][:5]) + cast = self.mediaItem.roles and u' / '.join([r.tag for r in self.mediaItem.roles()][:5]) or '' castLabel = T(32419, 'Cast').upper() self.setProperty('writers', cast and u'{0} {1}'.format(castLabel, cast) or '') @@ -171,7 +178,10 @@ def onAction(self, action): if not controlID and self.lastFocusID and not action == xbmcgui.ACTION_MOUSE_MOVE: self.setFocusId(self.lastFocusID) - if action == xbmcgui.ACTION_CONTEXT_MENU: + if controlID == self.SUB_ITEM_LIST_ID and action in (xbmcgui.ACTION_MOVE_LEFT, xbmcgui.ACTION_MOVE_RIGHT): + self.manuallySelectedSeason = True + + elif action == xbmcgui.ACTION_CONTEXT_MENU: if controlID == self.SUB_ITEM_LIST_ID: self.optionsButtonClicked(from_item=True) return @@ -185,10 +195,10 @@ def onAction(self, action): self.lastNonOptionsFocusID = None return - elif action in(xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_CONTEXT_MENU): + elif action in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_CONTEXT_MENU): if not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format( self.OPTIONS_GROUP_ID)) and \ - (not util.advancedSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU): + (not util.addonSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU): if self.getProperty('on.extras'): self.setFocusId(self.OPTIONS_GROUP_ID) return @@ -400,14 +410,18 @@ def infoButtonClicked(self): util.garbageCollect() def playButtonClicked(self, shuffle=False): + if self.playBtnClicked: + return + items = self.mediaItem.all() pl = playlist.LocalPlaylist(items, self.mediaItem.getServer()) resume = False if not shuffle and self.mediaItem.type == 'show': - resume = self.getPlaylistResume(pl, items, self.mediaItem.title) + resume = self.getNextShowEp(pl, items, self.mediaItem.title) if resume is None: return + self.playBtnClicked = True pl.shuffle(shuffle, first=True) videoplayer.play(play_queue=pl, resume=resume) @@ -487,7 +501,11 @@ def optionsButtonClicked(self, from_item=None): if self.delete(item): # cheap way of requesting a home hub refresh because of major deletion util.MONITOR.watchStatusChanged() - self.goHome() + self.initialized = False + self.setBoolProperty("initialized", False) + self.setup() + self.initialized = True + self.setFocusId(self.PLAY_BUTTON_ID) def roleClicked(self): mli = self.rolesListControl.getSelectedItem() @@ -524,7 +542,14 @@ def getRoleItemDDPosition(self): if xbmc.getCondVisibility('Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)'): y -= 500 - focus = int(xbmc.getInfoLabel('Container(401).Position')) + tries = 0 + focus = xbmc.getInfoLabel('Container(401).Position') + while tries < 2 and focus == '': + focus = xbmc.getInfoLabel('Container(401).Position') + xbmc.sleep(250) + tries += 1 + + focus = int(focus) x = ((focus + 1) * 304) - 100 return x, y @@ -542,7 +567,7 @@ def createListItem(self, obj): @busy.dialog() def fill(self, update=False): - self.fillSeasons(self.mediaItem, update=update) + self.fillSeasons(self.mediaItem, update=update, do_focus=not self.manuallySelectedSeason) def fillExtras(self): items = [] diff --git a/script.plexmod/lib/windows/tracks.py b/script.plexmod/lib/windows/tracks.py index 90dc430436..c94baf3233 100644 --- a/script.plexmod/lib/windows/tracks.py +++ b/script.plexmod/lib/windows/tracks.py @@ -1,21 +1,19 @@ from __future__ import absolute_import + from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui - -from lib import colors -from lib import util - from plexnet import playlist +from lib import util +from lib.util import T +from lib import player from . import busy -from . import musicplayer from . import dropdown -from . import windowutils +from . import kodigui +from . import musicplayer from . import opener from . import search - -from lib.util import T +from . import windowutils class AlbumWindow(kodigui.ControlledWindow, windowutils.UtilMixin): @@ -48,21 +46,41 @@ def __init__(self, *args, **kwargs): self.parentList = kwargs.get('parentList') self.albums = None self.exitCommand = None + self.lastPlayingRK = None def onFirstInit(self): self.trackListControl = kodigui.ManagedControlList(self, self.TRACKS_LIST_ID, 5) self.setup() self.setFocusId(self.TRACKS_LIST_ID) + player.PLAYER.on('started.audio', self.onPlayingTrackChanged) try: self.checkForHeaderFocus(xbmcgui.ACTION_MOVE_DOWN) except AttributeError: raise util.NoDataException + def onReInit(self): + if self.lastPlayingRK: + self.selectTrack(self.lastPlayingRK) + + def onPlayingTrackChanged(self, *args, **kwargs): + self.lastPlayingRK = util.getGlobalProperty("track.ID") + def setup(self): self.updateProperties() self.fillTracks() + def doClose(self): + player.PLAYER.off('started.audio', self.onPlayingTrackChanged) + kodigui.ControlledWindow.doClose(self) + + def selectTrack(self, ratingKey): + if not ratingKey: + return + for mli in self.trackListControl: + if mli.dataSource.ratingKey == ratingKey: + self.trackListControl.setSelectedItem(mli) + def onAction(self, action): controlID = self.getFocusId() try: diff --git a/script.plexmod/lib/windows/userselect.py b/script.plexmod/lib/windows/userselect.py index 656e705534..9053c76cec 100644 --- a/script.plexmod/lib/windows/userselect.py +++ b/script.plexmod/lib/windows/userselect.py @@ -1,15 +1,14 @@ from __future__ import absolute_import + from kodi_six import xbmc from kodi_six import xbmcgui - -from . import kodigui -from . import dropdown -from . import busy - -from lib import util from plexnet import plexapp +from lib import util from lib.util import T +from . import busy +from . import dropdown +from . import kodigui class UserSelectWindow(kodigui.BaseWindow): @@ -82,7 +81,7 @@ def onClick(self, controlID): with self.propertyContext('busy'): self.userList.reset() self.setProperty('initialized', '') - plexapp.ACCOUNT.updateHomeUsers() + plexapp.ACCOUNT.updateHomeUsers(refreshSubscription=True) self.start(with_busy=False) else: self.userSelected(item) @@ -195,7 +194,7 @@ def pinEntryClicked(self, controlID): def userSelected(self, item, pin=None): user = item.dataSource # xbmc.sleep(500) - util.DEBUG_LOG('Home user selected: {0}'.format(user)) + util.DEBUG_LOG('Home user selected: {0}', user) from lib import plex with plex.CallbackEvent(plexapp.util.APP, 'account:response') as e: @@ -216,8 +215,10 @@ def finished(self): self.task.cancel() -def start(): - w = UserSelectWindow.open() +def start(base_win_id): + w = UserSelectWindow.create() + if w.waitForOpen(base_win_id=base_win_id): + w.modal() selected = w.selected del w return selected diff --git a/script.plexmod/lib/windows/videoplayer.py b/script.plexmod/lib/windows/videoplayer.py index a67e5018df..db5db975ba 100644 --- a/script.plexmod/lib/windows/videoplayer.py +++ b/script.plexmod/lib/windows/videoplayer.py @@ -1,26 +1,25 @@ from __future__ import absolute_import -import time -import threading + import math +import threading +import time from kodi_six import xbmc from kodi_six import xbmcgui -from . import kodigui -from . import windowutils -from . import opener -from . import busy -from . import search -from . import dropdown -from . import pagination - -from lib import util -from lib import player from lib import colors from lib import kodijsonrpc - +from lib import player +from lib import util from lib.util import T - +from . import busy +from . import dropdown +from . import kodigui +from . import opener +from . import pagination +from . import search +from . import windowutils +from .mixins import SpoilersMixin PASSOUT_PROTECTION_DURATION_SECONDS = 7200 PASSOUT_LAST_VIDEO_DURATION_MILLIS = 1200000 @@ -44,17 +43,20 @@ def readyForPaging(self): def prepareListItem(self, data, mli): mli.setProperty('progress', util.getProgressImage(mli.dataSource)) mli.setProperty('unwatched', not mli.dataSource.isWatched and '1' or '') + mli.setProperty('watched', mli.dataSource.isFullyWatched and '1' or '') if data.type in 'episode': mli.setLabel2( - u'{0}{1} \u2022 {2}{3}'.format(T(32310, 'S'), data.parentIndex, T(32311, 'E'), data.index)) + u'{0} \u2022 {1}'.format(T(32310, 'S').format(data.parentIndex), T(32311, 'E').format(data.index))) else: mli.setLabel2(data.year) def createListItem(self, ondeck): title = ondeck.grandparentTitle or ondeck.title if ondeck.type == 'episode': - thumb = ondeck.thumb.asTranscodedImageURL(*self.parentWindow.ONDECK_DIM) + hide_spoilers = self.parentWindow.hideSpoilers(ondeck, use_cache=False) + thumb_opts = self.parentWindow.getThumbnailOpts(ondeck, hide_spoilers=hide_spoilers) + thumb = ondeck.thumb.asTranscodedImageURL(*self.parentWindow.ONDECK_DIM, **thumb_opts) else: thumb = ondeck.defaultArt.asTranscodedImageURL(*self.parentWindow.ONDECK_DIM) @@ -63,10 +65,13 @@ def createListItem(self, ondeck): return mli def getData(self, offset, amount): - return (self.parentWindow.prev or self.parentWindow.next).sectionOnDeck(offset=offset, limit=amount) + data = (self.parentWindow.prev or self.parentWindow.next).sectionOnDeck(offset=offset, limit=amount) + if self.parentWindow.next: + return list(filter(lambda x: x.ratingKey != self.parentWindow.next.ratingKey, data)) + return data -class VideoPlayerWindow(kodigui.ControlledWindow, windowutils.UtilMixin): +class VideoPlayerWindow(kodigui.ControlledWindow, windowutils.UtilMixin, SpoilersMixin): xmlFile = 'script-plex-video_player.xml' path = util.ADDON.getAddonInfo('path') theme = 'Main' @@ -97,6 +102,7 @@ class VideoPlayerWindow(kodigui.ControlledWindow, windowutils.UtilMixin): def __init__(self, *args, **kwargs): kodigui.ControlledWindow.__init__(self, *args, **kwargs) windowutils.UtilMixin.__init__(self) + SpoilersMixin.__init__(self, *args, **kwargs) self.playQueue = kwargs.get('play_queue') self.video = kwargs.get('video') self.resume = bool(kwargs.get('resume')) @@ -117,6 +123,7 @@ def __init__(self, *args, **kwargs): self.lastFocusID = None self.lastNonOptionsFocusID = None self.playBackStarted = False + self.handleBGM = kwargs.get('bgm') def doClose(self): util.DEBUG_LOG('VideoPlayerWindow: Closing') @@ -129,6 +136,9 @@ def doClose(self): def onFirstInit(self): player.PLAYER.on('session.ended', self.sessionEnded) player.PLAYER.on('av.started', self.playerPlaybackStarted) + player.PLAYER.on('starting.video', self.onVideoStarting) + player.PLAYER.on('started.video', self.onVideoStarted) + player.PLAYER.on('changed.video', self.onVideoChanged) player.PLAYER.on('post.play', self.postPlay) player.PLAYER.on('change.background', self.changeBackground) @@ -136,10 +146,20 @@ def onFirstInit(self): self.relatedListControl = kodigui.ManagedControlList(self, self.RELATED_LIST_ID, 5) self.rolesListControl = kodigui.ManagedControlList(self, self.ROLES_LIST_ID, 5) - util.DEBUG_LOG('VideoPlayerWindow: Starting session (ID: {0})'.format(id(self))) + util.DEBUG_LOG('VideoPlayerWindow: Starting session (ID: {0})', id(self)) self.resetPassoutProtection() self.play(resume=self.resume) + def onVideoStarting(self, *args, **kwargs): + util.setGlobalProperty('ignore_spinner', '1') + + def onVideoStarted(self, *args, **kwargs): + util.setGlobalProperty('ignore_spinner', '') + + def onVideoChanged(self, *args, **kwargs): + #util.setGlobalProperty('ignore_spinner', '') + pass + def onReInit(self): self.setBackground() @@ -152,7 +172,7 @@ def onAction(self, action): self.resetPassoutProtection() if action in(xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_CONTEXT_MENU): if not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format(self.OPTIONS_GROUP_ID)): - if not util.advancedSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU: + if not util.addonSettings.fastBack or action == xbmcgui.ACTION_CONTEXT_MENU: self.lastNonOptionsFocusID = self.lastFocusID self.setFocusId(self.OPTIONS_GROUP_ID) return @@ -195,7 +215,7 @@ def onClick(self, controlID): return timeoutCanceled = False - if util.advancedSettings.postplayCancel: + if util.addonSettings.postplayCancel: timeoutCanceled = bool(self.timeout) self.cancelTimer() @@ -275,7 +295,14 @@ def getRoleItemDDPosition(self): if xbmc.getCondVisibility('Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)'): y -= 500 - focus = int(xbmc.getInfoLabel('Container(403).Position')) + tries = 0 + focus = xbmc.getInfoLabel('Container(403).Position') + while tries < 2 and focus == '': + focus = xbmc.getInfoLabel('Container(403).Position') + xbmc.sleep(250) + tries += 1 + + focus = int(focus) x = ((focus + 1) * 304) - 100 return x, y @@ -290,10 +317,10 @@ def changeBackground(self, url, **kwargs): def sessionEnded(self, session_id=None, **kwargs): if session_id != id(self): - util.DEBUG_LOG('VideoPlayerWindow: Ignoring session end (ID: {0} - SessionID: {1})'.format(id(self), session_id)) + util.DEBUG_LOG('VideoPlayerWindow: Ignoring session end (ID: {0} - SessionID: {1})', id(self), session_id) return - util.DEBUG_LOG('VideoPlayerWindow: Session ended - closing (ID: {0})'.format(id(self))) + util.DEBUG_LOG('VideoPlayerWindow: Session ended - closing (ID: {0})', id(self)) self.doClose() def play(self, resume=False, handler=None): @@ -305,7 +332,7 @@ def anyOtherVPlayer(): if player.PLAYER.isPlayingVideo(): activePlayers = anyOtherVPlayer() if activePlayers: - util.DEBUG_LOG("Stopping other active players: {}".format(activePlayers)) + util.DEBUG_LOG("Stopping other active players: {}", activePlayers) xbmc.executebuiltin('PlayerControl(Stop)') ct = 0 while player.PLAYER.isPlayingVideo() or anyOtherVPlayer(): @@ -320,11 +347,26 @@ def anyOtherVPlayer(): return util.MONITOR.waitForAbort(0.5) + # wait for BGM to end if it's playing or queued + if self.handleBGM: + while not player.PLAYER.bgmPlaying and player.PLAYER.bgmStarting: + util.DEBUG_LOG("Waiting for BGM to start as it has been queued") + util.MONITOR.waitForAbort(0.1) + + if player.PLAYER.bgmPlaying: + util.DEBUG_LOG("Stopping BGM before starting playback") + player.PLAYER.stopAndWait() + + while player.PLAYER.bgmPlaying: + util.MONITOR.waitForAbort(0.1) + self.setBackground() if self.playQueue: - player.PLAYER.playVideoPlaylist(self.playQueue, resume=self.resume, session_id=id(self), handler=handler) + player.PLAYER.playVideoPlaylist(self.playQueue, resume=resume or self.resume, session_id=id(self), + handler=handler) elif self.video: - player.PLAYER.playVideo(self.video, resume=self.resume, force_update=True, session_id=id(self), handler=handler) + player.PLAYER.playVideo(self.video, resume=resume or self.resume, force_update=True, session_id=id(self), + handler=handler) def openItem(self, control=None, item=None): if not item: @@ -333,7 +375,7 @@ def openItem(self, control=None, item=None): return item = mli.dataSource - self.processCommand(opener.open(item)) + self.processCommand(opener.open(item, came_from="postplay")) def showPostPlay(self): self.postPlayMode = True @@ -420,9 +462,10 @@ def startTimer(self): return else: millis = (self.passoutProtection - time.time()) * 1000 - util.DEBUG_LOG('Post play auto-play: Passout protection in {0}'.format(util.durationToShortText(millis))) + util.DEBUG_LOG('Post play auto-play: Passout protection in {0}', + lambda: util.durationToShortText(millis)) - self.timeout = time.time() + abs(util.advancedSettings.postplayTimeout) + self.timeout = time.time() + abs(util.addonSettings.postplayTimeout) util.DEBUG_LOG('Starting post-play timer until: %i' % self.timeout) threading.Thread(target=self.countdown).start() @@ -447,8 +490,8 @@ def countdown(self): # self.playVideo() break elif self.timeout is not None: - cd = min(abs(util.advancedSettings.postplayTimeout-1), int((self.timeout or now) - now)) - base = 15 / float(util.advancedSettings.postplayTimeout-1) + cd = min(abs(util.addonSettings.postplayTimeout - 1), int((self.timeout or now) - now)) + base = 15 / float(util.addonSettings.postplayTimeout - 1) self.setProperty('countdown', str(int(math.ceil(base*cd)))) def getHubs(self): @@ -472,14 +515,26 @@ def getHubs(self): self.setProperty('has.next', '1') def setInfo(self): + hide_spoilers = False + if self.next and self.next.type == "episode": + hide_spoilers = self.hideSpoilers(self.next, use_cache=False) if self.next: self.setProperty( 'post.play.background', util.backgroundFromArt(self.next.art, width=self.width, height=self.height) ) - self.setProperty('info.title', self.next.title) + if self.next.type == "episode" and hide_spoilers: + if self.noTitles: + self.setProperty('info.title', + u'{0} \u2022 {1}'.format(T(32310, 'S').format(self.next.parentIndex), + T(32311, 'E').format(self.next.index))) + else: + self.setProperty('info.title', self.next.title) + self.setProperty('info.summary', T(33008, '')) + else: + self.setProperty('info.title', self.next.title) + self.setProperty('info.summary', self.next.summary) self.setProperty('info.duration', util.durationToText(self.next.duration.asInt())) - self.setProperty('info.summary', self.next.summary) if self.prev: self.setProperty( @@ -493,18 +548,25 @@ def setInfo(self): if self.prev.type == 'episode': self.setProperty('related.header', T(32306, 'Related Shows')) if self.next: - self.setProperty('next.thumb', self.next.thumb.asTranscodedImageURL(*self.NEXT_DIM)) - self.setProperty('info.date', util.cleanLeadingZeros(self.next.originallyAvailableAt.asDatetime('%B %d, %Y'))) + thumb_opts = {} + if hide_spoilers: + thumb_opts = self.getThumbnailOpts(self.next, hide_spoilers=hide_spoilers) + self.setProperty('next.thumb', self.next.thumb.asTranscodedImageURL(*self.NEXT_DIM, **thumb_opts)) + self.setProperty('info.date', + util.cleanLeadingZeros(self.next.originallyAvailableAt.asDatetime('%B %d, %Y'))) self.setProperty('next.title', self.next.grandparentTitle) self.setProperty( - 'next.subtitle', u'{0} {1} \u2022 {2} {3}'.format(T(32303, 'Season'), self.next.parentIndex, T(32304, 'Episode'), self.next.index) + 'next.subtitle', + u'{0} \u2022 {1}'.format(T(32303, 'Season').format(self.next.parentIndex), + T(32304, 'Episode').format(self.next.index)) ) if self.prev: self.setProperty('prev.thumb', self.prev.thumb.asTranscodedImageURL(*self.PREV_DIM)) self.setProperty('prev.title', self.prev.grandparentTitle) self.setProperty( - 'prev.subtitle', u'{0} {1} \u2022 {2} {3}'.format(T(32303, 'Season'), self.prev.parentIndex, T(32304, 'Episode'), self.prev.index) + 'prev.subtitle', u'{0} \u2022 {1}'.format(T(32303, 'Season').format(self.prev.parentIndex), + T(32304, 'Episode').format(self.prev.index)) ) self.setProperty('prev.info.date', util.cleanLeadingZeros(self.prev.originallyAvailableAt.asDatetime('%B %d, %Y'))) elif self.prev.type == 'movie': @@ -576,6 +638,7 @@ def fillRoles(self, has_prev=False): def playVideo(self, prev=False): self.cancelTimer() + resume = False try: if not self.next and self.playlist: if prev: @@ -583,7 +646,6 @@ def playVideo(self, prev=False): self.aborted = False self.playQueue = self.playlist self.video = None - self.play(handler=self.handler) else: video = self.next if prev: @@ -594,22 +656,46 @@ def playVideo(self, prev=False): self.video = None return + if not prev: + if video.viewOffset.asInt(): + choice = dropdown.showDropdown( + options=[ + {'key': 'resume', 'display': T(32429, 'Resume from {0}').format( + util.timeDisplay(video.viewOffset.asInt()).lstrip('0').lstrip(':'))}, + {'key': 'play', 'display': T(32317, 'Play from beginning')} + ], + pos=(660, "middle"), + close_direction='none', + set_dropdown_prop=False, + header=T(32314, 'In Progress'), + ) + + if not choice: + return + + if choice['key'] == 'resume': + resume = True + self.playQueue = None self.video = video - self.play(handler=self.handler) + + self.play(handler=self.handler, resume=resume) except: util.ERROR() -def play(video=None, play_queue=None, resume=False): +def play(video=None, play_queue=None, resume=False, bgm=False, **kwargs): try: - w = VideoPlayerWindow.open(video=video, play_queue=play_queue, resume=resume) + w = VideoPlayerWindow.open(video=video, play_queue=play_queue, resume=resume, bgm=bgm) except util.NoDataException: raise finally: player.PLAYER.off('session.ended', w.sessionEnded) player.PLAYER.off('post.play', w.postPlay) player.PLAYER.off('av.started', w.playerPlaybackStarted) + player.PLAYER.off('starting.video', w.onVideoStarting) + player.PLAYER.off('started.video', w.onVideoStarted) + player.PLAYER.off('changed.video', w.onVideoChanged) player.PLAYER.off('change.background', w.changeBackground) player.PLAYER.reset() command = w.exitCommand diff --git a/script.plexmod/lib/windows/windowutils.py b/script.plexmod/lib/windows/windowutils.py index 9914d8c879..7910ded9b6 100644 --- a/script.plexmod/lib/windows/windowutils.py +++ b/script.plexmod/lib/windows/windowutils.py @@ -1,10 +1,9 @@ from __future__ import absolute_import -from lib import util -from . import opener -from . import dropdown +from lib import util from lib.util import T - +from . import dropdown +from . import opener HOME = None @@ -13,13 +12,16 @@ class UtilMixin(): def __init__(self): self.exitCommand = None - def goHome(self, section=None): - HOME.show() + def goHome(self, section=None, with_root=False): + HOME.go_root = with_root + if section: self.closeWithCommand('HOME:{0}'.format(section)) else: self.closeWithCommand('HOME') + HOME.show() + def openItem(self, obj): self.processCommand(opener.open(obj)) @@ -41,44 +43,55 @@ def showAudioPlayer(self, **kwargs): from . import musicplayer self.processCommand(opener.handleOpen(musicplayer.MusicPlayerWindow, **kwargs)) - def getPlaylistResume(self, pl, items, title): - resume = False + def getNextShowEp(self, pl, items, title): + revitems = list(reversed(items)) + in_progress = [i for i in revitems if i.get('viewOffset').asInt()] + if in_progress: + n = in_progress[0] + pl.setCurrent(n) + choice = dropdown.showDropdown( + options=[ + {'key': 'resume', 'display': T(32429, 'Resume from {0}').format( + util.timeDisplay(n.viewOffset.asInt()).lstrip('0').lstrip(':'))}, + {'key': 'play', 'display': T(32317, 'Play from beginning')} + ], + pos=(660, 441), + close_direction='none', + set_dropdown_prop=False, + header=u'{0} - {1} \u2022 {2}'.format(title, + T(32310, 'S').format(n.parentIndex), + T(32311, 'E').format(n.index)) + ) + + if not choice: + return None + + if choice['key'] == 'resume': + return True + return False + watched = False - for i in items: - if (watched and not i.isWatched) or i.get('viewOffset').asInt(): - if i.get('viewOffset'): - choice = dropdown.showDropdown( - options=[ - {'key': 'resume', 'display': T(32429, 'Resume from {0}').format(util.timeDisplay(i.viewOffset.asInt()).lstrip('0').lstrip(':'))}, - {'key': 'play', 'display': T(32317, 'Play from beginning')} - ], - pos=(660, 441), - close_direction='none', - set_dropdown_prop=False, - header=u'{0} - {1}{2} \u2022 {3}{4}'.format(title, T(32310, 'S'), i.parentIndex, T(32311, 'E'), i.index) - ) - - if not choice: - return None - - if choice['key'] == 'resume': - resume = True - - pl.setCurrent(i) - break - elif i.isWatched: + for (k, i) in enumerate(revitems): + if watched: + try: + pl.setCurrent(revitems[k-2]) + return False + except IndexError: + break + if i.get('viewCount').asInt() > 0: watched = True - else: - break - return resume + non_special = [i for i in revitems if i.get('parentIndex').asInt() and i.get('viewCount').asInt() == 0] + use = items[0] + if non_special: + use = non_special[-1] + pl.setCurrent(use) + return False def shutdownHome(): global HOME if HOME: - HOME._shuttingDown = True HOME.shutdown() del HOME HOME = None - HOME diff --git a/script.plexmod/path_mapping.json.example b/script.plexmod/path_mapping.json.example new file mode 100644 index 0000000000..2d05c0b1c0 --- /dev/null +++ b/script.plexmod/path_mapping.json.example @@ -0,0 +1,45 @@ +/* +This is used to tell the addon to not use the HTTP handler for certain paths. +The paths are mapped by comparing the file path of a media item with the right-hand-side and then +replaced with the corresponding left-hand-side. + +e.g. +file path in Plex Server: "/library/path/on/server/data/movies/thisisfun.mkv" + left-hand-side right-hand-side +"smb://serverip/movies": "/library/path/on/server/data/movies", + +or, if all of your libraries are based on the same folder: +"smb://serverip/data": "/library/path/on/server/data", + +To find out how your Plex Server sees the paths of your media items, visit Plex Web, click the three dots on an item, +"Get Info", "View XML", then take note of the file="..." attribute of the <Part /> element. + +Let's say you have a common Movie library path of "/mnt/data/movies" and you've exposed that path via SMB/Samba to the +share "Movies", you'd do the following ([:port] is optional for SMB): +- Go to the Kodi file manager and add a new source +- Add a source with "smb://serverip[:port]/Movies" +- Copy this file to "userdata/addon_data/script.plexmod/path_mapping.json" +- Fill in your servername (the name of the server in Plex) in place of your_server_name below +- Add "smb://serverip[:port]/Movies": "/mnt/data/Movies" below "// add your own mounts here" below + +You can leave the examples in there, they don't matter (you can delete them if you want). + +Note: For paths containing backslashes ("\"), you need to escape them here, so "\\asdf\bla" becomes "\\\\asdf\\bla". + +This is not limited to SMB, though. You can add NFS, local mounts, webdav, whatever, (even http(s):// if you'd like) +as long as the current video file path starts with the right-hand-side of the mapping, and the left hand side exists +(you can disable the existence-checks in the addon settings), it will be replaced with the left-hand-side of it. +*/ +{ + "your_server_name": { + // add your own mounts here + + // standard SMB mounts in Kodi + "smb://serverip/mountname": "/library/path/on/server", + "smb://serverip/mountname2": "/library2/path/on/server", + // NVIDIA SHIELD direct mount + "/storage/SERVERNAME/this_is_a_SHIELD_mountpoint": "/library3/path/on/server", + // Plex Server running on Windows using network shares for libraries + "smb://serverip/share": "\\\\some_server_or_ip\\share" + } +} diff --git a/script.plexmod/plugin.py b/script.plexmod/plugin.py index 2c16c2b89a..b14decaedb 100644 --- a/script.plexmod/plugin.py +++ b/script.plexmod/plugin.py @@ -1,75 +1,11 @@ from __future__ import absolute_import -from kodi_six import xbmc -from kodi_six import xbmcplugin -from kodi_six import xbmcgui -import sys -import base64 -from lib import _included_packages, plex, util -from plexnet import audio, plexplayer, plexapp -from plexnet import util as plexnetUtil - -HANDLE = int(sys.argv[1]) - -BASE_LOG = util.LOG - - -def LOG(msg): - BASE_LOG('(plugin) - {0}'.format(plexnetUtil.cleanToken(msg))) - - -util.LOG = LOG - - -def playTrack(track): - track.reload() - apobj = plexplayer.PlexAudioPlayer(track) - url = apobj.build()['url'] - url = util.addURLParams(url, { - 'X-Plex-Client-Profile-Name': 'Generic', - 'X-Plex-Client-Identifier': plexapp.util.INTERFACE.getGlobal('clientIdentifier') - }) - LOG('Playing URL: {0}'.format(url)) - - return xbmcgui.ListItem(path=url) - - -def playVideo(video): - return None - - -def play(data): - try: - from plexnet import plexobjects - - plexObject = plexobjects.PlexObject.deSerialize(base64.urlsafe_b64decode(data.encode('utf-8'))) - - if plexObject.type == 'track': - listitem = playTrack(plexObject) - elif plexObject.type in ('episode', 'movie', 'clip'): - listitem = playVideo(plexObject) - except: - util.ERROR() - xbmcplugin.setResolvedUrl(HANDLE, False, None) - return - - xbmcplugin.setResolvedUrl(HANDLE, True, listitem) +from lib.kodi_util import ensureHome, xbmc def main(): - try: - if len(sys.argv) < 3: - return - - path = sys.argv[0].split('/', 3)[-1] - data = sys.argv[2].lstrip('?') - - if path == 'play': - play(data) - else: # This is a hack since it's both a plugin and a script. My Addons and Shortcuts otherwise can't launch the add-on - util.ensureHome() - xbmc.executebuiltin('RunScript(script.plexmod)') - except: - util.ERROR() + # This is a hack since it's both a plugin and a script. My Addons and Shortcuts otherwise can't launch the add-on + ensureHome() + xbmc.executebuiltin('RunScript(script.plexmod)') main() diff --git a/script.plexmod/resources/language/resource.language.de_de/strings.po b/script.plexmod/resources/language/resource.language.de_de/strings.po index e40ba633f3..cd1ee55ec9 100644 --- a/script.plexmod/resources/language/resource.language.de_de/strings.po +++ b/script.plexmod/resources/language/resource.language.de_de/strings.po @@ -4,7 +4,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: POEditor.com\n" -"Project-Id-Version: PM4K\n" +"Project-Id-Version: PM4K / PlexMod for Kodi\n" "Language: de\n" #: @@ -95,7 +95,7 @@ msgstr "Qualität für entfernte Geräte" #: msgctxt "#32022" msgid "Online Quality" -msgstr "Online Qualität" +msgstr "Online-Qualität" #: msgctxt "#32023" @@ -109,13 +109,13 @@ msgstr "Debug-Protokollierung" #: msgctxt "#32025" -msgid "Allow Direct Play" -msgstr "Direkte Wiedergabe erlauben" +msgid "Direct Play" +msgstr "Direkte Wiedergabe" -#: +#: msgctxt "#32026" -msgid "Allow Direct Stream" -msgstr "Direktes streamen erlauben" +msgid "Direct Stream" +msgstr "Direktes Streamen" #: msgctxt "#32027" @@ -130,18 +130,13 @@ msgstr "Immer" #: msgctxt "#32029" msgid "Only Image Formats" -msgstr "nur Bildformate" +msgstr "Nur Bildformate" #: msgctxt "#32030" msgid "Auto" msgstr "Automatisch" -#: -msgctxt "#32031" -msgid "Burn-in Subtitles" -msgstr "Untertitel einbrennen" - #: msgctxt "#32032" msgid "Allow Insecure Connections" @@ -164,13 +159,13 @@ msgstr "Immer" #: msgctxt "#32036" -msgid "Allow 4K" -msgstr "4K erlauben" +msgid "4K" +msgstr "4K" -#: +#: msgctxt "#32037" -msgid "Allow HEVC (h265)" -msgstr "HEVC erlauben (H265)" +msgid "HEVC (h265)" +msgstr "HEVC (H265)" #: msgctxt "#32038" @@ -185,17 +180,17 @@ msgstr "Automatisch nächsten Titel abspielen" #: msgctxt "#32040" msgid "Enable Subtitle Downloading" -msgstr "Untertitel download aktivieren" +msgstr "Untertitel-Download aktivieren" #: msgctxt "#32041" msgid "Enable Subtitle Downloading" -msgstr "Untertitel download aktivieren" +msgstr "Untertitel-Download aktivieren" #: msgctxt "#32042" msgid "Server Discovery (GDM)" -msgstr "Server Erkennung (GDM)" +msgstr "Server-Erkennung (GDM)" #: msgctxt "#32043" @@ -255,12 +250,12 @@ msgstr "Video" #: msgctxt "#32054" msgid "Addon Version" -msgstr "Erweiterung Version" +msgstr "Version der Erweiterung" #: msgctxt "#32055" msgid "Kodi Version" -msgstr "Kodi Version" +msgstr "Kodi-Version" #: msgctxt "#32056" @@ -270,7 +265,7 @@ msgstr "Bilschirmauflösung" #: msgctxt "#32057" msgid "Current Server Version" -msgstr "Aktuelle Server Version" +msgstr "Aktuelle Server-Version" #: msgctxt "#32058" @@ -287,41 +282,11 @@ msgctxt "#32060" msgid "Use Kodi audio channels" msgstr "Kodi-Audiokanäle verwenden" -#: -msgctxt "#32061" -msgid "When transcoding audio, target the audio channels set in Kodi." -msgstr "Beim Transkodieren von Audio werden die in Kodi eingestellten Audiokanäle verwendet." - -#: -msgctxt "#32062" -msgid "Transcode audio to AC3" -msgstr "Transkodiere Ton zu AC3" - -#: -msgctxt "#32063" -msgid "Transcode audio to AC3 in certain conditions (useful for passthrough)." -msgstr "Transkodiere Ton zu AC3 in bestimmten Umständen (nützlich für Passthrough)" - #: msgctxt "#32064" msgid "Treat DTS like AC3" msgstr "DTS wie AC3 behandeln" -#: -msgctxt "#32065" -msgid "When any of the force AC3 settings are enabled, treat DTS the same as AC3 (useful for Optical passthrough)" -msgstr "Wenn einer der AC3 Optionen aktiviert ist, wird DTS wie AC3 behandelt (nützlich für Optical Passthrough)" - - -msgctxt "#32066" -msgid "Force audio to AC3" -msgstr "Audio immer als AC3 erzwingen" - - -msgctxt "#32067" -msgid "Only force multichannel audio to AC3" -msgstr "Nur Mehrkanal-Audio als AC3 erzwingen" - #: msgctxt "#32100" msgid "Skip user selection and pin entry on startup." @@ -329,23 +294,23 @@ msgstr "Benutzerauswahl und Pin-Eingabe beim Start überspringen." #: msgctxt "#32101" -msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a 15 second delay." -msgstr "Falls aktiviert wird, sofern verfügbar, nachdem die Wiedergabe endet ein 'nächster Titel' automatisch nach 15 Sekunden gestartet." +msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a {} second delay." +msgstr "Falls die Option aktiviert und ein weiterer Titel verfügbar ist, wird dieser {} Sekunden nach der aktuellen Wiedergabe gestartet." #: msgctxt "#32102" msgid "Enable this if your hardware can handle 4K playback. Disable it to force transcoding." -msgstr "Aktiviert 4K Wiedergabe per Hardware. Deaktivierung erzwingt Transcodierung." +msgstr "Aktiviert 4K-Wiedergabe per Hardware. Deaktivierung erzwingt Transcodierung." #: msgctxt "#32103" msgid "Enable this if your hardware can handle HEVC/h265. Disable it to force transcoding." -msgstr "Aktiviert HEVC/H265 Wiedergabe per Hardware. Deaktivierung erzwingt Transcodierung." +msgstr "Aktiviert HEVC/H265-Wiedergabe per Hardware. Deaktivierung erzwingt Transcodierung." #: msgctxt "#32104" msgid "When to connect to servers with no secure connections.[CR][CR]* [B]Never[/B]: Never connect to a server insecurely[CR]* [B]On Same Network[/B]: Allow if on the same network[CR]* [B]Always[/B]: Allow same network and remote connections" -msgstr "Wann soll zu Servern ohne 'sichere Verbindung' verbunden werden[CR]* [B]Nie[/B]: Niemals unsicher zu eine Server verbinden.[CR]* [B]Im selben Netzwerk[/B]: Im selben Netzwerk erlauben[CR]* [B]Immer[/B]: Im selben Netzwerk und bei entfernter Verbindung erlauben" +msgstr "Wann soll zu Servern ohne 'sichere Verbindung' verbunden werden?[CR][CR]* [B]Nie[/B]: Niemals unsicher zu eine Server verbinden.[CR]* [B]Im selben Netzwerk[/B]: Im selben Netzwerk erlauben[CR]* [B]Immer[/B]: Im selben Netzwerk und bei entfernter Verbindung erlauben" #: msgctxt "#32201" @@ -380,7 +345,7 @@ msgstr "Szene" #: msgctxt "#32207" msgid "Live Music Video" -msgstr "Live Musikvideo" +msgstr "Live-Musikvideo" #: msgctxt "#32208" @@ -422,16 +387,6 @@ msgctxt "#32302" msgid "Go to {0}" msgstr "Gehe zu {0}" -#: -msgctxt "#32303" -msgid "Season" -msgstr "Staffel" - -#: -msgctxt "#32304" -msgid "Episode" -msgstr "Folge" - #: msgctxt "#32305" msgid "Extras" @@ -445,7 +400,7 @@ msgstr "Ähnliche Serien" #: msgctxt "#32307" msgid "More" -msgstr "Film" +msgstr "Mehr" #: msgctxt "#32308" @@ -457,16 +412,6 @@ msgctxt "#32309" msgid "None" msgstr "Ohne" -#: -msgctxt "#32310" -msgid "S" -msgstr "S" - -#: -msgctxt "#32311" -msgid "E" -msgstr "E" - #: msgctxt "#32312" msgid "Unavailable" @@ -545,7 +490,7 @@ msgstr "Wirklich löschen?" #: msgctxt "#32327" msgid "Are you sure you really want to delete this media?" -msgstr "Soll diese Mediandatei wirklich gelöscht werden?" +msgstr "Soll diese Mediendatei wirklich gelöscht werden?" #: msgctxt "#32328" @@ -585,7 +530,7 @@ msgstr "Beenden bestätigen" #: msgctxt "#32335" msgid "Are you ready to exit Plex?" -msgstr "Bereit um Plex zu beenden?" +msgstr "Bereit, um Plex zu beenden?" #: msgctxt "#32336" @@ -615,7 +560,7 @@ msgstr "Verbindungstests laufen. Bitte warten." #: msgctxt "#32341" msgid "Server is not accessible. Please sign into your server and check your connection." -msgstr "Der Server ist nicht erreichbar. Bitte einloggen und Verbindung prüfen." +msgstr "Der Server ist nicht erreichbar. Bitte am Server einloggen und Verbindung prüfen." #: msgctxt "#32342" @@ -694,13 +639,13 @@ msgstr "Gesehen am" #: msgctxt "#32357" -msgid "By Name" -msgstr "Nach Name" +msgid "By Title" +msgstr "Nach Titel" -#: +#: msgctxt "#32358" -msgid "Name" -msgstr "Name" +msgid "Title" +msgstr "Titel" #: msgctxt "#32359" @@ -900,12 +845,12 @@ msgstr "Qualität" #: msgctxt "#32398" msgid "Kodi Video Settings" -msgstr "Kodi Bild Einstellungen" +msgstr "Kodi-Bildeinstellungen" #: msgctxt "#32399" msgid "Kodi Audio Settings" -msgstr "Kodi Ton Einstellungen" +msgstr "Kodi-Toneinstellungen" #: msgctxt "#32400" @@ -925,7 +870,7 @@ msgstr "Autor(in)" #: msgctxt "#32403" msgid "Writers" -msgstr "Autoren" +msgstr "Autor(inn)en" #: msgctxt "#32404" @@ -940,7 +885,7 @@ msgstr "Untertitel downloaden" #: msgctxt "#32406" msgid "Subtitle Delay" -msgstr "Untertitel Verzögerung" +msgstr "Untertitel-Verzögerung" #: msgctxt "#32407" @@ -950,7 +895,7 @@ msgstr "Nächster Untertitel" #: msgctxt "#32408" msgid "Disable Subtitles" -msgstr "Untertitel deaktiviren" +msgstr "Untertitel deaktivieren" #: msgctxt "#32409" @@ -960,7 +905,7 @@ msgstr "Untertitel aktivieren" #: msgctxt "#32410" msgid "Platform Version" -msgstr "Platform Version" +msgstr "Platform-Version" #: msgctxt "#32411" @@ -975,7 +920,7 @@ msgstr "Bearbeiten oder bereinigen" #: msgctxt "#32413" msgid "Edit IP address or clear the current setting?" -msgstr "IP Adresse bearbeiten oder die aktuellen Einstellungen bereinigen?" +msgstr "IP-Adresse bearbeiten oder die aktuellen Einstellungen bereinigen?" #: msgctxt "#32414" @@ -990,12 +935,12 @@ msgstr "Ändern" #: msgctxt "#32416" msgid "Enter IP Address" -msgstr "IP Adresse eingeben" +msgstr "IP-Adresse eingeben" #: msgctxt "#32417" msgid "Enter Port Number" -msgstr "Port Nummer eingeben" +msgstr "Port-Nummer eingeben" #: msgctxt "#32418" @@ -1080,7 +1025,7 @@ msgstr "Bereinigen" #: msgctxt "#32434" msgid "Searching..." -msgstr "Suche..." +msgstr "Suche ..." #: msgctxt "#32435" @@ -1142,6 +1087,7 @@ msgctxt "#32446" msgid "Stereo" msgstr "Stereo" +#. Depending on context, this could also be translated differently. Same with all the "none"s in the list #: msgctxt "#32447" msgid "None" @@ -1165,12 +1111,12 @@ msgstr "Version auswählen" #: msgctxt "#32451" msgid "Play Version..." -msgstr "Version abspielen..." +msgstr "Version abspielen ..." #: msgctxt "#32452" msgid "No Content available in this library" -msgstr "In dieser Bibliothek ist nichts vorhanden" +msgstr "Keine Inhalte in dieser Bibliothek vorhanden" #: msgctxt "#32453" @@ -1240,7 +1186,7 @@ msgstr "Skip-Schritte-Einstellung von Kodi benutzen" #: msgctxt "#32466" msgid "Automatically seek selected position after a delay" -msgstr "Automatisch verzögert zur ausgewählten Position springen" +msgstr "Nach Verzögerung automatisch zur ausgewählten Position springen" #: msgctxt "#32467" @@ -1277,6 +1223,7 @@ msgctxt "#32481" msgid "Off" msgstr "Aus" +#. What is going on here? #: msgctxt "#32482" msgid "%(percentage)s %%" @@ -1285,17 +1232,17 @@ msgstr "%(percentage)s %%" #: msgctxt "#32483" msgid "Hide Stream Info" -msgstr "Stream Info nicht anzeigen" +msgstr "Stream-Info nicht anzeigen" #: msgctxt "#32484" msgid "Show Stream Info" -msgstr "Stream Info anzeigen" +msgstr "Stream-Info anzeigen" #: msgctxt "#32485" msgid "Go back instantly with the previous menu action in scrolled views" -msgstr "Mit der Previous-Menu-Aktion In gescrollten Ansichten sofort zurückgehen" +msgstr "Mit 'Vorheriges Menü' in gescrollten Ansichten sofort zurückgehen" #: msgctxt "#32487" @@ -1325,12 +1272,7 @@ msgstr "Ordner" #: msgctxt "#32492" msgid "Kodi Subtitle Settings" -msgstr "Kodi Untertitel-Einstellungen" - -#: -msgctxt "#32493" -msgid "When a media file has a forced/foreign subtitle for a subtitle-enabled language, the Plex Media Server preselects it. This behaviour is usually not necessary and not configurable. This setting fixes that by ignoring the PMSs decision and selecting the same language without a forced flag if possible." -msgstr "Hat eine Mediendatei erzwungenge Untertitel für eine Sprache, bei der Untertitel erwünscht sind, wählt der Plex Media Server diesen standardmäßig aus. Das Verhalten ist normalerweise unerwünscht und nicht konfigurierbar. Diese Einstellung behebt das Problem, indem versucht wird, einen Untertitel der selben Sprache ohne Erzwungen-Markierung zu wählen." +msgstr "Kodi-Untertiteleinstellungen" #: msgctxt "#32495" @@ -1345,12 +1287,12 @@ msgstr "Abspann überspringen" #: msgctxt "#32500" msgid "Always show post-play screen (even for short videos)" -msgstr "Immer den Nachwiedergabe-Bildschirm anzeigen (auch bei kurzen Videos)" +msgstr "Immer den Nach-Wiedergabe-Bildschirm anzeigen (auch bei kurzen Videos)" #: msgctxt "#32501" msgid "Time-to-wait between videos on post-play" -msgstr "Wartezeit zwischen Videos bei Nachwiedergabe" +msgstr "Wartezeit zwischen Videos bei Nach-Wiedergabe" #: msgctxt "#32505" @@ -1360,18 +1302,13 @@ msgstr "Medien in der Video-Wiedergabeliste anzeigen, anstatt sie abzuspielen" #: msgctxt "#32521" msgid "Skip Intro Button Timeout" -msgstr "Zeitlimit für die Schaltfläche Intro überspringen" +msgstr "Zeitlimit für die Schaltfläche 'Intro überspringen'" #: msgctxt "#32522" msgid "Automatically Skip Intro" msgstr "Intro automatisch überspringen" -#: -msgctxt "#32523" -msgid "Automatically skip intros if available. Doesn't override enabled binge mode.\nCan be disabled/enabled per TV show." -msgstr "Automatisches Überspringen von Intros, falls vorhanden. Überschreibt aktivierten Binge-Modus nicht.\nKann pro Serie aktiviert/deaktiviert werden." - #: msgctxt "#32524" msgid "Set how long the skip intro button shows for." @@ -1380,22 +1317,17 @@ msgstr "Festlegen, wie lange die Schaltfläche zum Überspringen des Intros ange #: msgctxt "#32525" msgid "Skip Credits Button Timeout" -msgstr "Zeitlimit für die Schaltfläche Abspann überspringen" +msgstr "Zeitlimit für die Schaltfläche 'Abspann überspringen'" #: msgctxt "#32526" msgid "Automatically Skip Credits" -msgstr "Automatisches Überspringen von Abspann" - -#: -msgctxt "#32527" -msgid "Automatically skip credits if available. Doesn't override enabled binge mode.\nCan be disabled/enabled per TV show." -msgstr "Automatisches Überspringen von Abspann, falls vorhanden. Überschreibt aktivierten Binge-Modus nicht.\nKann pro Serie aktiviert/deaktiviert werden." +msgstr "Abspann automatisch überspringen" #: msgctxt "#32528" msgid "Set how long the skip credits button shows for." -msgstr "Festlegen, wie lange die Schaltfläche zum Überspringen des Abspann angezeigt werden soll." +msgstr "Festlegen, wie lange die Schaltfläche zum Überspringen des Abspanns angezeigt werden soll." #: msgctxt "#32540" @@ -1405,12 +1337,12 @@ msgstr "Im Player anzeigen, wann das aktuelle Video endet" #: msgctxt "#32541" msgid "Shows time left and at which time the media will end." -msgstr "Zeigt im Player an, wann und zu welchem Zeitpunkt das aktuelle Video endet." +msgstr "Zeigt verbleibende Restzeit und Uhrzeit, wann das Video endet, im Player an." #: msgctxt "#32542" msgid "Show \"Ends at\" label for the end-time as well" -msgstr "\"Endet um\"-Label für die Endzeit auch anzeigen" +msgstr "'Endet um'-Label für Ende des Abspielens anzeigen" #: msgctxt "#32543" @@ -1419,8 +1351,8 @@ msgstr "Endet um" #: msgctxt "#32601" -msgid "Allow AV1" -msgstr "AV1 zulassen" +msgid "AV1" +msgstr "AV1" #: msgctxt "#32602" @@ -1460,7 +1392,7 @@ msgstr "Inhaltsbewertung" #: msgctxt "#33107" msgid "By Critic Rating" -msgstr "Nach kritischer Bewertung" +msgstr "Nach Kritikerwertung" #: msgctxt "#33108" @@ -1475,7 +1407,7 @@ msgstr "Hintergrundfarbe" #: msgctxt "#33201" msgid "Specify solid Background Color instead of using media images" -msgstr "Hintergrundfarbe anstatt Bilder verwenden" +msgstr "Hintergrundfarbe anstatt Medienbildern verwenden" #: msgctxt "#33400" @@ -1485,546 +1417,1449 @@ msgstr "Altes Kompatibilitätsprofil verwenden" #: msgctxt "#33401" msgid "Uses the Chrome client profile instead of the custom one. Might fix rare issues with 3D playback." -msgstr "Benutzt das alte Chrome Client-Profil anstatt des angepassten. Könnte seltene Fehler beim Abspielen von 3D-Inhalten verhindern." +msgstr "Benutzt das alte Chrome-Client-Profil anstatt des angepassten. Könnte seltene Fehler beim Abspielen von 3D-Inhalten verhindern." #: -msgctxt "#32348" -msgid "movies" -msgstr "Filme" +msgctxt "#32031" +msgid "Burn-in Subtitles" +msgstr "Untertitel einbrennen" #: -msgctxt "#32466" -msgid "Automatically seek to the selected timeline position after a second" -msgstr "Nach Verzögerung automatisch zur aktuell gewählten Position springen" +msgctxt "#32061" +msgid "When transcoding audio, target the audio channels set in Kodi." +msgstr "Beim Transkodieren von Audio werden die in Kodi eingestellten Audiokanäle verwendet." + +#: +msgctxt "#32062" +msgid "Transcode audio to AC3" +msgstr "Transkodiere Ton zu AC3" + +#: +msgctxt "#32063" +msgid "Transcode audio to AC3 in certain conditions (useful for passthrough)." +msgstr "Transkodiere Ton zu AC3 unter bestimmten Umständen (nützlich für Passthrough)" + +#: +msgctxt "#32065" +msgid "When any of the force AC3 settings are enabled, treat DTS the same as AC3 (useful for Optical passthrough)" +msgstr "Wenn eine der AC3-Optionen aktiviert ist, wird DTS wie AC3 behandelt (nützlich für Optical Passthrough)" + +#: +msgctxt "#32066" +msgid "Force audio to AC3" +msgstr "Audio immer als AC3 erzwingen" + +#: +msgctxt "#32067" +msgid "Only force multichannel audio to AC3" +msgstr "Nur Mehrkanal-Audio als AC3 erzwingen" + +#: +msgctxt "#32493" +msgid "When a media file has a forced/foreign subtitle for a subtitle-enabled language, the Plex Media Server preselects it. This behaviour is usually not necessary and not configurable. This setting fixes that by ignoring the PMSs decision and selecting the same language without a forced flag if possible." +msgstr "Hat eine Mediendatei erzwungenge Untertitel für eine Sprache, bei der Untertitel erwünscht sind, wählt der Plex Media Server diesen standardmäßig aus. Das Verhalten ist normalerweise unerwünscht und nicht konfigurierbar. Diese Einstellung behebt das Problem, indem versucht wird, einen Untertitel der selben Sprache ohne Erzwungen-Markierung zu wählen." + +#: +msgctxt "#32523" +msgid "Automatically skip intros if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Automatisches Überspringen vorhandener Intros. Überschreibt aktivierten Binge-Modus nicht.\n" +"Kann pro Serie aktiviert/deaktiviert werden." + +#: +msgctxt "#32527" +msgid "Automatically skip credits if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Automatisches Überspringen von vorhandenem Abspann. Überschreibt aktivierten Binge-Modus nicht.\n" +"Kann pro Serie aktiviert/deaktiviert werden." +#: msgctxt "#33501" msgid "Video played threshold" msgstr "Video-abgespielt-Grenzwert" +#: msgctxt "#33502" msgid "Set this to the same value as your Plex server (Settings>Library>Video played threshold) to avoid certain pitfalls, Default: 90 %" -msgstr "Auf dem selben wert wie im Plex server setzen (Einstellungen>Mediathek>Video played threshold) um bestimmte Fehler zu umgehen, Standardwert: 90 %" +msgstr "Auf den selben Wert wie im Plex-Server setzen (unter Einstellungen > Mediathek zu finden), um bestimmte Fehler zu umgehen; Standardwert: 90 %" +#: msgctxt "#33503" msgid "Use alternative hubs refresh" msgstr "Alternative Aktualisierung der Hubs" +#: msgctxt "#33504" msgid "Refreshes all hubs for all libraries after an item's watch-state has changed, instead of only those likely affected. Use this if you find a hub that doesn't update properly." msgstr "Aktualisiert alle Hubs aller Bibliotheken, anstatt nur die, die möglicherweise zutreffend sind, nachdem sich der Abspielstatus eines Items geändert hat. Benutzen, wenn sich ein Hub nicht aktualisiert." +#: msgctxt "#33505" msgid "Show intro skip button early" -msgstr "Intro überspringen früher anzeigen" +msgstr "'Intro überspringen' früher anzeigen" +#: msgctxt "#33506" -msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn\'t override enabled binge mode.\nCan be disabled/enabled per TV show." -msgstr "Zeige den Intro-Überspringen-Knopf von Anfang an. Die Automatische-Intro-Überspringen-Einstellung wird angewandt. Überschreibt aktivierten Binge-Modus nicht.\nKann pro Serie aktiviert/deaktiviert werden." +msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Zeige den 'Intro überspringen'-Knopf von Anfang an. Die 'Automatisch überspringen'-Einstellung wird weiterhin angewandt. Überschreibt aktivierten Binge-Modus nicht.\n" +"Kann pro Serie aktiviert/deaktiviert werden." +#: msgctxt "#33507" msgid "Enabled" msgstr "Aktiviert" +#: msgctxt "#33508" msgid "Disabled" msgstr "Deaktiviert" +#: msgctxt "#33509" msgid "Early intro skip threshold (default: < 60s/1m)" -msgstr "Frühes Intro-Überspringen Grenzwert (default: < 60s/1m)" +msgstr "Grenzwert für 'Früher Intro überspringen' (Standardwert < 60s)" +#: msgctxt "#33510" -msgid "When showing the intro skip button early, only do so if the intro starts within the first X seconds." -msgstr "Wenn der Into-Überspringen-Knopf früher angezeigt werden soll, nur anzeigen, wenn das Intro innerhalb der ersten X Sekunden startet." +msgid "When showing the intro skip button early, only do so if the intro occurs within the first X seconds." +msgstr "Wenn der 'Intro überspringen'-Knopf früher angezeigt werden soll, nur anzeigen, wenn das Intro innerhalb der ersten X Sekunden startet." +#: msgctxt "#33600" msgid "System" msgstr "System" +#: msgctxt "#33601" msgid "Show video chapters" msgstr "Video-Kapitel anzeigen" +#: msgctxt "#33602" msgid "If available, show video chapters from the video-file instead of the timeline-big-seek-steps." msgstr "Wenn verfügbar, Video-Kapitel aus der Video-Datei anstatt der Zeitleiste-Big-Seek-Schritte anzeigen." +#: msgctxt "#33603" msgid "Use virtual chapters" msgstr "Virtuelle Kapitel verwenden" +#: msgctxt "#33604" msgid "When the above is enabled and no video chapters are available, simulate them by using the markers identified by the Plex Server (Intro, Credits)." -msgstr "Wenn die obrige aktiviert ist und keine Video-Kapitel verfügbar sind, virtuelle Kapitel aus den Plex Server Markern (Intro, Abspann) erzeugen." +msgstr "Wenn die obige Option aktiviert ist und keine Video-Kapitel verfügbar sind, virtuelle Kapitel aus den Plex-Server-Markern (Intro, Abspann) erzeugen." +#: msgctxt "#33605" msgid "Video Chapters" msgstr "Video-Kapitel" +#: msgctxt "#33606" msgid "Virtual Chapters" msgstr "Virtuelle Kapitel" +#: msgctxt "#33607" msgid "Chapter {}" msgstr "Kapitel {}" +#: msgctxt "#33608" msgid "Intro" msgstr "Intro" +#: msgctxt "#33609" msgid "Credits" msgstr "Abspann" +#: msgctxt "#33610" msgid "Main" msgstr "Haupt" +#: msgctxt "#33611" msgid "Chapters" msgstr "Kapitel" +#: msgctxt "#33612" msgid "Markers" msgstr "Markierungen" +#: msgctxt "#33613" msgid "Kodi Buffer Size (MB)" msgstr "Kodi Puffergröße (MB)" +#: msgctxt "#33614" -msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~100 MB, Recommended max: {} MB, Default: 20 MB." -msgstr "Setzt die Kodi Cache/Puffer Größe. Frei: {} MB, empfohlen: ~100 MB, empfohlenes Max.: {} MB, Default: 20 MB." +msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~50 MB, Recommended max: {} MB, Default: 20 MB." +msgstr "Setzt die Kodi Cache/Puffer Größe. Frei: {} MB, empfohlen: ~50 MB, empfohlenes Max.: {} MB, Default: 20 MB." +#: msgctxt "#33615" msgid "{time} left" msgstr "{time} übrig" +#: msgctxt "#33616" msgid "Addon Path" msgstr "Addon-Pfad" +#: msgctxt "#33617" msgid "Userdata/Profile Path" msgstr "Benutzerdaten-/Profilpfad" +#: msgctxt "#33618" msgid "TV binge-viewing mode" -msgstr "TV Binge-Viewing-Modus" +msgstr "TV-Binge-Viewing-Modus" +#: msgctxt "#33619" -msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn\'t skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n\nCan be disabled/enabled per TV show.\nOverrides any setting below." -msgstr "Überspringt automatisch Intros und Abspänne von Episoden und versucht Recaps zu vermeiden. Überspringt das Intro der ersten Episode einer Staffel und den Abspann der letzten Episode einer Serie nicht.\n\nKann pro Serie aktiviert/deaktiviert werden.\nÜberschreibt jegliche Einstellung unterhalb dieser." +msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn't skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n" +"\n" +"Can be disabled/enabled per TV show.\n" +"Overrides any setting below." +msgstr "Überspringt automatisch Intros und Abspänne von Episoden und versucht Recaps zu vermeiden. Überspringt das Intro der ersten Episode einer Staffel und den Abspann der letzten Episode einer Serie nicht.\n" +"\n" +"Kann pro Serie aktiviert/deaktiviert werden.\n" +"Überschreibt jegliche Einstellung unterhalb dieser." +#: msgctxt "#33620" -msgid "Plex requests timeout (seconds)" -msgstr "Plex HTTP Zeitlimit (Sekunden)" +msgid "Plex server connect timeout" +msgstr "Plex-Serververbindungs-Zeitlimit" +#: msgctxt "#33621" -msgid "Set the (async and connection) timeout value of the Python requests library in seconds. Default: 5 seconds" -msgstr "Setzt das Zeitlimit für die Python Requests Bibliothek bei asynchronen Verbindungen und Verbindungsanfragen. Default: 5 Sekunden" +msgid "Sets the maximum amount of time to connect to a Plex Server in seconds. Default: 5" +msgstr "Setzt das Zeitlimit um sich mit einem Plex-Server zu verbinden, in Sekunden. Voreinstellung: 5" +#: msgctxt "#33622" msgid "LAN reachability timeout (ms)" msgstr "LAN-Erreichbarkeits-Zeitlimit (ms)" +#: msgctxt "#33623" -msgid "When checking for Server-in-LAN reachability, use this timeout. Default: 10ms" +msgid "When checking for LAN reachability, use this timeout. Default: 10ms" msgstr "Wenn die lokale Serververbindung im LAN überprüft wird, benutze dieses Zeitlimit. Default: 10ms" +#: msgctxt "#33624" msgid "Network" msgstr "Netzwerk" +#: msgctxt "#33625" msgid "Smart LAN/local server discovery" -msgstr "Smartes LAN/lokale Server-Auffinden" +msgstr "Smartes LAN/lokale Server auffinden" +#: msgctxt "#33626" -msgid "Checks whether servers returned from Plex.tv are actually local/in your LAN. For specific setups (e.g. Docker) Plex.tv might not properly detect a local server.\n\nNOTE: Only works on Kodi 19 or above." -msgstr "Überprüft, ob von Plex.tv zurückgegebene Server tatsächlich lokal/in Deinem LAN sind. Für bestimmte Setups (z. B. Docker) könnte Plex.tv einen lokalen Servern nicht als solchen entdecken.\n\nACHTUNG: Funktioniert nur unter Kodi 19 oder neuer." +msgid "Checks whether servers returned from Plex.tv are actually local/in your LAN. For specific setups (e.g. Docker) Plex.tv might not properly detect a local server.\n" +"\n" +"NOTE: Only works on Kodi 19 or above." +msgstr "Überprüft, ob von Plex.tv zurückgegebene Server tatsächlich lokal/in Deinem LAN sind. Für bestimmte Setups (z. B. Docker) könnte Plex.tv einen lokalen Server nicht als solchen entdecken.\n" +"\n" +"ACHTUNG: Funktioniert nur mit Kodi 19 oder neuer." +#: msgctxt "#33627" msgid "Prefer LAN/local servers over security" msgstr "LAN/lokale Server bevorzugen" +#: msgctxt "#33628" msgid "Prioritizes local connections over secure ones. Needs the proper setting in \"Allow Insecure Connections\" and the Plex Server's \"Secure connections\" at \"Preferred\". Can be used to enforce manual servers." -msgstr "Priorisiert lokale Verbindungen über sichere. Benötigt die korrekte Einstellung in \"Unsichere Verbindung erlauben\" und die Plex Server Einstellung \"Sichere Verbindungen\" auf \"Bevorzugt\". Kann verwendet werden um manuelle Server zu forcieren." +msgstr "Priorisiert lokale Verbindungen über sichere. Benötigt die korrekte Einstellung in \"Unsichere Verbindung erlauben\" und die Plex-Server-Einstellung \"Sichere Verbindungen\". Kann verwendet werden, um manuelle Server zu forcieren." +#: msgctxt "#33629" msgid "Auto-skip intro/credits offset" msgstr "Auto-Überspringen-Versatz" +#: msgctxt "#33630" msgid "Intro/credits markers might be a little early in Plex. When auto skipping add (or subtract) this many seconds from the marker. This avoids cutting off content, while possibly skipping the marker a little late." -msgstr "Intro-/Abspann-Markierungen können ein wenig früh erscheinen in Plex. Wenn diese automatisch übersprungen werden sollen, addiere (oder subtrahiere) diese Menge an Sekunden. Das verhindert das verfrühte Abschneiden von Inhalten, kann aber zu etwas verspätetem Springen führen." +msgstr "Intro-/Abspann-Markierungen können zeitversetzt sein. Um passend automatisch zu überspringen, addiere (oder subtrahiere) die eingestellte Menge an Sekunden. Das verhindert das verfrühte Abschneiden von Inhalten, kann aber zu etwas verspätetem Springen führen." +#: msgctxt "#32631" msgid "Playback (user-specific)" msgstr "Wiedergabe (benutzerspezifisch)" +#: msgctxt "#33632" msgid "Server connectivity check timeout (seconds)" -msgstr "Server Konnektivitätscheck-Timeout (Sekunden)" +msgstr "Timeout für Server-Konnektivitäts-Check (Sekunden)" +#: msgctxt "#33633" msgid "Set the maximum amount of time a server connection has to answer a connectivity request. Default: 2.5" msgstr "Setzt die maximale Zeit, in der eine Serververbindung antworten muss. Voreinstellung: 2.5" +#: msgctxt "#33634" msgid "Combined Chapters" msgstr "Kombinierte Kapitel" +#: msgctxt "#33635" msgid "Final Credits" msgstr "Finaler Abspann" +#: msgctxt "#32700" msgid "Action on Sleep event" msgstr "Aktion bei Sleep-Ereignis" +#: msgctxt "#32701" msgid "When Kodi receives a sleep event from the system, run the following action." msgstr "Wenn Kodi ein Sleep-Ereignis vom System erhält, folgende Aktion ausführen." +#: msgctxt "#32702" msgid "Nothing" msgstr "Nichts" +#: msgctxt "#32703" msgid "Stop playback" msgstr "Abspielen stoppen" +#: msgctxt "#32704" msgid "Quit Kodi" msgstr "Kodi beenden" +#: msgctxt "#32705" msgid "CEC Standby" msgstr "CEC Standby" +#: msgctxt "#32800" msgid "Skipping intro" msgstr "Überspringe Intro" +#: msgctxt "#32801" msgid "Skipping credits" msgstr "Überspringe Abspann" +#: msgctxt "#32900" msgid "While playing back an item and seeking on the seekbar, automatically seek to the selected position after a delay instead of having to confirm the selection." msgstr "Wird während des Abspielens die Position auf der Zeitleiste verändert, automatisch nach einer Verzögerung auf die gewählte Position springen, ohne diese bestätigen zu müssen." +#: msgctxt "#32901" msgid "Seek delay in seconds." msgstr "Sprungverzögerung in Sekunden." +#: msgctxt "#32902" msgid "Kodi has its own skip step settings. Try to use them if they're configured instead of the default ones." -msgstr "Kodi besitzt seine eigenen Sprungeinstellungen. Versuche diese anstatt der standardmäßigen zu verwenden, sollten sie konfiguriert sein." +msgstr "Kodi besitzt seine eigenen Sprungeinstellungen. Versuche diese zu verwenden, sollten sie konfiguriert sein." +#: msgctxt "#32903" msgid "Use the above for seeking on the timeline as well." -msgstr "Benutze die obrige Einstellung auch für die Zeitleiste." +msgstr "Benutze die obige Einstellung auch für die Zeitleiste." +#: msgctxt "#32904" msgid "In seconds." msgstr "In Sekunden." +#: msgctxt "#32905" msgid "Cancel post-play timer by pressing OK/SELECT" -msgstr "Post-Play Timer durch OK/AUSWAHL abbrechen" +msgstr "Post-Play-Timer durch OK/AUSWAHL abbrechen" +#: msgctxt "#32906" msgid "Cancel skip marker timer with BACK" msgstr "Markierung überspringen durch Zurück-Taste abbrechen" +#: msgctxt "#32907" msgid "When auto-skipping a marker, allow cancelling the timer by pressing BACK." msgstr "Wenn eine Markierung mit einem Zeitgeber automatisch übersprungen wird, durch Zurück-Taste abbrechen." +#: msgctxt "#32908" msgid "Immediately skip marker with OK/SELECT" msgstr "Markierung sofort überspringen mit OK/AUSWAHL" +#: msgctxt "#32909" msgid "When auto-skipping a marker with a timer, allow skipping immediately by pressing OK/SELECT." msgstr "Wenn eine Markierung mit einem Zeitgeber automatisch übersprungen wird, durch OK/AUSWAHL-Taste sofort überspringen." +#: msgctxt "#32912" msgid "Show buffer-state on timeline" msgstr "Zeige Puffer-Stand auf Zeitachse" +#: msgctxt "#32913" msgid "Shows the current Kodi buffer/cache state on the video player timeline." -msgstr "Zeigt den aktuellen Kodi Puffer/Cache-Stand auf der Videoplayer Zeitachse." +msgstr "Zeigt den aktuellen Kodi-Puffer/Cache-Stand auf der Videoplayer-Zeitachse." +#: msgctxt "#32914" msgid "Loading" msgstr "Lädt" +#: msgctxt "#32915" msgid "Slow connection" msgstr "Langsame Verbindung" +#: msgctxt "#32916" msgid "Use with a wonky/slow connection, e.g. in a hotel room. Adjusts the UI to visually wait for item refreshes and waits for the buffer to fill when starting playback. Automatically sets readfactor=20, requires Kodi restart." -msgstr "Bei langsamer Verbindung benutzen, z.B. im Hotel. Passt die Oberfläche visuell an um auf Media Auffrischungen zu warten und füllt den Kodi Puffer vor dem Abspielen. Setzt automatisch Kodi Cache readfactor=20, benötigt einen Kodi Neustart." +msgstr "Bei langsamer Verbindung benutzen, z.B. im Hotel. Passt die Oberfläche visuell an, um auf Medien-Auffrischungen zu warten, und füllt den Kodi-Puffer vor dem Abspielen. Setzt automatisch Kodi-Cache readfactor=20. Benötigt einen Kodi-Neustart." +#: msgctxt "#32917" msgid "Couldn't fill buffer in time ({}s)" msgstr "Konnte den Puffer nicht schnell genug füllen ({} Sek.)" +#: msgctxt "#32918" msgid "Buffer wait timeout (seconds)" msgstr "Puffer-Wartezeit (Sekunden)" +#: msgctxt "#32919" msgid "When slow connection is enabled in the addon, wait this long for the buffer to fill. Default: 120 s" -msgstr "Wenn Langsame Verbindung im Addon aktiviert ist, warte so lange bis der Puffer gefüllt ist. Voreinstellung: 120 Sek." +msgstr "Wenn 'Langsame Verbindung' im Addon aktiviert ist, warte so lange, bis der Puffer gefüllt ist. Voreinstellung: 120 Sek." +#: msgctxt "#32920" msgid "Insufficient buffer wait (seconds)" -msgstr "Ungenügender Puffer Wartezeit (Sekunden)" +msgstr "Ungenügender-Puffer-Wartezeit (Sekunden)" +#: msgctxt "#32921" -msgid "When slow connection is enabled in the addon and the configured cache/buffer isn't big enough for us to determine its fill state, wait this long when starting playback. Default: 10 s" -msgstr "Wenn \"Langsame Verbindung\" im Addon aktiviert ist und der konfigurierte Puffer/Cache nicht groß genug ist, um seinen Füllstand zu ermitteln, wird so lange gewartet, bevor die Wiedergabe gestartet wird. Voreinstellung: 10 Sek." +msgid "When slow connection is enabled in the addon and the configured buffer isn't big enough for us to determine its fill state, wait this long when starting playback. Default: 10 s" +msgstr "Wenn 'Langsame Verbindung' im Addon aktiviert ist und der konfigurierte Puffer/Cache nicht groß genug ist, um seinen Füllstand zu ermitteln, wird so lange gewartet, bevor die Wiedergabe gestartet wird. Voreinstellung: 10 Sek." +#: msgctxt "#32922" msgid "Kodi Cache Readfactor" -msgstr "Kodi Puffer Readfactor" +msgstr "Kodi-Puffer/Cache-Readfactor" +#: msgctxt "#32923" msgid "Sets the Kodi cache readfactor value. Default: {0}, recommended: {1}. With \"Slow connection\" enabled this will be set to {2}, as otherwise the cache doesn't fill fast/aggressively enough." -msgstr "Setzt den Kodi Cache/Puffer readfactor Wert. Standard: {0}, Empfohlen: {1}. Bei aktivem \"Langsame Verbindung\" wird dies automatisch auf {2} gesetzt, da ansonsten der Cache nicht schnell/agressiv genug gefüllt wird." +msgstr "Setzt den Kodi-Cache/Puffer-Readfactor-Wert. Standard: {0}, Empfohlen: {1}. Bei aktivem 'Langsame Verbindung' wird dies automatisch auf {2} gesetzt, da ansonsten der Cache nicht schnell/agressiv genug gefüllt wird." +#: msgctxt "#32924" msgid "Minimize" msgstr "Minimieren" +#: msgctxt "#32925" msgid "Playback Settings" -msgstr "Abspieleinstell." +msgstr "Abspieleinstellungen" +#: msgctxt "#32926" msgid "Wrong pin entered!" msgstr "Falsche PIN eingegeben!" +#: msgctxt "#32927" msgid "Use episode thumbnails in continue hub" msgstr "Vorschaubild für Episoden im Fortsetzen-Hub verwenden" +#: msgctxt "#32928" msgid "Instead of using media artwork, use thumbnails for episodes in the continue hub on the home screen if available." msgstr "Verwende Vorschaubilder anstatt Media-Artwork für Episoden im Fortsetzen-Hub auf der Start-Ansicht." +#: msgctxt "#32929" msgid "Use legacy background fallback image" -msgstr "Veraltetes Ausweich-Hintergrundbild verwenden" +msgstr "Klassisches Ausweichhintergrundbild verwenden" +#: msgctxt "#32930" msgid "Previous Subtitle" msgstr "Vorheriger Untertitel" +#: msgctxt "#32931" msgid "Audio/Subtitles" msgstr "Audio/Untertitel" +#: msgctxt "#32932" -msgid "Show subtitle quick-actions button" -msgstr "Zeige Untertitel-Schnellaktionen-Knopf" +msgid "Subtitle quick-actions" +msgstr "Untertitel-Schnellaktionen" +#: msgctxt "#32933" -msgid "Show FFWD/RWD buttons" -msgstr "Zeige Vorspulen-Zurückspulen-Knopf" +msgid "FFWD/RWD" +msgstr "Vor-/Zurückspulen" +#: msgctxt "#32934" -msgid "Show repeat button" -msgstr "Zeige Wiederholen-Knopf" +msgid "Repeat" +msgstr "Wiederholen" +#: msgctxt "#32935" -msgid "Show shuffle button" -msgstr "Zeige Zufällige-Wiedergabe-Knopf" +msgid "Shuffle" +msgstr "Zufällige-Wiedergabe" +#: msgctxt "#32936" msgid "Show playlist button" msgstr "Zeige Wiedergabeliste-Knopf" +#: msgctxt "#32937" msgid "Show prev/next button" msgstr "Zeige Vorheriger/Nächster-Knopf" -msgctxt "#32938" -msgid "Only for Episodes" -msgstr "Nur bei Episoden" - +#: msgctxt "#32939" -msgid "Only applies to video player UI" -msgstr "Gilt nur für die Video Abspieloberfläche" +msgid "User-specific.\n" +"Only applies to video player UI" +msgstr "Benutzerspezifisch.\n" +"Gilt nur für die Video-Abspieloberfläche" +#: msgctxt "#32940" -msgid "Player UI" -msgstr "Abspieloberfläche" +msgid "Video Player" +msgstr "Video-Player" +#: msgctxt "#32941" msgid "Forced subtitles fix" msgstr "Erzwungene Untertitel beheben" +#: msgctxt "#32942" msgid "Other seasons" msgstr "Weitere Staffeln" +#: msgctxt "#32943" msgid "Crossfade dynamic background art" msgstr "Dynamische Hintergrundbilder überblenden" +#: msgctxt "#32944" msgid "Burn-in SSA subtitles (DirectStream)" msgstr "SSA-Untertitel einbrennen (DirectStream)" +#: msgctxt "#32945" msgid "When Direct Streaming instruct the Plex Server to burn in SSA/ASS subtitles (thus transcoding the video stream). If disabled it will not touch the video stream, but will convert the subtitle to unstyled text." -msgstr "Wird Direct Streaming verwendet, den Plex Server dazu bringen, SSA/ASS-Untertitel einzubrennen (also den Video Stream zu transcoden). Wenn deaktiviert, wird dieser den Video Stream nicht anfassen, jedoch den Untertitel als reinen Text anzeigen." +msgstr "Wird Direct Streaming verwendet, den Plex-Server dazu bringen, SSA/ASS-Untertitel einzubrennen (mit Video-Stream-Transcode). Wenn deaktiviert, wird der Video-Stream nicht verändert, jedoch der Untertitel zu reinem Text konvertiert." +#: msgctxt "#32946" msgid "Stop video playback on idle after" msgstr "Bei Inaktivität Video stoppen nach" +#: msgctxt "#32947" msgid "Stop video playback on screensaver" msgstr "Video stoppen bei Bildschirmschoner" +#: msgctxt "#32948" msgid "Allow auto-skip when transcoding" msgstr "Überspringen beim Transkodieren erlauben" +#: msgctxt "#32949" msgid "When transcoding/DirectStreaming, allow auto-skip functionality." msgstr "Beim Transkodieren/DirectStream die automatische Überspringen-Funktionalität erlauben." +#: msgctxt "#32950" msgid "Use extended title for subtitles" msgstr "Erweiterten Titel für Untertitel verwenden" +#: msgctxt "#32951" msgid "When displaying subtitles use the extendedDisplayTitle Plex exposes." msgstr "Verwende erweiterte Namen wenn Untertitelnamen angezeigt werden." -msgctxt "#32952" -msgid "Dialog-Flackern beheben" -msgstr "" - +#: msgctxt "#32953" msgid "Reviews" msgstr "Kritik" +#: msgctxt "#32954" -msgid "Needs Kodi restart. WARNING: This will overwrite advancedsettings.xml!\n\nTo customize other cache/network-related values, copy \"script.plexmod/pm4k_cache_template.xml\" to profile folder and edit it to your liking. (See About section for the file paths)" -msgstr "Benötigt Kodi Neustart. ACHTUNG: Überschreibt advancedsettings.xml!\n\nUm weitere Cache-/Netzwerkbezogene Werte zu ändern, kopiere \"script.plexmod/pm4k_cache_template.xml\" in den Profilordner und editiere sie. (Für die Dateipfade schaue in die Über-Sektion)" +msgid "Needs Kodi restart. WARNING: This will overwrite advancedsettings.xml!\n" +"\n" +"To customize other cache/network-related values, copy \"script.plexmod/pm4k_cache_template.xml\" to profile folder and edit it to your liking. (See About section for the file paths)" +msgstr "Benötigt Kodi-Neustart. ACHTUNG: Überschreibt advancedsettings.xml!\n" +"\n" +"Um weitere Cache-/Netzwerkbezogene Werte zu ändern, kopiere \"script.plexmod/pm4k_cache_template.xml\" in den Profilordner und editiere sie. (Für die Dateipfade schaue in Abschnitt 'Über')" +#: msgctxt "#32955" msgid "Use Kodi keyboard for searching" msgstr "Kodi-Tastatur bei der Suche verwenden" +#: msgctxt "#32956" msgid "Poster resolution scaling %" msgstr "Poster Auflösungsskalierung %" +#: msgctxt "#32957" -msgid "In percent. Scales the resolution of all posters/thumbnails for better image quality. May impact PMS/PM4K performance, will increase the cache usage accordingly. Recommended: 200-300 % for big screens if your hardware can handle it. Needs addon restart." -msgstr "In Prozent. Skaliert die Auflösung aller Poster/Vorschaubilder für bessere Bildqualität. Kann die PMS/PM4K Performance beeinflussen, wird die Cache-Nutzung dementsprechend erhöhen. Empfohlen: 200-300 % für große Bildschirme, wenn die Hardware damit umgehen kann. Benötigt Addon-Neustart." +msgid "In percent. Scales the resolution of all posters/thumbnails for better image quality. May impact PMS/PM4K performance, will increase the cache usage accordingly. Recommended: 200-300 % for for big screens if your hardware can handle it. Needs addon restart." +msgstr "In Prozent. Skaliert die Auflösung aller Poster/Vorschaubilder für bessere Bildqualität. Kann die PMS/PM4K Performance beeinflussen; wird die Cache-Nutzung dementsprechend erhöhen. Empfohlen: 200-300 % für große Bildschirme, wenn die Hardware damit umgehen kann. Benötigt Addon-Neustart." +#: msgctxt "#32958" msgid "Calculate OpenSubtitles.com hash" -msgstr "OpenSubtitles.com Prüfsumme berechnen" +msgstr "OpenSubtitles.com-Prüfsumme berechnen" +#: msgctxt "#32959" msgid "When opening the subtitle download feature, automatically calculate the OpenSubtitles.com hash for the given file. Can improve search results, downloads 2*64 KB of the video file to calculate the hash." msgstr "Beim Öffnen der Untertitel-Herunterladen-Funktion die Prüfsumme der Datei für OpenSubtitles.com automatisch berechnen. Kann die Suchergebnisse verbessern, lädt 2*64 KB der Videodatei herunter um die Prüfsumme zu berechnen." +#: msgctxt "#32960" msgid "Similar Artists" msgstr "Ähnliche Künstler" +#: msgctxt "#32961" msgid "Show hub bifurcation lines" msgstr "Hub-Trennlinie anzeigen" +#: msgctxt "#32962" msgid "Visually separate hubs horizontally using a thin line." msgstr "Trennt Hubs visuell horizontal mit Hilfe einer dünnen Linie." +#: msgctxt "#32963" msgid "Wait between videos (s)" -msgstr "Zwischen Videos warten (s)" +msgstr "Zwischen Videos warten (in Sekunden)" +#: msgctxt "#32964" msgid "When playing back consecutive videos (e.g. TV shows), wait this long before starting the next one in the queue. Might fix compatibility issues with certain configurations." msgstr "Werden aufeinanderfolgende Videos abgespielt (z. B. Serien), so lange warten, bis das nächste Video in der Warteschlange abgespielt wird. Könnte Kompatibilitätsprobleme mit gewissen Konfigurationen beheben." +#: msgctxt "#32965" msgid "Quit Kodi on exit by default" -msgstr "Kodi beenden anstatt PM4K" +msgstr "Bei Beenden von PM4K auch Kodi beenden" +#: msgctxt "#32966" -msgid "When showing the addon exit confirmation, use \"Quit Kodi\" as default option. Can be dynamically switched using CONTEXT_MENU (often longpress SELECT)" -msgstr "Wenn die Addon-Beendigungsbestätigung angezeigt wird, \"Kodi beenden\" als Standardoption verwenden. Kann dynamisch mit CONTEXT_MENU (oft lange gedrücktes SELECT) getauscht werden." +msgid "When exiting the addon, use \"Quit Kodi\" as default option. Can be dynamically switched using CONTEXT_MENU (often longpress SELECT)" +msgstr "Wenn das Addon beendet wird, \"Kodi beenden\" als Standardoption verwenden. Kann dynamisch mit CONTEXT_MENU (oft lange gedrücktes SELECT) getauscht werden." +#: msgctxt "#32967" msgid "Kodi Colour Management" -msgstr "Kodi Farbeinstellungen" +msgstr "Kodi-Farbeinstellungen" +#: msgctxt "#32968" msgid "Kodi Resolution Settings" -msgstr "Kodi Auflösungseinstellungen" +msgstr "Kodi-Auflösungseinstellungen" +#: msgctxt "#32969" msgid "Always request all library media items at once" msgstr "Immer die vollständige Bibliothek laden" +#: msgctxt "#32970" msgid "Retrieve all media in library up front instead of fetching it in chunks as the user navigates through the library" msgstr "Alle Medieninhalte einer Bibliothek anfordern, anstatt diese gestückelt nachzuladen" +#: msgctxt "#32971" msgid "Library item-request chunk size" -msgstr "Bibliothek Anfrage-Blockgröße" +msgstr "Bibliotheksanfrage-Blockgröße" +#: msgctxt "#32972" msgid "Request this amount of media items per chunk request in library view (+6-30 depending on view mode; less can be less straining for the UI at first, but puts more strain on the server)" msgstr "Diese Anzahl an Medieninhalten pro gestückelter Anfrage in der Bibliothekenansicht laden (+6-30 abhängig von der Ansicht; weniger kann vorerst geringere UI-Last bedeuten, aber mehr Last beim Server erzeugen)" +#: msgctxt "#32973" msgid "Episodes: Skip Post Play screen" msgstr "Direkt zur nächsten Episode springen" +#: msgctxt "#32974" -msgid "When finishing an episode, don't show Post Play but go to the next one immediately.\nCan be disabled/enabled per TV show. Doesn't override enabled binge mode. Overrides the Post Play setting." -msgstr "Beim Beenden einer Episode nicht in die Post Play Ansicht gehen und stattdessen sofort zur nächsten Episode springen.\nCan be disabled/enabled per TV show. Überschreibt aktivierten Binge-Modus nicht. Überschreibt die \"Automatisch nächsten Titel abspielen\"-Einstellung" +msgid "When finishing an episode, don't show Post Play but go to the next one immediately.\n" +"Can be disabled/enabled per TV show. Doesn't override enabled binge mode. Overrides the Post Play setting." +msgstr "Beim Beenden einer Episode nicht in die Post-Play-Ansicht gehen und stattdessen sofort zur nächsten Episode springen.\n" +"Kann pro TV-Sendung eingestellt werden. Überschreibt aktivierten Binge-Modus nicht. Überschreibt die \"Automatisch nächsten Titel abspielen\"-Einstellung." +#: msgctxt "#32975" msgid "Delete Season" msgstr "Staffel löschen" +#: msgctxt "#32976" msgid "Adaptive" msgstr "Adaptiv" +#: msgctxt "#32977" -msgid "Allow VC1" -msgstr "VC1 zulassen" +msgid "VC1" +msgstr "VC1" +#: msgctxt "#32978" msgid "Enable this if your hardware can handle VC1. Disable it to force transcoding." msgstr "Diese Option aktivieren, wenn die Hardware VC1 verarbeiten kann. Deaktivieren, um die Transkodierung zu erzwingen." +#: msgctxt "#32979" msgid "Allows the server to only transcode streams of a video that need transcoding, while streaming the others unaltered. If disabled, force the server to transcode everything not direct playable." msgstr "Erlaubt dem Server nur Streams eines Videos zu transkodieren, die dies benötigen, während die anderen unverändert übertragen werden. Ist dies deaktiviert, wird der Server dazu gezwungen, alles zu transkodieren, was nicht direkt abspielbar ist." +#: msgctxt "#32980" msgid "Refresh Users" -msgstr "Benutzer aktual." +msgstr "Benutzer aktualisieren" + +#: +msgctxt "#32981" +msgid "Background worker count" +msgstr "Anzahl Hintergrund-Worker" + +#: +msgctxt "#32982" +msgid "Depending on how many cores your CPU has and how much it can handle, increasing this might improve certain situations. If you experience crashes or other annormalities, leave this at its default (3). Needs an addon restart." +msgstr "Je nachdem, wie viele Kerne Deine CPU hat und wie viel sie verarbeiten kann, kann eine höhere Zahl bestimmte Situationen verbessern. Solltest Du Abstürze oder andere Anomalien bemerken, stelle dies auf den Standardwert zurück (3). Benötigt einen Addon-Neustart." + +#: +msgctxt "#32983" +msgid "Theme" +msgstr "Aussehen" + +#: +msgctxt "#32984" +msgid "Sets the theme. Currently only customizes all control buttons. ATTENTION: [I]Might[/I] need an addon restart.\n" +"In order to customize this, copy one of the xml's in script.plexmod/resources/skins/Main/1080i/templates to addon_data/script.plexmod/templates/{templatename}_custom.xml and adjust it to your liking, then select \"Custom\" as your theme." +msgstr "Bestimmt das Aussehen. Verändert aktuell alle Abspiel-Knöpfe. ACHTUNG: Ein Addon-Neustart [I]könnte[/I] notwendig sein.\n" +"Um dies individuell anzupassen, kopiere eine der xml's aus script.plexmod/resources/skins/Main/1080i/templates nach addon_data/script.plexmod/templates/{templatename}_custom.xml und passe es nach Deinen Ansprüchen an; danach \"Individualisiert\" als Aussehen wählen." + +#: +msgctxt "#32985" +msgid "Modern" +msgstr "Modern" + +#: +msgctxt "#32986" +msgid "Modern (dotted)" +msgstr "Modern (gepunktet)" + +#: +msgctxt "#32987" +msgid "Classic" +msgstr "Klassisch" + +#: +msgctxt "#32988" +msgid "Custom" +msgstr "Individualisiert" + +#: +msgctxt "#32989" +msgid "Modern (colored)" +msgstr "Modern (eingefärbt)" + +#: +msgctxt "#32990" +msgid "Handle plex.direct mapping" +msgstr "plex.direct-Zuordnung abwickeln" + +#: +msgctxt "#32991" +msgid "Notify" +msgstr "Benachrichtigen" + +#: +msgctxt "#32992" +msgid "When using servers with a plex.direct connection (most of them), should we automatically adjust advancedsettings.xml to cope with plex.direct domains? If not, you might want to add plex.direct to your router's DNS rebind exemption list." +msgstr "Wenn Server mit einer plex.direct Verbindung verwendet werden (die meisten), sollen wir automatisch die advancedsettings.xml anpassen? Wenn nicht, solltest Du plex.direct in die DNS Rebind Ausschlussliste Deines Routers eintragen." + +#: +msgctxt "#32993" +msgid "{} unhandled plex.direct connections found" +msgstr "{} unbehandelte plex.direct-Verbindungen gefunden" + +#: +msgctxt "#32994" +msgid "In order for PM4K to work properly, we need to add special handling for plex.direct connections. We've found {} new unhandled connections. Do you want us to write those to Kodi's advancedsettings.xml automatically? If not, you might want to add plex.direct to your router's DNS rebind exemption list. This can be changed in the settings as well." +msgstr "Damit PM4K korrekt funktioniert, müssen wir spezielles Handling für plex.direct-Verbindungen einrichten. Es wurden {} neue unbehandelte Verbindungen gefunden. Sollen wir diese in Kodis advancedsettings.xml eintragen? Wenn nicht, solltest Du plex.direct in die DNS-Rebind-Ausschlussliste Deines Routers eintragen. Dies kann später in den Einstellungen verändert werden." + +#: +msgctxt "#32995" +msgid "Advancedsettings.xml modified (plex.direct mappings)" +msgstr "Advancedsettings.xml modifiziert (plex.direct mappings)" + +#: +msgctxt "#32996" +msgid "The advancedsettings.xml file has been modified. Please restart Kodi for the changes to apply." +msgstr "Die advancedsettings.xml-Datei wurde modifiziert. Bitte starte Kodi neu, damit die Änderungen angewandt werden." + +#: +msgctxt "#32997" +msgid "OK" +msgstr "OK" + +#: +msgctxt "#32998" +msgid "Use new Continue Watching hub on Home" +msgstr "Neuen 'Weiterschauen'-Home-Hub verwenden" + +#: +msgctxt "#32999" +msgid "Instead of separating Continue Watching and On Deck hubs, behave like the modern Plex clients, which combine those two types of hubs into one Continue Watching hub." +msgstr "Anstatt von separaten 'Fortsetzen' und 'Als nächstes'-Hubs, kombiniere beide in einen einzigen 'Weiterschauen'-Hub, wie bei anderen modernen Plex-Clients." + +#: +msgctxt "#33000" +msgid "Enable path mapping" +msgstr "Path-Mapping aktivieren" + +#: +msgctxt "#33001" +msgid "Long-press (or context menu) on a library item or: Honor path_mapping.json in the addon_data/script.plexmod folder when DirectPlaying media. This can be used to stream using other techniques such as SMB/NFS/etc. instead of the default HTTP handler. path_mapping.example.json is included in the addon's main directory." +msgstr "Lange-gedrückt-halten (oder Context-Menü) einer Bibliothek, oder: Nutze path_mapping.json im addon_data/script.plexmod-Ordner. Dies kann verwendet werden, um andere Dateizugriff-Technologien zu benutzen, wie z. B. SMB/NFS/usw., anstatt des HTTP-Handlers. path_mapping.example.json liegt im Hauptverzeichnis vom Addon." + +#: +msgctxt "#33002" +msgid "Verify mapped files exist" +msgstr "Gemappte Dateien verifizieren" + +#: +msgctxt "#33003" +msgid "When path mapping is enabled and we've successfully mapped a file, verify its existence." +msgstr "Wenn Path-Mapping aktiviert ist und wir erfolgreich eine Datei gemappt haben, auch ihre Existenz verifizieren." + +#: +msgctxt "#33004" +msgid "No spoilers without OSD" +msgstr "Keine Spoiler ohne OSD" + +#: +msgctxt "#33005" +msgid "When seeking without the OSD open, hide all time-related information from the user." +msgstr "Wenn ohne OSD gesprungen wird, alle zeitrelevanten Informationen verstecken." + +#: +msgctxt "#33006" +msgid "No TV spoilers" +msgstr "Keine TV-Spoiler" + +#: +msgctxt "#33007" +msgid "Select in which cases to blur TV episode thumbnails, previews, redact summaries, hide episode titles and whether to blur chapter images. When the Addon Setting \"Use episode thumbnails in continue hub\" is enabled, blur them as well." +msgstr "Wähle aus, in welchen Fällen Vorschaubilder von TV-Episoden verschleiert, Zusammenfassungen zensiert, Episodentitel versteckt und Kapitelbilder verschleiert werden sollen. Wenn die Addon-Einstellung \"Vorschaubild für Episoden im Fortsetzen-Hub verwenden\" aktiviert ist, diese ebenfalls verschleiern." + +#: +msgctxt "#33008" +msgid "[Spoilers removed]" +msgstr "[Spoiler entfernt]" + +#: +msgctxt "#33009" +msgid "Blur amount for unwatched/in-progress episodes" +msgstr "Stärke der Verschleierung nicht geschauter Episoden" + +#: +msgctxt "#33010" +msgid "Unwatched" +msgstr "Nicht geschaut" + +#: +msgctxt "#33011" +msgid "In progress" +msgstr "Angefangen" + +#: +msgctxt "#33012" +msgid "No unwatched episode titles" +msgstr "Keine Episodentitel für nicht geschaute Folgen" + +#: +msgctxt "#33013" +msgid "When the above is anything but \"off\", hide episode titles as well." +msgstr "Wenn die vorherige Einstellung nicht \"aus\" ist, Episodentitel ebenfalls zensieren." + +#: +msgctxt "#33014" +msgid "Ignore plex.direct docker hosts" +msgstr "plex.direct-Docker-Hosts ignorieren" + +#: +msgctxt "#33015" +msgid "When checking for plex.direct host mapping, ignore local Docker IPv4 addresses (172.16.0.0/12)." +msgstr "Wenn das plex.direct-Host-Mapping überprüft wird, lokale Docker-IPv4-Adressen ignorieren (172.16.0.0/12)." + +#: +msgctxt "#33016" +msgid "Allow TV spoilers for" +msgstr "Erlaube TV-Spoiler für" + +#: +msgctxt "#33017" +msgid "Overrides the above for specific genres. Default: Reality, Game Show, Documentary, Sport" +msgstr "Überschreibt die vorherigen Einstellungen für bestimmte Genres. Standard: Reality, Game Show, Documentary, Sport" + +#: +msgctxt "#32303" +msgid "Season {}" +msgstr "Staffel {}" + +#: +msgctxt "#32304" +msgid "Episode {}" +msgstr "Folge {}" + +#: +msgctxt "#32310" +msgid "S{}" +msgstr "S{}" + +#: +msgctxt "#32311" +msgid "E{}" +msgstr "E{}" + +#: +msgctxt "#32938" +msgid "Only for Episodes/Playlists" +msgstr "Nur bei Episoden/Wiedergabelisten" + +#: +msgctxt "#33018" +msgid "Cache Plex Home users" +msgstr "Plex-Heimbenutzer zwischenspeichern" + +#: +msgctxt "#33019" +msgid "Visit media item" +msgstr "Mediendetails anschauen" + +#: +msgctxt "#33020" +msgid "Play" +msgstr "Abspielen" + +#: +msgctxt "#33021" +msgid "Choose action" +msgstr "Aktion wählen" + +#: +msgctxt "#33022" +msgid "Watched indicators" +msgstr "Geschaut-Indikatoren" + +#: +msgctxt "#33023" +msgid "Classic: Show orange triangle for unwatched items\n" +"Modern: Show green checkmark for watched items\n" +"Modern (2024): Show white checkmark for watched items\n" +"(default: Modern (2024))" +msgstr "Klassisch: Zeige oranges Dreieck für nicht geschaute Elemente\n" +"Modern: Zeige grünen Haken für geschaute Elemente\n" +"Modern (2024): Zeige weißen Haken für geschaute Elements\n" +"(Standard: Modern (2024))" + +#: +msgctxt "#33024" +msgid "Hide background in modern indicators" +msgstr "Hintergrund moderner Intikatoren verstecken" + +#: +msgctxt "#33025" +msgid "When the above is enabled, hide the black backdrop of the watched state." +msgstr "Wenn die vorherige Option aktiviert ist, den schwarzen Hintergrund nicht darstellen." + +#: +msgctxt "#33026" +msgid "Map path: {}" +msgstr "Pfad zuordnen: {}" + +#: +msgctxt "#33027" +msgid "Remove mapping: {}" +msgstr "Zuordnung entfernen: {}" + +#: +msgctxt "#33028" +msgid "Hide library" +msgstr "Bibliothek verstecken" + +#: +msgctxt "#33029" +msgid "Show library: {}" +msgstr "Bibliothek anzeigen: {}" + +#: +msgctxt "#33030" +msgid "Choose action for: {}" +msgstr "Aktion wählen für: {}" + +#: +msgctxt "#33031" +msgid "Select Kodi source for {}" +msgstr "Kodi Quelle auswählen für {}" + +#: +msgctxt "#33032" +msgid "Show path mapping indicators" +msgstr "Pfadzuordnungs-Indikator anzeigen" + +#: +msgctxt "#33033" +msgid "When path mapping is active for a library, display an indicator." +msgstr "Wenn eine Pfadzuordnung für eine Bibliothek aktiv ist, einen Indikator anzeigen." + +#: +msgctxt "#33035" +msgid "Delete {}: {}?" +msgstr "{}: {} löschen?" + +#: +msgctxt "#33036" +msgid "Delete episode S{0:02d}E{1:02d} from {2}?" +msgstr "Episode S{0:02d}E{1:02d} von {2} löschen?" + +#: +msgctxt "#33037" +msgid "Maximum intro offset to consider" +msgstr "Maximales erwägtes Intro-Offset" + +#: +msgctxt "#33038" +msgid "When encountering an intro marker with a start time offset greater than this, ignore it (default: 600s/10m)" +msgstr "Wenn ein Intro-Marker mit einem Startzeitpunkt größer als diese Einstellung ist, diesen ignorieren (default: 600s/10m)" + +#: +msgctxt "#33039" +msgid "Move" +msgstr "Verschieben" + +#: +msgctxt "#33040" +msgid "Reset library order" +msgstr "Ordnung der Bibliotheken zurücksetzen" + +#: +msgctxt "#33034" +msgid "Library settings" +msgstr "Bibliothek-Einstellungen" + +#: +msgctxt "#33041" +msgid "Show hub: {}" +msgstr "Hub anzeigen: {}" + +#: +msgctxt "#33042" +msgid "Episode Date Added" +msgstr "Episode zuletzt hinz." + +#: +msgctxt "#33043" +msgid "Hubs round-robin" +msgstr "Hubs-Rundlauf" + +#: +msgctxt "#33044" +msgid "Allow round-robining in hubs. Attention: Loads a lot of items. Depending on the hub size, this can lead to crashes. Current limit: {}; can be adjusted in addon settings." +msgstr "Rundlauf für Hubs erlauben. Achtung: Lädt sehr viele Items. Je nach Hubgröße kann dies zu Abstürzen führen. Aktuelles Limit: {}; kann in den Addon-Einstellungen angepasst werden." + +#: +msgctxt "#33045" +msgid "Behave like official Plex clients" +msgstr "Verhalten wie Plex Clients" + +#: +msgctxt "#33046" +msgid "When pressing up/down while the OSD isn't shown, show OSD instead of skipping chapters. Additionally, when pressing down while the OSD is shown, open the chapters (if available)." +msgstr "Das OSD anzeigen wenn ohne OSD hoch/runter gedrückt wird, anstatt Kapitel zu wechseln. Darüberhinaus werden beim Runterdrücken während das OSD angezeigt wird, die Kapitel geöffnet (wenn vorhanden)." + +#: +msgctxt "#33047" +msgid "Hubs round-robin item limit" +msgstr "Hubs-Rundlauf Item Limit" + +#: +msgctxt "#33048" +msgid "When hubs round-robin is enabled, only round-robin until this item limit. If the hub size exceeds this limit, the remaining items will be lazy loaded as usual. Tested minimum safe value on NVIDIA SHIELD 2019 is 1000. Default: 250" +msgstr "Wenn Hubs-Rundlauf aktiviert ist, nur bis zu diesem Limit rundlaufen. Sollte der hub dieses Limit überschreiten, werden die übrigen Items nachgeladen. Minimal als sicher getesteter Wert auf der NVIDIA SHIELD 2019 ist 1000. Standard: 250" + +#: +msgctxt "#33049" +msgid "Max retries" +msgstr "Maximale Neuanfragen" + +#: +msgctxt "#33050" +msgid "The maximum number of retries each connection should attempt. The default (3) helps with hibernation/wakeup issues. Set higher for bad connections, setting this to 0 was the old default before 0.7.9" +msgstr "Die maximale Anzahl an Versuchen, die eine Verbindung unternehmen soll. Der Standardwert (3) hilft bei Ruhezustand/Aufwachen Probleme. Höher stellen bei schlechter Verbindung, 0 war der alte Standard vor 0.7.9" + +#: +msgctxt "#33051" +msgid "Use CA certificate bundle" +msgstr "CA-Zertifikat-Bundle benutzen" + +#: +msgctxt "#33052" +msgid "Which CA certificate bundle to use for request HTTPS verification. \"system\" uses the system-provided certificate bundle. \"ACME\" uses an extremely small bundle provided with the addon, which includes root certificates for Letsencrypt (plex.direct) and ZeroSSL. \"custom\" allows for a ca-certificate bundle in userdata/addon_data/script.plexmod/custom_bundle.crt" +msgstr "Welches CA-Zertifikat-Bundle für HTTPS-Anfragen benutzt werden soll. \"system\" benutzt das systemseitige Zertifikat-Bundle. \"ACME\" benutzt ein extrem kleines Bundle, bereitgestellt vom Addon, welches Root-Zertifikate für Letsencrypt (plex.direct) und ZeroSSL enthält. \"custom\" erlaubt es ein benutzerdefiniertes Bundle in userdata/addon_data/script.plexmod/custom_bundle.crt abzulegen" + +#: +msgctxt "#33053" +msgid "System" +msgstr "System" + +#: +msgctxt "#33054" +msgid "ACME (addon-supplied)" +msgstr "ACME (bereitgestellt vom Addon)" + +#: +msgctxt "#33055" +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: +msgctxt "#33056" +msgid "None" +msgstr "Keine" + +#: +msgctxt "#33057" +msgid "Show buttons" +msgstr "Knöpfe anzeigen" + +#: +msgctxt "#33058" +msgid "Playback features" +msgstr "Abspielfunktionen" + +#: +msgctxt "#33059" +msgid "Additional codecs" +msgstr "Weitere Codecs" + +#: +msgctxt "#33060" +msgid "{feature_ds}: {desc_ds}\n" +"{feature_4k}: {desc_4k}" +msgstr "{feature_ds}: {desc_ds}\n" +"{feature_4k}: {desc_4k}" + +#: +msgctxt "#33061" +msgid "Enable certain codecs if your hardware supports them. Disable them to force transcoding." +msgstr "Bestimmte Codecs erlauben, wenn die Hardware diese unterstützt. Deaktivierung erzwingt Transcodierung." + +#: +msgctxt "#33062" +msgid "Compiling templates" +msgstr "Kompiliere Templates" + +#: +msgctxt "#33063" +msgid "Looking for custom templates" +msgstr "Suche benutzerdef. Templates" + +#: +msgctxt "#33064" +msgid "Rendering: {}" +msgstr "Rendere: {}" + +#: +msgctxt "#33065" +msgid "Complete" +msgstr "Fertig" + +#: +msgctxt "#33066" +msgid "Cache template files" +msgstr "Templatedateien cachen" + +#: +msgctxt "#33067" +msgid "Doesn't throw away the template source files after compiling them. Uses slightly more memory but increases the speed of theme-related changes." +msgstr "Wirft die Templatequelle nicht weg, nachdem das Template kompiliert wurde. Benutzt minimal mehr Arbeitsspeicher, aber erhöht die Geschwindigkeit Aussehen-spezifischer Änderungen." + +#: +msgctxt "#33068" +msgid "Always compile templates" +msgstr "Templates immer kompilieren" + +#: +msgctxt "#33069" +msgid "Recompiles all templates on every startup. Useful for template/theme development." +msgstr "Rekompiliere alle Templates bei jedem Start. Nützlich für Template/Aussehen-Entwicklung." + +#: +msgctxt "#33070" +msgid "Action on Wake event" +msgstr "Aktion bei Wake-Ereignis" + +#: +msgctxt "#33071" +msgid "Restart PM4K" +msgstr "PM4K neustarten" + +#: +msgctxt "#33072" +msgid "Wait for {}s" +msgstr "Warten für {}s" + +#: +msgctxt "#33073" +msgid "Wait after wakeup" +msgstr "Warte nach Aufwachen" + +#: +msgctxt "#33074" +msgid "Waiting {} second(s)" +msgstr "Warte {} Sekunde(n)" + +#: +msgctxt "#33075" +msgid "Do something after waking up. Waiting for a time until resuming normal execution helps with networks coming back up after sleep events. Default: 1 second (5 seconds, CoreELEC)." +msgstr "Aktion ausführen nach dem Aufwachen. Warten, bis die normale Ausführung weiter geht, hilft beim Aufwachen von Netzwerken nach Sleep-Ereignissen. Standard: 1 Sekunde (5 Sekunden, CoreELEC)." + +#: +msgctxt "#33076" +msgid "Modern (2024)" +msgstr "Modern (2024)" + +#: +msgctxt "#33077" +msgid "Scale modern indicators" +msgstr "Moderne Indikatoren skalieren" + +#: +msgctxt "#33078" +msgid "Scale the modern indicators based on the poster size used. Default: On (tiny: 0.75, small: 1.0, medium: 1.175, big: 1.3)" +msgstr "Skaliere die modernen Geschaut-Indikatoren basierend auf der Postergröße. Standard: an (winzig: 0.75, klein: 1.0, mittel: 1.175, groß: 1.3)" + +#: +msgctxt "#33079" +msgid "Hi-Res Music" +msgstr "Hochauflös. Musik" + +#: +msgctxt "#33080" +msgid "Allow DirectPlay of high resolution music (e.g. FLAC, >= 192 kHz)" +msgstr "Direktes Abspielen von hochauflösender Musik erlauben (z.B. FLAC, >= 192 kHz)" + +#: +msgctxt "#33081" +msgid "Blur chapter images" +msgstr "Kapitelbilder verschleiern" + +#: +msgctxt "#33082" +msgid "Scan Library Files" +msgstr "Mediathek-Dateien einlesen" + +#: +msgctxt "#33083" +msgid "Empty Trash" +msgstr "Papierkorb leeren" + +#: +msgctxt "#33084" +msgid "Analyze" +msgstr "Analysieren" + +#: +msgctxt "#33085" +msgid "Map key to home" +msgstr "Taste zu Home zuordnen" + +#: +msgctxt "#33086" +msgid "Press the key you want to map to go to home within {} seconds" +msgstr "Drücke die Taste, die Du zuordnen willst, um sofort zu Home zu kommen binnen {} Sekunden" + +#: +msgctxt "#33087" +msgid "Bind a key to immediately go to the Home view. Cancel using BACK/PREVIOUS_MENU. Clear bound key using the STOP or CONTEXT_MENU (long press OK/Enter) button on the setting." +msgstr "Wähle eine Taste, um sofort zur Home-Ansicht zu kommen. Abbrechen via BACK/PREVIOUS_MENU. Gebundene Taste mit dem STOP oder CONTEXT_MENU (OK/Enter lange gedrückt halten) Knopf auf der Einstellung entbinden." + +#: +msgctxt "#33088" +msgid "Only applies to video player UI" +msgstr "Gilt nur für die Video-Abspieloberfläche" + +#: +msgctxt "#33089" +msgid "Automatic seek-back" +msgstr "Automatisch zurückspringen" + +#: +msgctxt "#33090" +msgid "If your audio doesn't resume as fast as the video, or you want to catch up after a longer pause, use this to seek back after resuming from pause to compensate for the delay. Default: Off" +msgstr "Wenn der Ton nicht so schnell nach dem Fortsetzen wieder einsetzt, wie das Bild, oder Du aufholen möchtest, benutze dies um beim Fortsetzen nach dem Pausieren eine bestimmte Zeitspanne zurück zu springen. Standard: Aus" + +#: +msgctxt "#33091" +msgid "{sec_or_ms} {unit_s_or_ms}" +msgstr "{sec_or_ms} {unit_s_or_ms}" + +#: +msgctxt "#33092" +msgid "Seek back on pause" +msgstr "Zurückspringen bei Pause" + +#: +msgctxt "#33093" +msgid "Seek back after" +msgstr "Zurückspringen nach" + +#: +msgctxt "#33094" +msgid "Only seek back after having paused at least a certain amount of seconds" +msgstr "Nur zurückspringen nachdem wenigstens eine gewisse Zeit pausiert war" + +#: +msgctxt "#33095" +msgid "Seek back on pause instead of on resume. When Transcoding you should enable this." +msgstr "Zurückspringen beim Pausieren anstatt nach dem Fortsetzen. Beim Transkodieren sollte dies aktiviert sein." + +#: +msgctxt "#33096" +msgid "Only with Direct Play" +msgstr "Nur bei Direkter Wiedergabe" + +#: +msgctxt "#33097" +msgid "Enable seek back ony when we're Direct Playing, not Transcoding." +msgstr "Zurückspringen nur bei Direkter Wiedergabe, nicht beim Transkodieren." + +#: +msgctxt "#33098" +msgid "Tickrate (Hz)" +msgstr "Tick-Rate (Hz)" + +#: +msgctxt "#33099" +msgid "Controls how often certain ticks are performed on GUI windows and the SeekDialog/VideoPlayer and how fast certain events are handled. Can be expensive when bigger than 1 Hz (once per second), can cause quirks when lower than 1 Hz (less than once per second). Depends on the hardware. Default: 1 Hz, Max: 10 Hz (every 100 ms), Sane highest and old default: 10 Hz (every 100 ms)" +msgstr "Stellt ein, wie häufig in GUI-Fenstern und dem SeekDialog/VideoPlayer getickt wird und wie schnell bestimmte Events verarbeitet werden. Kann teuer werden, wenn größer als 1 Hz (einmal pro Sekunde), kann Macken verursachen, wenn kleiner als 1 Hz (seltener als einmal pro Sekunde). Hängt von der Hardware ab. Standard: 1 Hz, Max: 10 Hz (alle 100 ms), vernünftiger höchster Wert und alter Standard: 10 Hz (alle 100 ms)" + +#: +msgctxt "#33636" +msgid "Plex server read timeout" +msgstr "Plex-Server-Lesezeitlimit" + +#: +msgctxt "#33637" +msgid "Sets the maximum amount of time to read from a Plex Server in seconds. Default: 10" +msgstr "Setzt das Zeitlimit beim Lesen von einem Plex-Server, in Sekunden. Voreinstellung: 10" + +#: +msgctxt "#33638" +msgid "Plex.tv connect timeout" +msgstr "Plex.tv-Verbindungszeitlimit" + +#: +msgctxt "#33639" +msgid "Plex.tv: Sets the maximum amount of time to connect to Plex.tv in seconds. Default: 1" +msgstr "Plex.tv: Setzt das Zeitlimit um sich mit Plex.tv zu verbinden, in Sekunden. Voreinstellung: 1" + +#: +msgctxt "#33640" +msgid "Plex.tv read timeout" +msgstr "Plex.tv Lesezeitlimit" + +#: +msgctxt "#33641" +msgid "Plex.tv: Sets the maximum amount of time to read from Plex.tv in seconds. Default: 2" +msgstr "Plex.tv: Setzt das Zeitlimit beim Lesen von Plex.tv, in Sekunden. Voreinstellung: 2" + +#: +msgctxt "#33642" +msgid "Dump config" +msgstr "Konfiguration ausgeben" + +#: +msgctxt "#33643" +msgid "Dumps all user settings into the log on startup, when DEBUG logging is enabled. Masks private information." +msgstr "Schreibt alle Benutzereinstellungen in die Logdatei beim Start, wenn DEBUG-Logging aktiviert ist. Verschleiert private Informationen." + +#: +msgctxt "#33644" +msgid "Tracks" +msgstr "Tracks" + +#: +msgctxt "#33645" +msgid "plex.direct: Honor plex.tv's dnsRebindingProtection flag (DNS)" +msgstr "plex.direct: plex.tv's dnsRebindingProtection-Flag beachten (DNS)" + +#: +msgctxt "#33646" +msgid "Only handle plex.direct hosts when the server's attributes dnsRebindingProtection=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "Nur plex.direct Hosts behandeln, wenn das Attribut des Servers dnsRebindingProtection=1 entspricht. Könnte in bestimmten Situationen nicht funktionieren. Deaktivieren, sollte es Verbindungsprobleme geben. Standard: An" + +#: +msgctxt "#33647" +msgid "plex.direct: Honor plex.tv's publicAddressMatches flag (DNS)" +msgstr "plex.direct: plex.tv's publicAddressMatches-Flag beachten (DNS)" + +#: +msgctxt "#33648" +msgid "Only handle plex.direct hosts when the server's attributes publicAddressMatches=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "Nur plex.direct Hosts behandeln, wenn das Attribut des Servers publicAddressMatches=1 entspricht. Könnte in bestimmten Situationen nicht funktionieren. Deaktivieren, sollte es Verbindungsprobleme geben. Standard: An" + +#: +msgctxt "#33649" +msgid "CoreELEC: Resume-fix wait for seek" +msgstr "CoreELEC: Fortsetzen-Fix Sprungwartezeit" + +#: +msgctxt "#33650" +msgid "This adjusts the delay between seek-tries on CoreELEC, which fixes resume not always working or double-seeking. When you have resume/double-seek issues, increase this. 100ms should be stable as well. Default: 350ms" +msgstr "Dies passt die Wartezeit zwischen Sprungversuchen auf CoreELEC an, welches den Fehler behebt, dass das Fortsetzen manchmal nicht funktioniert, oder doppelt gesprungen wird. Solltest Du Fortsetzen-/Doppelsprungprobleme haben, diesen Wert erhöhen. 100ms sollten ebenfalls stabil sein. Standard: 350ms" + +#: +msgctxt "#33651" +msgid "Startup delay" +msgstr "Start-Verzögerung" + +#: +msgctxt "#33652" +msgid "Never show Post Play" +msgstr "Niemals Post-Play-Fenster anzeigen" + diff --git a/script.plexmod/resources/language/resource.language.en_gb/strings.po b/script.plexmod/resources/language/resource.language.en_gb/strings.po index 3125aff8bb..0e75dc59d3 100644 --- a/script.plexmod/resources/language/resource.language.en_gb/strings.po +++ b/script.plexmod/resources/language/resource.language.en_gb/strings.po @@ -94,11 +94,11 @@ msgid "Debug Logging" msgstr "" msgctxt "#32025" -msgid "Allow Direct Play" +msgid "Direct Play" msgstr "" msgctxt "#32026" -msgid "Allow Direct Stream" +msgid "Direct Stream" msgstr "" msgctxt "#32027" @@ -138,11 +138,11 @@ msgid "Always" msgstr "" msgctxt "#32036" -msgid "Allow 4K" +msgid "4K" msgstr "" msgctxt "#32037" -msgid "Allow HEVC (h265)" +msgid "HEVC (h265)" msgstr "" msgctxt "#32038" @@ -270,7 +270,7 @@ msgid "Skip user selection and pin entry on startup." msgstr "" msgctxt "#32101" -msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a 15 second delay." +msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a {} second delay." msgstr "" msgctxt "#32102" @@ -346,11 +346,11 @@ msgid "Go to {0}" msgstr "" msgctxt "#32303" -msgid "Season" +msgid "Season {}" msgstr "" msgctxt "#32304" -msgid "Episode" +msgid "Episode {}" msgstr "" msgctxt "#32305" @@ -374,11 +374,11 @@ msgid "None" msgstr "" msgctxt "#32310" -msgid "S" +msgid "S{}" msgstr "" msgctxt "#32311" -msgid "E" +msgid "E{}" msgstr "" msgctxt "#32312" @@ -562,11 +562,11 @@ msgid "Date Viewed" msgstr "" msgctxt "#32357" -msgid "By Name" +msgid "By Title" msgstr "" msgctxt "#32358" -msgid "Name" +msgid "Title" msgstr "" msgctxt "#32359" @@ -1143,7 +1143,7 @@ msgid "Ends at" msgstr "" msgctxt "#32601" -msgid "Allow AV1" +msgid "AV1" msgstr "" msgctxt "#32602" @@ -1219,7 +1219,7 @@ msgid "Show intro skip button early" msgstr "" msgctxt "#33506" -msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn\'t override enabled binge mode.\nCan be disabled/enabled per TV show." +msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn't override enabled binge mode.\nCan be disabled/enabled per TV show." msgstr "" msgctxt "#33507" @@ -1295,7 +1295,7 @@ msgid "Kodi Buffer Size (MB)" msgstr "" msgctxt "#33614" -msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~100 MB, Recommended max: {} MB, Default: 20 MB." +msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~50 MB, Recommended max: {} MB, Default: 20 MB." msgstr "" msgctxt "#33615" @@ -1315,15 +1315,15 @@ msgid "TV binge-viewing mode" msgstr "" msgctxt "#33619" -msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn\'t skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n\nCan be disabled/enabled per TV show.\nOverrides any setting below." +msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn't skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n\nCan be disabled/enabled per TV show.\nOverrides any setting below." msgstr "" msgctxt "#33620" -msgid "Plex requests timeout (seconds)" +msgid "Plex server connect timeout" msgstr "" msgctxt "#33621" -msgid "Set the (async and connection) timeout value of the Python requests library in seconds. Default: 5" +msgid "Sets the maximum amount of time to connect to a Plex Server in seconds. Default: 5" msgstr "" msgctxt "#33622" @@ -1535,19 +1535,19 @@ msgid "Audio/Subtitles" msgstr "" msgctxt "#32932" -msgid "Show subtitle quick-actions button" +msgid "Subtitle quick-actions" msgstr "" msgctxt "#32933" -msgid "Show FFWD/RWD buttons" +msgid "FFWD/RWD" msgstr "" msgctxt "#32934" -msgid "Show repeat button" +msgid "Repeat" msgstr "" msgctxt "#32935" -msgid "Show shuffle button" +msgid "Shuffle" msgstr "" msgctxt "#32936" @@ -1559,15 +1559,15 @@ msgid "Show prev/next button" msgstr "" msgctxt "#32938" -msgid "Only for Episodes" +msgid "Only for Episodes/Playlists" msgstr "" msgctxt "#32939" -msgid "Only applies to video player UI" +msgid "User-specific.\nOnly applies to video player UI" msgstr "" msgctxt "#32940" -msgid "Player UI" +msgid "Video Player" msgstr "" msgctxt "#32941" @@ -1614,10 +1614,6 @@ msgctxt "#32951" msgid "When displaying subtitles use the extendedDisplayTitle Plex exposes." msgstr "" -msgctxt "#32952" -msgid "Dialog flicker fix" -msgstr "" - msgctxt "#32953" msgid "Reviews" msgstr "" @@ -1715,7 +1711,7 @@ msgid "Adaptive" msgstr "" msgctxt "#32977" -msgid "Allow VC1" +msgid "VC1" msgstr "" msgctxt "#32978" @@ -1729,3 +1725,547 @@ msgstr "" msgctxt "#32980" msgid "Refresh Users" msgstr "" + +msgctxt "#32981" +msgid "Background worker count" +msgstr "" + +msgctxt "#32982" +msgid "Depending on how many cores your CPU has and how much it can handle, increasing this might improve certain situations. If you experience crashes or other annormalities, leave this at its default (3). Needs an addon restart." +msgstr "" + +msgctxt "#32983" +msgid "Theme" +msgstr "" + +msgctxt "#32984" +msgid "Sets the theme. Currently only customizes all control buttons. ATTENTION: [I]Might[/I] need an addon restart.\nIn order to customize this, copy one of the xml's in script.plexmod/resources/skins/Main/1080i/templates to addon_data/script.plexmod/templates/{templatename}_custom.xml and adjust it to your liking, then select \"Custom\" as your theme." +msgstr "" + +msgctxt "#32985" +msgid "Modern" +msgstr "" + +msgctxt "#32986" +msgid "Modern (dotted)" +msgstr "" + +msgctxt "#32987" +msgid "Classic" +msgstr "" + +msgctxt "#32988" +msgid "Custom" +msgstr "" + +msgctxt "#32989" +msgid "Modern (colored)" +msgstr "" + +msgctxt "#32990" +msgid "Handle plex.direct mapping" +msgstr "" + +msgctxt "#32991" +msgid "Notify" +msgstr "" + +msgctxt "#32992" +msgid "When using servers with a plex.direct connection (most of them), should we automatically adjust advancedsettings.xml to cope with plex.direct domains? If not, you might want to add plex.direct to your router's DNS rebind exemption list." +msgstr "" + +msgctxt "#32993" +msgid "{} unhandled plex.direct connections found" +msgstr "" + +msgctxt "#32994" +msgid "In order for PM4K to work properly, we need to add special handling for plex.direct connections. We've found {} new unhandled connections. Do you want us to write those to Kodi's advancedsettings.xml automatically? If not, you might want to add plex.direct to your router's DNS rebind exemption list. This can be changed in the settings as well." +msgstr "" + +msgctxt "#32995" +msgid "Advancedsettings.xml modified (plex.direct mappings)" +msgstr "" + +msgctxt "#32996" +msgid "The advancedsettings.xml file has been modified. Please restart Kodi for the changes to apply." +msgstr "" + +msgctxt "#32997" +msgid "OK" +msgstr "" + +msgctxt "#32998" +msgid "Use new Continue Watching hub on Home" +msgstr "" + +msgctxt "#32999" +msgid "Instead of separating Continue Watching and On Deck hubs, behave like the modern Plex clients, which combine those two types of hubs into one Continue Watching hub." +msgstr "" + +msgctxt "#33000" +msgid "Enable path mapping" +msgstr "" + +msgctxt "#33001" +msgid "Long-press (or context menu) on a library item or: Honor path_mapping.json in the addon_data/script.plexmod folder when DirectPlaying media. This can be used to stream using other techniques such as SMB/NFS/etc. instead of the default HTTP handler. path_mapping.example.json is included in the addon's main directory." +msgstr "" + +msgctxt "#33002" +msgid "Verify mapped files exist" +msgstr "" + +msgctxt "#33003" +msgid "When path mapping is enabled and we've successfully mapped a file, verify its existence." +msgstr "" + +msgctxt "#33004" +msgid "No spoilers without OSD" +msgstr "" + +msgctxt "#33005" +msgid "When seeking without the OSD open, hide all time-related information from the user." +msgstr "" + +msgctxt "#33006" +msgid "No TV spoilers" +msgstr "" + +msgctxt "#33007" +msgid "Select in which cases to blur TV episode thumbnails, previews, redact summaries, hide episode titles and whether to blur chapter images. When the Addon Setting \"Use episode thumbnails in continue hub\" is enabled, blur them as well." +msgstr "" + +msgctxt "#33008" +msgid "[Spoilers removed]" +msgstr "" + +msgctxt "#33009" +msgid "Blur amount for unwatched/in-progress episodes" +msgstr "" + +msgctxt "#33010" +msgid "Unwatched" +msgstr "" + +msgctxt "#33011" +msgid "In progress" +msgstr "" + +msgctxt "#33012" +msgid "No unwatched episode titles" +msgstr "" + +msgctxt "#33013" +msgid "When the above is anything but \"off\", hide episode titles as well." +msgstr "" + +msgctxt "#33014" +msgid "Ignore plex.direct docker hosts" +msgstr "" + +msgctxt "#33015" +msgid "When checking for plex.direct host mapping, ignore local Docker IPv4 addresses (172.16.0.0/12)." +msgstr "" + +msgctxt "#33016" +msgid "Allow TV spoilers for" +msgstr "" + +msgctxt "#33017" +msgid "Overrides the above for specific genres. Default: Reality, Game Show, Documentary, Sport" +msgstr "" + +msgctxt "#33018" +msgid "Cache Plex Home users" +msgstr "" + +msgctxt "#33019" +msgid "Visit media item" +msgstr "" + +msgctxt "#33020" +msgid "Play" +msgstr "" + +msgctxt "#33021" +msgid "Choose action" +msgstr "" + +msgctxt "#33022" +msgid "Watched indicators" +msgstr "" + +msgctxt "#33023" +msgid "Classic: Show orange triangle for unwatched items\nModern: Show green checkmark for watched items\nModern (2024): Show white checkmark for watched items\n(default: Modern (2024))" +msgstr "" + +msgctxt "#33024" +msgid "Hide background in modern indicators" +msgstr "" + +msgctxt "#33025" +msgid "When the above is enabled, hide the black backdrop of the watched state." +msgstr "" + +msgctxt "#33026" +msgid "Map path: {}" +msgstr "" + +msgctxt "#33027" +msgid "Remove mapping: {}" +msgstr "" + +msgctxt "#33028" +msgid "Hide library" +msgstr "" + +msgctxt "#33029" +msgid "Show library: {}" +msgstr "" + +msgctxt "#33030" +msgid "Choose action for: {}" +msgstr "" + +msgctxt "#33031" +msgid "Select Kodi source for {}" +msgstr "" + +msgctxt "#33032" +msgid "Show path mapping indicators" +msgstr "" + +msgctxt "#33033" +msgid "When path mapping is active for a library, display an indicator." +msgstr "" + +msgctxt "#33034" +msgid "Library settings" +msgstr "" + +msgctxt "#33035" +msgid "Delete {}: {}?" +msgstr "" + +msgctxt "#33036" +msgid "Delete episode S{0:02d}E{1:02d} from {2}?" +msgstr "" + +msgctxt "#33037" +msgid "Maximum intro offset to consider" +msgstr "" + +msgctxt "#33038" +msgid "When encountering an intro marker with a start time offset greater than this, ignore it (default: 600s/10m)" +msgstr "" + +msgctxt "#33039" +msgid "Move" +msgstr "" + +msgctxt "#33040" +msgid "Reset library order" +msgstr "" + +msgctxt "#33041" +msgid "Show hub: {}" +msgstr "" + +msgctxt "#33042" +msgid "Episode Date Added" +msgstr "" + +msgctxt "#33043" +msgid "Hubs round-robin" +msgstr "" + +msgctxt "#33044" +msgid "Allow round-robining in hubs. Attention: Loads a lot of items. Depending on the hub size, this can lead to crashes. Current limit: {}; can be adjusted in addon settings." +msgstr "" + +msgctxt "#33045" +msgid "Behave like official Plex clients" +msgstr "" + +msgctxt "#33046" +msgid "When pressing up/down while the OSD isn't shown, show OSD instead of skipping chapters. Additionally, when pressing down while the OSD is shown, open the chapters (if available)." +msgstr "" + +msgctxt "#33047" +msgid "Hubs round-robin item limit" +msgstr "" + +msgctxt "#33048" +msgid "When hubs round-robin is enabled, only round-robin until this item limit. If the hub size exceeds this limit, the remaining items will be lazy loaded as usual. Tested minimum safe value on NVIDIA SHIELD 2019 is 1000. Default: 250" +msgstr "" + +msgctxt "#33049" +msgid "Max retries" +msgstr "" + +msgctxt "#33050" +msgid "The maximum number of retries each connection should attempt. The default (3) helps with hibernation/wakeup issues. Set higher for bad connections, setting this to 0 was the old default before 0.7.9" +msgstr "" + +msgctxt "#33051" +msgid "Use CA certificate bundle" +msgstr "" + +msgctxt "#33052" +msgid "Which CA certificate bundle to use for request HTTPS verification. \"system\" uses the system-provided certificate bundle. \"ACME\" uses an extremely small bundle provided with the addon, which includes root certificates for Letsencrypt (plex.direct) and ZeroSSL. \"custom\" allows for a ca-certificate bundle in userdata/addon_data/script.plexmod/custom_bundle.crt" +msgstr "" + +msgctxt "#33053" +msgid "System" +msgstr "" + +msgctxt "#33054" +msgid "ACME (addon-supplied)" +msgstr "" + +msgctxt "#33055" +msgid "Custom" +msgstr "" + +msgctxt "#33056" +msgid "None" +msgstr "" + +msgctxt "#33057" +msgid "Show buttons" +msgstr "" + +msgctxt "#33058" +msgid "Playback features" +msgstr "" + +msgctxt "#33059" +msgid "Additional codecs" +msgstr "" + +msgctxt "#33060" +msgid "{feature_ds}: {desc_ds}\n{feature_4k}: {desc_4k}" +msgstr "" + +msgctxt "#33061" +msgid "Enable certain codecs if your hardware supports them. Disable them to force transcoding." +msgstr "" + +msgctxt "#33062" +msgid "Compiling templates" +msgstr "" + +msgctxt "#33063" +msgid "Looking for custom templates" +msgstr "" + +msgctxt "#33064" +msgid "Rendering: {}" +msgstr "" + +msgctxt "#33065" +msgid "Complete" +msgstr "" + +msgctxt "#33066" +msgid "Cache template files" +msgstr "" + +msgctxt "#33067" +msgid "Doesn't throw away the template source files after compiling them. Uses slightly more memory but increases the speed of theme-related changes." +msgstr "" + +msgctxt "#33068" +msgid "Always compile templates" +msgstr "" + +msgctxt "#33069" +msgid "Recompiles all templates on every startup. Useful for template/theme development." +msgstr "" + +msgctxt "#33070" +msgid "Action on Wake event" +msgstr "" + +msgctxt "#33071" +msgid "Restart PM4K" +msgstr "" + +msgctxt "#33072" +msgid "Wait for {}s" +msgstr "" + +msgctxt "#33073" +msgid "Wait after wakeup" +msgstr "" + +msgctxt "#33074" +msgid "Waiting {} second(s)" +msgstr "" + +msgctxt "#33075" +msgid "Do something after waking up. Waiting for a time until resuming normal execution helps with networks coming back up after sleep events. Default: 1 second (5 seconds, CoreELEC)." +msgstr "" + +msgctxt "#33076" +msgid "Modern (2024)" +msgstr "" + +msgctxt "#33077" +msgid "Scale modern indicators" +msgstr "" + +msgctxt "#33078" +msgid "Scale the modern indicators based on the poster size used. Default: On (tiny: 0.75, small: 1.0, medium: 1.175, big: 1.3)" +msgstr "" + +msgctxt "#33079" +msgid "Hi-Res Music" +msgstr "" + +msgctxt "#33080" +msgid "Allow DirectPlay of high resolution music (e.g. FLAC, >= 192 kHz)" +msgstr "" + +msgctxt "#33081" +msgid "Blur chapter images" +msgstr "" + +msgctxt "#33082" +msgid "Scan Library Files" +msgstr "" + +msgctxt "#33083" +msgid "Empty Trash" +msgstr "" + +msgctxt "#33084" +msgid "Analyze" +msgstr "" + +msgctxt "#33085" +msgid "Map key to home" +msgstr "" + +msgctxt "#33086" +msgid "Press the key you want to map to go to home within {} seconds" +msgstr "" + +msgctxt "#33087" +msgid "Bind a key to immediately go to the Home view. Cancel using BACK/PREVIOUS_MENU. Clear bound key using the STOP or CONTEXT_MENU (long press OK/Enter) button on the setting." +msgstr "" + +msgctxt "#33088" +msgid "Only applies to video player UI" +msgstr "" + +msgctxt "#33089" +msgid "Automatic seek-back" +msgstr "" + +msgctxt "#33090" +msgid "If your audio doesn't resume as fast as the video, or you want to catch up after a longer pause, use this to seek back after resuming from pause to compensate for the delay. Default: Off" +msgstr "" + +msgctxt "#33091" +msgid "{sec_or_ms} {unit_s_or_ms}" +msgstr "" + +msgctxt "#33092" +msgid "Seek back on pause" +msgstr "" + +msgctxt "#33093" +msgid "Seek back after" +msgstr "" + +msgctxt "#33094" +msgid "Only seek back after having paused at least a certain amount of seconds" +msgstr "" + +msgctxt "#33095" +msgid "Seek back on pause instead of on resume. When Transcoding you should enable this." +msgstr "" + +msgctxt "#33096" +msgid "Only with Direct Play" +msgstr "" + +msgctxt "#33097" +msgid "Enable seek back ony when we're Direct Playing, not Transcoding." +msgstr "" + +msgctxt "#33098" +msgid "Tickrate (Hz)" +msgstr "" + +msgctxt "#33099" +msgid "Controls how often certain ticks are performed on GUI windows and the SeekDialog/VideoPlayer and how fast certain events are handled. Can be expensive when bigger than 1 Hz (once per second), can cause quirks when lower than 1 Hz (less than once per second). Depends on the hardware. Default: 1 Hz, Max: 10 Hz (every 100 ms), Sane highest and old default: 10 Hz (every 100 ms)" +msgstr "" + +msgctxt "#33636" +msgid "Plex server read timeout" +msgstr "" + +msgctxt "#33637" +msgid "Sets the maximum amount of time to read from a Plex Server in seconds. Default: 10" +msgstr "" + +msgctxt "#33638" +msgid "Plex.tv connect timeout" +msgstr "" + +msgctxt "#33639" +msgid "Plex.tv: Sets the maximum amount of time to connect to Plex.tv in seconds. Default: 1" +msgstr "" + +msgctxt "#33640" +msgid "Plex.tv read timeout" +msgstr "" + +msgctxt "#33641" +msgid "Plex.tv: Sets the maximum amount of time to read from Plex.tv in seconds. Default: 2" +msgstr "" + +msgctxt "#33642" +msgid "Dump config" +msgstr "" + +msgctxt "#33643" +msgid "Dumps all user settings into the log on startup, when DEBUG logging is enabled. Masks private information." +msgstr "" + +msgctxt "#33644" +msgid "Tracks" +msgstr "" + +msgctxt "#33645" +msgid "plex.direct: Honor plex.tv's dnsRebindingProtection flag (DNS)" +msgstr "" + +msgctxt "#33646" +msgid "Only handle plex.direct hosts when the server's attributes dnsRebindingProtection=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "" + +msgctxt "#33647" +msgid "plex.direct: Honor plex.tv's publicAddressMatches flag (DNS)" +msgstr "" + +msgctxt "#33648" +msgid "Only handle plex.direct hosts when the server's attributes publicAddressMatches=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "" + +msgctxt "#33649" +msgid "CoreELEC: Resume-fix wait for seek" +msgstr "" + +msgctxt "#33650" +msgid "This adjusts the delay between seek-tries on CoreELEC, which fixes resume not always working or double-seeking. When you have resume/double-seek issues, increase this. 100ms should be stable as well. Default: 350ms" +msgstr "" + +msgctxt "#33651" +msgid "Startup delay" +msgstr "" + +msgctxt "#33652" +msgid "Never show Post Play" +msgstr "" diff --git a/script.plexmod/resources/language/resource.language.es_es/strings.po b/script.plexmod/resources/language/resource.language.es_es/strings.po index ae77eb6a46..8a5987b2c0 100644 --- a/script.plexmod/resources/language/resource.language.es_es/strings.po +++ b/script.plexmod/resources/language/resource.language.es_es/strings.po @@ -1,1711 +1,2864 @@ -# XBMC Media Center language file msgid "" msgstr "" -"Project-Id-Version: XBMC-Addons\n" -"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n" -"POT-Creation-Date: 2013-12-12 22:56+0000\n" -"PO-Revision-Date: 2024-01-28 13:15+0100\n" -"Last-Translator: DeciBelioS\n" -"Language-Team: LANGUAGE\n" -"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.4.2\n" +"X-Generator: POEditor.com\n" +"Project-Id-Version: PM4K / PlexMod for Kodi\n" +"Language: es\n" +#: msgctxt "#32000" msgid "Main" msgstr "Principal" +#: msgctxt "#32001" msgid "Original" msgstr "Original" +#: msgctxt "#32002" msgid "20 Mbps 1080p" msgstr "20 Mbps 1080p" +#: msgctxt "#32003" msgid "12 Mbps 1080p" msgstr "12 Mbps 1080p" +#: msgctxt "#32004" msgid "10 Mbps 1080p" msgstr "10 Mbps 1080p" +#: msgctxt "#32005" msgid "8 Mbps 1080p" msgstr "8 Mbps 1080p" +#: msgctxt "#32006" msgid "4 Mbps 720p" msgstr "4 Mbps 720p" +#: msgctxt "#32007" msgid "3 Mbps 720p" msgstr "3 Mbps 720p" +#: msgctxt "#32008" msgid "2 Mbps 720p" msgstr "2 Mbps 720p" +#: msgctxt "#32009" msgid "1.5 Mbps 480p" msgstr "1.5 Mbps 480p" +#: msgctxt "#32010" msgid "720 kbps" msgstr "720 kbps" +#: msgctxt "#32011" msgid "320 kbps" msgstr "320 kbps" +#: msgctxt "#32012" msgid "208 kbps" msgstr "208 kbps" +#: msgctxt "#32013" msgid "96 kbps" msgstr "96 kbps" +#: msgctxt "#32014" msgid "64 kbps" msgstr "64 kbps" +#: msgctxt "#32020" msgid "Local Quality" msgstr "Calidad Local" +#: msgctxt "#32021" msgid "Remote Quality" -msgstr "Calidad Remoto" +msgstr "Calidad Remota" +#: msgctxt "#32022" msgid "Online Quality" -msgstr "Calidad Internet" +msgstr "Calidad en línea" +#: msgctxt "#32023" msgid "Transcode Format" msgstr "Formato transcodificación" +#: msgctxt "#32024" msgid "Debug Logging" -msgstr "Log Depuración" +msgstr "Log de Depuración" +#: msgctxt "#32025" -msgid "Allow Direct Play" -msgstr "Permitir reproducción directa" +msgid "Direct Play" +msgstr "Reproducción directa" +#: msgctxt "#32026" -msgid "Allow Direct Stream" -msgstr "Permitir transmisión directa" +msgid "Direct Stream" +msgstr "Transmisión directa" +#: msgctxt "#32027" msgid "Force" msgstr "Forzar" +#: msgctxt "#32028" msgid "Always" msgstr "Siempre" +#: msgctxt "#32029" msgid "Only Image Formats" msgstr "Solo formatos de imagen" +#: msgctxt "#32030" msgid "Auto" msgstr "Auto" -msgctxt "#32031" -msgid "Burn-in Subtitles" -msgstr "Subtítulos quemados" - +#: msgctxt "#32032" msgid "Allow Insecure Connections" -msgstr "Permetir conexiones inseguras" +msgstr "Permitir conexiones inseguras" +#: msgctxt "#32033" msgid "Never" msgstr "Nunca" +#: msgctxt "#32034" msgid "On Same network" msgstr "En la misma red" +#: msgctxt "#32035" msgid "Always" msgstr "Siempre" +#: msgctxt "#32036" -msgid "Allow 4K" -msgstr "Permitir 4K" +msgid "4K" +msgstr "4K" +#: msgctxt "#32037" -msgid "Allow HEVC (h265)" -msgstr "Permetir HEVC (h265)" +msgid "HEVC (h265)" +msgstr "HEVC (h265)" +#: msgctxt "#32038" msgid "Automatically Sign In" -msgstr "Accesso automatico" +msgstr "Accesso automático" +#: msgctxt "#32039" msgid "Post Play Auto Play" msgstr "Reproducción automática posterior" +#: msgctxt "#32040" msgid "Enable Subtitle Downloading" msgstr "Activar la descarga de subtítulos" +#: msgctxt "#32041" msgid "Enable Subtitle Downloading" msgstr "Activar la descarga de subtítulos" +#: msgctxt "#32042" msgid "Server Discovery (GDM)" msgstr "Detección del Servidor (GDM)" +#: msgctxt "#32043" msgid "Start Plex On Kodi Startup" msgstr "Arrancar Plex al iniciar Kodi" +#: msgctxt "#32044" msgid "Connection 1 IP" -msgstr "IP Conexión 1" +msgstr "Conexión IP 1" +#: msgctxt "#32045" msgid "Connection 1 Port" msgstr "Puerto Conexión 1" +#: msgctxt "#32046" msgid "Connection 2 IP" -msgstr "IP Conexión 2" +msgstr "Conexión IP 2" +#: msgctxt "#32047" msgid "Connection 2 Port" msgstr "Puerto conexión 2" +#: msgctxt "#32048" msgid "Audio" msgstr "Audio" +#: msgctxt "#32049" msgid "Advanced" -msgstr "Avanzar" +msgstr "Avanzado" +#: msgctxt "#32050" msgid "Manual Servers" msgstr "Servidores manuales" +#: msgctxt "#32051" msgid "Privacy" msgstr "Privacidad" +#: msgctxt "#32052" msgid "About" msgstr "Acerca de" +#: msgctxt "#32053" msgid "Video" msgstr "Video" +#: msgctxt "#32054" msgid "Addon Version" -msgstr "Versión Add-on" +msgstr "Versión del Add-on" +#: msgctxt "#32055" msgid "Kodi Version" -msgstr "Versión Kodi" +msgstr "Versión de Kodi" +#: msgctxt "#32056" msgid "Screen Resolution" msgstr "Resolución de Pantalla" +#: msgctxt "#32057" msgid "Current Server Version" -msgstr "Versión del Servidor" +msgstr "Versión actual del Servidor" +#: msgctxt "#32058" msgid "Never exceed original audio codec" -msgstr "No superar nunca el códec de audio original" +msgstr "Nunca superar el códec de audio original" +#: msgctxt "#32059" msgid "When transcoding audio, never exceed the original audio bitrate or channel count on the same codec." msgstr "Cuando transcodifiques audio, nunca superes la tasa de bits o el número de canales del audio original en el mismo códec." +#: msgctxt "#32060" msgid "Use Kodi audio channels" msgstr "Utilizar los canales de audio de Kodi" -msgctxt "#32061" -msgid "When transcoding audio, target the audio channels set in Kodi." -msgstr "Al transcodificar audio, apunte a los canales de audio configurados en Kodi." - -msgctxt "#32062" -msgid "Transcode audio to AC3" -msgstr "Transcodificar audio a AC3" - -msgctxt "#32063" -msgid "Transcode audio to AC3 in certain conditions (useful for passthrough)." -msgstr "Transcodifica el audio a AC3 en determinadas condiciones (útil para passthrough)." - +#: msgctxt "#32064" msgid "Treat DTS like AC3" msgstr "Tratar DTS como AC3" -msgctxt "#32065" -msgid "When any of the force AC3 settings are enabled, treat DTS the same as AC3 (useful for Optical passthrough)" -msgstr "Cuando cualquiera de los ajustes de forzar AC3 está activado, trata DTS igual que AC3 (útil para el passthrough)" - -msgctxt "#32066" -msgid "Force audio to AC3" -msgstr "Forzar audio a AC3" - -msgctxt "#32067" -msgid "Only force multichannel audio to AC3" -msgstr "Forzar sólo el audio multicanal a AC3" - +#: msgctxt "#32100" msgid "Skip user selection and pin entry on startup." -msgstr "Omitir selección de usuario y PIN al iniciar." +msgstr "Omitir la selección de usuario y PIN al iniciar." +#: msgctxt "#32101" -msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a 15 second delay." -msgstr "Si se activa, cuando acabe la reproducción y 'Siguiente Capítulo' esté disponible, se reproducirá automáticamente a los 15 segundos." +msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a {} second delay." +msgstr "Si está activada, cuando finalice la reproducción y haya un elemento 'Siguiente' disponible, éste se reproducirá automáticamente tras un retardo de {} segundos." +#: msgctxt "#32102" msgid "Enable this if your hardware can handle 4K playback. Disable it to force transcoding." -msgstr "Activa esto si se puede reproducir contenido 4K. Desactívalo para forzar la trasncodificación." +msgstr "Activa esto si tu Hardware soporta la reproducción de contenido 4K. Desactívalo para forzar la transcodificación." +#: msgctxt "#32103" msgid "Enable this if your hardware can handle HEVC/h265. Disable it to force transcoding." -msgstr "Activa esto si se puede reproducir HEVC/h265. Desactiva para forzar la trascodificación." +msgstr "Activa esto si tu Hardware soporta la reproducción HEVC/h265. Desactiva para forzar la transcodificación." +#: msgctxt "#32104" msgid "When to connect to servers with no secure connections.[CR][CR]* [B]Never[/B]: Never connect to a server insecurely[CR]* [B]On Same Network[/B]: Allow if on the same network[CR]* [B]Always[/B]: Allow same network and remote connections" -msgstr "Conectar a servidores con conexiones no seguras.[CR][CR]* [B]Nunca[/B]: Nunca conectarse a un servidor de forma no segura[CR]* [B]En la misma red[/B]: Permitir para la misma red[CR]* [B]Siempre[/B]: Permitir para todas las conexiones" +msgstr "Conectar a servidores con conexiones no seguras.[CR][CR]* [B]Nunca[/B]: Nunca conectarse a un servidor de forma no segura[CR]* [B]En la misma red[/B]: Permitir si está en la misma red[CR]* [B]Siempre[/B]: Permitir para todas las conexiones" +#: msgctxt "#32201" msgid "Trailer" msgstr "Tráiler" +#: msgctxt "#32202" msgid "Deleted Scene" msgstr "Escenas eliminadas" +#: msgctxt "#32203" msgid "Interview" msgstr "Entrevista" +#: msgctxt "#32204" msgid "Music Video" msgstr "Video musical" +#: msgctxt "#32205" msgid "Behind the Scenes" -msgstr "Detrás de las escenas" +msgstr "Detrás de escenas" +#: msgctxt "#32206" msgid "Scene" msgstr "Escena" +#: msgctxt "#32207" msgid "Live Music Video" -msgstr "Videos de música en vivo" +msgstr "Video musical en vivo" +#: msgctxt "#32208" msgid "Lyric Music Video" -msgstr "Videos de letras musicales" +msgstr "Video de letras musicales" +#: msgctxt "#32209" msgid "Concert" -msgstr "Conciertos" +msgstr "Concierto" +#: msgctxt "#32210" msgid "Featurette" msgstr "Featurette" +#: msgctxt "#32211" msgid "Short" msgstr "Cortos" +#: msgctxt "#32212" msgid "Other" msgstr "Otros" +#: msgctxt "#32300" msgid "Go to Album" msgstr "Ir a Album" +#: msgctxt "#32301" msgid "Go to Artist" msgstr "Ir a Artistas" +#: msgctxt "#32302" msgid "Go to {0}" msgstr "Ir a {0}" -msgctxt "#32303" -msgid "Season" -msgstr "Temporada" - -msgctxt "#32304" -msgid "Episode" -msgstr "Capítulo" - +#: msgctxt "#32305" msgid "Extras" msgstr "Extras" +#: msgctxt "#32306" msgid "Related Shows" msgstr "Series relacionadas" +#: msgctxt "#32307" msgid "More" msgstr "Más" +#: msgctxt "#32308" msgid "Available" msgstr "Disponible" +#: msgctxt "#32309" msgid "None" msgstr "Ninguno" -msgctxt "#32310" -msgid "S" -msgstr "S" - -msgctxt "#32311" -msgid "E" -msgstr "E" - +#: msgctxt "#32312" msgid "Unavailable" msgstr "No disponible" +#: msgctxt "#32313" msgid "This item is currently unavailable." msgstr "Este elemento no está disponible actualmente." +#: msgctxt "#32314" msgid "In Progress" msgstr "En curso" +#: msgctxt "#32315" msgid "Resume playback?" msgstr "¿Continuar reproducción?" +#: msgctxt "#32316" msgid "Resume" msgstr "Continuar" +#: msgctxt "#32317" msgid "Play from beginning" msgstr "Reproducir desde el principio" +#: msgctxt "#32318" msgid "Mark Unplayed" msgstr "Marcar como no visto" +#: msgctxt "#32319" msgid "Mark Played" msgstr "Marcar como visto" +#: msgctxt "#32320" msgid "Mark Season Unplayed" msgstr "Marca la Temporada como no vista" +#: msgctxt "#32321" msgid "Mark Season Played" msgstr "Marcar la Temporada como vista" +#: msgctxt "#32322" msgid "Delete" msgstr "Borrar" +#: msgctxt "#32323" msgid "Go To Show" msgstr "Ir a la Serie" +#: msgctxt "#32324" msgid "Go To {0}" msgstr "Ir a {0}" +#: msgctxt "#32325" msgid "Play Next" msgstr "Reproducir el siguiente" +#: msgctxt "#32326" msgid "Really Delete?" msgstr "¿Borrarlo de verdad?" +#: msgctxt "#32327" msgid "Are you sure you really want to delete this media?" msgstr "¿Seguro que quieres borrar este medio?" +#: msgctxt "#32328" msgid "Yes" msgstr "Sí" +#: msgctxt "#32329" msgid "No" msgstr "No" +#: msgctxt "#32330" msgid "Message" msgstr "Mensaje" +#: msgctxt "#32331" msgid "There was a problem while attempting to delete the media." msgstr "Hubo un problema al intentar borrar este medio." +#: msgctxt "#32332" msgid "Home" msgstr "Inicio" +#: msgctxt "#32333" msgid "Playlists" msgstr "Listas de reproducción" +#: msgctxt "#32334" msgid "Confirm Exit" msgstr "Confirmar salida" +#: msgctxt "#32335" msgid "Are you ready to exit Plex?" msgstr "¿Listo para salir de Plex?" +#: msgctxt "#32336" msgid "Exit" msgstr "Salir" +#: msgctxt "#32337" msgid "Cancel" msgstr "Cancelar" +#: msgctxt "#32338" msgid "No Servers Found" msgstr "Ningún servidor encontrado" +#: msgctxt "#32339" msgid "Server is not accessible" msgstr "Servidor no accessible" +#: msgctxt "#32340" msgid "Connection tests are in progress. Please wait." -msgstr "Tests de conexión en curso. Espere por favor." +msgstr "Pruebas de conexión en curso. Espere por favor." +#: msgctxt "#32341" msgid "Server is not accessible. Please sign into your server and check your connection." msgstr "Servidor no accessible. Por favor, comprueba la conexión de tu servidor." +#: msgctxt "#32342" msgid "Switch User" msgstr "Cambiar usuario" +#: msgctxt "#32343" msgid "Settings" msgstr "Configuración" +#: msgctxt "#32344" msgid "Sign Out" -msgstr "Desconectar" +msgstr "Cerrar sesión" +#: msgctxt "#32345" msgid "All" msgstr "Todo" +#: msgctxt "#32346" msgid "By Name" msgstr "Por Nombre" +#: msgctxt "#32347" msgid "Artists" msgstr "Artistas" +#: msgctxt "#32348" msgid "Movies" msgstr "Películas" +#: msgctxt "#32349" msgid "photos" msgstr "fotos" +#: msgctxt "#32350" msgid "Shows" msgstr "Series" +#: msgctxt "#32351" msgid "By Date Added" -msgstr "Por fecha" +msgstr "Por fecha de añadido" +#: msgctxt "#32352" msgid "Date Added" -msgstr "Fecha" +msgstr "Fecha de añadido" +#: msgctxt "#32353" msgid "By Release Date" msgstr "Por fecha de estreno" +#: msgctxt "#32354" msgid "Release Date" msgstr "Fecha de estreno" +#: msgctxt "#32355" msgid "By Date Viewed" -msgstr "Por fecha de visionado" +msgstr "Por fecha en la que se vio" +#: msgctxt "#32356" msgid "Date Viewed" -msgstr "Fecha de visionado" +msgstr "Fecha en la que se vio" +#: msgctxt "#32357" -msgid "By Name" -msgstr "Por nombre" +msgid "By Title" +msgstr "Por título" +#: msgctxt "#32358" -msgid "Name" -msgstr "Nombre" +msgid "Title" +msgstr "Título" +#: msgctxt "#32359" msgid "By Rating" msgstr "Por valoración" +#: msgctxt "#32360" msgid "Rating" msgstr "Valoración" +#: msgctxt "#32361" msgid "By Resolution" msgstr "Por Resolución" +#: msgctxt "#32362" msgid "Resolution" msgstr "Resolución" +#: msgctxt "#32363" msgid "By Duration" msgstr "Por Duración" +#: msgctxt "#32364" msgid "Duration" msgstr "Duración" +#: msgctxt "#32365" msgid "By First Aired" msgstr "Por primera emisión" +#: msgctxt "#32366" msgid "First Aired" msgstr "Primera emisión" +#: msgctxt "#32367" msgid "By Unplayed" msgstr "Por No Vistos" +#: msgctxt "#32368" msgid "Unplayed" -msgstr "Non visto" +msgstr "No visto" +#: msgctxt "#32369" msgid "By Date Played" msgstr "Por Fecha de Reproducción" +#: msgctxt "#32370" msgid "Date Played" msgstr "Fecha de Reproducción" +#: msgctxt "#32371" msgid "By Play Count" msgstr "Por Número de Reproducciones" +#: msgctxt "#32372" msgid "Play Count" msgstr "Número de Reproducciones" +#: msgctxt "#32373" msgid "By Date Taken" msgstr "Por Fecha de Captura" +#: msgctxt "#32374" msgid "Date Taken" msgstr "Fecha de Captura" +#: msgctxt "#32375" msgid "No filters available" -msgstr "Sin filtros disponbles" +msgstr "Sin filtros disponibles" +#: msgctxt "#32376" msgid "Clear Filter" msgstr "Quitar filtros" +#: msgctxt "#32377" msgid "Year" msgstr "Año" +#: msgctxt "#32378" msgid "Decade" msgstr "Década" +#: msgctxt "#32379" msgid "Genre" msgstr "Género" +#: msgctxt "#32380" msgid "Content Rating" msgstr "Clasificación por Edad" +#: msgctxt "#32381" msgid "Network" msgstr "Red" +#: msgctxt "#32382" msgid "Collection" msgstr "Colección" +#: msgctxt "#32383" msgid "Director" msgstr "Dirección" +#: msgctxt "#32384" msgid "Actor" -msgstr "Actores" +msgstr "Actor" +#: msgctxt "#32385" msgid "Country" msgstr "País" +#: msgctxt "#32386" msgid "Studio" msgstr "Estudio" +#: msgctxt "#32387" msgid "Labels" msgstr "Etiquetas" +#: msgctxt "#32388" msgid "Camera Make" msgstr "Marca de Cámara" +#: msgctxt "#32389" msgid "Camera Model" msgstr "Modelo de Cámera" +#: msgctxt "#32390" msgid "Aperture" msgstr "Apertura" +#: msgctxt "#32391" msgid "Shutter Speed" msgstr "Velocidad de apertura" +#: msgctxt "#32392" msgid "Lens" msgstr "Lente" +#: msgctxt "#32393" msgid "TV Shows" msgstr "Series de TV" +#: msgctxt "#32394" msgid "Music" msgstr "Música" +#: msgctxt "#32395" msgid "Audio" msgstr "Audio" +#: msgctxt "#32396" msgid "Subtitles" msgstr "Subtítulos" +#: msgctxt "#32397" msgid "Quality" msgstr "Calidad" +#: msgctxt "#32398" msgid "Kodi Video Settings" msgstr "Configuración de Video de Kodi" +#: msgctxt "#32399" msgid "Kodi Audio Settings" msgstr "Configuración de Audio de Kodi" +#: msgctxt "#32400" msgid "Go To Season" msgstr "Ir a Temporada" +#: msgctxt "#32401" msgid "Directors" msgstr "Dirección" +#: msgctxt "#32402" msgid "Writer" msgstr "Autor" +#: msgctxt "#32403" msgid "Writers" msgstr "Guionistas" +#: msgctxt "#32404" msgid "Related Movies" msgstr "Películas relacionadas" +#: msgctxt "#32405" msgid "Download Subtitles" msgstr "Descargar Subtítulos" +#: msgctxt "#32406" msgid "Subtitle Delay" msgstr "Retardo en Subtítulos" +#: msgctxt "#32407" msgid "Next Subtitle" msgstr "Siguiente Subtítulo" +#: msgctxt "#32408" msgid "Disable Subtitles" msgstr "Desactivar Subtítulos" +#: msgctxt "#32409" msgid "Enable Subtitles" msgstr "Activar Subtítulos" +#: msgctxt "#32410" msgid "Platform Version" msgstr "Versión de la Plataforma" +#: msgctxt "#32411" msgid "Unknown" msgstr "Desconocido" +#: msgctxt "#32412" msgid "Edit Or Clear" msgstr "Modificar o Borrar" +#: msgctxt "#32413" msgid "Edit IP address or clear the current setting?" -msgstr "¿Editar la direeción IP o borrar la configuración?" +msgstr "¿Editar la direción IP o borrar la configuración?" +#: msgctxt "#32414" msgid "Clear" msgstr "Borrar" +#: msgctxt "#32415" msgid "Edit" msgstr "Modificar" +#: msgctxt "#32416" msgid "Enter IP Address" msgstr "Introduce la Dirección IP" +#: msgctxt "#32417" msgid "Enter Port Number" msgstr "Introduce el Puerto" +#: msgctxt "#32418" msgid "Creator" msgstr "Creador" +#: msgctxt "#32419" msgid "Cast" msgstr "Elenco" +#: msgctxt "#32420" msgid "Disc" msgstr "Disco" +#: msgctxt "#32421" msgid "Sign Out" -msgstr "Desconectar" +msgstr "Cerrar sesión" +#: msgctxt "#32422" msgid "Exit" msgstr "Salir" +#: msgctxt "#32423" msgid "Shutdown" msgstr "Apagar" +#: msgctxt "#32424" msgid "Suspend" msgstr "Suspender" +#: msgctxt "#32425" msgid "Hibernate" msgstr "Hibernar" +#: msgctxt "#32426" msgid "Reboot" msgstr "Reiniciar" +#: msgctxt "#32427" msgid "Failed" msgstr "Fallo" +#: msgctxt "#32428" msgid "Login failed!" msgstr "¡El acceso falló!" +#: msgctxt "#32429" msgid "Resume from {0}" msgstr "Continuar desde {0}" +#: msgctxt "#32430" msgid "Discovery" msgstr "Descubrimiento" +#: msgctxt "#32431" msgid "Search" msgstr "Búsqueda" +#: msgctxt "#32432" msgid "Space" msgstr "Espacio" +#: msgctxt "#32433" msgid "Clear" msgstr "Borrar" +#: msgctxt "#32434" msgid "Searching..." msgstr "Buscando..." +#: msgctxt "#32435" msgid "No Results" msgstr "Sin resultados" +#: msgctxt "#32436" msgid "Paused" msgstr "En Pausa" +#: msgctxt "#32437" msgid "Welcome" msgstr "Bienvenido" +#: msgctxt "#32438" msgid "Previous" msgstr "Anterior" +#: msgctxt "#32439" msgid "Playing Next" msgstr "Reproducir el Siguiente" +#: msgctxt "#32440" msgid "On Deck" msgstr "En Portada" +#: msgctxt "#32441" msgid "Unknown" msgstr "Desconocido" +#: msgctxt "#32442" msgid "Embedded" msgstr "Integrado" +#: msgctxt "#32443" msgid "Forced" msgstr "Forzado" +#: msgctxt "#32444" msgid "Lyrics" msgstr "Letras" +#: msgctxt "#32445" msgid "Mono" msgstr "Mono" +#: msgctxt "#32446" msgid "Stereo" msgstr "Stereo" +#: msgctxt "#32447" msgid "None" msgstr "Ninguno" +#: msgctxt "#32448" msgid "Playback Failed!" msgstr "¡La reproducción falló!" +#: msgctxt "#32449" msgid "Can't connect to plex.tv[CR]Check your internet connection and try again." -msgstr "No pude conectarme a plex.tv[CR]Comprueba la conexión y vuelve a intentarlo." +msgstr "No se pudo conectar a plex.tv[CR]Comprueba la conexión y vuelve a intentarlo." +#: msgctxt "#32450" msgid "Choose Version" msgstr "Elegir una Versión" +#: msgctxt "#32451" msgid "Play Version..." msgstr "Reproduce un Versión..." +#: msgctxt "#32452" msgid "No Content available in this library" msgstr "No hay contenido disponible en esta bilioteca" +#: msgctxt "#32453" msgid "Please add content and/or check that 'Include in dashboard' is enabled." -msgstr "Por favo, añade contenido y/o comprueba que 'Incluir en el dashboard' esté activado." +msgstr "Por favor, añade contenido y/o comprueba que 'Incluir en el dashboard' esté activado." +#: msgctxt "#32454" msgid "No Content available for this filter" msgstr "Sin contenido disponible por este filtro" +#: msgctxt "#32455" msgid "Please change change or remove the current filter" msgstr "Por favor, cambie o quite el filtro actual" +#: msgctxt "#32456" msgid "Show" msgstr "Serie" +#: msgctxt "#32457" msgid "By Show" msgstr "Por Serie" +#: msgctxt "#32458" msgid "Episodes" msgstr "Capítulo" +#: msgctxt "#32459" msgid "Offline Mode" msgstr "Modo Offline" +#: msgctxt "#32460" msgid "Sign In" -msgstr "Acceso" +msgstr "Iniciar sesión" +#: msgctxt "#32461" msgid "Albums" -msgstr "Albums" +msgstr "Álbumes" +#: msgctxt "#32462" msgid "Artist" msgstr "Artista" +#: msgctxt "#32463" msgid "By Artist" msgstr "Por Artista" +#: msgctxt "#32464" msgid "Player" msgstr "Reproductor" +#: msgctxt "#32465" msgid "Use skip step settings from Kodi" msgstr "Utilizar la configuración de salto de paso de Kodi" +#: msgctxt "#32466" msgid "Automatically seek selected position after a delay" msgstr "Búsqueda automática de la posición seleccionada tras un retardo" +#: msgctxt "#32467" msgid "User Interface" msgstr "Interfaz de usuario" +#: msgctxt "#32468" msgid "Show dynamic background art" msgstr "Mostrar arte de fondo dinámico" +#: msgctxt "#32469" msgid "Background art blur amount" msgstr "Cantidad de desenfoque del arte de fondo" +#: msgctxt "#32470" msgid "Background art opacity" msgstr "Opacidad del arte de fondo" +#: msgctxt "#32471" msgid "Use Plex/Kodi steps for timeline" msgstr "Utiliza los pasos de Plex/Kodi para la línea de tiempo" +#: msgctxt "#32480" msgid "Theme music" msgstr "Tema musical" +#: msgctxt "#32481" msgid "Off" msgstr "Apagado" +#: msgctxt "#32482" msgid "%(percentage)s %%" msgstr "%(percentage)s %%" +#: msgctxt "#32483" msgid "Hide Stream Info" msgstr "Ocultar mediainfo" +#: msgctxt "#32484" msgid "Show Stream Info" msgstr "Mostrar mediainfo" +#: msgctxt "#32485" msgid "Go back instantly with the previous menu action in scrolled views" msgstr "Retroceder instantáneamente con la acción del menú anterior en vistas desplazadas" +#: msgctxt "#32487" msgid "Seek Delay" msgstr "Retraso de búsqueda" +#: msgctxt "#32488" msgid "Screensaver" msgstr "Salvapantallas" +#: msgctxt "#32489" msgid "Quiz Mode" msgstr "Modo concurso" +#: msgctxt "#32490" msgid "Collections" msgstr "Colecciones" +#: msgctxt "#32491" msgid "Folders" msgstr "Carpetas" +#: msgctxt "#32492" msgid "Kodi Subtitle Settings" msgstr "Configuración de subtítulos de Kodi" -msgctxt "#32493" -msgid "When a media file has a forced/foreign subtitle for a subtitle-enabled language, the Plex Media Server preselects it. This behaviour is usually not necessary and not configurable. This setting fixes that by ignoring the PMSs decision and selecting the same language without a forced flag if possible." -msgstr "Cuando un archivo multimedia tiene un subtítulo forzado/extranjero para un idioma habilitado para subtítulos, el Plex Media Server lo preselecciona. Este comportamiento no suele ser necesario y no es configurable. Este ajuste lo soluciona ignorando la decisión del PMS y seleccionando el mismo idioma sin bandera forzada si es posible." - +#: msgctxt "#32495" msgid "Skip intro" msgstr "Saltar introducción" +#: msgctxt "#32496" msgid "Skip credits" msgstr "Saltar créditos" +#: msgctxt "#32500" msgid "Always show post-play screen (even for short videos)" -msgstr "Mostrar siempre la pantalla posterior a la reproducción (incluso para vídeos cortos)" +msgstr "Mostrar siempre la pantalla posterior a la reproducción (incluso para videos cortos)" +#: msgctxt "#32501" msgid "Time-to-wait between videos on post-play" -msgstr "Tiempo de espera entre vídeos en post-play" +msgstr "Tiempo de espera entre videos en post-play" +#: msgctxt "#32505" msgid "Visit media in video playlist instead of playing it" msgstr "Visitar medios en la lista de reproducción de vídeo en lugar de reproducirlos" +#: msgctxt "#32521" msgid "Skip Intro Button Timeout" msgstr "Tiempo de espera del botón de intro" +#: msgctxt "#32522" msgid "Automatically Skip Intro" msgstr "Saltar automáticamente la introducción" -msgctxt "#32523" -msgid "Automatically skip intros if available. Doesn't override enabled binge mode.\nCan be disabled/enabled per TV show." -msgstr "Salta automáticamente las intros si están disponibles. No anula el modo atracón activado.\nPuede desactivarse/activarse por programa de TV." - +#: msgctxt "#32524" msgid "Set how long the skip intro button shows for." msgstr "Establece el tiempo que se mostrará el botón de salto de introducción." +#: msgctxt "#32525" msgid "Skip Credits Button Timeout" msgstr "Salto del tiempo de espera del botón de créditos" +#: msgctxt "#32526" msgid "Automatically Skip Credits" msgstr "Saltar créditos automáticamente" -msgctxt "#32527" -msgid "Automatically skip credits if available. Doesn't override enabled binge mode.\nCan be disabled/enabled per TV show." -msgstr "Salta automáticamente los créditos si están disponibles. No anula el modo atracón activado.\nPuede desactivarse/activarse por programa de TV." - +#: msgctxt "#32528" msgid "Set how long the skip credits button shows for." msgstr "Establece el tiempo que se mostrará el botón de saltar créditos." +#: msgctxt "#32540" msgid "Show when the current video will end in player" msgstr "Mostrar cuándo terminará el vídeo actual en el reproductor" +#: msgctxt "#32541" msgid "Shows time left and at which time the media will end." msgstr "Muestra el tiempo restante y a qué hora terminará el medio." +#: msgctxt "#32542" msgid "Show \"Ends at\" label for the end-time as well" msgstr "Mostrar la etiqueta \"Finaliza en\" también para la hora de finalización" +#: msgctxt "#32543" msgid "Ends at" msgstr "Termina en" +#: msgctxt "#32601" -msgid "Allow AV1" -msgstr "Permitir AV1" +msgid "AV1" +msgstr "AV1" +#: msgctxt "#32602" msgid "Enable this if your hardware can handle AV1. Disable it to force transcoding." msgstr "Actívelo si su hardware puede manejar AV1. Desactívalo para forzar la transcodificación." +#: msgctxt "#33101" msgid "By Audience Rating" msgstr "Por índice de audiencia" +#: msgctxt "#33102" msgid "Audience Rating" msgstr "Clasificación del público" +#: msgctxt "#33103" msgid "By my Rating" msgstr "Según mi valoración" +#: msgctxt "#33104" msgid "My Rating" msgstr "Mi valoración" +#: msgctxt "#33105" msgid "By Content Rating" msgstr "Por clasificación de contenidos" +#: msgctxt "#33106" msgid "Content Rating" msgstr "Clasificación del contenido" +#: msgctxt "#33107" msgid "By Critic Rating" msgstr "Por valoración crítica" +#: msgctxt "#33108" msgid "Critic Rating" msgstr "Valoración de la crítica" +#: msgctxt "#33200" msgid "Background Color" msgstr "Color de fondo" +#: msgctxt "#33201" msgid "Specify solid Background Color instead of using media images" msgstr "Especifique un color de fondo sólido en lugar de utilizar imágenes multimedia" +#: msgctxt "#33400" msgid "Use old compatibility profile" msgstr "Utilizar el antiguo perfil de compatibilidad" +#: msgctxt "#33401" msgid "Uses the Chrome client profile instead of the custom one. Might fix rare issues with 3D playback." msgstr "Utiliza el perfil de cliente de Chrome en lugar del personalizado. Podría solucionar problemas poco frecuentes con la reproducción 3D." +#: +msgctxt "#32031" +msgid "Burn-in Subtitles" +msgstr "Subtítulos quemados" + +#: +msgctxt "#32061" +msgid "When transcoding audio, target the audio channels set in Kodi." +msgstr "Al transcodificar audio, apunte a los canales de audio configurados en Kodi." + +#: +msgctxt "#32062" +msgid "Transcode audio to AC3" +msgstr "Transcodificar audio a AC3" + +#: +msgctxt "#32063" +msgid "Transcode audio to AC3 in certain conditions (useful for passthrough)." +msgstr "Transcodifica el audio a AC3 en determinadas condiciones (útil para passthrough)." + +#: +msgctxt "#32065" +msgid "When any of the force AC3 settings are enabled, treat DTS the same as AC3 (useful for Optical passthrough)" +msgstr "Cuando cualquiera de los ajustes de forzar AC3 está activado, trata DTS igual que AC3 (útil para el passthrough)" + +#: +msgctxt "#32066" +msgid "Force audio to AC3" +msgstr "Forzar audio a AC3" + +#: +msgctxt "#32067" +msgid "Only force multichannel audio to AC3" +msgstr "Forzar sólo el audio multicanal a AC3" + +#: +msgctxt "#32493" +msgid "When a media file has a forced/foreign subtitle for a subtitle-enabled language, the Plex Media Server preselects it. This behaviour is usually not necessary and not configurable. This setting fixes that by ignoring the PMSs decision and selecting the same language without a forced flag if possible." +msgstr "Cuando un archivo multimedia tiene un subtítulo forzado/extranjero para un idioma habilitado para subtítulos, el Plex Media Server lo preselecciona. Este comportamiento no suele ser necesario y no es configurable. Este ajuste lo soluciona ignorando la decisión del PMS y seleccionando el mismo idioma sin bandera forzada si es posible." + +#: +msgctxt "#32523" +msgid "Automatically skip intros if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Salta automáticamente las intros si están disponibles. No anula el modo maratón activado.\n" +"Puede desactivarse/activarse por programa de TV." + +#: +msgctxt "#32527" +msgid "Automatically skip credits if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Salta automáticamente los créditos si están disponibles. No anula el modo maratón activado.\n" +"Puede desactivarse/activarse por programa de TV." + +#: msgctxt "#33501" msgid "Video played threshold" msgstr "Umbral de reproducción de vídeo" +#: msgctxt "#33502" msgid "Set this to the same value as your Plex server (Settings>Library>Video played threshold) to avoid certain pitfalls, Default: 90 %" -msgstr "Ajústelo al mismo valor que su servidor Plex (Configuración>Biblioteca>Umbral de vídeo reproducido) para evitar ciertas trampas, Predeterminado: 90%" +msgstr "Ajústelo al mismo valor que su servidor Plex (Configuración>Biblioteca>Umbral de vídeo reproducido) para evitar ciertas caídas, Predeterminado: 90%" +#: msgctxt "#33503" msgid "Use alternative hubs refresh" -msgstr "Utilizar centros alternativos refrescar" +msgstr "Utilizar un método alternativo para refrescar los Hubs" +#: msgctxt "#33504" msgid "Refreshes all hubs for all libraries after an item's watch-state has changed, instead of only those likely affected. Use this if you find a hub that doesn't update properly." -msgstr "Actualiza todos los concentradores de todas las bibliotecas después de que el estado de vigilancia de un elemento haya cambiado, en lugar de sólo los probablemente afectados. Utilícelo si encuentra un concentrador que no se actualiza correctamente." +msgstr "Actualiza todos los Hubs de todas las bibliotecas después de que el estado de reproducción de un elemento haya cambiado, en lugar de sólo los probablemente afectados. Utilícelo si encuentra un Hub que no se actualiza correctamente." +#: msgctxt "#33505" msgid "Show intro skip button early" msgstr "Mostrar el botón de salto de introducción antes de tiempo" +#: msgctxt "#33506" -msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn\'t override enabled binge mode.\nCan be disabled/enabled per TV show." -msgstr "Mostrar el botón de salto de introducción desde el inicio de un vídeo con un marcador de introducción. Se aplica la configuración de salto automático. No anula el modo atracón activado.\nPuede desactivarse/activarse por programa de TV." +msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Mostrar el botón de salto de introducción desde el inicio de un vídeo con un marcador de introducción. Se aplica la configuración de salto automático. No anula el modo maratón activado.\n" +"Puede desactivarse/activarse por programa de TV." +#: msgctxt "#33507" msgid "Enabled" msgstr "Activado" +#: msgctxt "#33508" msgid "Disabled" msgstr "Desactivado" +#: msgctxt "#33509" msgid "Early intro skip threshold (default: < 60s/1m)" msgstr "Umbral de salto de introducción temprana (por defecto: < 60s/1m)" +#: msgctxt "#33510" msgid "When showing the intro skip button early, only do so if the intro occurs within the first X seconds." -msgstr "Cuando muestre el botón de salto de introducción antes de tiempo, hágalo sólo si la introducción se produce en los primeros X segundos." +msgstr "Cuando se muestre el botón de salto de introducción antes de tiempo, hacerlo sólo si la introducción se produce en los primeros X segundos." +#: msgctxt "#33600" msgid "System" msgstr "Sistema" +#: msgctxt "#33601" msgid "Show video chapters" msgstr "Mostrar capítulos de vídeo" +#: msgctxt "#33602" msgid "If available, show video chapters from the video-file instead of the timeline-big-seek-steps." msgstr "Si está disponible, mostrar capítulos de vídeo del archivo de vídeo en lugar de la línea de tiempo-grandes-pasos-de-búsqueda." +#: msgctxt "#33603" msgid "Use virtual chapters" msgstr "Utilizar capítulos virtuales" +#: msgctxt "#33604" msgid "When the above is enabled and no video chapters are available, simulate them by using the markers identified by the Plex Server (Intro, Credits)." msgstr "Cuando lo anterior esté activado y no haya capítulos de vídeo disponibles, simúlelos utilizando los marcadores identificados por el Servidor Plex (Intro, Créditos)." +#: msgctxt "#33605" msgid "Video Chapters" msgstr "Capítulos de vídeo" +#: msgctxt "#33606" msgid "Virtual Chapters" msgstr "Capítulos virtuales" +#: msgctxt "#33607" msgid "Chapter {}" msgstr "Capítulo {}" +#: msgctxt "#33608" msgid "Intro" msgstr "Introducción" +#: msgctxt "#33609" msgid "Credits" msgstr "Créditos" +#: msgctxt "#33610" msgid "Main" msgstr "Principal" +#: msgctxt "#33611" msgid "Chapters" msgstr "Capítulos" +#: msgctxt "#33612" msgid "Markers" msgstr "Marcadores" +#: msgctxt "#33613" msgid "Kodi Buffer Size (MB)" msgstr "Tamaño del búfer de Kodi (MB)" +#: msgctxt "#33614" -msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~100 MB, Recommended max: {} MB, Default: 20 MB." -msgstr "Establece el tamaño de la Caché/Buffer de Kodi. Libre: {} MB, Recomendado: ~100 MB, Máximo recomendado: {} MB, Por defecto: 20 MB." +msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~50 MB, Recommended max: {} MB, Default: 20 MB." +msgstr "Colocar la Caché de Kodi/Tamaño de Buffer. Libre: {} MB, Recomendado: ~50 MB, Recomendado máximo: {} MB, Por defecto: 20 MB." +#: msgctxt "#33615" msgid "{time} left" msgstr "{time} restante" +#: msgctxt "#33616" msgid "Addon Path" msgstr "Ruta de Addon" +#: msgctxt "#33617" msgid "Userdata/Profile Path" -msgstr "Ruta de datos de usuario/perfil" +msgstr "Ruta Userdata/profile" +#: msgctxt "#33618" msgid "TV binge-viewing mode" -msgstr "Modo \"atracón\" de TV" +msgstr "Modo \"maratón\" de TV" +#: msgctxt "#33619" -msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn\'t skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n\nCan be disabled/enabled per TV show.\nOverrides any setting below." -msgstr "Se salta automaticamente las intros de los episodios, los créditos e intenta saltarse los resúmenes de los episodios. No salta la intro del primer episodio de una temporada y no salta los créditos finales de un programa.\nPuede ser desactivado/activado por programa de TV.\nAnula cualquier configuración de abajo." +msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn't skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n\nCan be disabled/enabled per TV show.\nOverrides any setting below." +msgstr "Se salta automaticamente las intros de los episodios, los créditos e intenta saltarse los resúmenes de los episodios. No salta la intro del primer episodio de una temporada y no salta los créditos finales de un programa.\n" +"Puede ser desactivado/activado por programa de TV.\n" +"Anula cualquier configuración de abajo." +#: msgctxt "#33620" -msgid "Plex requests timeout (seconds)" -msgstr "Tiempo de espera de las solicitudes de Plex (segundos)" +msgid "Plex server connect timeout" +msgstr "Tiempo de espera de conexión al servidor Plex" +#: msgctxt "#33621" -msgid "Set the (async and connection) timeout value of the Python requests library in seconds. Default: 5" -msgstr "Establece el valor del tiempo de espera (asíncrono y de conexión) de la biblioteca de peticiones de Python en segundos. Predeterminado: 5" +msgid "Sets the maximum amount of time to connect to a Plex Server in seconds. Default: 5" +msgstr "Establece la cantidad máxima de tiempo para conectarse a un servidor Plex en segundos. Predeterminado: 5" +#: msgctxt "#33622" msgid "LAN reachability timeout (ms)" -msgstr "Tiempo de espera de alcanzabilidad de LAN (ms)" +msgstr "Tiempo de espera de accesibilidad LAN (ms)" +#: msgctxt "#33623" msgid "When checking for LAN reachability, use this timeout. Default: 10ms" msgstr "Cuando compruebe la accesibilidad de la LAN, utilice este tiempo de espera. Por defecto: 10ms" +#: msgctxt "#33624" msgid "Network" msgstr "Red" +#: msgctxt "#33625" msgid "Smart LAN/local server discovery" msgstr "Detección inteligente de LAN/servidores locales" +#: msgctxt "#33626" -msgid "Checks whether servers returned from Plex.tv are actually local/in your LAN. For specific setups (e.g. Docker) Plex.tv might not properly detect a local server.\n\nNOTE: Only works on Kodi 19 or above." -msgstr "Comprueba si los servidores devueltos por Plex.tv son realmente locales en su LAN. Para configuraciones específicas (por ejemplo, Docker) Plex.tv podría no detectar correctamente un servidor local.\n\nNOTA: Sólo funciona en Kodi 19 o superior." - +msgid "Checks whether servers returned from Plex.tv are actually local/in your LAN. For specific setups (e.g. Docker) Plex.tv might not properly detect a local server.\n" +"\n" +"NOTE: Only works on Kodi 19 or above." +msgstr "Comprueba si los servidores devueltos por Plex.tv son realmente locales/ en su LAN. Para configuraciones específicas (por ejemplo, Docker) Plex.tv podría no detectar correctamente un servidor local.\n" +"\n" +"NOTA: Sólo funciona en Kodi 19 o superior." + +#: msgctxt "#33627" msgid "Prefer LAN/local servers over security" msgstr "Preferir los servidores LAN/locales a la seguridad" +#: msgctxt "#33628" msgid "Prioritizes local connections over secure ones. Needs the proper setting in \"Allow Insecure Connections\" and the Plex Server's \"Secure connections\" at \"Preferred\". Can be used to enforce manual servers." msgstr "Prioriza las conexiones locales sobre las seguras. Necesita la configuración adecuada en \"Permitir conexiones inseguras\" y las \"Conexiones seguras\" del servidor Plex en \"Preferidas\". Puede utilizarse para reforzar servidores manuales." +#: msgctxt "#33629" msgid "Auto-skip intro/credits offset" -msgstr "Desplazamiento automático de introducción/créditos" +msgstr "Intervalo de salto automático de introducción/créditos" +#: msgctxt "#33630" msgid "Intro/credits markers might be a little early in Plex. When auto skipping add (or subtract) this many seconds from the marker. This avoids cutting off content, while possibly skipping the marker a little late." msgstr "Los marcadores de introducción/créditos pueden ser un poco tempranos en Plex. Al saltar automáticamente, añada (o reste) esta cantidad de segundos al marcador. Esto evita cortar el contenido, mientras que posiblemente salta el marcador un poco tarde." +#: msgctxt "#32631" msgid "Playback (user-specific)" msgstr "Reproducción (específica del usuario)" +#: msgctxt "#33632" msgid "Server connectivity check timeout (seconds)" msgstr "Tiempo de espera de comprobación de conectividad del servidor (segundos)" +#: msgctxt "#33633" msgid "Set the maximum amount of time a server connection has to answer a connectivity request. Default: 2.5" msgstr "Establece la cantidad máxima de tiempo que una conexión de servidor tiene para responder a una solicitud de conectividad. Predeterminado: 2,5" +#: msgctxt "#33634" msgid "Combined Chapters" msgstr "Capítulos combinados" +#: msgctxt "#33635" msgid "Final Credits" msgstr "Créditos finales" +#: msgctxt "#32700" msgid "Action on Sleep event" msgstr "Acción sobre el evento de suspensión" +#: msgctxt "#32701" msgid "When Kodi receives a sleep event from the system, run the following action." msgstr "Cuando Kodi reciba un evento de suspensión del sistema, ejecuta la siguiente acción." +#: msgctxt "#32702" msgid "Nothing" msgstr "Nada" +#: msgctxt "#32703" msgid "Stop playback" msgstr "Detener la reproducción" +#: msgctxt "#32704" msgid "Quit Kodi" msgstr "Salir de Kodi" +#: msgctxt "#32705" msgid "CEC Standby" msgstr "CEC En espera" +#: msgctxt "#32800" msgid "Skipping intro" msgstr "Saltar introducción" +#: msgctxt "#32801" msgid "Skipping credits" msgstr "Saltar créditos" +#: msgctxt "#32900" msgid "While playing back an item and seeking on the seekbar, automatically seek to the selected position after a delay instead of having to confirm the selection." msgstr "Mientras se reproduce un elemento y se busca en la barra de búsqueda, se busca automáticamente la posición seleccionada tras un retardo en lugar de tener que confirmar la selección." +#: msgctxt "#32901" msgid "Seek delay in seconds." msgstr "Retraso de búsqueda en segundos." +#: msgctxt "#32902" msgid "Kodi has its own skip step settings. Try to use them if they're configured instead of the default ones." msgstr "Kodi tiene sus propios ajustes para saltar pasos. Intenta usarlos si están configurados en lugar de los predeterminados." +#: msgctxt "#32903" msgid "Use the above for seeking on the timeline as well." msgstr "Utilice lo anterior también para buscar en la línea de tiempo." +#: msgctxt "#32904" msgid "In seconds." msgstr "En segundos." +#: msgctxt "#32905" msgid "Cancel post-play timer by pressing OK/SELECT" msgstr "Cancelar el temporizador post-play pulsando OK/SELECCIONAR" +#: msgctxt "#32906" msgid "Cancel skip marker timer with BACK" msgstr "Cancelar el temporizador de salto de marcador con VOLVER" +#: msgctxt "#32907" msgid "When auto-skipping a marker, allow cancelling the timer by pressing BACK." msgstr "Cuando se salta automáticamente un marcador, permite cancelar el temporizador pulsando VOLVER." +#: msgctxt "#32908" msgid "Immediately skip marker with OK/SELECT" msgstr "Saltar inmediatamente el marcador con OK/SELECCIONAR" +#: msgctxt "#32909" msgid "When auto-skipping a marker with a timer, allow skipping immediately by pressing OK/SELECT." msgstr "Cuando se omita automáticamente un marcador con temporizador, permita la omisión inmediatamente pulsando OK/SELECCIONAR." +#: msgctxt "#32912" msgid "Show buffer-state on timeline" -msgstr "Mostrar el estado de la memoria intermedia en la línea de tiempo" +msgstr "Mostrar el estado del Buffer en la línea de tiempo" +#: msgctxt "#32913" msgid "Shows the current Kodi buffer/cache state on the video player timeline." msgstr "Muestra el estado actual del búfer/caché de Kodi en la línea de tiempo del reproductor de vídeo." +#: msgctxt "#32914" msgid "Loading" msgstr "Cargando" +#: msgctxt "#32915" msgid "Slow connection" msgstr "Conexión lenta" +#: msgctxt "#32916" msgid "Use with a wonky/slow connection, e.g. in a hotel room. Adjusts the UI to visually wait for item refreshes and waits for the buffer to fill when starting playback. Automatically sets readfactor=20, requires Kodi restart." msgstr "Utilícelo con una conexión lenta o inestable, por ejemplo, en una habitación de hotel. Ajusta la interfaz de usuario para esperar visualmente a que se actualicen los elementos y espera a que se llene el búfer al iniciar la reproducción. Establece automáticamente readfactor=20, requiere reiniciar Kodi." +#: msgctxt "#32917" msgid "Couldn't fill buffer in time ({}s)" msgstr "No se ha podido llenar el buffer a tiempo ({}s)" +#: msgctxt "#32918" msgid "Buffer wait timeout (seconds)" msgstr "Tiempo de espera del búfer (segundos)" +#: msgctxt "#32919" msgid "When slow connection is enabled in the addon, wait this long for the buffer to fill. Default: 120 s" msgstr "Cuando la conexión lenta está activada en el addon, espera este tiempo a que se llene el búfer. Por defecto: 120 s" +#: msgctxt "#32920" msgid "Insufficient buffer wait (seconds)" msgstr "Espera de búfer insuficiente (segundos)" +#: msgctxt "#32921" msgid "When slow connection is enabled in the addon and the configured buffer isn't big enough for us to determine its fill state, wait this long when starting playback. Default: 10 s" msgstr "Cuando la conexión lenta está activada en el addon y el búfer configurado no es lo suficientemente grande como para que podamos determinar su estado de llenado, espere este tiempo al iniciar la reproducción. Predeterminado: 10 s" +#: msgctxt "#32922" msgid "Kodi Cache Readfactor" -msgstr "Factor de lectura de la caché de Kodi" +msgstr "Factor de lectura (Readfactor) de la caché de Kodi" +#: msgctxt "#32923" msgid "Sets the Kodi cache readfactor value. Default: {0}, recommended: {1}. With \"Slow connection\" enabled this will be set to {2}, as otherwise the cache doesn't fill fast/aggressively enough." -msgstr "Establece el valor del factor de lectura de la caché de Kodi. Por defecto: {0}, recomendado: {1}. Con \"Conexión lenta\" activada, este valor será {2}, ya que de lo contrario la caché no se llena lo suficientemente rápido/agresivamente." +msgstr "Establece el valor del factor de lectura (Readfactor) de la caché de Kodi. Por defecto: {0}, recomendado: {1}. Con \"Conexión lenta\" activada, este valor será {2}, ya que de lo contrario la caché no se llena lo suficientemente rápido/agresivamente." +#: msgctxt "#32924" msgid "Minimize" msgstr "Minimizar" +#: msgctxt "#32925" msgid "Playback Settings" msgstr "Ajustes de reproducción" +#: msgctxt "#32926" msgid "Wrong pin entered!" msgstr "¡Pin introducido erróneo!" +#: msgctxt "#32927" msgid "Use episode thumbnails in continue hub" msgstr "Utilizar miniaturas de episodios en el hub de continuación" +#: msgctxt "#32928" msgid "Instead of using media artwork, use thumbnails for episodes in the continue hub on the home screen if available." msgstr "En lugar de utilizar ilustraciones multimedia, utiliza miniaturas de los episodios en el hub de continuación de la pantalla de inicio, si está disponible." +#: msgctxt "#32929" msgid "Use legacy background fallback image" msgstr "Utilizar la imagen de fondo anterior" +#: msgctxt "#32930" msgid "Previous Subtitle" msgstr "Subtítulos anteriores" +#: msgctxt "#32931" msgid "Audio/Subtitles" msgstr "Audio/Subtítulos" +#: msgctxt "#32932" -msgid "Show subtitle quick-actions button" -msgstr "Botón de acciones rápidas para mostrar subtítulos" +msgid "Subtitle quick-actions" +msgstr "Acciones rápidas de subtítulos" +#: msgctxt "#32933" -msgid "Show FFWD/RWD buttons" -msgstr "Mostrar botones FFWD/RWD" +msgid "FFWD/RWD" +msgstr "FFWD/RWD" +#: msgctxt "#32934" -msgid "Show repeat button" -msgstr "Mostrar botón de repetición" +msgid "Repeat" +msgstr "Repetir" +#: msgctxt "#32935" -msgid "Show shuffle button" -msgstr "Botón de reproducción aleatoria" +msgid "Shuffle" +msgstr "Aleatorio" +#: msgctxt "#32936" msgid "Show playlist button" msgstr "Botón Mostrar lista de reproducción" +#: msgctxt "#32937" msgid "Show prev/next button" msgstr "Mostrar botón anterior/siguiente" -msgctxt "#32938" -msgid "Only for Episodes" -msgstr "Sólo para episodios" - +#: msgctxt "#32939" -msgid "Only applies to video player UI" -msgstr "Sólo se aplica a la interfaz de usuario del reproductor de vídeo" +msgid "User-specific.\n" +"Only applies to video player UI" +msgstr "Específico del usuario.\n" +"Sólo se aplica a la interfaz de usuario del reproductor de vídeo" +#: msgctxt "#32940" -msgid "Player UI" -msgstr "Interfaz del reproductor" +msgid "Video Player" +msgstr "Reproductor de vídeo" +#: msgctxt "#32941" msgid "Forced subtitles fix" msgstr "Corrección de subtítulos forzados" +#: msgctxt "#32942" msgid "Other seasons" msgstr "Otras temporadas" +#: msgctxt "#32943" msgid "Crossfade dynamic background art" -msgstr "Arte de fondo dinámico con fundido cruzado" +msgstr "Arte de fondo dinámico con Crossfade" +#: msgctxt "#32944" msgid "Burn-in SSA subtitles (DirectStream)" msgstr "Subtítulos SSA quemados (DirectStream)" +#: msgctxt "#32945" msgid "When Direct Streaming instruct the Plex Server to burn in SSA/ASS subtitles (thus transcoding the video stream). If disabled it will not touch the video stream, but will convert the subtitle to unstyled text." -msgstr "Cuando se hace Direct Streaming, ordena al Servidor Plex que grabe los subtítulos SSA/ASS (transcodificando así el flujo de vídeo). Si se desactiva no tocará el flujo de vídeo, pero convertirá los subtítulos en texto sin estilo." +msgstr "Cuando se hace Direct Streaming, ordena al Servidor Plex que grabe los subtítulos SSA/ASS (transcodificando así la transmisión del video). Si se desactiva, no tocará la transmisión del video, pero convertirá los subtítulos en texto sin estilo." +#: msgctxt "#32946" msgid "Stop video playback on idle after" msgstr "Detener la reproducción de vídeo en reposo después de" +#: msgctxt "#32947" msgid "Stop video playback on screensaver" msgstr "Detener la reproducción de vídeo en el salvapantallas" +#: msgctxt "#32948" msgid "Allow auto-skip when transcoding" msgstr "Permitir el salto automático al transcodificar" +#: msgctxt "#32949" msgid "When transcoding/DirectStreaming, allow auto-skip functionality." msgstr "Al transcodificar/transmitir directamente, permita la función de salto automático." +#: msgctxt "#32950" msgid "Use extended title for subtitles" msgstr "Utilizar el título ampliado para los subtítulos" +#: msgctxt "#32951" msgid "When displaying subtitles use the extendedDisplayTitle Plex exposes." msgstr "Cuando muestre subtítulos utilice el título de pantalla extendida que Plex expone." -msgctxt "#32952" -msgid "Dialog flicker fix" -msgstr "Corrección del parpadeo de los diálogos" - +#: msgctxt "#32953" msgid "Reviews" msgstr "Reseñas" +#: msgctxt "#32954" -msgid "Needs Kodi restart. WARNING: This will overwrite advancedsettings.xml!\n\nTo customize other cache/network-related values, copy \"script.plexmod/pm4k_cache_template.xml\" to profile folder and edit it to your liking. (See About section for the file paths)" -msgstr "Necesita reiniciar Kodi. ADVERTENCIA: ¡Esto sobrescribirá advancedsettings.xml!\n\nPara personalizar otros valores relacionados con la caché/red, copia \"script.plexmod/pm4k_cache_template.xml\" a la carpeta profile y edítalo a tu gusto. (Consulta la sección Acerca de para ver las rutas de los archivos)" - +msgid "Needs Kodi restart. WARNING: This will overwrite advancedsettings.xml!\n" +"\n" +"To customize other cache/network-related values, copy \"script.plexmod/pm4k_cache_template.xml\" to profile folder and edit it to your liking. (See About section for the file paths)" +msgstr "Necesita reiniciar Kodi. ADVERTENCIA: ¡Esto sobrescribirá advancedsettings.xml!\n" +"\n" +"Para personalizar otros valores relacionados con la caché/red, copia \"script.plexmod/pm4k_cache_template.xml\" a la carpeta profile y edítalo a tu gusto. (Consulta la sección Acerca de para ver las rutas de los archivos)" + +#: msgctxt "#32955" msgid "Use Kodi keyboard for searching" msgstr "Usa el teclado de Kodi para buscar" +#: msgctxt "#32956" msgid "Poster resolution scaling %" msgstr "Escalado de la resolución del póster %" +#: msgctxt "#32957" msgid "In percent. Scales the resolution of all posters/thumbnails for better image quality. May impact PMS/PM4K performance, will increase the cache usage accordingly. Recommended: 200-300 % for for big screens if your hardware can handle it. Needs addon restart." msgstr "En porcentaje. Escala la resolución de todos los pósters/miniaturas para una mejor calidad de imagen. Puede afectar al rendimiento de PMS/PM4K, aumentará el uso de caché en consecuencia. Recomendado: 200-300 % para pantallas grandes si tu hardware puede soportarlo. Necesita reiniciar el addon." +#: msgctxt "#32958" msgid "Calculate OpenSubtitles.com hash" msgstr "Calcular el hash de OpenSubtitles.com" +#: msgctxt "#32959" msgid "When opening the subtitle download feature, automatically calculate the OpenSubtitles.com hash for the given file. Can improve search results, downloads 2*64 KB of the video file to calculate the hash." msgstr "Al abrir la función de descarga de subtítulos, calcula automáticamente el hash de OpenSubtitles.com para el archivo dado. Puede mejorar los resultados de búsqueda, descarga 2*64 KB del archivo de vídeo para calcular el hash." +#: msgctxt "#32960" msgid "Similar Artists" msgstr "Artistas similares" +#: msgctxt "#32961" msgid "Show hub bifurcation lines" msgstr "Mostrar líneas de bifurcación del buje" +#: msgctxt "#32962" msgid "Visually separate hubs horizontally using a thin line." msgstr "Separe visualmente los cubos horizontalmente mediante una línea fina." +#: msgctxt "#32963" msgid "Wait between videos (s)" -msgstr "Espera entre vídeos (s)" +msgstr "Espera entre videos (s)" +#: msgctxt "#32964" msgid "When playing back consecutive videos (e.g. TV shows), wait this long before starting the next one in the queue. Might fix compatibility issues with certain configurations." -msgstr "Al reproducir vídeos consecutivos (por ejemplo, programas de TV), espere este tiempo antes de iniciar el siguiente de la cola. Podría solucionar problemas de compatibilidad con determinadas configuraciones." +msgstr "Al reproducir videos consecutivos (por ejemplo, programas de TV), espere este tiempo antes de iniciar el siguiente de la cola. Podría solucionar problemas de compatibilidad con determinadas configuraciones." +#: msgctxt "#32965" msgid "Quit Kodi on exit by default" -msgstr "Salir de Kodi al salir por defecto" +msgstr "Cerrar Kodi al salir por defecto" +#: msgctxt "#32966" msgid "When exiting the addon, use \"Quit Kodi\" as default option. Can be dynamically switched using CONTEXT_MENU (often longpress SELECT)" msgstr "Al salir del addon, usa \"Salir de Kodi\" como opción por defecto. Se puede cambiar dinámicamente usando CONTEXT_MENU (a menudo pulsando prolongadamente SELECCIONAR)" +#: msgctxt "#32967" msgid "Kodi Colour Management" msgstr "Gestión del color en Kodi" +#: msgctxt "#32968" msgid "Kodi Resolution Settings" msgstr "Ajustes de resolución de Kodi" +#: msgctxt "#32969" msgid "Always request all library media items at once" -msgstr "Solicite siempre todos los materiales de la biblioteca a la vez" +msgstr "Solicite siempre todos los medios de la biblioteca a la vez" +#: msgctxt "#32970" msgid "Retrieve all media in library up front instead of fetching it in chunks as the user navigates through the library" msgstr "Recuperar todos los medios de la biblioteca por adelantado en lugar de hacerlo por partes a medida que el usuario navega por la biblioteca" +#: msgctxt "#32971" msgid "Library item-request chunk size" msgstr "Tamaño del fragmento de solicitud de ítem de biblioteca" +#: msgctxt "#32972" msgid "Request this amount of media items per chunk request in library view (+6-30 depending on view mode; less can be less straining for the UI at first, but puts more strain on the server)" msgstr "Solicita esta cantidad de elementos multimedia por petición de chunk en la vista de biblioteca (+6-30 dependiendo del modo de vista; menos puede ser menos estresante para la interfaz de usuario al principio, pero pone más tensión en el servidor)" +#: msgctxt "#32973" msgid "Episodes: Skip Post Play screen" msgstr "Episodios: Saltar pantalla de reproducción" +#: msgctxt "#32974" -msgid "When finishing an episode, don't show Post Play but go to the next one immediately.\nCan be disabled/enabled per TV show. Doesn't override enabled binge mode. Overrides the Post Play setting." -msgstr "Al terminar un episodio, no muestra Post Play sino que pasa al siguiente inmediatamente.\nPuede desactivarse/activarse por programa de TV. No anula el modo atracón activado. Anula la configuración de Post Play." +msgid "When finishing an episode, don't show Post Play but go to the next one immediately.\n" +"Can be disabled/enabled per TV show. Doesn't override enabled binge mode. Overrides the Post Play setting." +msgstr "Al terminar un episodio, no muestra Post Play sino que pasa al siguiente inmediatamente.\n" +"Puede desactivarse/activarse por programa de TV. No anula el modo maratón activado. Anula la configuración de Post Play." +#: msgctxt "#32975" msgid "Delete Season" msgstr "Borrar temporada" + +#: +msgctxt "#32976" +msgid "Adaptive" +msgstr "Adaptable" + +#: +msgctxt "#32977" +msgid "VC1" +msgstr "VC1" + +#: +msgctxt "#32978" +msgid "Enable this if your hardware can handle VC1. Disable it to force transcoding." +msgstr "Activa esto si tu Hardware puede manejar VC1. Desactiva esto para forzar la transcodificación." + +#: +msgctxt "#32979" +msgid "Allows the server to only transcode streams of a video that need transcoding, while streaming the others unaltered. If disabled, force the server to transcode everything not direct playable." +msgstr "Permitir al servidor solo transcodificar la reproducción de video que necesita de transcodificación, mientras se reproduce el resto sin cambios. Si se deshabilita, fuerza al servidor a transcodificar todo lo que no sea directamente reproducible." + +#. Refrescar Usuarios o Recargar Usuarios +#: +msgctxt "#32980" +msgid "Refresh Users" +msgstr "Volver a cargar usuarios" + +#. In this sentence Workers should not be translated to Trabajadores in Spanish because there's no real translation for it in the programming context. +#: +msgctxt "#32981" +msgid "Background worker count" +msgstr "Recuento de Workers en segundo plano" + +#: +msgctxt "#32982" +msgid "Depending on how many cores your CPU has and how much it can handle, increasing this might improve certain situations. If you experience crashes or other annormalities, leave this at its default (3). Needs an addon restart." +msgstr "Según cuántos núcleos tenga tu procesador y cuánto pueda manejar, incrementar esto podría mejorar ciertas situaciones. Si experimentas cierres repentinos u otros errores, déjalo con su configuración por defecto (3). Necesita un reinicio del Addon." + +#: +msgctxt "#32983" +msgid "Theme" +msgstr "Tema" + +#: +msgctxt "#32984" +msgid "Sets the theme. Currently only customizes all control buttons. ATTENTION: [I]Might[/I] need an addon restart.\n" +"In order to customize this, copy one of the xml's in script.plexmod/resources/skins/Main/1080i/templates to addon_data/script.plexmod/templates/{templatename}_custom.xml and adjust it to your liking, then select \"Custom\" as your theme." +msgstr "Configura el tema. Actualmente sólo personaliza todos los botones de control. ATENCIÓN: [I]Podría[/I] necesitar un reinicio del addon.\n" +"Para personalizar esto, copia uno de los xml's en script.plexmod/resources/skins/Main/1080i/templates a addon_data/script.plexmod/templates/{templatename}_custom.xml y ajústalo a tu gusto, luego selecciona \"Personalizado\" como tu tema." + +#: +msgctxt "#32985" +msgid "Modern" +msgstr "Moderno" + +#: +msgctxt "#32986" +msgid "Modern (dotted)" +msgstr "Moderno (puntos)" + +#: +msgctxt "#32987" +msgid "Classic" +msgstr "Clásico" + +#: +msgctxt "#32988" +msgid "Custom" +msgstr "Perzonalizado" + +#: +msgctxt "#32989" +msgid "Modern (colored)" +msgstr "Moderno (coloreado)" + +#: +msgctxt "#32990" +msgid "Handle plex.direct mapping" +msgstr "Manejar el mapeo de plex.direct" + +#: +msgctxt "#32991" +msgid "Notify" +msgstr "Notificar" + +#. Haven't heard about an actual translation for "Rebind" in Spanish. These techie words are usually not translated in Spanish. +#: +msgctxt "#32992" +msgid "When using servers with a plex.direct connection (most of them), should we automatically adjust advancedsettings.xml to cope with plex.direct domains? If not, you might want to add plex.direct to your router's DNS rebind exemption list." +msgstr "Cuando se utilicen servidores con una conexión a plex.direct (la mayoría), ¿deberíamos ajustar advancedsettings.xml para lidiar con los dominios de plex.direct? Si no, podrías necesitar añadir plex.direct a la lista de excepción de DNS Rebind de tu router." + +#: +msgctxt "#32993" +msgid "{} unhandled plex.direct connections found" +msgstr "{} conexiones a plex.direct sin manejar encontradas" + +#: +msgctxt "#32994" +msgid "In order for PM4K to work properly, we need to add special handling for plex.direct connections. We've found {} new unhandled connections. Do you want us to write those to Kodi's advancedsettings.xml automatically? If not, you might want to add plex.direct to your router's DNS rebind exemption list. This can be changed in the settings as well." +msgstr "Para que PM4K funcione correctamente, necesitamos añadir un manejo especial para las conexiones a plex.direct. Se han encontrado {} nuevas conexiones sin manejar. ¿Quieres que las coloquemos en el archivo advancedsettings.xml de Kodi automáticamente? Si no, podrías necesitar añadir plex.direct a la lista de excepción de DNS Rebind de tu router. Esto también puede ser cambiado en los ajustes." + +#: +msgctxt "#32995" +msgid "Advancedsettings.xml modified (plex.direct mappings)" +msgstr "Advancedsettings.xml modificado (mapeos de plex.direct)" + +#: +msgctxt "#32996" +msgid "The advancedsettings.xml file has been modified. Please restart Kodi for the changes to apply." +msgstr "El archivo advancedsettings.xml ha sido modificado. Por favor renicia Kodi para que los cambios sean aplicados." + +#: +msgctxt "#32997" +msgid "OK" +msgstr "OK" + +#. Apartado was the best interpretation for Hub that I could think of +#: +msgctxt "#32998" +msgid "Use new Continue Watching hub on Home" +msgstr "Utilizar el nuevo apartado de Continuar Viendo en Inicio" + +#. Cartelera was the best interpretation for On Deck that I could think of +#: +msgctxt "#32999" +msgid "Instead of separating Continue Watching and On Deck hubs, behave like the modern Plex clients, which combine those two types of hubs into one Continue Watching hub." +msgstr "En lugar de separar los apartados de Continuar Viendo y Cartelera, comportarse como los clientes modernos de Plex, los cuales combinan estos dos apartados en uno solo de Continuar Viendo." + +#: +msgctxt "#33000" +msgid "Enable path mapping" +msgstr "Activar mapeo de rutas" + +#: +msgctxt "#33001" +msgid "Long-press (or context menu) on a library item or: Honor path_mapping.json in the addon_data/script.plexmod folder when DirectPlaying media. This can be used to stream using other techniques such as SMB/NFS/etc. instead of the default HTTP handler. path_mapping.example.json is included in the addon's main directory." +msgstr "Pulsación larga (o menú contextual) en un elemento de la biblioteca o: Honor path_mapping.json en la carpeta addon_data/script.plexmod cuando DirectPlaying medios de comunicación. Esto puede usarse para transmitir usando otras técnicas como SMB/NFS/etc. en lugar del manejador HTTP por defecto. path_mapping.example.json está incluido en el directorio principal del addon." + +#: +msgctxt "#33002" +msgid "Verify mapped files exist" +msgstr "Verificar que los archivos mapeados existan" + +#: +msgctxt "#33003" +msgid "When path mapping is enabled and we've successfully mapped a file, verify its existence." +msgstr "Cuando el Mapeo de Rutas está activo y se ha mapeado un archivo con éxito, verificar su existencia." + +#: +msgctxt "#33004" +msgid "No spoilers without OSD" +msgstr "No Spoilers sin el OSD" + +#: +msgctxt "#33005" +msgid "When seeking without the OSD open, hide all time-related information from the user." +msgstr "Cuando se adelanta o retrocede la reproducción sin el OSD abierto, oculta toda la información relacionada con el tiempo de reproducción al usuario." + +#: +msgctxt "#33006" +msgid "No TV spoilers" +msgstr "Sin Spoilers de TV" + +#: +msgctxt "#33007" +msgid "Select in which cases to blur TV episode thumbnails, previews, redact summaries, hide episode titles and whether to blur chapter images. When the Addon Setting \"Use episode thumbnails in continue hub\" is enabled, blur them as well." +msgstr "Seleccione en qué casos desea difuminar las miniaturas de los episodios de TV, los avances, redactar los resúmenes, ocultar los títulos de los episodios y si desea difuminar las imágenes de los capítulos. Si la opción del addon \"Usar miniaturas de episodios en el hub de continuación\" está activada, difumínalas también." + +#: +msgctxt "#33008" +msgid "[Spoilers removed]" +msgstr "[Spoilers removidos]" + +#: +msgctxt "#33009" +msgid "Blur amount for unwatched/in-progress episodes" +msgstr "Cantidad de desenfoque para episodios No vistos/En progreso" + +#: +msgctxt "#33010" +msgid "Unwatched" +msgstr "No vistos" + +#: +msgctxt "#33011" +msgid "In progress" +msgstr "En curso" + +#: +msgctxt "#33012" +msgid "No unwatched episode titles" +msgstr "Títulos de Episodios no vistos" + +#: +msgctxt "#33013" +msgid "When the above is anything but \"off\", hide episode titles as well." +msgstr "Cuando lo de arriba es cualquier cosa menos \"Apagado\", ocultar los títulos de episodios también." + +#: +msgctxt "#33014" +msgid "Ignore plex.direct docker hosts" +msgstr "Ignorar los Hosts plex.direct de docker" + +#: +msgctxt "#33015" +msgid "When checking for plex.direct host mapping, ignore local Docker IPv4 addresses (172.16.0.0/12)." +msgstr "Cuando se verifica el mapeo de Host de plex.direct, ignorar las direcciones locales IPv4 de Docker (172.16.0.0/12)." + +#: +msgctxt "#33016" +msgid "Allow TV spoilers for" +msgstr "Permitir spoilers de TV para" + +#: +msgctxt "#33017" +msgid "Overrides the above for specific genres. Default: Reality, Game Show, Documentary, Sport" +msgstr "Anula lo anterior para géneros específicos. Por defecto: Reality, Game Show, Documental, Deporte" + +#: +msgctxt "#32303" +msgid "Season {}" +msgstr "Temporada {}" + +#: +msgctxt "#32304" +msgid "Episode {}" +msgstr "Episodio {}" + +#: +msgctxt "#32310" +msgid "S{}" +msgstr "S{}" + +#: +msgctxt "#32311" +msgid "E{}" +msgstr "E{}" + +#: +msgctxt "#32938" +msgid "Only for Episodes/Playlists" +msgstr "Solo para Episodios/Listas de reproducción" + +#: +msgctxt "#33018" +msgid "Cache Plex Home users" +msgstr "Guardar en Caché los usuarios de Plex Home" + +#: +msgctxt "#33019" +msgid "Visit media item" +msgstr "Visitar un archivo de medio" + +#: +msgctxt "#33020" +msgid "Play" +msgstr "Reproducir" + +#: +msgctxt "#33021" +msgid "Choose action" +msgstr "Elegir acción" + +#: +msgctxt "#33022" +msgid "Watched indicators" +msgstr "Indicadores de vigilancia" + +#: +msgctxt "#33023" +msgid "Classic: Show orange triangle for unwatched items\n" +"Modern: Show green checkmark for watched items\n" +"Modern (2024): Show white checkmark for watched items\n" +"(default: Modern (2024))" +msgstr "Clásico: Mostrar triángulo naranja para los elementos no vistos\n" +"Moderno: Mostrar una marca verde para los elementos vigilados\n" +"Moderno (2024): Mostrar marca blanca para los elementos vigilados\n" +"(por defecto: Modern (2024))" + +#: +msgctxt "#33024" +msgid "Hide background in modern indicators" +msgstr "Ocultar fondo en indicadores modernos" + +#: +msgctxt "#33025" +msgid "When the above is enabled, hide the black backdrop of the watched state." +msgstr "Cuando se activa lo anterior, oculta el fondo negro del estado vigilado." + +#: +msgctxt "#33026" +msgid "Map path: {}" +msgstr "Asignación de rutas: {}" + +#: +msgctxt "#33027" +msgid "Remove mapping: {}" +msgstr "Quitar mapeo: {}" + +#: +msgctxt "#33028" +msgid "Hide library" +msgstr "Ocultar biblioteca" + +#: +msgctxt "#33029" +msgid "Show library: {}" +msgstr "Mostrar biblioteca: {}" + +#: +msgctxt "#33030" +msgid "Choose action for: {}" +msgstr "Elegir acción para: {}" + +#: +msgctxt "#33031" +msgid "Select Kodi source for {}" +msgstr "Seleccione la fuente Kodi para {}" + +#: +msgctxt "#33032" +msgid "Show path mapping indicators" +msgstr "Mostrar indicadores de asignación de rutas" + +#: +msgctxt "#33033" +msgid "When path mapping is active for a library, display an indicator." +msgstr "Cuando la asignación de rutas está activa para una biblioteca, muestra un indicador." + +#: +msgctxt "#33035" +msgid "Delete {}: {}?" +msgstr "Borrar {}: {}?" + +#: +msgctxt "#33036" +msgid "Delete episode S{0:02d}E{1:02d} from {2}?" +msgstr "¿Borrar episodio S{0:02d}E{1:02d} de {2}?" + +#: +msgctxt "#33037" +msgid "Maximum intro offset to consider" +msgstr "Desplazamiento de introducción máximo a considerar" + +#: +msgctxt "#33038" +msgid "When encountering an intro marker with a start time offset greater than this, ignore it (default: 600s/10m)" +msgstr "Cuando encuentre un marcador de introducción con un desfase de tiempo de inicio superior a este valor, ignórelo (por defecto: 600s/10m)" + +#: +msgctxt "#33039" +msgid "Move" +msgstr "Mover" + +#: +msgctxt "#33040" +msgid "Reset library order" +msgstr "Restablecer el orden de la biblioteca" + +#: +msgctxt "#33034" +msgid "Library settings" +msgstr "Configuración de la biblioteca" + +#: +msgctxt "#33041" +msgid "Show hub: {}" +msgstr "Mostrar centro: {}" + +#: +msgctxt "#33042" +msgid "Episode Date Added" +msgstr "Fecha del episodio añadida" + +#: +msgctxt "#33043" +msgid "Hubs round-robin" +msgstr "Hubs round-robin" + +#: +msgctxt "#33044" +msgid "Allow round-robining in hubs. Attention: Loads a lot of items. Depending on the hub size, this can lead to crashes. Current limit: {}; can be adjusted in addon settings." +msgstr "Permitir round-robin en hubs. Atención: Carga muchos elementos. Dependiendo del tamaño del hub, esto puede provocar fallos. Límite actual: {}; se puede ajustar en la configuración del addon." + +#: +msgctxt "#33045" +msgid "Behave like official Plex clients" +msgstr "Comportarse como clientes oficiales de Plex" + +#: +msgctxt "#33046" +msgid "When pressing up/down while the OSD isn't shown, show OSD instead of skipping chapters. Additionally, when pressing down while the OSD is shown, open the chapters (if available)." +msgstr "Al presionar arriba/abajo mientras el OSD no está mostrado, mostrar el OSD en lugar de saltar capítulos. Además, al presionar abajo mientras el OSD está mostrado, abrir los capítulos (si están disponibles)." + +#: +msgctxt "#33047" +msgid "Hubs round-robin item limit" +msgstr "Límite de elementos round-robin en hubs" + +#: +msgctxt "#33048" +msgid "When hubs round-robin is enabled, only round-robin until this item limit. If the hub size exceeds this limit, the remaining items will be lazy loaded as usual. Tested minimum safe value on NVIDIA SHIELD 2019 is 1000. Default: 250" +msgstr "Cuando el round-robin en hubs está habilitado, solo hacer round-robin hasta este límite de elementos. Si el tamaño del hub excede este límite, los elementos restantes se cargarán de manera diferida como de costumbre. El valor mínimo seguro probado en NVIDIA SHIELD 2019 es 1000. Por defecto: 250." + +#: +msgctxt "#33049" +msgid "Max retries" +msgstr "Reintentos máximos" + +#: +msgctxt "#33050" +msgid "The maximum number of retries each connection should attempt. The default (3) helps with hibernation/wakeup issues. Set higher for bad connections, setting this to 0 was the old default before 0.7.9" +msgstr "El número máximo de reintentos que debe intentar cada conexión. El valor por defecto (3) ayuda con problemas de hibernación/despertar. Establézcalo más alto para malas conexiones, establecerlo a 0 era el antiguo valor por defecto antes de 0.7.9" + +#: +msgctxt "#33051" +msgid "Use CA certificate bundle" +msgstr "Utilizar paquete de certificados CA" + +#: +msgctxt "#33052" +msgid "Which CA certificate bundle to use for request HTTPS verification. Default is \"system\", which uses the system-provided certificate bundle. \"plex.direct\" uses an extremely small bundle provided with the addon, which only applies to plex.direct connections (any other connections will use the system bundle) and might slightly improve performance. \"custom\" allows for a certificate bundle in userdata/addon_data/script.plexmod/custom_bundle.crt" +msgstr "Qué paquete de certificados CA utilizar para la verificación HTTPS de la solicitud. Por defecto es \"system\", que utiliza el paquete de certificados proporcionado por el sistema. \"plex.direct \" utiliza un paquete extremadamente pequeño proporcionado con el complemento, que sólo se aplica a las conexiones plex.direct (cualquier otra conexión utilizará el paquete del sistema) y podría mejorar ligeramente el rendimiento. \"custom\" permite un paquete de certificados en userdata/addon_data/script.plexmod/custom_bundle.crt" + +#: +msgctxt "#33053" +msgid "System" +msgstr "Sistema" + +#: +msgctxt "#33054" +msgid "plex.direct (addon-supplied)" +msgstr "plex.direct (suministrado por el addon)" + +#: +msgctxt "#33055" +msgid "Custom" +msgstr "Personalizado" + +#: +msgctxt "#33056" +msgid "None" +msgstr "Ninguno" + +#: +msgctxt "#33057" +msgid "Show buttons" +msgstr "Mostrar botones" + +#: +msgctxt "#33058" +msgid "Playback features" +msgstr "Funciones de reproducción" + +#: +msgctxt "#33059" +msgid "Additional codecs" +msgstr "Códecs adicionales" + +#: +msgctxt "#33060" +msgid "{feature_ds}: {desc_ds}\n" +"{feature_4k}: {desc_4k}" +msgstr "{feature_ds}: {desc_ds}\n" +"{feature_4k}: {desc_4k}" + +#: +msgctxt "#33061" +msgid "Enable certain codecs if your hardware supports them. Disable them to force transcoding." +msgstr "Activa determinados códecs si tu hardware los admite. Desactívalos para forzar la transcodificación." + +#: +msgctxt "#33062" +msgid "Compiling templates" +msgstr "Compilación de plantillas" + +#: +msgctxt "#33063" +msgid "Looking for custom templates" +msgstr "Búsqueda de plantillas personalizadas" + +#: +msgctxt "#33064" +msgid "Rendering: {}" +msgstr "Renderizado: {}" + +#: +msgctxt "#33065" +msgid "Complete" +msgstr "Completo" + +#: +msgctxt "#33066" +msgid "Cache template files" +msgstr "Caché de archivos de plantilla" + +#: +msgctxt "#33067" +msgid "Doesn't throw away the template source files after compiling them. Uses slightly more memory but increases the speed of theme-related changes." +msgstr "No tira los archivos fuente de la plantilla después de compilarlos. Utiliza algo más de memoria, pero aumenta la velocidad de los cambios relacionados con los temas." + +#: +msgctxt "#33068" +msgid "Always compile templates" +msgstr "Compilar siempre las plantillas" + +#: +msgctxt "#33069" +msgid "Recompiles all templates on every startup. Useful for template/theme development." +msgstr "Recompila todas las plantillas en cada inicio. Útil para el desarrollo de plantillas/temas." + +#: +msgctxt "#33070" +msgid "Action on Wake event" +msgstr "Acción al evento de activación" + +#: +msgctxt "#33071" +msgid "Restart PM4K" +msgstr "Reiniciar PM4K" + +#: +msgctxt "#33072" +msgid "Wait for {}s" +msgstr "Esperar {}s" + +#: +msgctxt "#33073" +msgid "Wait after wakeup" +msgstr "Esperar después de despertar" + +#: +msgctxt "#33074" +msgid "Waiting {} second(s)" +msgstr "Esperando {} segundo(s)" + +#: +msgctxt "#33075" +msgid "Do something after waking up. Waiting for a time until resuming normal execution helps with networks coming back up after sleep events. Default: 1 second (5 seconds, CoreELEC)." +msgstr "Hacer algo después de despertar. Esperar un tiempo hasta reanudar la ejecución normal ayuda con las redes que vuelven a funcionar después de eventos de reposo. Por defecto: 1 segundo (5 segundos, CoreELEC)." + +#: +msgctxt "#33076" +msgid "Modern (2024)" +msgstr "Moderno (2024)" + +#: +msgctxt "#33077" +msgid "Scale modern indicators" +msgstr "Escala de indicadores modernos" + +#: +msgctxt "#33078" +msgid "Scale the modern indicators based on the poster size used. Default: On (tiny: 0.75, small: 1.0, medium: 1.175, big: 1.3)" +msgstr "Escala los indicadores modernos en función del tamaño del póster utilizado. Por defecto: Activado (diminuto: 0.75, pequeño: 1.0, mediano: 1.175, grande: 1.3)" + +#: +msgctxt "#33079" +msgid "Hi-Res Music" +msgstr "Música de alta resolución" + +#: +msgctxt "#33080" +msgid "Allow DirectPlay of high resolution music (e.g. FLAC, >= 192 kHz)" +msgstr "Permitir la reproducción directa de música de alta resolución (por ejemplo, FLAC, >= 192 kHz)" + +#: +msgctxt "#33081" +msgid "Blur chapter images" +msgstr "Difuminar imágenes de capítulos" + +#: +msgctxt "#33082" +msgid "Scan Library Files" +msgstr "Escanear archivos de biblioteca" + +#: +msgctxt "#33083" +msgid "Empty Trash" +msgstr "Vaciar papelera" + +#: +msgctxt "#33084" +msgid "Analyze" +msgstr "Analizar" + +#: +msgctxt "#33085" +msgid "Map key to home" +msgstr "Asignar tecla a inicio" + +#: +msgctxt "#33086" +msgid "Press the key you want to map to go to home within {} seconds" +msgstr "Presiona la tecla que deseas asignar para ir a inicio dentro de {} segundos" + +#: +msgctxt "#33087" +msgid "Bind a key to immediately go to the Home view. Cancel using BACK/PREVIOUS_MENU. Clear bound key using the STOP or CONTEXT_MENU (long press OK/Enter) button on the setting." +msgstr "Vincule una tecla para ir inmediatamente a la vista Inicio. Cancele usando BACK/PREVIOUS_MENU. Borre la tecla vinculada utilizando el botón STOP o CONTEXT_MENU (pulsación larga OK/Enter) en el ajuste." + +#: +msgctxt "#33088" +msgid "Only applies to video player UI" +msgstr "Sólo se aplica a la interfaz de usuario del reproductor de vídeo" + +#: +msgctxt "#33089" +msgid "Automatic seek-back" +msgstr "Retroceso automático" + +#: +msgctxt "#33090" +msgid "If your audio doesn't resume as fast as the video, or you want to catch up after a longer pause, use this to seek back after resuming from pause to compensate for the delay. Default: Off" +msgstr "Si el audio no se reanuda tan rápido como el vídeo, o si desea ponerse al día después de una pausa larga, utilice esta opción para buscar hacia atrás después de reanudar desde la pausa para compensar el retraso. Predeterminado: Desactivado" + +#: +msgctxt "#33091" +msgid "{sec_or_ms} {unit_s_or_ms}" +msgstr "{sec_or_ms} {unit_s_or_ms}" + +#: +msgctxt "#33092" +msgid "Seek back on pause" +msgstr "Buscar de nuevo en pausa" + +#: +msgctxt "#33093" +msgid "Seek back after" +msgstr "Volver a buscar después" + +#: +msgctxt "#33094" +msgid "Only seek back after having paused at least a certain amount of seconds" +msgstr "Sólo buscar de nuevo después de haber hecho una pausa de al menos una cierta cantidad de segundos" + +#: +msgctxt "#33095" +msgid "Seek back on pause instead of on resume. When Transcoding you should enable this." +msgstr "Retroceder en la pausa en lugar de en la reanudación. Al transcodificar debe activar esta opción." + +#: +msgctxt "#33096" +msgid "Only with Direct Play" +msgstr "Sólo con reproducción directa" + +#: +msgctxt "#33097" +msgid "Enable seek back ony when we're Direct Playing, not Transcoding." +msgstr "Activar la búsqueda sólo cuando estemos reproduciendo directamente, no transcodificando." + +#: +msgctxt "#33098" +msgid "Tickrate (Hz)" +msgstr "Frecuencia de tick (Hz)" + +#: +msgctxt "#33099" +msgid "Controls how often certain ticks are performed on GUI windows and the SeekDialog/VideoPlayer and how fast certain events are handled. Can be expensive when bigger than 1 Hz (once per second), can cause quirks when lower than 1 Hz (less than once per second). Depends on the hardware. Default: 1 Hz, Max: 10 Hz (every 100 ms), Sane highest and old default: 10 Hz (every 100 ms)" +msgstr "Controla la frecuencia con la que se realizan ciertos ticks en las ventanas de la GUI y en el diálogo de búsqueda/reproductor de vídeo, así como la rapidez con la que se gestionan ciertos eventos. Puede ser costoso cuando es mayor a 1 Hz (una vez por segundo), puede causar problemas cuando es menor a 1 Hz (menos de una vez por segundo). Depende del hardware. Por defecto: 1 Hz, Max: 10 Hz (cada 100 ms), Valor predeterminado más alto y antiguo sensato: 10 Hz (cada 100 ms)" + +#: +msgctxt "#33636" +msgid "Plex server read timeout" +msgstr "Tiempo de espera de lectura del servidor Plex" + +#: +msgctxt "#33637" +msgid "Sets the maximum amount of time to read from a Plex Server in seconds. Default: 10" +msgstr "Establece la cantidad máxima de tiempo para leer desde un servidor Plex en segundos. Predeterminado: 10" + +#: +msgctxt "#33638" +msgid "Plex.tv connect timeout" +msgstr "Tiempo de espera de conexión de Plex.tv" + +#: +msgctxt "#33639" +msgid "Plex.tv: Sets the maximum amount of time to connect to Plex.tv in seconds. Default: 5" +msgstr "Plex.tv: Establece la cantidad máxima de tiempo para conectarse a Plex.tv en segundos. Predeterminado: 5" + +#: +msgctxt "#33640" +msgid "Plex.tv read timeout" +msgstr "Tiempo de espera de lectura de Plex.tv" + +#: +msgctxt "#33641" +msgid "Plex.tv: Sets the maximum amount of time to read from Plex.tv in seconds. Default: 20" +msgstr "Plex.tv: Establece la cantidad máxima de tiempo para leer de Plex.tv en segundos. Predeterminado: 20" + +#: +msgctxt "#33642" +msgid "Dump config" +msgstr "Volcar configuración" + +#: +msgctxt "#33643" +msgid "Dumps all user settings into the log on startup, when DEBUG logging is enabled. Masks private information." +msgstr "Vuelca toda la configuración del usuario en el registro al inicio, cuando el registro DEBUG está activado. Enmascara la información privada." + +#: +msgctxt "#33644" +msgid "Tracks" +msgstr "Pistas" + +#: +msgctxt "#33645" +msgid "plex.direct: Honor plex.tv's dnsRebindingProtection flag (DNS)" +msgstr "plex.direct: Respete la bandera dnsRebindingProtection de plex.tv (DNS)" + +#: +msgctxt "#33646" +msgid "Only handle plex.direct hosts when the server's attributes dnsRebindingProtection=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "Solo maneja hosts plex.direct cuando los atributos del servidor dnsRebindingProtection=1. Puede no funcionar en ciertas situaciones. Desactivar si tiene problemas de conexión. Por defecto: En" + +#: +msgctxt "#33647" +msgid "plex.direct: Honor plex.tv's publicAddressMatches flag (DNS)" +msgstr "plex.direct: Respete la bandera publicAddressMatches de plex.tv (DNS)" + +#: +msgctxt "#33648" +msgid "Only handle plex.direct hosts when the server's attributes publicAddressMatches=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "Sólo maneja hosts plex.direct cuando los atributos publicAddressMatches=1 del servidor. Puede no funcionar en ciertas situaciones. Desactivar si tiene problemas de conexión. Por defecto: En" + +#: +msgctxt "#33649" +msgid "CoreELEC: Resume-fix wait for seek" +msgstr "CoreELEC: Reanudar y corregir la espera de búsqueda" + +#: +msgctxt "#33650" +msgid "This adjusts the delay between seek-tries on CoreELEC, which fixes resume not always working or double-seeking. When you have resume/double-seek issues, increase this. 100ms should be stable as well. Default: 350ms" +msgstr "Ajusta el retardo entre los intentos de búsqueda en CoreELEC, lo que corrige la reanudación que no siempre funciona o la doble búsqueda. Cuando tenga problemas de reanudación/doble búsqueda, auméntelo. 100ms debería ser estable también. Por defecto: 350ms" + +#: +msgctxt "#33651" +msgid "Startup delay" +msgstr "Retraso en el arranque" + +#: +msgctxt "#33652" +msgid "Never show Post Play" +msgstr "No mostrar nunca la reproducción posterior" + diff --git a/script.plexmod/resources/language/resource.language.it_it/strings.po b/script.plexmod/resources/language/resource.language.it_it/strings.po index 50dee38bce..2142657d7d 100644 --- a/script.plexmod/resources/language/resource.language.it_it/strings.po +++ b/script.plexmod/resources/language/resource.language.it_it/strings.po @@ -1,951 +1,3019 @@ -# XBMC Media Center language file msgid "" msgstr "" -"Project-Id-Version: XBMC-Addons\n" -"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n" -"POT-Creation-Date: 2013-12-12 22:56+0000\n" -"PO-Revision-Date: 2017-05-25 10:52+0200\n" -"Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: POEditor.com\n" +"Project-Id-Version: PM4K / PlexMod for Kodi\n" "Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Last-Translator: \n" -"X-Generator: Poedit 2.0.2\n" +#: msgctxt "#32000" msgid "Main" msgstr "Principale" +#: msgctxt "#32001" msgid "Original" msgstr "Originale" +#: msgctxt "#32002" msgid "20 Mbps 1080p" msgstr "20 Mbps 1080p" +#: msgctxt "#32003" msgid "12 Mbps 1080p" msgstr "12 Mbps 1080p" +#: msgctxt "#32004" msgid "10 Mbps 1080p" msgstr "10 Mbps 1080p" +#: msgctxt "#32005" msgid "8 Mbps 1080p" msgstr "8 Mbps 1080p" +#: msgctxt "#32006" msgid "4 Mbps 720p" msgstr "4 Mbps 720p" +#: msgctxt "#32007" msgid "3 Mbps 720p" msgstr "3 Mbps 720p" +#: msgctxt "#32008" msgid "2 Mbps 720p" msgstr "2 Mbps 720p" +#: msgctxt "#32009" msgid "1.5 Mbps 480p" msgstr "1.5 Mbps 480p" +#: msgctxt "#32010" msgid "720 kbps" msgstr "720 kbps" +#: msgctxt "#32011" msgid "320 kbps" msgstr "320 kbps" +#: msgctxt "#32012" msgid "208 kbps" msgstr "208 kbps" +#: msgctxt "#32013" msgid "96 kbps" msgstr "96 kbps" +#: msgctxt "#32014" msgid "64 kbps" msgstr "64 kbps" +#: msgctxt "#32020" msgid "Local Quality" msgstr "Qualità Locale" +#: msgctxt "#32021" msgid "Remote Quality" msgstr "Qualità Remota" +#: msgctxt "#32022" msgid "Online Quality" msgstr "Qualità Online" +#: msgctxt "#32023" msgid "Transcode Format" msgstr "Formato transcodifica" +#: msgctxt "#32024" msgid "Debug Logging" msgstr "Log di Debug" +#: msgctxt "#32025" msgid "Allow Direct Play" msgstr "Permetti Play Diretto" +#: msgctxt "#32026" msgid "Allow Direct Stream" msgstr "Permetti Stream Diretto" +#: msgctxt "#32027" msgid "Force" msgstr "Forza" +#: msgctxt "#32028" msgid "Always" msgstr "Sempre" +#: msgctxt "#32029" msgid "Only Image Formats" msgstr "Solo formati immagine" +#: msgctxt "#32030" msgid "Auto" msgstr "Auto" -msgctxt "#32031" -msgid "Burn Subtitles (Direct Play Only)" -msgstr "Sottotitoli (Solo Play Diretto)" - +#: msgctxt "#32032" msgid "Allow Insecure Connections" msgstr "Permetti connessioni non sicure" +#: msgctxt "#32033" msgid "Never" msgstr "Mai" +#: msgctxt "#32034" msgid "On Same network" msgstr "Sulla stessa rete" +#: msgctxt "#32035" msgid "Always" msgstr "Sempre" +#: msgctxt "#32036" msgid "Allow 4K" msgstr "Permetti 4K" +#: msgctxt "#32037" msgid "Allow HEVC (h265)" msgstr "Permetti HEVC (h265)" +#: msgctxt "#32038" msgid "Automatically Sign In" msgstr "Accesso (Sign In) automatico" +#: msgctxt "#32039" msgid "Post Play Auto Play" msgstr "Post Play Auto Play" +#: msgctxt "#32040" msgid "Enable Subtitle Downloading" msgstr "Abilita il download dei sottotitoli" +#: msgctxt "#32041" msgid "Enable Subtitle Downloading" msgstr "Abilita il download dei sottotitoli" +#: msgctxt "#32042" msgid "Server Discovery (GDM)" msgstr "Ricerca Server (GDM)" +#: msgctxt "#32043" msgid "Start Plex On Kodi Startup" msgstr "Esegui Plex all'avvio di Kodi" +#: msgctxt "#32044" msgid "Connection 1 IP" msgstr "IP connessione 1" +#: msgctxt "#32045" msgid "Connection 1 Port" msgstr "Porta connessione 1" +#: msgctxt "#32046" msgid "Connection 2 IP" msgstr "IP connessione 2" +#: msgctxt "#32047" msgid "Connection 2 Port" msgstr "Porta connessione 2" +#: msgctxt "#32048" msgid "Audio" msgstr "Audio" +#: msgctxt "#32049" msgid "Advanced" msgstr "Avanzate" +#: msgctxt "#32050" msgid "Manual Servers" msgstr "Server manuali" +#: msgctxt "#32051" msgid "Privacy" msgstr "Privacy" +#: msgctxt "#32052" msgid "About" -msgstr "Circa" +msgstr "Informazioni" +#: msgctxt "#32053" msgid "Video" msgstr "Video" +#: msgctxt "#32054" msgid "Addon Version" msgstr "Versione Addon" +#: msgctxt "#32055" msgid "Kodi Version" msgstr "Versione Kodi" +#: msgctxt "#32056" msgid "Screen Resolution" msgstr "Risoluzione schermo" +#: msgctxt "#32057" msgid "Current Server Version" msgstr "Versione Server attuale" +#: +msgctxt "#32058" +msgid "Never exceed original audio codec" +msgstr "Non superare il codec audio originale" + +#: +msgctxt "#32059" +msgid "When transcoding audio, never exceed the original audio bitrate or channel count on the same codec." +msgstr "Durante la transcodifica dell'audio, non superare mai il bitrate audio originale o il numero di canali sullo stesso codec." + +#: +msgctxt "#32060" +msgid "Use Kodi audio channels" +msgstr "Utilizza i canali audio Kodi" + +#: +msgctxt "#32064" +msgid "Treat DTS like AC3" +msgstr "Tratta DTS come AC3" + +#: msgctxt "#32100" msgid "Skip user selection and pin entry on startup." msgstr "All'avvio salta l'immissione del PIN e la selezione utente." +#: msgctxt "#32101" msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a 15 second delay." msgstr "Se abilitato, quando la riproduzione finisce e un 'Titolo Successivo' è disponibile, sarà automaticamente riprodotto dopo un ritardo di 15 secondi." +#: msgctxt "#32102" msgid "Enable this if your hardware can handle 4K playback. Disable it to force transcoding." msgstr "Abilita se il tuo hardware supporta la riproduzione 4K. Disabilita per forzare la trascodifica." +#: msgctxt "#32103" msgid "Enable this if your hardware can handle HEVC/h265. Disable it to force transcoding." msgstr "Abilita se il tuo hardware supporta HEVC/h265. Disabilita per forzare la trascodifica." +#: msgctxt "#32104" msgid "When to connect to servers with no secure connections.[CR][CR]* [B]Never[/B]: Never connect to a server insecurely[CR]* [B]On Same Network[/B]: Allow if on the same network[CR]* [B]Always[/B]: Allow same network and remote connections" msgstr "Quando connettersi a Server con connessioni non sicure.[CR][CR]* [B]Mai[/B]: Mai connettersi a Server non sicuri[CR]* [B]Sulla stessa Rete[/B]: Permetti se nella stessa Rete[CR]* [B]Sempre[/B]: Permetti sulla stessa Rete e su Reti remote" +#: msgctxt "#32201" msgid "Trailer" msgstr "Trailer" +#: msgctxt "#32202" msgid "Deleted Scene" msgstr "Scene cancellate" +#: msgctxt "#32203" msgid "Interview" msgstr "Intervista" +#: msgctxt "#32204" msgid "Music Video" msgstr "Video musicali" +#: msgctxt "#32205" msgid "Behind the Scenes" msgstr "Dietro le scene" +#: msgctxt "#32206" msgid "Scene" msgstr "Scena" +#: msgctxt "#32207" msgid "Live Music Video" msgstr "Video musicali dal vivo" +#: msgctxt "#32208" msgid "Lyric Music Video" msgstr "Testi video musicali" +#: msgctxt "#32209" msgid "Concert" msgstr "Concerto" +#: msgctxt "#32210" msgid "Featurette" msgstr "Featurette" +#: msgctxt "#32211" msgid "Short" msgstr "Corto" +#: msgctxt "#32212" msgid "Other" msgstr "Altro" +#: msgctxt "#32300" msgid "Go to Album" msgstr "Vai all'Album" +#: msgctxt "#32301" msgid "Go to Artist" msgstr "Vai all'Artista" +#: msgctxt "#32302" msgid "Go to {0}" msgstr "Vai a {0}" -msgctxt "#32303" -msgid "Season" -msgstr "Stagione" - -msgctxt "#32304" -msgid "Episode" -msgstr "Episodio" - +#: msgctxt "#32305" msgid "Extras" msgstr "Extras" +#: msgctxt "#32306" msgid "Related Shows" msgstr "Serie correlate" +#: msgctxt "#32307" msgid "More" msgstr "Più" +#: msgctxt "#32308" msgid "Available" msgstr "Disponibile" +#: msgctxt "#32309" msgid "None" msgstr "Nessuno" -msgctxt "#32310" -msgid "S" -msgstr "S" - -msgctxt "#32311" -msgid "E" -msgstr "E" - +#: msgctxt "#32312" msgid "Unavailable" msgstr "Non disponibile" +#: msgctxt "#32313" msgid "This item is currently unavailable." msgstr "Questo elemento non è al momento diponibile" +#: msgctxt "#32314" msgid "In Progress" msgstr "In Corso" +#: msgctxt "#32315" msgid "Resume playback?" msgstr "Riprendere la riproduzione?" +#: msgctxt "#32316" msgid "Resume" msgstr "Riprendi" +#: msgctxt "#32317" msgid "Play from beginning" msgstr "Riproduci dall'inizio" +#: msgctxt "#32318" msgid "Mark Unplayed" msgstr "Marca come non visto" +#: msgctxt "#32319" msgid "Mark Played" msgstr "Marca come visto" +#: msgctxt "#32320" msgid "Mark Season Unplayed" msgstr "Marca la Stagione come non vista" +#: msgctxt "#32321" msgid "Mark Season Played" msgstr "Marca la Stagione come vista" +#: msgctxt "#32322" msgid "Delete" msgstr "Cancellato" +#: msgctxt "#32323" msgid "Go To Show" msgstr "Vai alla Serie" +#: msgctxt "#32324" msgid "Go To {0}" msgstr "Vai a {0}" +#: msgctxt "#32325" msgid "Play Next" msgstr "Riproduci il titolo succesivo" +#: msgctxt "#32326" msgid "Really Delete?" msgstr "Cancellare veramente?" +#: msgctxt "#32327" msgid "Are you sure you really want to delete this media?" msgstr "Sei sucuro che vuoi davvero cancellare questo media?" +#: msgctxt "#32328" msgid "Yes" msgstr "Sì" +#: msgctxt "#32329" msgid "No" msgstr "No" +#: msgctxt "#32330" msgid "Message" msgstr "Messaggio" +#: msgctxt "#32331" msgid "There was a problem while attempting to delete the media." msgstr "C'è stato un problema nella cancellazione del media." +#: msgctxt "#32332" msgid "Home" msgstr "Home" +#: msgctxt "#32333" msgid "Playlists" msgstr "Playlists" +#: msgctxt "#32334" msgid "Confirm Exit" msgstr "Conferma Uscita" +#: msgctxt "#32335" msgid "Are you ready to exit Plex?" msgstr "Sei pronto per uscire da Plex?" +#: msgctxt "#32336" msgid "Exit" msgstr "Esci" +#: msgctxt "#32337" msgid "Cancel" msgstr "Cancella" +#: msgctxt "#32338" msgid "No Servers Found" msgstr "Nessun Server trovato" +#: msgctxt "#32339" msgid "Server is not accessible" msgstr "Server non accessibile" +#: msgctxt "#32340" msgid "Connection tests are in progress. Please wait." msgstr "Test di connessione in corso. Per favore attenti." +#: msgctxt "#32341" msgid "Server is not accessible. Please sign into your server and check your connection." msgstr "Server non accessibile. Per favore fai il sign in nel Server a controlla la connessione." +#: msgctxt "#32342" msgid "Switch User" msgstr "Cambia utente" +#: msgctxt "#32343" msgid "Settings" msgstr "Impostazioni" +#: msgctxt "#32344" msgid "Sign Out" msgstr "Esci (Sign Out)" +#: msgctxt "#32345" msgid "All" msgstr "Tutto" +#: msgctxt "#32346" msgid "By Name" msgstr "Per Nome" +#: msgctxt "#32347" msgid "Artists" msgstr "Artisti" +#: msgctxt "#32348" -msgid "movies" -msgstr "film" +msgid "Movies" +msgstr "Film" +#: msgctxt "#32349" msgid "photos" msgstr "foto" +#: msgctxt "#32350" msgid "Shows" msgstr "Serie" +#: msgctxt "#32351" msgid "By Date Added" msgstr "Per data di aggiunta" +#: msgctxt "#32352" msgid "Date Added" msgstr "Data di aggiunta" +#: msgctxt "#32353" msgid "By Release Date" msgstr "Per data di uscita" +#: msgctxt "#32354" msgid "Release Date" msgstr "Data di uscita" +#: msgctxt "#32355" msgid "By Date Viewed" msgstr "Per data di già visto" +#: msgctxt "#32356" msgid "Date Viewed" msgstr "Data di già visto" +#: msgctxt "#32357" msgid "By Name" msgstr "Per nome" +#: msgctxt "#32358" msgid "Name" msgstr "Nome" +#: msgctxt "#32359" msgid "By Rating" msgstr "Per Valutazione" +#: msgctxt "#32360" msgid "Rating" msgstr "Valutazione" +#: msgctxt "#32361" msgid "By Resolution" msgstr "Per Risoluzione" +#: msgctxt "#32362" msgid "Resolution" msgstr "Risoluzione" +#: msgctxt "#32363" msgid "By Duration" msgstr "Per Durata" +#: msgctxt "#32364" msgid "Duration" msgstr "Durata" +#: msgctxt "#32365" msgid "By First Aired" msgstr "Per prima trasmissione" +#: msgctxt "#32366" msgid "First Aired" msgstr "Prima trasmissione" +#: msgctxt "#32367" msgid "By Unplayed" msgstr "Per Non visto" +#: msgctxt "#32368" msgid "Unplayed" msgstr "Non visto" +#: msgctxt "#32369" msgid "By Date Played" msgstr "Per data di riproduzione" +#: msgctxt "#32370" msgid "Date Played" msgstr "Data di riproduzione" +#: msgctxt "#32371" msgid "By Play Count" msgstr "Per numero di volte riprodotto" +#: msgctxt "#32372" msgid "Play Count" msgstr "Numero di volte riprodotto" +#: msgctxt "#32373" msgid "By Date Taken" msgstr "Per data di ripresa" +#: msgctxt "#32374" msgid "Date Taken" msgstr "Data di ripresa" +#: msgctxt "#32375" msgid "No filters available" msgstr "Nussun filtro disponibile" +#: msgctxt "#32376" msgid "Clear Filter" msgstr "Pulisci i filtri" +#: msgctxt "#32377" msgid "Year" msgstr "Anno" +#: msgctxt "#32378" msgid "Decade" msgstr "Decennio" +#: msgctxt "#32379" msgid "Genre" msgstr "Genere" +#: msgctxt "#32380" msgid "Content Rating" msgstr "Classificazione dei contenuti" +#: msgctxt "#32381" msgid "Network" msgstr "Rete" +#: msgctxt "#32382" msgid "Collection" msgstr "Collezione" +#: msgctxt "#32383" msgid "Director" msgstr "Regista" +#: msgctxt "#32384" msgid "Actor" msgstr "Attore" +#: msgctxt "#32385" msgid "Country" msgstr "Nazione" +#: msgctxt "#32386" msgid "Studio" msgstr "Studio" +#: msgctxt "#32387" msgid "Labels" msgstr "Etichette" +#: msgctxt "#32388" msgid "Camera Make" msgstr "Marca camera" +#: msgctxt "#32389" msgid "Camera Model" msgstr "Modello camera" +#: msgctxt "#32390" msgid "Aperture" msgstr "Apertura" +#: msgctxt "#32391" msgid "Shutter Speed" msgstr "Velocità di scatto" +#: msgctxt "#32392" msgid "Lens" msgstr "Lenti" +#: msgctxt "#32393" msgid "TV Shows" msgstr "Serie televisive" +#: msgctxt "#32394" msgid "Music" msgstr "Musica" +#: msgctxt "#32395" msgid "Audio" msgstr "Audio" +#: msgctxt "#32396" msgid "Subtitles" msgstr "Sottotitoli" +#: msgctxt "#32397" msgid "Quality" msgstr "Qualità" +#: msgctxt "#32398" msgid "Kodi Video Settings" msgstr "Impostazioni Video di Kodi" +#: msgctxt "#32399" msgid "Kodi Audio Settings" msgstr "Impostazioni Audio di Kodi" +#: msgctxt "#32400" msgid "Go To Season" msgstr "Vai alla Stagione" +#: msgctxt "#32401" msgid "Directors" msgstr "Registi" +#: msgctxt "#32402" msgid "Writer" msgstr "Autore" +#: msgctxt "#32403" msgid "Writers" msgstr "Autori" +#: msgctxt "#32404" msgid "Related Movies" msgstr "Film correlati" +#: msgctxt "#32405" msgid "Download Subtitles" msgstr "Scarica Sottotitoli" +#: msgctxt "#32406" msgid "Subtitle Delay" msgstr "Ritardo Sottotitolo" +#: msgctxt "#32407" msgid "Next Subtitle" msgstr "Sottotitolo successivo" +#: msgctxt "#32408" msgid "Disable Subtitles" msgstr "Disabilita sottotitoli" +#: msgctxt "#32409" msgid "Enable Subtitles" msgstr "Abilita Sottotitoli" +#: msgctxt "#32410" msgid "Platform Version" msgstr "Versione piattaforma" +#: msgctxt "#32411" msgid "Unknown" msgstr "Sconosciuto" +#: msgctxt "#32412" msgid "Edit Or Clear" msgstr "Modifica o Cancella" +#: msgctxt "#32413" msgid "Edit IP address or clear the current setting?" msgstr "Modificare l'indirizzo IP o cancellare le impostazioni correnti?" +#: msgctxt "#32414" msgid "Clear" msgstr "Cancella" +#: msgctxt "#32415" msgid "Edit" msgstr "Modifica" +#: msgctxt "#32416" msgid "Enter IP Address" msgstr "Inserisci l'indirizzo IP" +#: msgctxt "#32417" msgid "Enter Port Number" msgstr "Inserisci il numero della Porta" +#: msgctxt "#32418" msgid "Creator" msgstr "Creatore" +#: msgctxt "#32419" msgid "Cast" msgstr "Cast" +#: msgctxt "#32420" msgid "Disc" msgstr "Disc" +#: msgctxt "#32421" msgid "Sign Out" msgstr "Esci (Sign Out)" +#: msgctxt "#32422" msgid "Exit" msgstr "Esci" +#: msgctxt "#32423" msgid "Shutdown" msgstr "Spegni" +#: msgctxt "#32424" msgid "Suspend" msgstr "Sospenti" +#: msgctxt "#32425" msgid "Hibernate" msgstr "Iberna" +#: msgctxt "#32426" msgid "Reboot" msgstr "Riavvia" +#: msgctxt "#32427" msgid "Failed" msgstr "Fallito" +#: msgctxt "#32428" msgid "Login failed!" msgstr "Login fallita!" +#: msgctxt "#32429" msgid "Resume from {0}" msgstr "Riprendi da {0}" +#: msgctxt "#32430" msgid "Discovery" msgstr "Ricerca" +#: msgctxt "#32431" msgid "Search" msgstr "Cerca" +#: msgctxt "#32432" msgid "Space" msgstr "Spazio" +#: msgctxt "#32433" msgid "Clear" msgstr "Pulisci" +#: msgctxt "#32434" msgid "Searching..." msgstr "In ricerca..." +#: msgctxt "#32435" msgid "No Results" msgstr "Nessun risultato" +#: msgctxt "#32436" msgid "Paused" msgstr "In Pausa" +#: msgctxt "#32437" msgid "Welcome" msgstr "Benvenuto" +#: msgctxt "#32438" msgid "Previous" msgstr "Precedente" +#: msgctxt "#32439" msgid "Playing Next" msgstr "Titolo successivo" +#: msgctxt "#32440" msgid "On Deck" msgstr "Scoprire" +#: msgctxt "#32441" msgid "Unknown" msgstr "Sconosciuto" +#: msgctxt "#32442" msgid "Embedded" msgstr "Integrato" +#: msgctxt "#32443" msgid "Forced" msgstr "Forzato" +#: msgctxt "#32444" msgid "Lyrics" msgstr "Testi" +#: msgctxt "#32445" msgid "Mono" msgstr "Mono" +#: msgctxt "#32446" msgid "Stereo" msgstr "Stereo" +#: msgctxt "#32447" msgid "None" msgstr "Nessuno" +#: msgctxt "#32448" msgid "Playback Failed!" msgstr "Riproduzione fallita!" +#: msgctxt "#32449" msgid "Can't connect to plex.tv[CR]Check your internet connection and try again." msgstr "Impossibile connettersi a plex.tv[CR]Controlla la tua connessione ad Internet e riprova." +#: msgctxt "#32450" msgid "Choose Version" msgstr "Seleziona Versione" +#: msgctxt "#32451" msgid "Play Version..." msgstr "Versione in Play..." +#: msgctxt "#32452" msgid "No Content available in this library" msgstr "Nessun contenuto disponibile in questa libreria" +#: msgctxt "#32453" msgid "Please add content and/or check that 'Include in dashboard' is enabled." msgstr "Per favore aggiungi contenuti e/o controlla che 'Includi nella dashboard' è abilitato." +#: msgctxt "#32454" msgid "No Content available for this filter" msgstr "Nessun contenuto disponibile per questo filtro" +#: msgctxt "#32455" msgid "Please change change or remove the current filter" msgstr "Per favore cambia o rimuovi il filtro corrente" +#: msgctxt "#32456" msgid "Show" msgstr "Serie" +#: msgctxt "#32457" msgid "By Show" msgstr "Per Serie" +#: msgctxt "#32458" msgid "Episodes" msgstr "Episodi" +#: msgctxt "#32459" msgid "Offline Mode" msgstr "Modo Offline" +#: msgctxt "#32460" msgid "Sign In" msgstr "Accedi (Sign In)" +#: msgctxt "#32461" msgid "Albums" msgstr "Albums" +#: msgctxt "#32462" msgid "Artist" msgstr "Artista" +#: msgctxt "#32463" msgid "By Artist" msgstr "Per Artista" + +#: +msgctxt "#32464" +msgid "Player" +msgstr "Player" + +#: +msgctxt "#32465" +msgid "Use skip step settings from Kodi" +msgstr "Utilizza intervallo salta di Kodi" + +#: +msgctxt "#32466" +msgid "Automatically seek selected position after a delay" +msgstr "Ricerca automaticamente la posizione selezionata dopo un certo ritardo." + +#: +msgctxt "#32467" +msgid "User Interface" +msgstr "Interfaccia Utente" + +#: +msgctxt "#32468" +msgid "Show dynamic background art" +msgstr "Mostra poster dinamici in backgroud" + +#: +msgctxt "#32469" +msgid "Background art blur amount" +msgstr "Trasparenza poster in background" + +#: +msgctxt "#32470" +msgid "Background art opacity" +msgstr "Opacità poster in background" + +#: +msgctxt "#32471" +msgid "Use Plex/Kodi steps for timeline" +msgstr "Usa Plex/Kodi intervalli salta nella timeline" + +#: +msgctxt "#32480" +msgid "Theme music" +msgstr "Tema Musicale" + +#: +msgctxt "#32481" +msgid "Off" +msgstr "Off" + +#: +msgctxt "#32482" +msgid "%(percentage)s %%" +msgstr "%(percentage)s %%" + +#: +msgctxt "#32483" +msgid "Hide Stream Info" +msgstr "Nascondi Steam Info" + +#: +msgctxt "#32484" +msgid "Show Stream Info" +msgstr "Mostra Stream Info" + +#: +msgctxt "#32485" +msgid "Go back instantly with the previous menu action in scrolled views" +msgstr "Torna istantaneamente indietro con l'azione del menu precedente nelle visualizzazioni scorrevoli" + +#: +msgctxt "#32487" +msgid "Seek Delay" +msgstr "Ritardo di ricerca" + +#: +msgctxt "#32488" +msgid "Screensaver" +msgstr "Salvaschermo" + +#: +msgctxt "#32489" +msgid "Quiz Mode" +msgstr "Modalità Quiz" + +#: +msgctxt "#32490" +msgid "Collections" +msgstr "Collezioni" + +#: +msgctxt "#32491" +msgid "Folders" +msgstr "Cartelle" + +#: +msgctxt "#32492" +msgid "Kodi Subtitle Settings" +msgstr "Impostazioni sottotitoli di Kodi" + +#: +msgctxt "#32495" +msgid "Skip intro" +msgstr "Salta Intro" + +#: +msgctxt "#32496" +msgid "Skip credits" +msgstr "Salta Crediti" + +#: +msgctxt "#32500" +msgid "Always show post-play screen (even for short videos)" +msgstr "Mostra sempre la schermata di post-riproduzione (anche per video brevi)" + +#: +msgctxt "#32501" +msgid "Time-to-wait between videos on post-play" +msgstr "Tempo di attesa tra i video in post-riproduzione" + +#: +msgctxt "#32505" +msgid "Visit media in video playlist instead of playing it" +msgstr "Mostra i media nella playlist video anziché riprodurli" + +#: +msgctxt "#32521" +msgid "Skip Intro Button Timeout" +msgstr "Timeout del pulsante Salta Intro" + +#: +msgctxt "#32522" +msgid "Automatically Skip Intro" +msgstr "Salta automaticamente le Intro" + +#: +msgctxt "#32524" +msgid "Set how long the skip intro button shows for." +msgstr "Imposta per quanto tempo il pulsante Salta Intro viene visualizzato." + +#: +msgctxt "#32525" +msgid "Skip Credits Button Timeout" +msgstr "Timeout del pulsante Salta Crediti" + +#: +msgctxt "#32526" +msgid "Automatically Skip Credits" +msgstr "Salta automaticamente i Crediti" + +#: +msgctxt "#32528" +msgid "Set how long the skip credits button shows for." +msgstr "Imposta per quanto tempo il pulsante Salta Crediti viene visualizzato." + +#: +msgctxt "#32540" +msgid "Show when the current video will end in player" +msgstr "Mostra quando il video attuale finirà nel player" + +#: +msgctxt "#32541" +msgid "Shows time left and at which time the media will end." +msgstr "Mostra il tempo rimasto e a che ora il video finirà." + +#: +msgctxt "#32542" +msgid "Show \"Ends at\" label for the end-time as well" +msgstr "Mostra l'etichetta \"Termina alle\" anche per l'orario di fine" + +#: +msgctxt "#32543" +msgid "Ends at" +msgstr "Termina alle" + +#: +msgctxt "#32601" +msgid "Allow AV1" +msgstr "Abilita AV1" + +#: +msgctxt "#32602" +msgid "Enable this if your hardware can handle AV1. Disable it to force transcoding." +msgstr "Attiva questa opzione se il tuo hardware supporta AV1. Disattivala per forzare la transcodifica." + +#: +msgctxt "#33101" +msgid "By Audience Rating" +msgstr "Secondo Valutazione degli Spettatori" + +#: +msgctxt "#33102" +msgid "Audience Rating" +msgstr "Valutazione degli Spettatori" + +#: +msgctxt "#33103" +msgid "By my Rating" +msgstr "Secondo la valutazione personale" + +#: +msgctxt "#33104" +msgid "My Rating" +msgstr "Valutazione Personale" + +#: +msgctxt "#33105" +msgid "By Content Rating" +msgstr "Secondo Classificazione del Contenuto" + +#: +msgctxt "#33106" +msgid "Content Rating" +msgstr "Classificazione del Contenuto" + +#: +msgctxt "#33107" +msgid "By Critic Rating" +msgstr "Secondo la Valutazione della Critica" + +#: +msgctxt "#33108" +msgid "Critic Rating" +msgstr "Valutazione della Critica" + +#: +msgctxt "#33200" +msgid "Background Color" +msgstr "Colore di Sfondo" + +#: +msgctxt "#33201" +msgid "Specify solid Background Color instead of using media images" +msgstr "Scegli un Colore di Sfondo anziché utilizzare immagini multimediali." + +#: +msgctxt "#33400" +msgid "Use old compatibility profile" +msgstr "Utilizza il vecchio profilo di compatibilità." + +#: +msgctxt "#33401" +msgid "Uses the Chrome client profile instead of the custom one. Might fix rare issues with 3D playback." +msgstr "Utilizza il profilo del client Chrome invece di quello personalizzato.\n" +"Potrebbe risolvere i problemi con la riproduzione in 3D." + +#: +msgctxt "#32031" +msgid "Burn-in Subtitles" +msgstr "Sottotitoli Incisi" + +#: +msgctxt "#32061" +msgid "When transcoding audio, target the audio channels set in Kodi." +msgstr "Durante la transcodifica dell'audio, utilizza i canali audio impostati in Kodi." + +#: +msgctxt "#32062" +msgid "Transcode audio to AC3" +msgstr "Trascodifica audio in AC3" + +#: +msgctxt "#32063" +msgid "Transcode audio to AC3 in certain conditions (useful for passthrough)." +msgstr "Trascodifica l'audio in AC3 in determinate condizioni (utile per il passaggio diretto)." + +#: +msgctxt "#32065" +msgid "When any of the force AC3 settings are enabled, treat DTS the same as AC3 (useful for Optical passthrough)" +msgstr "Quando uno qualsiasi dei settaggi di forzatura AC3 è attivato, trattare il DTS allo stesso modo dell'AC3 (utile per il passthrough ottico)" + +#: +msgctxt "#32066" +msgid "Force audio to AC3" +msgstr "Forza l'audio in AC3" + +#: +msgctxt "#32067" +msgid "Only force multichannel audio to AC3" +msgstr "Permetti solo all'audio multicanale di essere forzato in AC3." + +#: +msgctxt "#32493" +msgid "When a media file has a forced/foreign subtitle for a subtitle-enabled language, the Plex Media Server preselects it. This behaviour is usually not necessary and not configurable. This setting fixes that by ignoring the PMSs decision and selecting the same language without a forced flag if possible." +msgstr "Quando un file multimediale ha un sottotitolo forzato/esterno per una lingua abilitata ai sottotitoli, il server multimediale Plex lo preseleziona. Questo comportamento di solito non è necessario e non è configurabile. Questa impostazione risolve il problema ignorando la decisione del server multimediale Plex e selezionando la stessa lingua senza il flag forzato, se possibile." + +#: +msgctxt "#32523" +msgid "Automatically skip intros if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Salta automaticamente le intro se disponibili. Non annulla la modalità maratona abilitata. Può essere disattivato/attivato per ogni serie TV." + +#: +msgctxt "#32527" +msgid "Automatically skip credits if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Salta automaticamente i crediti se disponibili. Non annulla la modalità maratona abilitata.\n" +"Può essere disattivato/attivato per ogni serie TV." + +#: +msgctxt "#33501" +msgid "Video played threshold" +msgstr "Soglia di riproduzione dei video" + +#: +msgctxt "#33502" +msgid "Set this to the same value as your Plex server (Settings>Library>Video played threshold) to avoid certain pitfalls, Default: 90 %" +msgstr "Imposta questo valore allo stesso valore del tuo server Plex (Impostazioni>Libreria>Soglia di riproduzione dei video) per evitare certi problemi, Predefinito: 90%" + +#: +msgctxt "#33503" +msgid "Use alternative hubs refresh" +msgstr "Utilizza l'aggiornamento degli hub alternativo" + +#: +msgctxt "#33504" +msgid "Refreshes all hubs for all libraries after an item's watch-state has changed, instead of only those likely affected. Use this if you find a hub that doesn't update properly." +msgstr "Aggiorna tutti gli hub per tutte le librerie dopo che lo stato di visione di un elemento è cambiato, invece di solo quelli interessati. Usa questa opzione se trovi un hub che non si aggiorna correttamente." + +#: +msgctxt "#33505" +msgid "Show intro skip button early" +msgstr "Mostra il pulsante di salto intro in anticipo" + +#: +msgctxt "#33506" +msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "Mostra il pulsante di salto intro dall'inizio di un video con un indicatore di intro. L'impostazione di auto-salto si applica. Non annulla la modalità maratona abilitata. \n" +"Può essere disattivato/attivato per ogni serie TV." + +#: +msgctxt "#33507" +msgid "Enabled" +msgstr "Attivato" + +#: +msgctxt "#33508" +msgid "Disabled" +msgstr "Disattivato" + +#: +msgctxt "#33509" +msgid "Early intro skip threshold (default: < 60s/1m)" +msgstr "Soglia di salto anticipato delle Intro (predefinito: < 60s/1m)" + +#: +msgctxt "#33510" +msgid "When showing the intro skip button early, only do so if the intro occurs within the first X seconds." +msgstr "Quando si mostra il pulsante di salto intro anticipato, fallo solo se l'introduzione avviene entro i primi X secondi." + +#: +msgctxt "#33600" +msgid "System" +msgstr "Sistema" + +#: +msgctxt "#33601" +msgid "Show video chapters" +msgstr "Mostra capitoli video" + +#: +msgctxt "#33602" +msgid "If available, show video chapters from the video-file instead of the timeline-big-seek-steps." +msgstr "Se disponibili, mostra i capitoli video dal file video invece degli intervalli della timeline." + +#: +msgctxt "#33603" +msgid "Use virtual chapters" +msgstr "Usa capitoli virtuali" + +#: +msgctxt "#33604" +msgid "When the above is enabled and no video chapters are available, simulate them by using the markers identified by the Plex Server (Intro, Credits)." +msgstr "Quando quanto sopra è abilitato e non ci sono capitoli video disponibili, simulali utilizzando i marker identificati dal server Plex (Introduzione, Crediti)." + +#: +msgctxt "#33605" +msgid "Video Chapters" +msgstr "Capitoli Video" + +#: +msgctxt "#33606" +msgid "Virtual Chapters" +msgstr "Capitoli Virtuali" + +#: +msgctxt "#33607" +msgid "Chapter {}" +msgstr "Capitolo {}" + +#: +msgctxt "#33608" +msgid "Intro" +msgstr "Intro" + +#: +msgctxt "#33609" +msgid "Credits" +msgstr "Crediti" + +#: +msgctxt "#33610" +msgid "Main" +msgstr "Principale" + +#: +msgctxt "#33611" +msgid "Chapters" +msgstr "Capitoli" + +#: +msgctxt "#33612" +msgid "Markers" +msgstr "Indicatori" + +#: +msgctxt "#33613" +msgid "Kodi Buffer Size (MB)" +msgstr "Dimensione del buffer di Kodi (MB)" + +#: +msgctxt "#33614" +msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~50 MB, Recommended max: {} MB, Default: 20 MB." +msgstr "Imposta la dimensione della cache/buffer di Kodi. Libero: {} MB, Consigliato: ~50 MB, Massimo consigliato: {} MB, Predefinito: 20 MB." + +#: +msgctxt "#33615" +msgid "{time} left" +msgstr "{time} rimanenti" + +#: +msgctxt "#33616" +msgid "Addon Path" +msgstr "Addon Path" + +#: +msgctxt "#33617" +msgid "Userdata/Profile Path" +msgstr "Userdata/Profile Path" + +#: +msgctxt "#33618" +msgid "TV binge-viewing mode" +msgstr "Modalità maratona TV" + +#: +msgctxt "#33619" +msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn't skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n" +"\n" +"Can be disabled/enabled per TV show.\n" +"Overrides any setting below." +msgstr "Modalità maratona TV: Salta automaticamente le intro degli episodi, i crediti e cerca di saltare i riassunti degli episodi. Non salta l'introduzione del primo episodio di una stagione e non salta i crediti finali di uno spettacolo. \n" +"\n" +"\n" +"Può essere disattivata/attivata per singoli spettacoli TV. Sovrascrive qualsiasi impostazione seguente." + +#: +msgctxt "#33620" +msgid "Plex requests timeout (seconds)" +msgstr "Timeout delle richieste Plex (secondi)" + +#: +msgctxt "#33621" +msgid "Set the (async and connection) timeout value of the Python requests library in seconds. Default: 5" +msgstr "Imposta il valore di timeout (asincrono e di connessione) della libreria delle richieste Python in secondi. Predefinito: 5" + +#: +msgctxt "#33622" +msgid "LAN reachability timeout (ms)" +msgstr "Timeout di raggiungibilità LAN (ms)" + +#: +msgctxt "#33623" +msgid "When checking for LAN reachability, use this timeout. Default: 10ms" +msgstr "Durante il controllo della raggiungibilità LAN, utilizza questo timeout. Predefinito: 10ms" + +#: +msgctxt "#33624" +msgid "Network" +msgstr "Rete" + +#: +msgctxt "#33625" +msgid "Smart LAN/local server discovery" +msgstr "Smart LAN/Locale server discovery" + +#: +msgctxt "#33626" +msgid "Checks whether servers returned from Plex.tv are actually local/in your LAN. For specific setups (e.g. Docker) Plex.tv might not properly detect a local server.\n" +"\n" +"NOTE: Only works on Kodi 19 or above." +msgstr "Verifica se i server restituiti da Plex.tv sono effettivamente locali/nella LAN. Per configurazioni specifiche (es. Docker), Plex.tv potrebbe non rilevare correttamente un server locale.\n" +"\n" +"NOTA: Funziona solo su Kodi 19 o versioni successive." + +#: +msgctxt "#33627" +msgid "Prefer LAN/local servers over security" +msgstr "Preferire server LAN/locali rispetto alla sicurezza." + +#: +msgctxt "#33628" +msgid "Prioritizes local connections over secure ones. Needs the proper setting in \"Allow Insecure Connections\" and the Plex Server's \"Secure connections\" at \"Preferred\". Can be used to enforce manual servers." +msgstr "Prioritizza le connessioni locali rispetto a quelle sicure. Richiede l'impostazione corretta di \"Consenti connessioni non sicure\" e le impostazioni del server Plex su \"Connessioni sicure\" impostate su \"Preferite\". Può essere utilizzato per imporre server manuali." + +#: +msgctxt "#33629" +msgid "Auto-skip intro/credits offset" +msgstr "Offset di auto-salto intro/crediti" + +#: +msgctxt "#33630" +msgid "Intro/credits markers might be a little early in Plex. When auto skipping add (or subtract) this many seconds from the marker. This avoids cutting off content, while possibly skipping the marker a little late." +msgstr "I marker dell'intro/crediti potrebbero essere un po' anticipati in Plex. Quando si salta automaticamente, aggiungi (o sottrai) questo numero di secondi dal marker. Questo evita di interrompere il contenuto, anche se potrebbe causare lo skipping del marker un po' in ritardo." + +#: +msgctxt "#32631" +msgid "Playback (user-specific)" +msgstr "Riproduzione (specifica dell'utente)" + +#: +msgctxt "#33632" +msgid "Server connectivity check timeout (seconds)" +msgstr "Timeout del controllo di connettività del server (secondi)" + +#: +msgctxt "#33633" +msgid "Set the maximum amount of time a server connection has to answer a connectivity request. Default: 2.5" +msgstr "Imposta il tempo massimo entro il quale una connessione al server deve rispondere a una richiesta di connettività. Predefinito: 2.5" + +#: +msgctxt "#33634" +msgid "Combined Chapters" +msgstr "Combina Capitoli" + +#: +msgctxt "#33635" +msgid "Final Credits" +msgstr "Crediti Finiali" + +#: +msgctxt "#32700" +msgid "Action on Sleep event" +msgstr "Azione in caso di evento di sospensione" + +#: +msgctxt "#32701" +msgid "When Kodi receives a sleep event from the system, run the following action." +msgstr "Quando Kodi riceve un evento di sospensione dal sistema, esegui l'azione seguente." + +#: +msgctxt "#32702" +msgid "Nothing" +msgstr "Niente" + +#: +msgctxt "#32703" +msgid "Stop playback" +msgstr "Interrompi la riproduzione." + +#: +msgctxt "#32704" +msgid "Quit Kodi" +msgstr "Esci da Kodi" + +#: +msgctxt "#32705" +msgid "CEC Standby" +msgstr "CEC Standby" + +#: +msgctxt "#32800" +msgid "Skipping intro" +msgstr "Salto dell'Intro" + +#: +msgctxt "#32801" +msgid "Skipping credits" +msgstr "Salto dei Crediti" + +#: +msgctxt "#32900" +msgid "While playing back an item and seeking on the seekbar, automatically seek to the selected position after a delay instead of having to confirm the selection." +msgstr "Durante la riproduzione di un elemento e navigando nella timeline, esegui automaticamente la ricerca nella posizione selezionata dopo un ritardo anziché dover confermare la selezione." + +#: +msgctxt "#32901" +msgid "Seek delay in seconds." +msgstr "Ritardo Intervallo Salta" + +#: +msgctxt "#32902" +msgid "Kodi has its own skip step settings. Try to use them if they're configured instead of the default ones." +msgstr "Kodi ha le sue impostazioni di intervalli salta. Prova a utilizzarle se sono configurate invece di quelle predefinite." + +#: +msgctxt "#32903" +msgid "Use the above for seeking on the timeline as well." +msgstr "Utilizza quanto sopra anche per cercare nella timeline." + +#: +msgctxt "#32904" +msgid "In seconds." +msgstr "In secondi." + +#: +msgctxt "#32905" +msgid "Cancel post-play timer by pressing OK/SELECT" +msgstr "Annulla il timer di post-riproduzione premendo OK/SELEZIONA" + +#: +msgctxt "#32906" +msgid "Cancel skip marker timer with BACK" +msgstr "Annulla il timer del marker di salto premendo INDIETRO." + +#: +msgctxt "#32907" +msgid "When auto-skipping a marker, allow cancelling the timer by pressing BACK." +msgstr "Quando si salta automaticamente un marker, consenti di annullare il timer premendo INDIETRO." + +#: +msgctxt "#32908" +msgid "Immediately skip marker with OK/SELECT" +msgstr "Salta immediatamente il marker premendo OK/SELEZIONA" + +#: +msgctxt "#32909" +msgid "When auto-skipping a marker with a timer, allow skipping immediately by pressing OK/SELECT." +msgstr "Quando si salta automaticamente un marker con un timer, consenti di saltare immediatamente premendo OK/SELEZIONA" + +#: +msgctxt "#32912" +msgid "Show buffer-state on timeline" +msgstr "Mostra lo stato del buffer nella timeline" + +#: +msgctxt "#32913" +msgid "Shows the current Kodi buffer/cache state on the video player timeline." +msgstr "Mostra lo stato corrente del buffer/cache di Kodi nella timeline del Player." + +#: +msgctxt "#32914" +msgid "Loading" +msgstr "Caricamento" + +#: +msgctxt "#32915" +msgid "Slow connection" +msgstr "Connessione lenta" + +#: +msgctxt "#32916" +msgid "Use with a wonky/slow connection, e.g. in a hotel room. Adjusts the UI to visually wait for item refreshes and waits for the buffer to fill when starting playback. Automatically sets readfactor=20, requires Kodi restart." +msgstr "Utilizzare con una connessione instabile/lenta, es. in una stanza d'albergo. Regola l'interfaccia utente per attendere visivamente il refresh degli elementi e attende che il buffer si riempia all'avvio della riproduzione. Imposta automaticamente readfactor=20, richiede il riavvio di Kodi." + +#: +msgctxt "#32917" +msgid "Couldn't fill buffer in time ({}s)" +msgstr "Impossibile riempire il buffer in tempo ({}s)" + +#: +msgctxt "#32918" +msgid "Buffer wait timeout (seconds)" +msgstr "Timeout di attesa del buffer (secondi)" + +#: +msgctxt "#32919" +msgid "When slow connection is enabled in the addon, wait this long for the buffer to fill. Default: 120 s" +msgstr "Quando la connessione lenta è abilitata nell'addon, attendi questo tempo per riempire il buffer. Predefinito: 120 s" + +#: +msgctxt "#32920" +msgid "Insufficient buffer wait (seconds)" +msgstr "Attesa del buffer insufficiente (secondi)" + +#: +msgctxt "#32921" +msgid "When slow connection is enabled in the addon and the configured buffer isn't big enough for us to determine its fill state, wait this long when starting playback. Default: 10 s" +msgstr "Quando la connessione lenta è abilitata nell'addon e il buffer configurato non è abbastanza grande per determinare il suo stato di riempimento, attendi questo tempo all'avvio della riproduzione. Predefinito: 10 s" + +#: +msgctxt "#32922" +msgid "Kodi Cache Readfactor" +msgstr "Kodi Cache Readfactor" + +#: +msgctxt "#32923" +msgid "Sets the Kodi cache readfactor value. Default: {0}, recommended: {1}. With \"Slow connection\" enabled this will be set to {2}, as otherwise the cache doesn't fill fast/aggressively enough." +msgstr "Imposta il valore di readfactor della cache di Kodi. Predefinito: {0}, consigliato: {1}. Con 'Connessione lenta' abilitata, questo verrà impostato su {2}, altrimenti la cache non si riempie abbastanza rapidamente/aggressivamente." + +#: +msgctxt "#32924" +msgid "Minimize" +msgstr "Minimizza" + +#: +msgctxt "#32925" +msgid "Playback Settings" +msgstr "Impostazioni di Riproduzione" + +#: +msgctxt "#32926" +msgid "Wrong pin entered!" +msgstr "Pin inserito errato!" + +#: +msgctxt "#32927" +msgid "Use episode thumbnails in continue hub" +msgstr "Utilizza le miniature degli episodi nel riquadro di continua a guardare" + +#: +msgctxt "#32928" +msgid "Instead of using media artwork, use thumbnails for episodes in the continue hub on the home screen if available." +msgstr "Se disponibili, utilizza le miniature degli episodi invece del poster nel riquadro di continua a guardare sulla schermata principale." + +#: +msgctxt "#32929" +msgid "Use legacy background fallback image" +msgstr "Utilizza l'immagine di fallback dello sfondo legacy" + +#: +msgctxt "#32930" +msgid "Previous Subtitle" +msgstr "Sottotitolo Precedente" + +#: +msgctxt "#32931" +msgid "Audio/Subtitles" +msgstr "Audio/Sottotitoli" + +#: +msgctxt "#32932" +msgid "Show subtitle quick-actions button" +msgstr "Mostra il pulsante delle azioni rapide dei sottotitoli" + +#: +msgctxt "#32933" +msgid "Show FFWD/RWD buttons" +msgstr "Mostra i pulsanti FFWD/RWD" + +#: +msgctxt "#32934" +msgid "Show repeat button" +msgstr "Mostra il pulsante Ripeti" + +#: +msgctxt "#32935" +msgid "Show shuffle button" +msgstr "Mostra il pulsante Casuale" + +#: +msgctxt "#32936" +msgid "Show playlist button" +msgstr "Mostra il pulsante Playlist" + +#: +msgctxt "#32937" +msgid "Show prev/next button" +msgstr "Mostra il pulsante prev/next" + +#: +msgctxt "#32939" +msgid "Only applies to video player UI" +msgstr "Si applica solo all'interfaccia del Player" + +#: +msgctxt "#32940" +msgid "Player UI" +msgstr "Interfaccia del Player" + +#: +msgctxt "#32941" +msgid "Forced subtitles fix" +msgstr "Fix sottotitoli forzati" + +#: +msgctxt "#32942" +msgid "Other seasons" +msgstr "Altre stagioni" + +#: +msgctxt "#32943" +msgid "Crossfade dynamic background art" +msgstr "Dissolvenza incrociata poster di sfondo" + +#: +msgctxt "#32944" +msgid "Burn-in SSA subtitles (DirectStream)" +msgstr "Sottotitoli SSA incisi (DirectStream)" + +#: +msgctxt "#32945" +msgid "When Direct Streaming instruct the Plex Server to burn in SSA/ASS subtitles (thus transcoding the video stream). If disabled it will not touch the video stream, but will convert the subtitle to unstyled text." +msgstr "Quando si esegue lo Streaming Diretto, istruisci il Server Plex a imprimere i sottotitoli SSA/ASS (trascodificando quindi lo stream video). Se disabilitato, non modificherà lo stream video, ma convertirà i sottotitoli in testo senza stile." + +#: +msgctxt "#32946" +msgid "Stop video playback on idle after" +msgstr "Interrompi la riproduzione video inattiva dopo" + +#: +msgctxt "#32947" +msgid "Stop video playback on screensaver" +msgstr "Interrompi la riproduzione video durante lo screensaver" + +#: +msgctxt "#32948" +msgid "Allow auto-skip when transcoding" +msgstr "Consenti auto-salto durante la trascodifica" + +#: +msgctxt "#32949" +msgid "When transcoding/DirectStreaming, allow auto-skip functionality." +msgstr "Durante la trascodifica/DirectStreaming, consenti la funzionalità di auto-salto." + +#: +msgctxt "#32950" +msgid "Use extended title for subtitles" +msgstr "Utilizza il titolo esteso per i sottotitoli" + +#: +msgctxt "#32951" +msgid "When displaying subtitles use the extendedDisplayTitle Plex exposes." +msgstr "Quando si visualizzano i sottotitoli, utilizza l'extendedDisplayTitle fornito da Plex." + +#: +msgctxt "#32953" +msgid "Reviews" +msgstr "Recensioni" + +#: +msgctxt "#32954" +msgid "Needs Kodi restart. WARNING: This will overwrite advancedsettings.xml!\n" +"\n" +"To customize other cache/network-related values, copy \"script.plexmod/pm4k_cache_template.xml\" to profile folder and edit it to your liking. (See About section for the file paths)" +msgstr "Necessita riavvio di Kodi. ATTENZIONE: Questo sovrascriverà il file advancedsettings.xml!\n" +"\n" +"Per personalizzare altri valori relativi alla cache/rete, copia \"script.plexmod/pm4k_cache_template.xml\" nella cartella del profilo e modificalo secondo le tue preferenze. (Consulta la sezione Informazioni per i percorsi dei file)" + +#: +msgctxt "#32955" +msgid "Use Kodi keyboard for searching" +msgstr "Utilizza la tastiera di Kodi per la ricerca" + +#: +msgctxt "#32956" +msgid "Poster resolution scaling %" +msgstr "Ridimensionamento della risoluzione dei poster %" + +#: +msgctxt "#32957" +msgid "In percent. Scales the resolution of all posters/thumbnails for better image quality. May impact PMS/PM4K performance, will increase the cache usage accordingly. Recommended: 200-300 % for for big screens if your hardware can handle it. Needs addon restart." +msgstr "In percentuale. Ridimensiona la risoluzione di tutti i poster/miniature per una migliore qualità dell'immagine. Potrebbe influire sulle prestazioni di PMS/PM4K, aumenterà di conseguenza l'utilizzo della cache. Consigliato: 200-300 % per schermi grandi se l'hardware lo supporta. Necessita riavvio dell'addon." + +#: +msgctxt "#32958" +msgid "Calculate OpenSubtitles.com hash" +msgstr "Calcola l'hash di OpenSubtitles.com" + +#: +msgctxt "#32959" +msgid "When opening the subtitle download feature, automatically calculate the OpenSubtitles.com hash for the given file. Can improve search results, downloads 2*64 KB of the video file to calculate the hash." +msgstr "Quando si apre la funzione di download dei sottotitoli, calcola automaticamente l'hash di OpenSubtitles.com per il file fornito. Può migliorare i risultati della ricerca, scarica 2*64 KB del file video per calcolare l'hash." + +#: +msgctxt "#32960" +msgid "Similar Artists" +msgstr "Artisti Simili" + +#: +msgctxt "#32961" +msgid "Show hub bifurcation lines" +msgstr "Mostra linee di biforcazione dell'hub" + +#: +msgctxt "#32962" +msgid "Visually separate hubs horizontally using a thin line." +msgstr "Separa visualmente gli hub orizzontalmente utilizzando una linea sottile." + +#: +msgctxt "#32963" +msgid "Wait between videos (s)" +msgstr "Attesa tra i video" + +#: +msgctxt "#32964" +msgid "When playing back consecutive videos (e.g. TV shows), wait this long before starting the next one in the queue. Might fix compatibility issues with certain configurations." +msgstr "Quando riproduci video consecutivi (es. serie TV), attendi questo tempo prima di avviare il successivo nella coda. Potrebbe risolvere problemi di compatibilità con determinate configurazioni." + +#: +msgctxt "#32965" +msgid "Quit Kodi on exit by default" +msgstr "Esci da Kodi all'uscita per impostazione predefinita" + +#: +msgctxt "#32966" +msgid "When exiting the addon, use \"Quit Kodi\" as default option. Can be dynamically switched using CONTEXT_MENU (often longpress SELECT)" +msgstr "All'uscita dall'addon, utilizza \"Esci da Kodi\" come opzione predefinita. Può essere cambiato dinamicamente utilizzando CONTEXT_MENU (spesso premendo a lungo SELECT)" + +#: +msgctxt "#32967" +msgid "Kodi Colour Management" +msgstr "Gestione del Colore di Kodi" + +#: +msgctxt "#32968" +msgid "Kodi Resolution Settings" +msgstr "Impostazioni di Risoluzione di Kodi" + +#: +msgctxt "#32969" +msgid "Always request all library media items at once" +msgstr "Richiedi sempre tutti gli elementi multimediali della libreria in una volta sola" + +#: +msgctxt "#32970" +msgid "Retrieve all media in library up front instead of fetching it in chunks as the user navigates through the library" +msgstr "Recupera tutti i media nella libreria anticipatamente invece di recuperarli man mano che l'utente naviga attraverso la libreria" + +#: +msgctxt "#32971" +msgid "Library item-request chunk size" +msgstr "Dimensione del blocco di richiesta degli elementi della libreria" + +#: +msgctxt "#32972" +msgid "Request this amount of media items per chunk request in library view (+6-30 depending on view mode; less can be less straining for the UI at first, but puts more strain on the server)" +msgstr "Richiedi questa quantità di elementi multimediali per ciascuna richiesta a blocchi nella visualizzazione della libreria (+6-30 a seconda della modalità di visualizzazione; meno può essere meno carico per l'interfaccia utente all'inizio, ma mette più carico sul server)" + +#: +msgctxt "#32973" +msgid "Episodes: Skip Post Play screen" +msgstr "Episodi: Salta la schermata di post-riproduzione" + +#: +msgctxt "#32974" +msgid "When finishing an episode, don't show Post Play but go to the next one immediately.\n" +"Can be disabled/enabled per TV show. Doesn't override enabled binge mode. Overrides the Post Play setting." +msgstr "Quando si termina un episodio, non mostrare la schermata di post-riproduzione ma passa immediatamente al successivo.\n" +"Può essere disattivato/attivato per ogni serie TV. Non annulla la modalità maratona abilitata. Sovrascrive l'impostazione di Post Play." + +#: +msgctxt "#32975" +msgid "Delete Season" +msgstr "Elimina Stagione" + +#: +msgctxt "#32976" +msgid "Adaptive" +msgstr "Adattivo" + +#: +msgctxt "#32977" +msgid "Allow VC1" +msgstr "Abilita VC1" + +#: +msgctxt "#32978" +msgid "Enable this if your hardware can handle VC1. Disable it to force transcoding." +msgstr "Attiva questa opzione se l'hardware supporta VC1. Disattivala per forzare la trascodifica." + +#: +msgctxt "#32979" +msgid "Allows the server to only transcode streams of a video that need transcoding, while streaming the others unaltered. If disabled, force the server to transcode everything not direct playable." +msgstr "Consente al server di transcodificare solo i flussi video che necessitano della transcodifica, mentre trasmette gli altri inalterati. Se disabilitato, forza il server a trascodificare tutto ciò che non è riproducibile direttamente." + +#: +msgctxt "#32980" +msgid "Refresh Users" +msgstr "Aggiorna Utenti" + +#: +msgctxt "#32981" +msgid "Background worker count" +msgstr "Numero di Background worker" + +#: +msgctxt "#32982" +msgid "Depending on how many cores your CPU has and how much it can handle, increasing this might improve certain situations. If you experience crashes or other annormalities, leave this at its default (3). Needs an addon restart." +msgstr "A seconda di quanti core ha la tua CPU e di quanto può gestire, aumentare questo valore potrebbe migliorare certe situazioni. Se riscontri crash o altre anomalie, lascia questo valore a default(3). Richiede un riavvio dell'addon." + +#: +msgctxt "#32983" +msgid "Player Theme" +msgstr "Tema del Player" + +#: +msgctxt "#32984" +msgid "Sets the player theme. Currently only customizes the playback control buttons. ATTENTION: [I]Might[/I] need an addon restart.\n" +"In order to customize this, copy one of the xml's in script.plexmod/resources/skins/Main/1080i/templates to addon_data/script.plexmod/templates/seek_dialog_buttons_custom.xml and adjust it to your liking, then select \"Custom\" as your theme." +msgstr "Imposta il tema del lettore. Attualmente personalizza solo i pulsanti di controllo della riproduzione. ATTENZIONE: [I]Potrebbe[/I] essere necessario riavviare l'addon. \n" +"Per personalizzarlo, copia uno degli xml in script.plexmod/resources/skins/Main/1080i/templates in addon_data/script.plexmod/templates/seek_dialog_buttons_custom.xml e modificalo secondo le tue preferenze, quindi seleziona \"Personalizzato\" come tema." + +#: +msgctxt "#32985" +msgid "Modern" +msgstr "Moderno" + +#: +msgctxt "#32986" +msgid "Modern (dotted)" +msgstr "Moderno (a puntini)" + +#: +msgctxt "#32987" +msgid "Classic" +msgstr "Classico" + +#: +msgctxt "#32988" +msgid "Custom" +msgstr "Custom" + +#: +msgctxt "#32989" +msgid "Modern (colored)" +msgstr "Moderno (colorato)" + +#: +msgctxt "#32990" +msgid "Handle plex.direct mapping" +msgstr "Gestisci la mappatura plex.direct" + +#: +msgctxt "#32991" +msgid "Notify" +msgstr "Notifiche" + +#: +msgctxt "#32992" +msgid "When using servers with a plex.direct connection (most of them), should we automatically adjust advancedsettings.xml to cope with plex.direct domains? If not, you might want to add plex.direct to your router's DNS rebind exemption list." +msgstr "Quando si utilizzano server con una connessione plex.direct (la maggior parte di essi), dovremmo regolare automaticamente il file advancedsettings.xml per gestire i domini plex.direct? Se non lo facciamo, potresti dover aggiungere plex.direct all'elenco di eccezioni del reindirizzamento DNS del router." + +#: +msgctxt "#32993" +msgid "{} unhandled plex.direct connections found" +msgstr "{} connessioni plex.direct non gestite trovate" + +#: +msgctxt "#32994" +msgid "In order for PM4K to work properly, we need to add special handling for plex.direct connections. We've found {} new unhandled connections. Do you want us to write those to Kodi's advancedsettings.xml automatically? If not, you might want to add plex.direct to your router's DNS rebind exemption list. This can be changed in the settings as well." +msgstr "Perché PM4K funzioni correttamente, è necessario aggiungere un trattamento speciale per le connessioni plex.direct. Abbiamo trovato {} nuove connessioni non gestite. Vuoi che le scriviamo automaticamente nel file advancedsettings.xml di Kodi? In alternativa, dovresti aggiungere plex.direct all'elenco di eccezioni del reindirizzamento DNS del router. Questo può essere cambiato anche nelle impostazioni." + +#: +msgctxt "#32995" +msgid "Advancedsettings.xml modified (plex.direct mappings)" +msgstr "Modificato il file advancedsettings.xml (mappature plex.direct)" + +#: +msgctxt "#32996" +msgid "The advancedsettings.xml file has been modified. Please restart Kodi for the changes to apply." +msgstr "Il file advancedsettings.xml è stato modificato. Si prega di riavviare Kodi affinché le modifiche abbiano effetto." + +#: +msgctxt "#32997" +msgid "OK" +msgstr "OK" + +#: +msgctxt "#32998" +msgid "Use new Continue Watching hub on Home" +msgstr "Usa il nuovo hub Continua a Guardare nella Schermata Principale" + +#: +msgctxt "#32999" +msgid "Instead of separating Continue Watching and On Deck hubs, behave like the modern Plex clients, which combine those two types of hubs into one Continue Watching hub." +msgstr "Piuttosto che separare i riquadri 'Continua a guardare' e 'In evidenza', comportati come i client Plex moderni, che combinano questi due tipi di riquadri in un unico riquadro 'Continua a guardare'." + +#: +msgctxt "#33000" +msgid "Enable path mapping" +msgstr "Abilita path mapping" + +#: +msgctxt "#33001" +msgid "Honor path_mapping.json in the addon_data/script.plexmod folder when DirectPlaying media. This can be used to stream using other techniques such as SMB/NFS/etc. instead of the default HTTP handler. path_mapping.example.json is included in the addon's main directory." +msgstr "Rispetta path_mapping.json nella cartella addon_data/script.plexmod quando riproduci direttamente i media. Questo può essere utilizzato per lo streaming utilizzando altre tecniche come SMB/NFS/ecc. invece dell'handler HTTP predefinito. È incluso un'esempio di path_mapping.json nella cartella principale dell'addon come path_mapping.example.json." + +#: +msgctxt "#33002" +msgid "Verify mapped files exist" +msgstr "Verifica che i file mappati esistano" + +#: +msgctxt "#33003" +msgid "When path mapping is enabled and we've successfully mapped a file, verify its existence." +msgstr "Quando il path mapping è abilitato e è stato mappato con successo un file, verifica la sua esistenza." + +#: +msgctxt "#33004" +msgid "No spoilers without OSD" +msgstr "Nessun spoiler senza OSD" + +#: +msgctxt "#33005" +msgid "When seeking without the OSD open, hide all time-related information from the user." +msgstr "Quando si cerca senza OSD aperto, nascondi tutte le informazioni relative al tempo dall'utente." + +#: +msgctxt "#33006" +msgid "No TV spoilers" +msgstr "No TV spoilers" + +#: +msgctxt "#33007" +msgid "When visiting an episode/season view, blur unwatched/unwatched+in-progress episode thumbnails, previews and redact summaries. When the Addon Setting \"Use episode thumbnails in continue hub\" is enabled, blur them as well." +msgstr "Quando si accede alla vista episodio/stagione, sfoca le miniature degli episodi non visti/o + in corso, anteprime e redige i riepiloghi. Quando l'impostazione dell'Addon \"Usa le miniature degli episodi nel riquadro continua a guardare\" è abilitata, sfoca anche loro." + +#: +msgctxt "#33008" +msgid "[Spoilers removed]" +msgstr "[Spoileri rimossi]" + +#: +msgctxt "#33009" +msgid "Blur amount for unwatched/in-progress episodes" +msgstr "Livello di sfocatura per gli episodi non visti/in corso" + +#: +msgctxt "#33010" +msgid "Unwatched" +msgstr "Non visti" + +#: +msgctxt "#33011" +msgid "Unwatched/in progress" +msgstr "Non visti/in corso" + +#: +msgctxt "#33012" +msgid "No unwatched episode titles" +msgstr "Nessun titolo di episodi non visti" + +#: +msgctxt "#33013" +msgid "When the above is anything but \"off\", hide episode titles as well." +msgstr "Quando quanto sopra non è impostato su \"Off\", nascondi anche i titoli degli episodi." + +#: +msgctxt "#33014" +msgid "Ignore plex.direct docker hosts" +msgstr "Ignora gli host docker di plex.direct" + +#: +msgctxt "#33015" +msgid "When checking for plex.direct host mapping, ignore local Docker IPv4 addresses (172.16.0.0/12)." +msgstr "Nel controllo della mappatura dell'host plex.direct, ignorare gli indirizzi IPv4 locali di Docker (172.16.0.0/12)." + +#: +msgctxt "#33016" +msgid "Allow TV spoilers for specific genres" +msgstr "Consenti spoiler TV per generi specifici" + +#: +msgctxt "#33017" +msgid "Overrides the above for: {}" +msgstr "Sovrascrive quanto sopra per: {}" + +#: +msgctxt "#32303" +msgid "Season {}" +msgstr "Stagione {}" + +#: +msgctxt "#32304" +msgid "Episode {}" +msgstr "Episodio {}" + +#: +msgctxt "#32310" +msgid "S{}" +msgstr "S{}" + +#: +msgctxt "#32311" +msgid "E{}" +msgstr "E{}" + +#: +msgctxt "#32938" +msgid "Only for Episodes/Playlists" +msgstr "" + +#: +msgctxt "#33018" +msgid "Cache Plex Home users" +msgstr "" + +#: +msgctxt "#33019" +msgid "Visit media item" +msgstr "" + +#: +msgctxt "#33020" +msgid "Play" +msgstr "" + +#: +msgctxt "#33021" +msgid "Choose action" +msgstr "" + +#: +msgctxt "#33022" +msgid "Use modern inverted watched states" +msgstr "" + +#: +msgctxt "#33023" +msgid "Instead of marking unwatched items, mark watched items with a checkmark (modern clients; default: off)" +msgstr "" + +#: +msgctxt "#33024" +msgid "Hide black backdrop in inverted watched states" +msgstr "" + +#: +msgctxt "#33025" +msgid "When the above is enabled, hide the black backdrop of the watched state." +msgstr "" + +#: +msgctxt "#33026" +msgid "Map path: {}" +msgstr "" + +#: +msgctxt "#33027" +msgid "Remove mapping: {}" +msgstr "" + +#: +msgctxt "#33028" +msgid "Hide library" +msgstr "" + +#: +msgctxt "#33029" +msgid "Show library: {}" +msgstr "" + +#: +msgctxt "#33030" +msgid "Choose action for: {}" +msgstr "" + +#: +msgctxt "#33031" +msgid "Select Kodi source for {}" +msgstr "" + +#: +msgctxt "#33032" +msgid "Show path mapping indicators" +msgstr "" + +#: +msgctxt "#33033" +msgid "When path mapping is active for a library, display an indicator." +msgstr "" + +#: +msgctxt "#33035" +msgid "Delete {}: {}?" +msgstr "" + +#: +msgctxt "#33036" +msgid "Delete episode S{0:02d}E{1:02d} from {2}?" +msgstr "" + +#: +msgctxt "#33037" +msgid "Maximum intro offset to consider" +msgstr "" + +#: +msgctxt "#33038" +msgid "When encountering an intro marker with a start time offset greater than this, ignore it (default: 600s/10m)" +msgstr "" + +#: +msgctxt "#33039" +msgid "Move" +msgstr "" + +#: +msgctxt "#33040" +msgid "Reset library order" +msgstr "" + +#: +msgctxt "#33034" +msgid "Library settings" +msgstr "" + +#: +msgctxt "#32357" +msgid "By Title" +msgstr "" + +#: +msgctxt "#32358" +msgid "Title" +msgstr "" + +#: +msgctxt "#33041" +msgid "Show hub: {}" +msgstr "" + +#: +msgctxt "#33042" +msgid "Episode Date Added" +msgstr "" + +#: +msgctxt "#33001" +msgid "Long-press (or context menu) on a library item or: Honor path_mapping.json in the addon_data/script.plexmod folder when DirectPlaying media. This can be used to stream using other techniques such as SMB/NFS/etc. instead of the default HTTP handler. path_mapping.example.json is included in the addon's main directory." +msgstr "" + +#: +msgctxt "#33043" +msgid "Hubs round-robin" +msgstr "" + +#: +msgctxt "#33044" +msgid "Allow round-robining in hubs" +msgstr "" + +#: +msgctxt "#33045" +msgid "Behave like official Plex clients" +msgstr "" + +#: +msgctxt "#33046" +msgid "Show OSD when pressing up/down without OSD instead of showing chapters." +msgstr "" + +#: +msgctxt "#33046" +msgid "When pressing up/down while the OSD isn't shown, show OSD instead of skipping chapters." +msgstr "" + +#: +msgctxt "#32025" +msgid "Direct Play" +msgstr "" + +#: +msgctxt "#32026" +msgid "Direct Stream" +msgstr "" + +#: +msgctxt "#32036" +msgid "4K" +msgstr "" + +#: +msgctxt "#32037" +msgid "HEVC (h265)" +msgstr "" + +#: +msgctxt "#32601" +msgid "AV1" +msgstr "" + +#: +msgctxt "#32932" +msgid "Subtitle quick-actions" +msgstr "" + +#: +msgctxt "#32933" +msgid "FFWD/RWD" +msgstr "" + +#: +msgctxt "#32934" +msgid "Repeat" +msgstr "" + +#: +msgctxt "#32935" +msgid "Shuffle" +msgstr "" + +#: +msgctxt "#32939" +msgid "User-specific.\n" +"Only applies to video player UI" +msgstr "" + +#: +msgctxt "#32977" +msgid "VC1" +msgstr "" + +#: +msgctxt "#32983" +msgid "Theme" +msgstr "" + +#: +msgctxt "#32984" +msgid "Sets the theme. Currently only customizes all control buttons. ATTENTION: [I]Might[/I] need an addon restart.\n" +"In order to customize this, copy one of the xml's in script.plexmod/resources/skins/Main/1080i/templates to addon_data/script.plexmod/templates/{templatename}_custom.xml and adjust it to your liking, then select \"Custom\" as your theme." +msgstr "" + +#: +msgctxt "#33007" +msgid "Select in which cases to blur TV episode thumbnails, previews, redact summaries, hide episode titles and whether to blur chapter images. When the Addon Setting \"Use episode thumbnails in continue hub\" is enabled, blur them as well." +msgstr "" + +#: +msgctxt "#33011" +msgid "In progress" +msgstr "" + +#: +msgctxt "#33016" +msgid "Allow TV spoilers for" +msgstr "" + +#: +msgctxt "#33017" +msgid "Overrides the above for specific genres. Default: Reality, Game Show, Documentary, Sport" +msgstr "" + +#: +msgctxt "#33022" +msgid "Watched indicators" +msgstr "" + +#: +msgctxt "#33023" +msgid "Classic: Show orange triangle for unwatched items\n" +"Modern: Show green checkmark for watched items\n" +"Modern (2024): Show white checkmark for watched items\n" +"(default: Modern (2024))" +msgstr "" + +#: +msgctxt "#33024" +msgid "Hide background in modern indicators" +msgstr "" + +#: +msgctxt "#33044" +msgid "Allow round-robining in hubs. Attention: Loads a lot of items. Depending on the hub size, this can lead to crashes. Current limit: {}; can be adjusted in addon settings." +msgstr "" + +#: +msgctxt "#33046" +msgid "When pressing up/down while the OSD isn't shown, show OSD instead of skipping chapters. Additionally, when pressing down while the OSD is shown, open the chapters (if available)." +msgstr "" + +#: +msgctxt "#33047" +msgid "Hubs round-robin item limit" +msgstr "" + +#: +msgctxt "#33048" +msgid "When hubs round-robin is enabled, only round-robin until this item limit. If the hub size exceeds this limit, the remaining items will be lazy loaded as usual. Tested minimum safe value on NVIDIA SHIELD 2019 is 1000. Default: 250" +msgstr "" + +#: +msgctxt "#33049" +msgid "Max retries" +msgstr "" + +#: +msgctxt "#33050" +msgid "The maximum number of retries each connection should attempt. The default (1) helps with hibernation/wakeup issues. Set higher for bad connections, setting this to 0 was the old default before 0.7.9" +msgstr "" + +#: +msgctxt "#33051" +msgid "Use CA certificate bundle" +msgstr "" + +#: +msgctxt "#33052" +msgid "Which CA certificate bundle to use for request HTTPS verification. Default is \"system\", which uses the system-provided certificate bundle. \"plex.direct\" uses an extremely small bundle provided with the addon, which only applies to plex.direct connections (any other connections will use the system bundle) and might slightly improve performance. \"custom\" allows for a certificate bundle in userdata/addon_data/script.plexmod/custom_bundle.crt" +msgstr "" + +#: +msgctxt "#33053" +msgid "System" +msgstr "" + +#: +msgctxt "#33054" +msgid "plex.direct (addon-supplied)" +msgstr "" + +#: +msgctxt "#33055" +msgid "Custom" +msgstr "" + +#: +msgctxt "#33056" +msgid "None" +msgstr "" + +#: +msgctxt "#33057" +msgid "Show buttons" +msgstr "" + +#: +msgctxt "#33058" +msgid "Playback features" +msgstr "" + +#: +msgctxt "#33059" +msgid "Additional codecs" +msgstr "" + +#: +msgctxt "#33060" +msgid "{feature_ds}: {desc_ds}\n" +"{feature_4k}: {desc_4k}" +msgstr "" + +#: +msgctxt "#33061" +msgid "Enable certain codecs if your hardware supports them. Disable them to force transcoding." +msgstr "" + +#: +msgctxt "#33062" +msgid "Compiling templates" +msgstr "" + +#: +msgctxt "#33063" +msgid "Looking for custom templates" +msgstr "" + +#: +msgctxt "#33064" +msgid "Rendering: {}" +msgstr "" + +#: +msgctxt "#33065" +msgid "Complete" +msgstr "" + +#: +msgctxt "#33066" +msgid "Cache template files" +msgstr "" + +#: +msgctxt "#33067" +msgid "Doesn't throw away the template source files after compiling them. Uses slightly more memory but increases the speed of theme-related changes." +msgstr "" + +#: +msgctxt "#33068" +msgid "Always compile templates" +msgstr "" + +#: +msgctxt "#33069" +msgid "Recompiles all templates on every startup. Useful for template/theme development." +msgstr "" + +#: +msgctxt "#33070" +msgid "Action on Wake event" +msgstr "" + +#: +msgctxt "#33071" +msgid "Restart PM4K" +msgstr "" + +#: +msgctxt "#33072" +msgid "Wait for {}s" +msgstr "" + +#: +msgctxt "#33073" +msgid "Wait after wakeup" +msgstr "" + +#: +msgctxt "#33074" +msgid "Waiting {} second(s)" +msgstr "" + +#: +msgctxt "#33075" +msgid "Do something after waking up. Waiting for a time until resuming normal execution helps with networks coming back up after sleep events. Default: 1 second (5 seconds, CoreELEC)" +msgstr "" + +#: +msgctxt "#33076" +msgid "Modern (2024)" +msgstr "" + +#: +msgctxt "#33077" +msgid "Scale modern indicators" +msgstr "" + +#: +msgctxt "#33078" +msgid "Scale the modern indicators based on the poster size used. Default: On (tiny: 0.75, small: 1.0, medium: 1.175, big: 1.3)" +msgstr "" + +#: +msgctxt "#33079" +msgid "Hi-Res Music" +msgstr "" + +#: +msgctxt "#33080" +msgid "Allow DirectPlay of high resolution music (e.g. FLAC, >= 192 kHz)" +msgstr "" + +#: +msgctxt "#33081" +msgid "Blur chapter images" +msgstr "" + +#: +msgctxt "#33082" +msgid "Scan Library Files" +msgstr "" + +#: +msgctxt "#33083" +msgid "Empty Trash" +msgstr "" + +#: +msgctxt "#33084" +msgid "Analyze" +msgstr "" + +#: +msgctxt "#33085" +msgid "Map key to home" +msgstr "" + +#: +msgctxt "#33086" +msgid "Press the key you want to map to go to home within {} seconds" +msgstr "" + +#: +msgctxt "#33087" +msgid "Bind a key to immediately go to the Home view. Cancel using BACK/PREVIOUS_MENU. Clear bound key using the STOP button on the setting." +msgstr "" + +#: +msgctxt "#33620" +msgid "Plex server connect timeout" +msgstr "" + +#: +msgctxt "#33621" +msgid "Sets the maximum amount of time to connect to a Plex Server in seconds. Default: 5" +msgstr "" + +#: +msgctxt "#32940" +msgid "Video Player" +msgstr "" + +#: +msgctxt "#33050" +msgid "The maximum number of retries each connection should attempt. The default (3) helps with hibernation/wakeup issues. Set higher for bad connections, setting this to 0 was the old default before 0.7.9" +msgstr "" + +#: +msgctxt "#33075" +msgid "Do something after waking up. Waiting for a time until resuming normal execution helps with networks coming back up after sleep events. Default: 1 second (5 seconds, CoreELEC)." +msgstr "" + +#: +msgctxt "#33087" +msgid "Bind a key to immediately go to the Home view. Cancel using BACK/PREVIOUS_MENU. Clear bound key using the STOP or CONTEXT_MENU (long press OK/Enter) button on the setting." +msgstr "" + +#: +msgctxt "#33088" +msgid "Only applies to video player UI" +msgstr "" + +#: +msgctxt "#33089" +msgid "Automatic seek-back" +msgstr "" + +#: +msgctxt "#33090" +msgid "If your audio doesn't resume as fast as the video, or you want to catch up after a longer pause, use this to seek back after resuming from pause to compensate for the delay. Default: Off" +msgstr "" + +#: +msgctxt "#33091" +msgid "{sec_or_ms} {unit_s_or_ms}" +msgstr "" + +#: +msgctxt "#33092" +msgid "Seek back on pause" +msgstr "" + +#: +msgctxt "#33093" +msgid "Seek back after" +msgstr "" + +#: +msgctxt "#33094" +msgid "Only seek back after having paused at least a certain amount of seconds" +msgstr "" + +#: +msgctxt "#33095" +msgid "Seek back on pause instead of on resume. When Transcoding you should enable this." +msgstr "" + +#: +msgctxt "#33096" +msgid "Only with Direct Play" +msgstr "" + +#: +msgctxt "#33097" +msgid "Enable seek back ony when we're Direct Playing, not Transcoding." +msgstr "" + +#: +msgctxt "#33098" +msgid "Tickrate (Hz)" +msgstr "" + +#: +msgctxt "#33099" +msgid "Controls how often certain ticks are performed on GUI windows and the SeekDialog/VideoPlayer and how fast certain events are handled. Can be expensive when bigger than 1 Hz (once per second), can cause quirks when lower than 1 Hz (less than once per second). Depends on the hardware. Default: 1 Hz, Max: 10 Hz (every 100 ms), Sane highest and old default: 10 Hz (every 100 ms)" +msgstr "" + +#: +msgctxt "#33636" +msgid "Plex server read timeout" +msgstr "" + +#: +msgctxt "#33637" +msgid "Sets the maximum amount of time to read from a Plex Server in seconds. Default: 10" +msgstr "" + +#: +msgctxt "#33638" +msgid "Plex.tv connect timeout" +msgstr "" + +#: +msgctxt "#33639" +msgid "Plex.tv: Sets the maximum amount of time to connect to Plex.tv in seconds. Default: 5" +msgstr "" + +#: +msgctxt "#33640" +msgid "Plex.tv read timeout" +msgstr "" + +#: +msgctxt "#33641" +msgid "Plex.tv: Sets the maximum amount of time to read from Plex.tv in seconds. Default: 20" +msgstr "" + +#: +msgctxt "#33642" +msgid "Dump config" +msgstr "" + +#: +msgctxt "#33643" +msgid "Dumps all user settings into the log on startup, when DEBUG logging is enabled. Masks private information." +msgstr "" + +#: +msgctxt "#33644" +msgid "Tracks" +msgstr "" + +#: +msgctxt "#33645" +msgid "Ignore plex.direct DNS handling for remote hosts" +msgstr "" + +#: +msgctxt "#33646" +msgid "Only handle plex.direct hosts when the server's attributes dnsRebindingProtection=1 and publicAddressMatches=1. Might not work in certain situations. Disable if you have connection issues." +msgstr "" + +#: +msgctxt "#33645" +msgid "plex.direct: Honor plex.tv's dnsRebindingProtection flag (DNS)" +msgstr "" + +#: +msgctxt "#33646" +msgid "Only handle plex.direct hosts when the server's attributes dnsRebindingProtection=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "" + +#: +msgctxt "#33647" +msgid "plex.direct: Honor plex.tv's publicAddressMatches flag (DNS)" +msgstr "" + +#: +msgctxt "#33648" +msgid "Only handle plex.direct hosts when the server's attributes publicAddressMatches=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "" + +#: +msgctxt "#33649" +msgid "CoreELEC: Resume-fix wait for seek" +msgstr "" + +#: +msgctxt "#33650" +msgid "This adjusts the delay between seek-tries on CoreELEC, which fixes resume not always working or double-seeking. When you have resume/double-seek issues, increase this. 100ms should be stable as well. Default: 350ms" +msgstr "" + diff --git a/script.plexmod/resources/language/resource.language.zh_cn/strings.po b/script.plexmod/resources/language/resource.language.zh_cn/strings.po index 46b8c93dac..be188a2d8c 100644 --- a/script.plexmod/resources/language/resource.language.zh_cn/strings.po +++ b/script.plexmod/resources/language/resource.language.zh_cn/strings.po @@ -1,1075 +1,2861 @@ -# XBMC Media Center language file msgid "" msgstr "" -"Project-Id-Version: XBMC-Addons\n" -"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n" -"POT-Creation-Date: 2020-3-4 22:56+0000\n" -"PO-Revision-Date: 2022-02-08 19:00+0800\n" -"Last-Translator: Qianyu Li <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: zh_CN\n" -"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: POEditor.com\n" +"Project-Id-Version: PM4K / PlexMod for Kodi\n" +"Language: zh-CN\n" +#: msgctxt "#32000" msgid "Main" -msgstr "一般" +msgstr "通用" +#: msgctxt "#32001" msgid "Original" msgstr "原始" +#: msgctxt "#32002" msgid "20 Mbps 1080p" -msgstr "" +msgstr "20 Mbps 1080p" +#: msgctxt "#32003" msgid "12 Mbps 1080p" -msgstr "" +msgstr "12 Mbps 1080p" +#: msgctxt "#32004" msgid "10 Mbps 1080p" -msgstr "" +msgstr "10 Mbps 1080p" +#: msgctxt "#32005" msgid "8 Mbps 1080p" -msgstr "" +msgstr "8 Mbps 1080p" +#: msgctxt "#32006" msgid "4 Mbps 720p" -msgstr "" +msgstr "4 Mbps 720p" +#: msgctxt "#32007" msgid "3 Mbps 720p" -msgstr "" +msgstr "3 Mbps 720p" +#: msgctxt "#32008" msgid "2 Mbps 720p" -msgstr "" +msgstr "2 Mbps 720p" +#: msgctxt "#32009" msgid "1.5 Mbps 480p" -msgstr "" +msgstr "1.5 Mbps 480p" +#: msgctxt "#32010" msgid "720 kbps" -msgstr "" +msgstr "720 kbps" +#: msgctxt "#32011" msgid "320 kbps" -msgstr "" +msgstr "320 kbps" +#: msgctxt "#32012" msgid "208 kbps" -msgstr "" +msgstr "208 kbps" +#: msgctxt "#32013" msgid "96 kbps" -msgstr "" +msgstr "96 kbps" +#: msgctxt "#32014" msgid "64 kbps" -msgstr "" +msgstr "64 kbps" +#: msgctxt "#32020" msgid "Local Quality" msgstr "本地播放质量" +#: msgctxt "#32021" msgid "Remote Quality" msgstr "远程播放质量" +#: msgctxt "#32022" msgid "Online Quality" msgstr "在线播放质量" +#: msgctxt "#32023" msgid "Transcode Format" msgstr "转码格式" +#: msgctxt "#32024" msgid "Debug Logging" msgstr "调试日志" +#: msgctxt "#32025" -msgid "Allow Direct Play" -msgstr "允许直接播放" +msgid "Direct Play" +msgstr "直接播放" +#: msgctxt "#32026" -msgid "Allow Direct Stream" -msgstr "允许直连串流" +msgid "Direct Stream" +msgstr "直接串流" +#: msgctxt "#32027" msgid "Force" msgstr "强制直接播放" +#: msgctxt "#32028" msgid "Always" msgstr "总是" +#: msgctxt "#32029" msgid "Only Image Formats" msgstr "仅图像格式" +#: msgctxt "#32030" msgid "Auto" msgstr "自动" -msgctxt "#32031" -msgid "Burn Subtitles (Direct Play Only)" -msgstr "固化字幕(仅直接播放)" - +#: msgctxt "#32032" msgid "Allow Insecure Connections" msgstr "允许非加密连接" +#: msgctxt "#32033" msgid "Never" msgstr "从不" +#: msgctxt "#32034" msgid "On Same network" msgstr "在同一网络" +#: msgctxt "#32035" msgid "Always" msgstr "总是" -msgctxt "#32036" -msgid "Allow 4K" -msgstr "允许4K" - -msgctxt "#32037" -msgid "Allow HEVC (h265)" -msgstr "允许HEVC (h265)" - +#: msgctxt "#32038" msgid "Automatically Sign In" msgstr "自动登录" +#: msgctxt "#32039" msgid "Post Play Auto Play" -msgstr "点击海报自动播放" +msgstr "播放结束后自动播放" +#: msgctxt "#32040" msgid "Enable Subtitle Downloading" msgstr "允许下载字幕" +#: msgctxt "#32041" msgid "Enable Subtitle Downloading" msgstr "允许下载字幕" +#: msgctxt "#32042" msgid "Server Discovery (GDM)" -msgstr "发现服务器(GDM)" +msgstr "发现服务器(GDM)" +#: msgctxt "#32043" msgid "Start Plex On Kodi Startup" -msgstr "打开Kodi时自动启动PLEX" +msgstr "打开 Kodi 时自动启动 Plex" +#: msgctxt "#32044" msgid "Connection 1 IP" -msgstr "服务器1的IP" +msgstr "服务器 1 的 IP" +#: msgctxt "#32045" msgid "Connection 1 Port" -msgstr "服务器1的端口" +msgstr "服务器 1 的端口" +#: msgctxt "#32046" msgid "Connection 2 IP" -msgstr "服务器2的IP" +msgstr "服务器 2 的 IP" +#: msgctxt "#32047" msgid "Connection 2 Port" -msgstr "服务器2的端口" +msgstr "服务器 2 的端口" +#: msgctxt "#32048" msgid "Audio" msgstr "音频" +#: msgctxt "#32049" msgid "Advanced" msgstr "高级" +#: msgctxt "#32050" msgid "Manual Servers" msgstr "手动输入服务器地址" +#: msgctxt "#32051" msgid "Privacy" msgstr "隐私" +#: msgctxt "#32052" msgid "About" msgstr "关于" +#: msgctxt "#32053" msgid "Video" msgstr "视频" +#: msgctxt "#32054" msgid "Addon Version" msgstr "插件版本" +#: msgctxt "#32055" msgid "Kodi Version" -msgstr "Kodi版本" +msgstr "Kodi 版本" +#: msgctxt "#32056" msgid "Screen Resolution" msgstr "屏幕分辨率" +#: msgctxt "#32057" msgid "Current Server Version" -msgstr "PLEX服务器版本" +msgstr "服务器版本" + +#: +msgctxt "#32058" +msgid "Never exceed original audio codec" +msgstr "从不超过原始音频编解码器" + +#: +msgctxt "#32059" +msgid "When transcoding audio, never exceed the original audio bitrate or channel count on the same codec." +msgstr "在转码音频时,永远不要超出相同编解码器的原始音频比特率或声道数量。" + +#: +msgctxt "#32060" +msgid "Use Kodi audio channels" +msgstr "使用 Kodi 音频通道" + +#: +msgctxt "#32064" +msgid "Treat DTS like AC3" +msgstr "把 DTS 当做 AC3 处理" +#: msgctxt "#32100" msgid "Skip user selection and pin entry on startup." -msgstr "启动时跳过选择用户和图钉." +msgstr "在启动时跳过用户选择和 PIN 码输入。" +#: msgctxt "#32101" -msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a 15 second delay." -msgstr "如果启用,当播放结束并且有一个“Next Up”项目可用时,它将在15秒的延迟后自动播放." +msgid "If enabled, when playback ends and there is a 'Next Up' item available, it will be automatically be played after a {} second delay." +msgstr "如果启用,当播放结束且有 “下一个” 项目可用时,它将在 {} 秒延迟后自动播放。" +#: msgctxt "#32102" msgid "Enable this if your hardware can handle 4K playback. Disable it to force transcoding." -msgstr "如果您的硬件可以处理4K播放,请启用此选项.禁用它以强制转码." +msgstr "如果您的硬件支持 4K 播放,请启用此选项。禁用会强制转码。" +#: msgctxt "#32103" msgid "Enable this if your hardware can handle HEVC/h265. Disable it to force transcoding." -msgstr "如果您的硬件可以处理HEVC/h265,请启用此选项.禁用它以强制转码." +msgstr "如果您的硬件支持 HEVC/h265,请启用此选项。禁用会强制转码。" +#: msgctxt "#32104" msgid "When to connect to servers with no secure connections.[CR][CR]* [B]Never[/B]: Never connect to a server insecurely[CR]* [B]On Same Network[/B]: Allow if on the same network[CR]* [B]Always[/B]: Allow same network and remote connections" msgstr "何时连接到没有安全连接的服务器。[CR][CR]* [B]从不[/B]: 从不以不安全方式连接服务器[CR]* [B]在同一网络[/B]: 允许同一网络时[CR]* [B]总是[/B]: 允许同一网络和远程连接时" +#: msgctxt "#32201" msgid "Trailer" msgstr "预告片" +#: msgctxt "#32202" msgid "Deleted Scene" msgstr "删除的场景" +#: msgctxt "#32203" msgid "Interview" msgstr "访问" +#: msgctxt "#32204" msgid "Music Video" msgstr "音乐视频" +#: msgctxt "#32205" msgid "Behind the Scenes" msgstr "幕后花絮" +#: msgctxt "#32206" msgid "Scene" -msgstr "现场" +msgstr "场景" +#: msgctxt "#32207" msgid "Live Music Video" msgstr "现场音乐视频" +#: msgctxt "#32208" msgid "Lyric Music Video" msgstr "歌词音乐视频" +#: msgctxt "#32209" msgid "Concert" -msgstr "演奏会" +msgstr "演唱会" +#: msgctxt "#32210" msgid "Featurette" -msgstr "电影短片" +msgstr "特辑" +#: msgctxt "#32211" msgid "Short" -msgstr "短篇" +msgstr "短片" +#: msgctxt "#32212" msgid "Other" msgstr "其他" +#: msgctxt "#32300" msgid "Go to Album" -msgstr "跳转到相册" +msgstr "前往专辑" +#: msgctxt "#32301" msgid "Go to Artist" -msgstr "跳转到演员" +msgstr "前往艺人主页" +#: msgctxt "#32302" msgid "Go to {0}" -msgstr "跳转到 {0}" - -msgctxt "#32303" -msgid "Season" -msgstr "季数" - -msgctxt "#32304" -msgid "Episode" -msgstr "集数" +msgstr "前往 {0}" +#: msgctxt "#32305" msgid "Extras" -msgstr "其他" +msgstr "额外内容" +#: msgctxt "#32306" msgid "Related Shows" -msgstr "相关节目" +msgstr "相关电视节目" +#: msgctxt "#32307" msgid "More" msgstr "更多" +#: msgctxt "#32308" msgid "Available" msgstr "可用的" +#: msgctxt "#32309" msgid "None" msgstr "无" -msgctxt "#32310" -msgid "S" -msgstr "" - -msgctxt "#32311" -msgid "E" -msgstr "" - +#: msgctxt "#32312" msgid "Unavailable" msgstr "不可用" +#: msgctxt "#32313" msgid "This item is currently unavailable." -msgstr "这个项目现在不可用." +msgstr "此项目现在不可用。" +#: msgctxt "#32314" msgid "In Progress" -msgstr "进行中" +msgstr "观看中" +#: msgctxt "#32315" msgid "Resume playback?" -msgstr "恢复播放?" +msgstr "继续播放?" +#: msgctxt "#32316" msgid "Resume" -msgstr "恢复" +msgstr "继续" +#: msgctxt "#32317" msgid "Play from beginning" msgstr "从头播放" +#: msgctxt "#32318" msgid "Mark Unplayed" msgstr "标记为未播放" +#: msgctxt "#32319" msgid "Mark Played" msgstr "标记为已播放" +#: msgctxt "#32320" msgid "Mark Season Unplayed" -msgstr "标记整季未播放" +msgstr "标记整季为未播放" +#: msgctxt "#32321" msgid "Mark Season Played" -msgstr "标记整季已播放" +msgstr "标记整季为已播放" +#: msgctxt "#32322" msgid "Delete" msgstr "删除" +#: msgctxt "#32323" msgid "Go To Show" -msgstr "转到剧集" +msgstr "前往电视节目" +#: msgctxt "#32324" msgid "Go To {0}" -msgstr "跳转到 {0}" +msgstr "前往 {0}" +#: msgctxt "#32325" msgid "Play Next" msgstr "播放下一个" +#: msgctxt "#32326" msgid "Really Delete?" -msgstr "确定删除?" +msgstr "确定要删除吗?" +#: msgctxt "#32327" msgid "Are you sure you really want to delete this media?" -msgstr "你确定你要删除这个媒体么?" +msgstr "您确定您真的想要删除这个媒体吗?" +#: msgctxt "#32328" msgid "Yes" msgstr "是" +#: msgctxt "#32329" msgid "No" msgstr "否" +#: msgctxt "#32330" msgid "Message" msgstr "消息" +#: msgctxt "#32331" msgid "There was a problem while attempting to delete the media." -msgstr "尝试删除媒体时出现问题." +msgstr "尝试删除媒体时出现了问题。" +#: msgctxt "#32332" msgid "Home" msgstr "主页" +#: msgctxt "#32333" msgid "Playlists" msgstr "播放列表" +#: msgctxt "#32334" msgid "Confirm Exit" msgstr "确定退出" +#: msgctxt "#32335" msgid "Are you ready to exit Plex?" -msgstr "你确定要退出PLEX么?" +msgstr "您确定要退出 Plex 吗?" +#: msgctxt "#32336" msgid "Exit" msgstr "退出" +#: msgctxt "#32337" msgid "Cancel" msgstr "返回" +#: msgctxt "#32338" msgid "No Servers Found" msgstr "没有找到服务器" +#: msgctxt "#32339" msgid "Server is not accessible" msgstr "服务器不能访问" +#: msgctxt "#32340" msgid "Connection tests are in progress. Please wait." -msgstr "连接测试正在进行中.请耐心等待." +msgstr "连接测试正在进行中,请稍候。" +#: msgctxt "#32341" msgid "Server is not accessible. Please sign into your server and check your connection." -msgstr "服务器不可访问.请登录您的服务器并检查您的连接." +msgstr "无法访问服务器。请登录您的服务器并检查您的网络连接。" +#: msgctxt "#32342" msgid "Switch User" msgstr "切换用户" +#: msgctxt "#32343" msgid "Settings" msgstr "设置" +#: msgctxt "#32344" msgid "Sign Out" msgstr "登出" +#: msgctxt "#32345" msgid "All" msgstr "所有" +#: msgctxt "#32346" msgid "By Name" msgstr "按名称排序" +#: msgctxt "#32347" msgid "Artists" msgstr "艺人" +#: msgctxt "#32348" msgid "Movies" msgstr "电影" +#: msgctxt "#32349" msgid "photos" -msgstr "相片" +msgstr "照片" +#: msgctxt "#32350" msgid "Shows" -msgstr "演出" +msgstr "电视节目" +#: msgctxt "#32351" msgid "By Date Added" msgstr "按添加日期排序" +#: msgctxt "#32352" msgid "Date Added" msgstr "添加日期" +#: msgctxt "#32353" msgid "By Release Date" msgstr "按发布日期排序" +#: msgctxt "#32354" msgid "Release Date" msgstr "发布日期" +#: msgctxt "#32355" msgid "By Date Viewed" msgstr "按观看日期排序" +#: msgctxt "#32356" msgid "Date Viewed" msgstr "观看日期" +#: msgctxt "#32357" -msgid "By Name" -msgstr "按名称排序" +msgid "By Title" +msgstr "按标题" +#: msgctxt "#32358" -msgid "Name" -msgstr "名称" +msgid "Title" +msgstr "标题" +#: msgctxt "#32359" msgid "By Rating" -msgstr "按热度排序" +msgstr "按评分排序" +#: msgctxt "#32360" msgid "Rating" -msgstr "热度" +msgstr "评分" +#: msgctxt "#32361" msgid "By Resolution" msgstr "按分辨率排序" +#: msgctxt "#32362" msgid "Resolution" msgstr "分辨率" +#: msgctxt "#32363" msgid "By Duration" msgstr "按时长排序" +#: msgctxt "#32364" msgid "Duration" msgstr "时长" +#: msgctxt "#32365" msgid "By First Aired" msgstr "按首次播出排序" +#: msgctxt "#32366" msgid "First Aired" msgstr "首次播出" +#: msgctxt "#32367" msgid "By Unplayed" msgstr "按未播放排序" +#: msgctxt "#32368" msgid "Unplayed" msgstr "未播放" +#: msgctxt "#32369" msgid "By Date Played" msgstr "按播放日期排序" +#: msgctxt "#32370" msgid "Date Played" msgstr "播放日期" +#: msgctxt "#32371" msgid "By Play Count" msgstr "按播放次数排序" +#: msgctxt "#32372" msgid "Play Count" msgstr "播放次数" +#: msgctxt "#32373" msgid "By Date Taken" msgstr "按拍摄日期排序" +#: msgctxt "#32374" msgid "Date Taken" msgstr "拍摄日期" +#: msgctxt "#32375" msgid "No filters available" msgstr "没找到相关内容" +#: msgctxt "#32376" msgid "Clear Filter" -msgstr "清空内容" +msgstr "清空筛选" +#: msgctxt "#32377" msgid "Year" msgstr "年" +#: msgctxt "#32378" msgid "Decade" msgstr "年代" +#: msgctxt "#32379" msgid "Genre" msgstr "类型" +#: msgctxt "#32380" msgid "Content Rating" msgstr "内容分级" +#: msgctxt "#32381" msgid "Network" -msgstr "网络" +msgstr "播出平台" +#: msgctxt "#32382" msgid "Collection" msgstr "合集" +#: msgctxt "#32383" msgid "Director" msgstr "导演" +#: msgctxt "#32384" msgid "Actor" msgstr "演员" +#: msgctxt "#32385" msgid "Country" msgstr "国家" +#: msgctxt "#32386" msgid "Studio" -msgstr "工作室" +msgstr "制片公司" +#: msgctxt "#32387" msgid "Labels" msgstr "标签" +#: msgctxt "#32388" msgid "Camera Make" msgstr "相机品牌" +#: msgctxt "#32389" msgid "Camera Model" msgstr "相机型号" +#: msgctxt "#32390" msgid "Aperture" msgstr "光圈" +#: msgctxt "#32391" msgid "Shutter Speed" msgstr "快门速度" +#: msgctxt "#32392" msgid "Lens" msgstr "镜头" +#: msgctxt "#32393" msgid "TV Shows" -msgstr "剧集" +msgstr "电视节目" +#: msgctxt "#32394" msgid "Music" msgstr "音乐" +#: msgctxt "#32395" msgid "Audio" msgstr "音频" +#: msgctxt "#32396" msgid "Subtitles" msgstr "字幕" +#: msgctxt "#32397" msgid "Quality" msgstr "质量" +#: msgctxt "#32398" msgid "Kodi Video Settings" -msgstr "KODI视频设置" +msgstr "Kodi 视频设置" +#: msgctxt "#32399" msgid "Kodi Audio Settings" -msgstr "KODI音频设置" +msgstr "Kodi 音频设置" +#: msgctxt "#32400" msgid "Go To Season" -msgstr "跳转到季" +msgstr "前往季" +#: msgctxt "#32401" msgid "Directors" msgstr "导演" +#: msgctxt "#32402" msgid "Writer" msgstr "编剧" +#: msgctxt "#32403" msgid "Writers" msgstr "编剧" +#: msgctxt "#32404" msgid "Related Movies" msgstr "相关电影" +#: msgctxt "#32405" msgid "Download Subtitles" msgstr "下载字幕" +#: msgctxt "#32406" msgid "Subtitle Delay" msgstr "字幕延迟" +#: msgctxt "#32407" msgid "Next Subtitle" msgstr "下一个字幕" +#: msgctxt "#32408" msgid "Disable Subtitles" msgstr "禁用字幕" +#: msgctxt "#32409" msgid "Enable Subtitles" -msgstr "允许字幕" +msgstr "启用字幕" +#: msgctxt "#32410" msgid "Platform Version" msgstr "平台版本" +#: msgctxt "#32411" msgid "Unknown" msgstr "未知" +#: msgctxt "#32412" msgid "Edit Or Clear" msgstr "编辑或清除" +#: msgctxt "#32413" msgid "Edit IP address or clear the current setting?" -msgstr "编辑IP地址或清除当前设置?" +msgstr "编辑 IP 地址还是清除当前设置?" +#: msgctxt "#32414" msgid "Clear" msgstr "清除" +#: msgctxt "#32415" msgid "Edit" msgstr "编辑" +#: msgctxt "#32416" msgid "Enter IP Address" -msgstr "填写IP地址" +msgstr "填写 IP 地址" +#: msgctxt "#32417" msgid "Enter Port Number" msgstr "填写端口" +#: msgctxt "#32418" msgid "Creator" msgstr "创作者" +#: msgctxt "#32419" msgid "Cast" -msgstr "阵容" +msgstr "演员" +#: msgctxt "#32420" msgid "Disc" -msgstr "碟片" +msgstr "光盘" +#: msgctxt "#32421" msgid "Sign Out" msgstr "登出" +#: msgctxt "#32422" msgid "Exit" -msgstr "离开" +msgstr "退出" +#: msgctxt "#32423" msgid "Shutdown" msgstr "关机" +#: msgctxt "#32424" msgid "Suspend" msgstr "暂停" +#: msgctxt "#32425" msgid "Hibernate" msgstr "休眠" +#: msgctxt "#32426" msgid "Reboot" msgstr "重启" +#: msgctxt "#32427" msgid "Failed" msgstr "失败" +#: msgctxt "#32428" msgid "Login failed!" msgstr "登陆失败!" +#: msgctxt "#32429" msgid "Resume from {0}" -msgstr "从{0}恢复" +msgstr "从 {0} 继续" +#: msgctxt "#32430" msgid "Discovery" msgstr "发现" +#: msgctxt "#32431" msgid "Search" msgstr "搜索" +#: msgctxt "#32432" msgid "Space" msgstr "空格" +#: msgctxt "#32433" msgid "Clear" msgstr "清除" +#: msgctxt "#32434" msgid "Searching..." msgstr "搜索中..." +#: msgctxt "#32435" msgid "No Results" msgstr "无结果" +#: msgctxt "#32436" msgid "Paused" msgstr "暂停" +#: msgctxt "#32437" msgid "Welcome" msgstr "欢迎" +#: msgctxt "#32438" msgid "Previous" -msgstr "重播" +msgstr "上一个" +#: msgctxt "#32439" msgid "Playing Next" -msgstr "播放下一集" +msgstr "播放下一个" +#: msgctxt "#32440" msgid "On Deck" msgstr "已播项目" +#: msgctxt "#32441" msgid "Unknown" msgstr "未知" +#: msgctxt "#32442" msgid "Embedded" -msgstr "内嵌" +msgstr "内封" +#: msgctxt "#32443" msgid "Forced" msgstr "强制" +#: msgctxt "#32444" msgid "Lyrics" msgstr "歌词" +#: msgctxt "#32445" msgid "Mono" msgstr "单声道" +#: msgctxt "#32446" msgid "Stereo" msgstr "立体声" +#: msgctxt "#32447" msgid "None" msgstr "无" +#: msgctxt "#32448" msgid "Playback Failed!" -msgstr "播放失败!" +msgstr "播放失败!" +#: msgctxt "#32449" msgid "Can't connect to plex.tv[CR]Check your internet connection and try again." -msgstr "无法连接至plex.tv[CR]检查您的互联网连接,然后重试." +msgstr "无法连接到 plex.tv[CR] ,请检查您的网络连接并重试。" +#: msgctxt "#32450" msgid "Choose Version" msgstr "选择版本" +#: msgctxt "#32451" msgid "Play Version..." msgstr "播放版本" +#: msgctxt "#32452" msgid "No Content available in this library" msgstr "库里没有可播放的内容" +#: msgctxt "#32453" msgid "Please add content and/or check that 'Include in dashboard' is enabled." -msgstr "请添加内容和/或检查 '包括在仪表板' 是否已启用." +msgstr "请添加内容和/或检查 '包括在仪表板' 是否已启用。" +#: msgctxt "#32454" msgid "No Content available for this filter" msgstr "没有可用于此过滤器的内容" +#: msgctxt "#32455" msgid "Please change change or remove the current filter" msgstr "请更改或删除当前过滤器" +#: msgctxt "#32456" msgid "Show" -msgstr "节目" +msgstr "电视节目" +#: msgctxt "#32457" msgid "By Show" -msgstr "按节目排序" +msgstr "按电视节目排序" +#: msgctxt "#32458" msgid "Episodes" msgstr "集数" +#: msgctxt "#32459" msgid "Offline Mode" msgstr "离线模式" +#: msgctxt "#32460" msgid "Sign In" msgstr "登录" +#: msgctxt "#32461" msgid "Albums" msgstr "专辑" +#: msgctxt "#32462" msgid "Artist" msgstr "艺人" +#: msgctxt "#32463" msgid "By Artist" msgstr "按艺人排序" +#: msgctxt "#32464" msgid "Player" msgstr "播放" +#: msgctxt "#32465" msgid "Use skip step settings from Kodi" -msgstr "使用Kodi设置的跳过步骤" +msgstr "使用 Kodi 设置的跳过步骤" +#: msgctxt "#32466" msgid "Automatically seek selected position after a delay" msgstr "延迟后自动跳到所选位置" +#: msgctxt "#32467" msgid "User Interface" msgstr "用户界面" +#: msgctxt "#32468" msgid "Show dynamic background art" -msgstr "显示动态背景艺术" +msgstr "显示动态背景图片" +#: msgctxt "#32469" msgid "Background art blur amount" -msgstr "背景艺术模糊量" +msgstr "背景图片模糊度" +#: msgctxt "#32470" msgid "Background art opacity" -msgstr "背景艺术不透明度" +msgstr "背景图片不透明度" +#: msgctxt "#32471" msgid "Use Plex/Kodi steps for timeline" -msgstr "使用Plex/Kodi的时间轴步骤" +msgstr "使用 Plex/Kodi 的时间轴步骤" +#: msgctxt "#32480" msgid "Theme music" msgstr "主题音乐" +#: msgctxt "#32481" msgid "Off" msgstr "关闭" +#: msgctxt "#32482" msgid "%(percentage)s %%" -msgstr "" +msgstr "%(percentage)s %%" +#: msgctxt "#32483" msgid "Hide Stream Info" msgstr "隐藏流信息" +#: msgctxt "#32484" msgid "Show Stream Info" msgstr "显示流信息" +#: msgctxt "#32485" msgid "Go back instantly with the previous menu action in scrolled views" msgstr "滚动视图中的上一个菜单操作后立即返回" +#: msgctxt "#32487" msgid "Seek Delay" msgstr "跳过延迟" +#: msgctxt "#32488" msgid "Screensaver" msgstr "屏幕保护" +#: msgctxt "#32489" msgid "Quiz Mode" msgstr "测验模式" +#: msgctxt "#32490" msgid "Collections" msgstr "合集" +#: msgctxt "#32491" msgid "Folders" msgstr "文件夹" +#: msgctxt "#32492" msgid "Kodi Subtitle Settings" -msgstr "KODI字幕设置" - -msgctxt "#32493" -msgid "Prefer normal over forced subtitles if available (PMS selects forced by default)" -msgstr "如果有的话,优先选择正常字幕而不是强制字幕(PMS默认选择强制字幕)" +msgstr "Kodi 字幕设置" +#: msgctxt "#32495" msgid "Skip intro" msgstr "跳过片头" +#: +msgctxt "#32496" +msgid "Skip credits" +msgstr "跳过片尾" + +#: msgctxt "#32500" msgid "Always show post-play screen (even for short videos)" msgstr "始终显示播放后的画面(即使是短视频)" +#: msgctxt "#32501" msgid "Time-to-wait between videos on post-play" msgstr "播放后的视频之间的等待时间" +#: msgctxt "#32505" msgid "Visit media in video playlist instead of playing it" msgstr "访问视频播放列表中的媒体而不是播放它" -msgctxt "#32601" -msgid "Allow AV1" -msgstr "允许AV1" - -msgctxt "#32602" -msgid "Enable this if your hardware can handle AV1. Disable it to force transcoding." -msgstr "如果你的硬件可以处理AV1,请启用此功能.禁用它可以强制进行转码." - +#: msgctxt "#32521" msgid "Skip Intro Button Timeout" msgstr "跳过片头按钮超时" +#: msgctxt "#32522" msgid "Automatically Skip Intro" msgstr "自动跳过片头" -msgctxt "#32523" -msgid "Automatically skip intros if available." -msgstr "如果可用既自动跳过片头." - +#: msgctxt "#32524" msgid "Set how long the skip intro button shows for." -msgstr "设置跳过片头按钮的显示时间." +msgstr "设置跳过片头按钮的显示时长。" + +#: +msgctxt "#32525" +msgid "Skip Credits Button Timeout" +msgstr "跳过片尾按钮超时时间" + +#: +msgctxt "#32526" +msgid "Automatically Skip Credits" +msgstr "自动跳过片尾" + +#: +msgctxt "#32528" +msgid "Set how long the skip credits button shows for." +msgstr "设置跳过片尾按钮的显示时长。" + +#: +msgctxt "#32540" +msgid "Show when the current video will end in player" +msgstr "在播放器中显示当前视频播放结束的时间" + +#: +msgctxt "#32541" +msgid "Shows time left and at which time the media will end." +msgstr "显示剩余时长和媒体播放结束的时间。" + +#: +msgctxt "#32542" +msgid "Show \"Ends at\" label for the end-time as well" +msgstr "同时显示结束时间的 “结束于” 标签" + +#: +msgctxt "#32543" +msgid "Ends at" +msgstr "结束时间" + +#: +msgctxt "#32602" +msgid "Enable this if your hardware can handle AV1. Disable it to force transcoding." +msgstr "如果你的硬件可以处理 AV1,请启用此选项。禁用会强制转码。" + +#: +msgctxt "#33101" +msgid "By Audience Rating" +msgstr "按观众评分" + +#: +msgctxt "#33102" +msgid "Audience Rating" +msgstr "观众评分" + +#: +msgctxt "#33103" +msgid "By my Rating" +msgstr "按我的评分" + +#: +msgctxt "#33104" +msgid "My Rating" +msgstr "我的评分" + +#: +msgctxt "#33105" +msgid "By Content Rating" +msgstr "按内容分级" + +#: +msgctxt "#33106" +msgid "Content Rating" +msgstr "内容分级" + +#: +msgctxt "#33107" +msgid "By Critic Rating" +msgstr "按评论家评分" + +#: +msgctxt "#33108" +msgid "Critic Rating" +msgstr "评论家评分" + +#: +msgctxt "#33200" +msgid "Background Color" +msgstr "背景颜色" + +#: +msgctxt "#33201" +msgid "Specify solid Background Color instead of using media images" +msgstr "使用纯色背景而不是媒体图片" + +#: +msgctxt "#33400" +msgid "Use old compatibility profile" +msgstr "采用旧的兼容性配置模式" + +#: +msgctxt "#33401" +msgid "Uses the Chrome client profile instead of the custom one. Might fix rare issues with 3D playback." +msgstr "使用 Chrome 客户端配置文件而不是自定义的配置文件。可能修复与 3D 播放相关的罕见问题。" + +#: +msgctxt "#32031" +msgid "Burn-in Subtitles" +msgstr "烧录字幕" + +#: +msgctxt "#32061" +msgid "When transcoding audio, target the audio channels set in Kodi." +msgstr "在音频转码时,按照 Kodi 中设置的音频通道处理。" + +#: +msgctxt "#32062" +msgid "Transcode audio to AC3" +msgstr "将音频转码为 AC3 格式" + +#: +msgctxt "#32063" +msgid "Transcode audio to AC3 in certain conditions (useful for passthrough)." +msgstr "在特定条件下将音频转码为 AC3 格式(对音频直通非常有用)。" + +#: +msgctxt "#32065" +msgid "When any of the force AC3 settings are enabled, treat DTS the same as AC3 (useful for Optical passthrough)" +msgstr "当任何强制 AC3 设置被启用时,将 DTS 视为 AC3 对待(对于光纤直通非常有用)" + +#: +msgctxt "#32066" +msgid "Force audio to AC3" +msgstr "将音频强制转码为 AC3 格式" + +#: +msgctxt "#32067" +msgid "Only force multichannel audio to AC3" +msgstr "仅将多声道音频强制转码为 AC3 格式" + +#: +msgctxt "#32493" +msgid "When a media file has a forced/foreign subtitle for a subtitle-enabled language, the Plex Media Server preselects it. This behaviour is usually not necessary and not configurable. This setting fixes that by ignoring the PMSs decision and selecting the same language without a forced flag if possible." +msgstr "当媒体文件的字幕语言为强制字幕或外语字幕时,Plex 媒体服务器会预选该字幕。这通常不必要,也不可配置。此设置可忽略 PMS 的决定,尽可能选择不带强制标志的相同语言,可以解决这一问题。" + +#: +msgctxt "#32523" +msgid "Automatically skip intros if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "如果可用,自动跳过片头。不会覆盖已启用的连续播放模式。\n" +"可以单独为每个电视节目禁用/启用。" + +#: +msgctxt "#32527" +msgid "Automatically skip credits if available. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "如果可用,自动跳过片尾。不会覆盖已启用的连续播放模式。\n" +"可以单独为每个电视节目禁用/启用。" + +#: +msgctxt "#33501" +msgid "Video played threshold" +msgstr "视频完播的阈值" + +#: +msgctxt "#33502" +msgid "Set this to the same value as your Plex server (Settings>Library>Video played threshold) to avoid certain pitfalls, Default: 90 %" +msgstr "将其设置为您在 Plex 服务器中设置的相同值(设置 > 资料库 > 视频完播的阈值),以避免某些问题,默认值为:90%" + +#: +msgctxt "#33503" +msgid "Use alternative hubs refresh" +msgstr "使用备用内容版块刷新" + +#: +msgctxt "#33504" +msgid "Refreshes all hubs for all libraries after an item's watch-state has changed, instead of only those likely affected. Use this if you find a hub that doesn't update properly." +msgstr "在项目的观看状态更改后,刷新所有库的所有内容版块,而不仅仅是那些可能受影响的内容版块。如果发现某个内容版块未正确更新,请使用此功能。" + +#: +msgctxt "#33505" +msgid "Show intro skip button early" +msgstr "提前显示跳过片头按钮" + +#: +msgctxt "#33506" +msgid "Show the intro skip button from the start of a video with an intro marker. The auto-skipping setting applies. Doesn't override enabled binge mode.\n" +"Can be disabled/enabled per TV show." +msgstr "在有跳过片头标记的视频开始时显示跳过片头按钮。适用于自动跳过。不会覆盖启用的追剧模式。\n" +"可以单独为每个电视节目禁用/启用。" + +#: +msgctxt "#33507" +msgid "Enabled" +msgstr "启用" + +#: +msgctxt "#33508" +msgid "Disabled" +msgstr "禁用" + +#: +msgctxt "#33509" +msgid "Early intro skip threshold (default: < 60s/1m)" +msgstr "提前跳过片头阈值(默认:< 60s/1m)" + +#: +msgctxt "#33510" +msgid "When showing the intro skip button early, only do so if the intro occurs within the first X seconds." +msgstr "何时提前显示跳过片头按钮,仅在片头出现在前 X 秒内时才这样做。" + +#: +msgctxt "#33600" +msgid "System" +msgstr "系统" + +#: +msgctxt "#33601" +msgid "Show video chapters" +msgstr "显示视频章节" + +#: +msgctxt "#33602" +msgid "If available, show video chapters from the video-file instead of the timeline-big-seek-steps." +msgstr "如果可用,从视频文件中获取视频章节,而不是从时间线生成。" + +#: +msgctxt "#33603" +msgid "Use virtual chapters" +msgstr "使用虚拟章节" + +#: +msgctxt "#33604" +msgid "When the above is enabled and no video chapters are available, simulate them by using the markers identified by the Plex Server (Intro, Credits)." +msgstr "当上述功能已启用但并没有可用的视频章节时,使用 Plex 服务器识别的标记(片头、片尾)来模拟它们。" + +#: +msgctxt "#33605" +msgid "Video Chapters" +msgstr "视频章节" + +#: +msgctxt "#33606" +msgid "Virtual Chapters" +msgstr "虚拟章节" + +#: +msgctxt "#33607" +msgid "Chapter {}" +msgstr "章节 {}" + +#: +msgctxt "#33608" +msgid "Intro" +msgstr "片头" + +#: +msgctxt "#33609" +msgid "Credits" +msgstr "片尾" + +#: +msgctxt "#33610" +msgid "Main" +msgstr "正片" + +#: +msgctxt "#33611" +msgid "Chapters" +msgstr "章节" + +#: +msgctxt "#33612" +msgid "Markers" +msgstr "标记" + +#: +msgctxt "#33613" +msgid "Kodi Buffer Size (MB)" +msgstr "Kodi 缓存大小(MB)" + +#: +msgctxt "#33614" +msgid "Set the Kodi Cache/Buffer size. Free: {} MB, Recommended: ~50 MB, Recommended max: {} MB, Default: 20 MB." +msgstr "设置 Kodi 缓存/缓冲大小。空闲:{} MB,推荐:~50 MB,推荐最大值:{} MB,默认:20 MB。" + +#: +msgctxt "#33615" +msgid "{time} left" +msgstr "剩余 {time}" + +#: +msgctxt "#33616" +msgid "Addon Path" +msgstr "插件路径" + +#: +msgctxt "#33617" +msgid "Userdata/Profile Path" +msgstr "用户数据/配置文件路径" + +#: +msgctxt "#33618" +msgid "TV binge-viewing mode" +msgstr "追剧模式" + +#: +msgctxt "#33619" +msgid "Automatically skips episode intros, credits and tries to skip episode recaps. Doesn't skip the intro of the first episode of a season and doesn't skip the final credits of a show.\n" +"\n" +"Can be disabled/enabled per TV show.\n" +"Overrides any setting below." +msgstr "自动跳过片头、片尾,并尝试跳过剧集回顾。不跳过每季第一集的片头,不跳过电视节目的最后一个片尾。\n" +"\n" +"可以单独为每个电视节目禁用/启用。\n" +"覆盖任何以下设置。" + +#: +msgctxt "#33620" +msgid "Plex server connect timeout" +msgstr "Plex 服务器连接超时" + +#: +msgctxt "#33621" +msgid "Sets the maximum amount of time to connect to a Plex Server in seconds. Default: 5" +msgstr "设置尝试连接 Plex 服务器的最长时间(以秒为单位)。默认:5" + +#: +msgctxt "#33622" +msgid "LAN reachability timeout (ms)" +msgstr "局域网可达性超时时间(毫秒)" + +#: +msgctxt "#33623" +msgid "When checking for LAN reachability, use this timeout. Default: 10ms" +msgstr "在检查局域网可达性时,使用此超时时间。默认值:10 毫秒" + +#: +msgctxt "#33624" +msgid "Network" +msgstr "网络" + +#: +msgctxt "#33625" +msgid "Smart LAN/local server discovery" +msgstr "智能发现局域网/本地服务器" + +#: +msgctxt "#33626" +msgid "Checks whether servers returned from Plex.tv are actually local/in your LAN. For specific setups (e.g. Docker) Plex.tv might not properly detect a local server.\n" +"\n" +"NOTE: Only works on Kodi 19 or above." +msgstr "检查从 Plex.tv 返回的服务器是否是本地的/在您的局域网中。对于特定设置(例如 Docker),Plex.tv 可能无法正确检测到本地服务器。\n" +"\n" +"注意:仅适用于 Kodi 19 或更高版本。" + +#: +msgctxt "#33627" +msgid "Prefer LAN/local servers over security" +msgstr "优先使用局域网/本地服务器而不是安全连接" + +#: +msgctxt "#33628" +msgid "Prioritizes local connections over secure ones. Needs the proper setting in \"Allow Insecure Connections\" and the Plex Server's \"Secure connections\" at \"Preferred\". Can be used to enforce manual servers." +msgstr "优先考虑本地连接而不是安全连接。需要在 “允许不安全连接” 和 Plex 服务器的 “首选安全连接” 中进行适当设置。可用于强制手动服务器。" + +#: +msgctxt "#33629" +msgid "Auto-skip intro/credits offset" +msgstr "自动跳过片头/片尾的偏移时间" + +#: +msgctxt "#33630" +msgid "Intro/credits markers might be a little early in Plex. When auto skipping add (or subtract) this many seconds from the marker. This avoids cutting off content, while possibly skipping the marker a little late." +msgstr "Plex 中的片头/片尾标记可能会有些提前。在自动跳过时从标记中增加(或减少)对应的秒数。可以避免错过内容,也可能会延迟跳过标记的时间。" + +#: +msgctxt "#32631" +msgid "Playback (user-specific)" +msgstr "播放(用户自定义)" + +#: +msgctxt "#33632" +msgid "Server connectivity check timeout (seconds)" +msgstr "服务器连接检查超时时间(秒)" + +#: +msgctxt "#33633" +msgid "Set the maximum amount of time a server connection has to answer a connectivity request. Default: 2.5" +msgstr "设置服务器连接必须响应连接请求的最长时间。默认:2.5" + +#: +msgctxt "#33634" +msgid "Combined Chapters" +msgstr "合并章节" + +#: +msgctxt "#33635" +msgid "Final Credits" +msgstr "最后一个片尾" + +#: +msgctxt "#32700" +msgid "Action on Sleep event" +msgstr "睡眠事件触发的操作" + +#: +msgctxt "#32701" +msgid "When Kodi receives a sleep event from the system, run the following action." +msgstr "当 Kodi 从系统接收到睡眠事件时,执行以下操作。" + +#: +msgctxt "#32702" +msgid "Nothing" +msgstr "无" + +#: +msgctxt "#32703" +msgid "Stop playback" +msgstr "停止播放" + +#: +msgctxt "#32704" +msgid "Quit Kodi" +msgstr "退出 Kodi" + +#: +msgctxt "#32705" +msgid "CEC Standby" +msgstr "CEC 待机" + +#: +msgctxt "#32800" +msgid "Skipping intro" +msgstr "跳过片头" + +#: +msgctxt "#32801" +msgid "Skipping credits" +msgstr "跳过片尾" + +#: +msgctxt "#32900" +msgid "While playing back an item and seeking on the seekbar, automatically seek to the selected position after a delay instead of having to confirm the selection." +msgstr "播放项目并在进度条上移动位置时,在延迟后自动定位到选定的位置,无需确认选择。" + +#: +msgctxt "#32901" +msgid "Seek delay in seconds." +msgstr "进度条定位延迟(秒)。" + +#: +msgctxt "#32902" +msgid "Kodi has its own skip step settings. Try to use them if they're configured instead of the default ones." +msgstr "Kodi 有自己的跳过设置。如果已配置,请尝试使用它们,而不是默认设置。" + +#: +msgctxt "#32903" +msgid "Use the above for seeking on the timeline as well." +msgstr "将上述设置应用到时间线定位。" + +#: +msgctxt "#32904" +msgid "In seconds." +msgstr "以秒为单位。" + +#: +msgctxt "#32905" +msgid "Cancel post-play timer by pressing OK/SELECT" +msgstr "按确认/选择键取消播放完毕后的倒计时" + +#: +msgctxt "#32906" +msgid "Cancel skip marker timer with BACK" +msgstr "按返回键取消跳过按钮倒计时" + +#: +msgctxt "#32907" +msgid "When auto-skipping a marker, allow cancelling the timer by pressing BACK." +msgstr "在自动跳过标记时,允许通过按返回键取消倒计时。" + +#: +msgctxt "#32908" +msgid "Immediately skip marker with OK/SELECT" +msgstr "按确认/选择键立刻跳过标记。" + +#: +msgctxt "#32909" +msgid "When auto-skipping a marker with a timer, allow skipping immediately by pressing OK/SELECT." +msgstr "在自动跳过带有倒计时的标记时,允许通过按确认/选择键立刻跳过。" + +#: +msgctxt "#32912" +msgid "Show buffer-state on timeline" +msgstr "在进度条上显示缓冲状态" + +#: +msgctxt "#32913" +msgid "Shows the current Kodi buffer/cache state on the video player timeline." +msgstr "在视频播放器的进度条上显示当前 Kodi 的缓冲/缓存状态。" + +#: +msgctxt "#32914" +msgid "Loading" +msgstr "加载中" + +#: +msgctxt "#32915" +msgid "Slow connection" +msgstr "连接缓慢" + +#: +msgctxt "#32916" +msgid "Use with a wonky/slow connection, e.g. in a hotel room. Adjusts the UI to visually wait for item refreshes and waits for the buffer to fill when starting playback. Automatically sets readfactor=20, requires Kodi restart." +msgstr "在连接不稳定/缓慢的情况下使用,例如在酒店房间。在播放项目时优化项目刷新和缓冲加载的 UI 显示。自动将缓存读取比例设置为 20,重启 Kodi 后生效。" + +#: +msgctxt "#32917" +msgid "Couldn't fill buffer in time ({}s)" +msgstr "无法在指定时间内完成缓冲({} 秒)" + +#: +msgctxt "#32918" +msgid "Buffer wait timeout (seconds)" +msgstr "缓冲等待超时时间(秒)" + +#: +msgctxt "#32919" +msgid "When slow connection is enabled in the addon, wait this long for the buffer to fill. Default: 120 s" +msgstr "当插件启用缓慢连接时,等待指定时长来完成缓冲。默认:120 秒" + +#: +msgctxt "#32920" +msgid "Insufficient buffer wait (seconds)" +msgstr "缓冲等待时间不足(秒)" + +#: +msgctxt "#32921" +msgid "When slow connection is enabled in the addon and the configured buffer isn't big enough for us to determine its fill state, wait this long when starting playback. Default: 10 s" +msgstr "当插件启用缓慢连接并且配置的缓冲区不足以判断缓冲状态时,等待指定时长后再开始播放。默认:10 秒" + +#: +msgctxt "#32922" +msgid "Kodi Cache Readfactor" +msgstr "Kodi 缓存读取比例" + +#: +msgctxt "#32923" +msgid "Sets the Kodi cache readfactor value. Default: {0}, recommended: {1}. With \"Slow connection\" enabled this will be set to {2}, as otherwise the cache doesn't fill fast/aggressively enough." +msgstr "设置 Kodi 缓存读取比例的值。默认:{0},推荐:{1}。启用 “缓慢连接” 时将设置为 {2},否则缓冲速度将会不足。" + +#: +msgctxt "#32924" +msgid "Minimize" +msgstr "最小化" + +#: +msgctxt "#32925" +msgid "Playback Settings" +msgstr "播放设置" + +#: +msgctxt "#32926" +msgid "Wrong pin entered!" +msgstr "输入的 PIN 码有误!" + +#: +msgctxt "#32927" +msgid "Use episode thumbnails in continue hub" +msgstr "在继续观看中使用剧集缩略图" + +#: +msgctxt "#32928" +msgid "Instead of using media artwork, use thumbnails for episodes in the continue hub on the home screen if available." +msgstr "如果存在剧集缩略图,就在主页的继续观看中使用剧集缩略图而不是背景图片。" + +#: +msgctxt "#32929" +msgid "Use legacy background fallback image" +msgstr "使用经典背景作为备用图片" + +#: +msgctxt "#32930" +msgid "Previous Subtitle" +msgstr "上一个字幕" + +#: +msgctxt "#32931" +msgid "Audio/Subtitles" +msgstr "音频/字幕" + +#: +msgctxt "#32932" +msgid "Subtitle quick-actions" +msgstr "字幕快捷操作" + +#: +msgctxt "#32933" +msgid "FFWD/RWD" +msgstr "快进/快退" + +#: +msgctxt "#32934" +msgid "Repeat" +msgstr "循环播放" + +#: +msgctxt "#32935" +msgid "Shuffle" +msgstr "随机播放" + +#: +msgctxt "#32936" +msgid "Show playlist button" +msgstr "显示播放列表按钮" + +#: +msgctxt "#32937" +msgid "Show prev/next button" +msgstr "显示上一个/下一个按钮" + +#: +msgctxt "#32939" +msgid "User-specific.\nOnly applies to video player UI" +msgstr "用户自定义。\n仅适用于视频播放器界面" + +#: +msgctxt "#32940" +msgid "Video Player" +msgstr "视频播放器" + +#: +msgctxt "#32941" +msgid "Forced subtitles fix" +msgstr "强制字幕修复" + +#: +msgctxt "#32942" +msgid "Other seasons" +msgstr "其他季" + +#: +msgctxt "#32943" +msgid "Crossfade dynamic background art" +msgstr "渐变动态背景图片" + +#: +msgctxt "#32944" +msgid "Burn-in SSA subtitles (DirectStream)" +msgstr "烧录 SSA 字幕(直接串流)" + +#: +msgctxt "#32945" +msgid "When Direct Streaming instruct the Plex Server to burn in SSA/ASS subtitles (thus transcoding the video stream). If disabled it will not touch the video stream, but will convert the subtitle to unstyled text." +msgstr "在直接串流播放时,指示 Plex 服务器烧录 SSA/ASS 字幕(转码视频流)。如果禁用,则不会更改视频流,而是将字幕转换为无样式的文本字幕。" + +#: +msgctxt "#32946" +msgid "Stop video playback on idle after" +msgstr "空闲时停止视频播放" + +#: +msgctxt "#32947" +msgid "Stop video playback on screensaver" +msgstr "屏保时停止视频播放" + +#: +msgctxt "#32948" +msgid "Allow auto-skip when transcoding" +msgstr "允许在转码时自动跳过" + +#: +msgctxt "#32949" +msgid "When transcoding/DirectStreaming, allow auto-skip functionality." +msgstr "在转码/直接串流时,允许自动跳过功能。" + +#: +msgctxt "#32950" +msgid "Use extended title for subtitles" +msgstr "使用字幕的扩展标题" + +#: +msgctxt "#32951" +msgid "When displaying subtitles use the extendedDisplayTitle Plex exposes." +msgstr "使用 Plex 提供的 extendedDisplayTitle 作为字幕标题。" + +#: +msgctxt "#32953" +msgid "Reviews" +msgstr "评论" + +#: +msgctxt "#32954" +msgid "Needs Kodi restart. WARNING: This will overwrite advancedsettings.xml!\n" +"\n" +"To customize other cache/network-related values, copy \"script.plexmod/pm4k_cache_template.xml\" to profile folder and edit it to your liking. (See About section for the file paths)" +msgstr "需要重启 Kodi。警告:advancedsettings.xml 将会被覆盖!\n" +"\n" +"要自定义其他缓存/网络相关的值,请将 “script.plexmod/pm4k_cache_template.xml” 复制到配置文件夹并根据需要进行编辑。(请查阅相关内容获取文件路径)" + +#: +msgctxt "#32955" +msgid "Use Kodi keyboard for searching" +msgstr "使用 Kodi 键盘进行搜索" + +#: +msgctxt "#32956" +msgid "Poster resolution scaling %" +msgstr "海报分辨率缩放百分比" + +#: +msgctxt "#32957" +msgid "In percent. Scales the resolution of all posters/thumbnails for better image quality. May impact PMS/PM4K performance, will increase the cache usage accordingly. Recommended: 200-300 % for for big screens if your hardware can handle it. Needs addon restart." +msgstr "按百分比。缩放所有海报/缩略图的分辨率以获得更好的图像质量。可能会影响 PMS/PM4K 的性能,并增加缓存使用量。推荐:对于大屏幕,如果硬件能够处理,可设置为 200-300%。需要重启插件。" + +#: +msgctxt "#32958" +msgid "Calculate OpenSubtitles.com hash" +msgstr "计算 OpenSubtitles.com 的哈希值" + +#: +msgctxt "#32959" +msgid "When opening the subtitle download feature, automatically calculate the OpenSubtitles.com hash for the given file. Can improve search results, downloads 2*64 KB of the video file to calculate the hash." +msgstr "启用字幕下载功能时,自动计算指定文件的 OpenSubtitles.com 哈希值。为了优化搜索结果,需要下载 2*64 KB 的视频文件来计算哈希值。" + +#: +msgctxt "#32960" +msgid "Similar Artists" +msgstr "相似的艺人" + +#: +msgctxt "#32961" +msgid "Show hub bifurcation lines" +msgstr "显示内容版块分隔线" + +#: +msgctxt "#32962" +msgid "Visually separate hubs horizontally using a thin line." +msgstr "通过细线在视觉上水平分隔内容版块。" + +#: +msgctxt "#32963" +msgid "Wait between videos (s)" +msgstr "视频之间的等待时间(秒)" + +#: +msgctxt "#32964" +msgid "When playing back consecutive videos (e.g. TV shows), wait this long before starting the next one in the queue. Might fix compatibility issues with certain configurations." +msgstr "在播放连续视频(例如电视节目)时,等待指定时长再开始播放队列中的下一个视频。可能会修复某些配置的兼容性问题。" + +#: +msgctxt "#32965" +msgid "Quit Kodi on exit by default" +msgstr "默认退出时退出 Kodi" + +#: +msgctxt "#32966" +msgid "When exiting the addon, use \"Quit Kodi\" as default option. Can be dynamically switched using CONTEXT_MENU (often longpress SELECT)" +msgstr "退出插件时,使用 “退出 Kodi” 作为默认选项。可以使用右键菜单(通常是长按 SELECT)切换" + +#: +msgctxt "#32967" +msgid "Kodi Colour Management" +msgstr "Kodi 颜色管理" + +#: +msgctxt "#32968" +msgid "Kodi Resolution Settings" +msgstr "Kodi 分辨率设置" + +#: +msgctxt "#32969" +msgid "Always request all library media items at once" +msgstr "始终一次性请求所有库媒体项目" + +#: +msgctxt "#32970" +msgid "Retrieve all media in library up front instead of fetching it in chunks as the user navigates through the library" +msgstr "预先检索库中的所有媒体,而不是在用户浏览库时分批获取" + +#: +msgctxt "#32971" +msgid "Library item-request chunk size" +msgstr "库项目请求块大小" + +#: +msgctxt "#32972" +msgid "Request this amount of media items per chunk request in library view (+6-30 depending on view mode; less can be less straining for the UI at first, but puts more strain on the server)" +msgstr "在库视图中,每次请求块请求的媒体项目数量(+6-30 取决于视图模式;较少可能更灵敏;较多可能更快加载大型库)" + +#: +msgctxt "#32973" +msgid "Episodes: Skip Post Play screen" +msgstr "剧集:跳过播放结束界面" + +#: +msgctxt "#32974" +msgid "When finishing an episode, don't show Post Play but go to the next one immediately.\n" +"Can be disabled/enabled per TV show. Doesn't override enabled binge mode. Overrides the Post Play setting." +msgstr "在剧集播放结束时,不显示播放结束界面,而是立刻播放下一集。\n" +"可以单独为每个电视节目禁用/启用。不会覆盖启用的追剧模式。会覆盖播放结束设置。" + +#: +msgctxt "#32975" +msgid "Delete Season" +msgstr "删除季" + +#: +msgctxt "#32976" +msgid "Adaptive" +msgstr "自适应" + +#: +msgctxt "#32977" +msgid "VC1" +msgstr "VC1" + +#: +msgctxt "#32978" +msgid "Enable this if your hardware can handle VC1. Disable it to force transcoding." +msgstr "如果您的硬件支持 VC1,请启用此选项。禁用会强制转码。" + +#: +msgctxt "#32979" +msgid "Allows the server to only transcode streams of a video that need transcoding, while streaming the others unaltered. If disabled, force the server to transcode everything not direct playable." +msgstr "允许服务器仅转码需要被转码的视频流,同时不改变其他流的传输。如果禁用,则会强制服务器转码所有不能直接播放的内容。" + +#: +msgctxt "#32980" +msgid "Refresh Users" +msgstr "刷新用户" + +#: +msgctxt "#32981" +msgid "Background worker count" +msgstr "后台工作线程数" + +#: +msgctxt "#32982" +msgid "Depending on how many cores your CPU has and how much it can handle, increasing this might improve certain situations. If you experience crashes or other annormalities, leave this at its default (3). Needs an addon restart." +msgstr "根据您的 CPU 核心数及其处理能力,增加此值可能会改善某些使用场景的体验。如果您遇到崩溃或其他异常情况,请使用默认值(3)。重启插件后生效。" + +#: +msgctxt "#32983" +msgid "Theme" +msgstr "主题" + +#: +msgctxt "#32984" +msgid "Sets the theme. Currently only customizes all control buttons. ATTENTION: [I]Might[/I] need an addon restart.\n" +"In order to customize this, copy one of the xml's in script.plexmod/resources/skins/Main/1080i/templates to addon_data/script.plexmod/templates/{templatename}_custom.xml and adjust it to your liking, then select \"Custom\" as your theme." +msgstr "设置主题。目前仅支持自定义控制按钮。注意:[I]可能[/I]需要重启插件。\n" +"要自定义此项,请将 script.plexmod/resources/skins/Main/1080i/templates 中的一个 XML 文件复制到 addon_data/script.plexmod/templates/{templatename}_custom.xml 并根据您的喜好进行调整,然后选择 “自定义” 作为主题。" + +#: +msgctxt "#32985" +msgid "Modern" +msgstr "现代" + +#: +msgctxt "#32986" +msgid "Modern (dotted)" +msgstr "现代(波点)" + +#: +msgctxt "#32987" +msgid "Classic" +msgstr "经典" + +#: +msgctxt "#32988" +msgid "Custom" +msgstr "自定义" + +#: +msgctxt "#32989" +msgid "Modern (colored)" +msgstr "现代(彩色)" + +#: +msgctxt "#32990" +msgid "Handle plex.direct mapping" +msgstr "处理 plex.direct 映射" + +#: +msgctxt "#32991" +msgid "Notify" +msgstr "通知" + +#: +msgctxt "#32992" +msgid "When using servers with a plex.direct connection (most of them), should we automatically adjust advancedsettings.xml to cope with plex.direct domains? If not, you might want to add plex.direct to your router's DNS rebind exemption list." +msgstr "当使用带有 plex.direct 连接的服务器(大部分服务器)时,是否自动调整 advancedsettings.xml 以应对 plex.direct 域名?如果不这样做,您可能需要将 plex.direct 添加到路由器的 DNS 重新绑定豁免列表中。" + +#: +msgctxt "#32993" +msgid "{} unhandled plex.direct connections found" +msgstr "发现 {} 个未处理的 plex.direct 连接" + +#: +msgctxt "#32994" +msgid "In order for PM4K to work properly, we need to add special handling for plex.direct connections. We've found {} new unhandled connections. Do you want us to write those to Kodi's advancedsettings.xml automatically? If not, you might want to add plex.direct to your router's DNS rebind exemption list. This can be changed in the settings as well." +msgstr "为了使 PM4K 正常工作,我们需要为 plex.direct 连接添加特殊处理。我们发现了 {} 个新的未处理连接。您是否希望我们自动将这些写入 Kodi 的advancedsettings.xml?如果不这样做,您可能需要将 plex.direct 添加到路由器的 DNS 重新绑定豁免列表中。此项也可以在设置中更改。" + +#: +msgctxt "#32995" +msgid "Advancedsettings.xml modified (plex.direct mappings)" +msgstr "Advancedsettings.xml 已修改(plex.direct 映射)" + +#: +msgctxt "#32996" +msgid "The advancedsettings.xml file has been modified. Please restart Kodi for the changes to apply." +msgstr "Advancedsettings.xml 文件已被修改。请重新启动 Kodi 以应用更改。" + +#: +msgctxt "#32997" +msgid "OK" +msgstr "确认" + +#: +msgctxt "#32998" +msgid "Use new Continue Watching hub on Home" +msgstr "在主页使用新版继续观看" + +#: +msgctxt "#32999" +msgid "Instead of separating Continue Watching and On Deck hubs, behave like the modern Plex clients, which combine those two types of hubs into one Continue Watching hub." +msgstr "使用现代 Plex 客户端的风格,将继续观看和待播项目合并为继续观看显示。" + +#: +msgctxt "#33000" +msgid "Enable path mapping" +msgstr "启用路径映射" + +#: +msgctxt "#33001" +msgid "Long-press (or context menu) on a library item or: Honor path_mapping.json in the addon_data/script.plexmod folder when DirectPlaying media. This can be used to stream using other techniques such as SMB/NFS/etc. instead of the default HTTP handler. path_mapping.example.json is included in the addon's main directory." +msgstr "长按(或右键菜单)库项目或:在 DirectPlaying 媒体时遵循 addon_data/script.plexmod 文件夹中的 path_mapping.json。这可以用于使用 SMB/NFS 等其他技术进行流式传输,而不是默认的 HTTP 处理程序。path_mapping.example.json 包含在插件的主目录中。" + +#: +msgctxt "#33002" +msgid "Verify mapped files exist" +msgstr "验证映射文件是否存在" + +#: +msgctxt "#33003" +msgid "When path mapping is enabled and we've successfully mapped a file, verify its existence." +msgstr "在启用路径映射并且成功映射文件时,验证文件是否存在。" + +#: +msgctxt "#33004" +msgid "No spoilers without OSD" +msgstr "没有屏幕菜单时不显示剧透" + +#: +msgctxt "#33005" +msgid "When seeking without the OSD open, hide all time-related information from the user." +msgstr "在未打开屏幕菜单并进行搜索时,隐藏所有与时间相关的信息。" + +#: +msgctxt "#33006" +msgid "No TV spoilers" +msgstr "无剧透" + +#: +msgctxt "#33007" +msgid "Select in which cases to blur TV episode thumbnails, previews, redact summaries, hide episode titles and whether to blur chapter images. When the Addon Setting \"Use episode thumbnails in continue hub\" is enabled, blur them as well." +msgstr "选择在哪些情况下模糊电视节目的剧集缩略图、预览、简介、隐藏剧集标题以及是否模糊章节图像。即使在插件设置种启用了 “在继续观看使用剧集缩略图”,也会模糊它们。" + +#: +msgctxt "#33008" +msgid "[Spoilers removed]" +msgstr "[剧透已移除]" + +#: +msgctxt "#33009" +msgid "Blur amount for unwatched/in-progress episodes" +msgstr "未观看/观看中剧集的缩略图的模糊程度" + +#: +msgctxt "#33010" +msgid "Unwatched" +msgstr "未观看" + +#: +msgctxt "#33011" +msgid "In progress" +msgstr "观看中" + +#: +msgctxt "#33012" +msgid "No unwatched episode titles" +msgstr "无未观看的剧集" + +#: +msgctxt "#33013" +msgid "When the above is anything but \"off\", hide episode titles as well." +msgstr "当上述选项非 “关闭” 时,同时隐藏剧集标题。" + +#: +msgctxt "#33014" +msgid "Ignore plex.direct docker hosts" +msgstr "忽略 plex.direct docker 主机" + +#: +msgctxt "#33015" +msgid "When checking for plex.direct host mapping, ignore local Docker IPv4 addresses (172.16.0.0/12)." +msgstr "在检查 plex.direct 主机映射时,忽略本地 Docker IPv4 地址(172.16.0.0/12)。" + +#: +msgctxt "#33016" +msgid "Allow TV spoilers for" +msgstr "允许剧透" + +#: +msgctxt "#33017" +msgid "Overrides the above for specific genres. Default: Reality, Game Show, Documentary, Sport" +msgstr "为指定类型的电视节目应用上述设置。默认:真人秀、游戏、纪录片、体育" + +#: +msgctxt "#32303" +msgid "Season {}" +msgstr "第{}季" + +#: +msgctxt "#32304" +msgid "Episode {}" +msgstr "第{}集" + +#: +msgctxt "#32310" +msgid "S{}" +msgstr "第{}季" + +#: +msgctxt "#32311" +msgid "E{}" +msgstr "第{}集" + +#: +msgctxt "#32938" +msgid "Only for Episodes/Playlists" +msgstr "仅适用于剧集/播放列表" + +#: +msgctxt "#33018" +msgid "Cache Plex Home users" +msgstr "缓存 Plex 家庭用户" + +#: +msgctxt "#33019" +msgid "Visit media item" +msgstr "访问媒体项目" + +#: +msgctxt "#33020" +msgid "Play" +msgstr "播放" + +#: +msgctxt "#33021" +msgid "Choose action" +msgstr "选择操作" + +#: +msgctxt "#33022" +msgid "Watched indicators" +msgstr "观看状态角标" + +#: +msgctxt "#33023" +msgid "Classic: Show orange triangle for unwatched items\n" +"Modern: Show green checkmark for watched items\n" +"Modern (2024): Show white checkmark for watched items\n" +"(default: Modern (2024))" +msgstr "经典:为未观看的项目显示橙色三角形角标\n" +"现代:为已观看的项目显示绿色对钩角标\n" +"现代(2024):为已观看的项目显示白色对钩角标\n" +"(默认:现代(2024))" + +#: +msgctxt "#33024" +msgid "Hide background in modern indicators" +msgstr "为现代角标隐藏背景" + +#: +msgctxt "#33025" +msgid "When the above is enabled, hide the black backdrop of the watched state." +msgstr "启用上述功能时,隐藏观看状态角标的黑色背景。" + +#: +msgctxt "#33026" +msgid "Map path: {}" +msgstr "映射路径:{}" + +#: +msgctxt "#33027" +msgid "Remove mapping: {}" +msgstr "移除映射:{}" + +#: +msgctxt "#33028" +msgid "Hide library" +msgstr "隐藏资料库" + +#: +msgctxt "#33029" +msgid "Show library: {}" +msgstr "显示资料库:{}" + +#: +msgctxt "#33030" +msgid "Choose action for: {}" +msgstr "为 {} 选择操作" + +#: +msgctxt "#33031" +msgid "Select Kodi source for {}" +msgstr "为 {} 选择 Kodi 源" + +#: +msgctxt "#33032" +msgid "Show path mapping indicators" +msgstr "显示路径映射指示器" + +#: +msgctxt "#33033" +msgid "When path mapping is active for a library, display an indicator." +msgstr "当路径映射在库中激活时,显示指示器。" + +#: +msgctxt "#33035" +msgid "Delete {}: {}?" +msgstr "删除 {}:{}?" + +#: +msgctxt "#33036" +msgid "Delete episode S{0:02d}E{1:02d} from {2}?" +msgstr "删除 {2} 第 {0:02d} 季的第 {1:02d} 集?" + +#: +msgctxt "#33037" +msgid "Maximum intro offset to consider" +msgstr "最大片头偏移量" + +#: +msgctxt "#33038" +msgid "When encountering an intro marker with a start time offset greater than this, ignore it (default: 600s/10m)" +msgstr "当遇到开始时间偏移量大于此值的片头标记时,忽略它(默认:600 秒/10 分钟)" + +#: +msgctxt "#33039" +msgid "Move" +msgstr "移动" + +#: +msgctxt "#33040" +msgid "Reset library order" +msgstr "重置资料库顺序" + +#: +msgctxt "#33034" +msgid "Library settings" +msgstr "资料库设置" + +#: +msgctxt "#33041" +msgid "Show hub: {}" +msgstr "显示内容版块:{}" + +#: +msgctxt "#33042" +msgid "Episode Date Added" +msgstr "剧集添加日期" + +#: +msgctxt "#33043" +msgid "Hubs round-robin" +msgstr "内容版块循环" + +#: +msgctxt "#33044" +msgid "Allow round-robining in hubs. Attention: Loads a lot of items. Depending on the hub size, this can lead to crashes. Current limit: {}; can be adjusted in addon settings." +msgstr "允许内容版块循环显示项目。注意:会加载大量项目。根据版块内容的多少,有可能导致崩溃。当前限制:{};可以在插件设置中进行调整。" + +#: +msgctxt "#33045" +msgid "Behave like official Plex clients" +msgstr "遵循 Plex 官方客户端" + +#: +msgctxt "#33046" +msgid "When pressing up/down while the OSD isn't shown, show OSD instead of skipping chapters. Additionally, when pressing down while the OSD is shown, open the chapters (if available)." +msgstr "在未显示屏幕菜单时,按上下键显示屏幕菜单而不是章节。同时,在显示屏幕菜单时,按下键打开章节(如果有)。" + +#: +msgctxt "#32036" +msgid "4K" +msgstr "4K" + +#: +msgctxt "#32037" +msgid "HEVC (h265)" +msgstr "HEVC (h265)" + +#: +msgctxt "#32601" +msgid "AV1" +msgstr "AV1" + +#: +msgctxt "#33047" +msgid "Hubs round-robin item limit" +msgstr "内容版块循环项目数量限制" + +#: +msgctxt "#33048" +msgid "When hubs round-robin is enabled, only round-robin until this item limit. If the hub size exceeds this limit, the remaining items will be lazy loaded as usual. Tested minimum safe value on NVIDIA SHIELD 2019 is 1000. Default: 250" +msgstr "在启用内容版块循环时,仅循环数量限制以内的项目。如果版块项目超过此限制,剩余项目将延迟加载。NVIDIA SHIELD 2019 上测试的最小安全值为 1000。默认值:250" + +#: +msgctxt "#33049" +msgid "Max retries" +msgstr "最大重试次数" + +#: +msgctxt "#33050" +msgid "The maximum number of retries each connection should attempt. The default (3) helps with hibernation/wakeup issues. Set higher for bad connections, setting this to 0 was the old default before 0.7.9" +msgstr "每次连接可尝试的最大重试次数。默认值(3)有助于解决休眠/唤醒问题。若连接情况不佳,可以设置的大一些。版本 0.7.9 之前的默认值为 0" + +#: +msgctxt "#33051" +msgid "Use CA certificate bundle" +msgstr "使用 CA 证书包" + +#: +msgctxt "#33052" +msgid "Which CA certificate bundle to use for request HTTPS verification. Default is \"system\", which uses the system-provided certificate bundle. \"plex.direct\" uses an extremely small bundle provided with the addon, which only applies to plex.direct connections (any other connections will use the system bundle) and might slightly improve performance. \"custom\" allows for a certificate bundle in userdata/addon_data/script.plexmod/custom_bundle.crt" +msgstr "用于请求 HTTPS 验证的 CA 证书包。默认是 “系统”,使用系统提供的证书包。“plex.direct” 使用插件提供的极小包,仅适用于 plex.direct 连接(任何其他连接将使用系统包),可能略微提高性能。“自定义” 允许在 userdata/addon_data/script.plexmod/custom_bundle.crt 中使用证书包。" + +#: +msgctxt "#33053" +msgid "System" +msgstr "系统" + +#: +msgctxt "#33054" +msgid "plex.direct (addon-supplied)" +msgstr "plex.direct(插件提供)" + +#: +msgctxt "#33055" +msgid "Custom" +msgstr "自定义" + +#: +msgctxt "#33056" +msgid "None" +msgstr "无" + +#: +msgctxt "#33057" +msgid "Show buttons" +msgstr "显示按钮" + +#: +msgctxt "#33058" +msgid "Playback features" +msgstr "播放功能" + +#: +msgctxt "#33059" +msgid "Additional codecs" +msgstr "附加编解码器" + +#: +msgctxt "#33060" +msgid "{feature_ds}: {desc_ds}\n" +"{feature_4k}: {desc_4k}" +msgstr "{feature_ds}:{desc_ds}\n" +"{feature_4k}:{desc_4k}" + +#: +msgctxt "#33061" +msgid "Enable certain codecs if your hardware supports them. Disable them to force transcoding." +msgstr "如果您的硬件支持,启用某些编解码器。禁用会强制转码。" + +#: +msgctxt "#33062" +msgid "Compiling templates" +msgstr "编译模板" + +#: +msgctxt "#33063" +msgid "Looking for custom templates" +msgstr "寻找自定义模板" + +#: +msgctxt "#33064" +msgid "Rendering: {}" +msgstr "渲染:{}" + +#: +msgctxt "#33065" +msgid "Complete" +msgstr "完成" + +#: +msgctxt "#33066" +msgid "Cache template files" +msgstr "缓存模板文件" + +#: +msgctxt "#33067" +msgid "Doesn't throw away the template source files after compiling them. Uses slightly more memory but increases the speed of theme-related changes." +msgstr "编译后不丢弃模板源文件。使用的内存略多,但增加了主题相关更改的速度。" + +#: +msgctxt "#33068" +msgid "Always compile templates" +msgstr "始终编译模板" + +#: +msgctxt "#33069" +msgid "Recompiles all templates on every startup. Useful for template/theme development." +msgstr "每次启动时重新编译所有模板。对模板/主题开发非常有用。" + +#: +msgctxt "#33070" +msgid "Action on Wake event" +msgstr "唤醒事件的操作" + +#: +msgctxt "#33071" +msgid "Restart PM4K" +msgstr "重启 PM4K" + +#: +msgctxt "#33072" +msgid "Wait for {}s" +msgstr "等待 {} 秒" + +#: +msgctxt "#33073" +msgid "Wait after wakeup" +msgstr "唤醒后等待" + +#: +msgctxt "#33074" +msgid "Waiting {} second(s)" +msgstr "等待 {} 秒" + +#: +msgctxt "#33075" +msgid "Do something after waking up. Waiting for a time until resuming normal execution helps with networks coming back up after sleep events. Default: 1 second (5 seconds, CoreELEC)." +msgstr "唤醒后执行一些操作。等待一段时间后恢复正常操作有助于网络在休眠事件后恢复。默认:1 秒(5 秒,CoreELEC)" + +#: +msgctxt "#33076" +msgid "Modern (2024)" +msgstr "现代(2024)" + +#: +msgctxt "#33077" +msgid "Scale modern indicators" +msgstr "缩放现代角标" + +#: +msgctxt "#33078" +msgid "Scale the modern indicators based on the poster size used. Default: On (tiny: 0.75, small: 1.0, medium: 1.175, big: 1.3)" +msgstr "根据所使用的海报尺寸缩放现代角标。默认:开(最小:0.75,小:1.0,中:1.175,大:1.3)" + +#: +msgctxt "#33079" +msgid "Hi-Res Music" +msgstr "Hi-Res 音乐" + +#: +msgctxt "#33080" +msgid "Allow DirectPlay of high resolution music (e.g. FLAC, >= 192 kHz)" +msgstr "允许直接播放高解析音乐(例如 FLAC,>= 192 kHz)" + +#: +msgctxt "#33081" +msgid "Blur chapter images" +msgstr "模糊章节图片" + +#: +msgctxt "#33082" +msgid "Scan Library Files" +msgstr "扫描资料库文件" + +#: +msgctxt "#33083" +msgid "Empty Trash" +msgstr "清空回收站" + +#: +msgctxt "#33084" +msgid "Analyze" +msgstr "分析" + +#: +msgctxt "#33085" +msgid "Map key to home" +msgstr "映射前往主页的按键" + +#: +msgctxt "#33086" +msgid "Press the key you want to map to go to home within {} seconds" +msgstr "在 {} 秒内按下您想映射的前往主页的按键" + +#: +msgctxt "#33087" +msgid "Bind a key to immediately go to the Home view. Cancel using BACK/PREVIOUS_MENU. Clear bound key using the STOP or CONTEXT_MENU (long press OK/Enter) button on the setting." +msgstr "绑定一个按键以立刻前往主页视图。使用返回/上一个菜单取消。使用设置中的停止按钮或右键菜单(长按 OK/Enter)清除绑定的按键。" + +#: +msgctxt "#33088" +msgid "Only applies to video player UI" +msgstr "仅适用于视频播放器 UI" + +#: +msgctxt "#33089" +msgid "Automatic seek-back" +msgstr "自动回退" + +#: +msgctxt "#33090" +msgid "If your audio doesn't resume as fast as the video, or you want to catch up after a longer pause, use this to seek back after resuming from pause to compensate for the delay. Default: Off" +msgstr "如果音频恢复速度不如视频,或在暂停较长时间后希望回顾内容,可以在恢复播放后回退,以弥补延迟。默认:关闭" + +#: +msgctxt "#33091" +msgid "{sec_or_ms} {unit_s_or_ms}" +msgstr "{sec_or_ms} {unit_s_or_ms}" + +#: +msgctxt "#33092" +msgid "Seek back on pause" +msgstr "暂停时回退" + +#: +msgctxt "#33093" +msgid "Seek back after" +msgstr "在以下情况时回退" + +#: +msgctxt "#33094" +msgid "Only seek back after having paused at least a certain amount of seconds" +msgstr "仅在暂停至少一定时间后回退" + +#: +msgctxt "#33095" +msgid "Seek back on pause instead of on resume. When Transcoding you should enable this." +msgstr "暂停时回退而不是继续播放时回退。在转码时应启用此功能。" + +#: +msgctxt "#33096" +msgid "Only with Direct Play" +msgstr "仅适用于直接播放" + +#: +msgctxt "#33097" +msgid "Enable seek back ony when we're Direct Playing, not Transcoding." +msgstr "仅在直接播放时启用回退,转码时不启用。" + +#: +msgctxt "#33098" +msgid "Tickrate (Hz)" +msgstr "计时频率(Hz)" + +#: +msgctxt "#33099" +msgid "Controls how often certain ticks are performed on GUI windows and the SeekDialog/VideoPlayer and how fast certain events are handled. Can be expensive when bigger than 1 Hz (once per second), can cause quirks when lower than 1 Hz (less than once per second). Depends on the hardware. Default: 1 Hz, Max: 10 Hz (every 100 ms), Sane highest and old default: 10 Hz (every 100 ms)" +msgstr "控制在 GUI 窗口和 SeekDialog/视频播放器上执行特定计时操作的频率,以及处理某些事件的速度。当频率大于 1 Hz(每秒一次)时,可能会增加资源消耗;当频率低于 1 Hz(少于每秒一次)时,可能会出现异常行为。频率取决于硬件。默认值:1 Hz,最大值:10 Hz(每 100 毫秒),合理的最高值和旧默认值为 10 Hz(每 100 毫秒)。" + +#: +msgctxt "#33636" +msgid "Plex server read timeout" +msgstr "Plex 服务器读取超时" + +#: +msgctxt "#33637" +msgid "Sets the maximum amount of time to read from a Plex Server in seconds. Default: 10" +msgstr "设置尝试从 Plex 服务器读取的最长时间(以秒为单位)。默认:10" + +#: +msgctxt "#33638" +msgid "Plex.tv connect timeout" +msgstr "Plex.tv 连接超时" + +#: +msgctxt "#33639" +msgid "Plex.tv: Sets the maximum amount of time to connect to Plex.tv in seconds. Default: 5" +msgstr "Plex.tv:设置尝试连接 Plex.tv 的最长时间(以秒为单位)。默认:5" + +#: +msgctxt "#33640" +msgid "Plex.tv read timeout" +msgstr "Plex.tv 读取超时" + +#: +msgctxt "#33641" +msgid "Plex.tv: Sets the maximum amount of time to read from Plex.tv in seconds. Default: 20" +msgstr "Plex.tv:设置尝试从 Plex.tv 读取的最长时间(以秒为单位)。默认:20" + +#: +msgctxt "#33642" +msgid "Dump config" +msgstr "导出配置" + +#: +msgctxt "#33643" +msgid "Dumps all user settings into the log on startup, when DEBUG logging is enabled. Masks private information." +msgstr "当启用 DEBUG 日志记录时,在启动时将所有用户设置导出到日志中。屏蔽私人信息。" + +#: +msgctxt "#33644" +msgid "Tracks" +msgstr "曲目" + +#: +msgctxt "#33645" +msgid "plex.direct: Honor plex.tv's dnsRebindingProtection flag (DNS)" +msgstr "plex.direct:遵循 plex.tv 的 dnsRebindingProtection 标志(DNS)" + +#: +msgctxt "#33646" +msgid "Only handle plex.direct hosts when the server's attributes dnsRebindingProtection=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "仅当服务器属性 dnsRebindingProtection=1 时处理 plex.direct 主机。在某些情况下可能不起作用。如果出现连接问题,请禁用此选项。默认:启用" + +#: +msgctxt "#33647" +msgid "plex.direct: Honor plex.tv's publicAddressMatches flag (DNS)" +msgstr "plex.direct:遵循 plex.tv 的 publicAddressMatches 标志(DNS)" + +#: +msgctxt "#33648" +msgid "Only handle plex.direct hosts when the server's attributes publicAddressMatches=1. Might not work in certain situations. Disable if you have connection issues. Default: On" +msgstr "仅当服务器属性 publicAddressMatches=1 时处理 plex.direct 主机。在某些情况下可能不起作用。如果出现连接问题,请禁用此选项。默认:启用" + +#: +msgctxt "#33649" +msgid "CoreELEC: Resume-fix wait for seek" +msgstr "CoreELEC:恢复修复等待跳转" + +#: +msgctxt "#33650" +msgid "This adjusts the delay between seek-tries on CoreELEC, which fixes resume not always working or double-seeking. When you have resume/double-seek issues, increase this. 100ms should be stable as well. Default: 350ms" +msgstr "调整 CoreELEC 上跳转尝试之间的延迟,修复恢复播放不总是有效或双重跳转的问题。当出现恢复/双重跳转问题时,请增加此值。100ms 也应是稳定的。默认值:350ms" + +#: +msgctxt "#33651" +msgid "Startup delay" +msgstr "启动延迟" + +#: +msgctxt "#33652" +msgid "Never show Post Play" +msgstr "禁用播放结束界面" diff --git a/script.plexmod/resources/settings.xml b/script.plexmod/resources/settings.xml index b994c848fe..9e9cd8e3ec 100644 --- a/script.plexmod/resources/settings.xml +++ b/script.plexmod/resources/settings.xml @@ -13,11 +13,6 @@ <default>false</default> <control type="toggle"/> </setting> - <setting id="oldprofile" type="boolean" label="33400" help="33401"> - <level>0</level> - <default>false</default> - <control type="toggle"/> - </setting> <setting id="subtitle_use_extended_title" type="boolean" label="32950" help="32951"> <level>0</level> <default>true</default> @@ -59,6 +54,31 @@ </dependencies> <control type="list" format="string"/> </setting> + <setting id="hubs_round_robin" type="boolean" label="33043"> + <level>0</level> + <default>false</default> + <control type="toggle"/> + </setting> + <setting id="hubs_rr_max" type="integer" label="33047" help="33048"> + <level>0</level> + <default>250</default> + <constraints> + <minimum>50</minimum> + <step>50</step> + <maximum>5000</maximum> + </constraints> + <control type="slider" format="integer"> + <popup>false</popup> + </control> + <dependencies> + <dependency type="enable" setting="hubs_round_robin">true</dependency> + </dependencies> + </setting> + <setting id="cache_home_users" type="boolean" label="33018"> + <level>0</level> + <default>true</default> + <control type="toggle"/> + </setting> </group> </category> <!-- Player --> @@ -94,6 +114,18 @@ <default>false</default> <control type="toggle"/> </setting> + <setting id="coreelec_resume_seek_wait" type="integer" label="33649" help="33650"> + <level>0</level> + <default>350</default> + <constraints> + <minimum>100</minimum> + <step>50</step> + <maximum>1000</maximum> + </constraints> + <control type="slider" format="integer"> + <popup>false</popup> + </control> + </setting> <setting id="show_media_ends_info" type="boolean" label="32540" help="32541"> <level>0</level> <default>true</default> @@ -194,7 +226,7 @@ </setting> <setting id="skip_intro_button_show_early_threshold1" type="integer" label="33509" help="33510"> <level>0</level> - <default>60</default> + <default>70</default> <constraints> <minimum>10</minimum> <step>10</step> @@ -205,6 +237,19 @@ <popup>false</popup> </control> </setting> + <setting id="intro_marker_max_offset" type="integer" label="33037" help="33038"> + <level>0</level> + <default>600</default> + <constraints> + <minimum>1</minimum> + <step>10</step> + <maximum>1800</maximum> + </constraints> + <control type="slider" format="integer"> + <heading>33510</heading> + <popup>false</popup> + </control> + </setting> <setting id="skip_marker_timer_cancel" type="boolean" label="32906" help="32907"> <level>0</level> <default>true</default> @@ -294,9 +339,21 @@ <default>true</default> <control type="toggle"/> </setting> + <setting id="episode_no_spoiler_blur" type="integer" label="33009"> + <level>0</level> + <default>16</default> + <constraints> + <minimum>0</minimum> + <step>1</step> + <maximum>256</maximum> + </constraints> + <control type="slider" format="integer"> + <popup>false</popup> + </control> + </setting> <setting id="playlist_visit_media" type="boolean" label="32505"> <level>0</level> - <default>true</default> + <default>false</default> <control type="toggle"/> </setting> <setting id="postplay_timeout" type="integer" label="32501" help="32904"> @@ -324,13 +381,92 @@ </category> <category id="system" label="33600"> <group id="6" label=""> - <setting id="requests_timeout" type="number" label="33620" help="33621"> + <setting id="cache_templates" type="boolean" label="33066" help="33067"> + <level>0</level> + <default>true</default> + <control type="toggle"/> + </setting> + <setting id="always_compile_templates" type="boolean" label="33068" help="33069"> + <level>0</level> + <default>false</default> + <control type="toggle"/> + </setting> + <setting id="verify_mapped_files" type="boolean" label="33002" help="33003"> + <level>0</level> + <default>true</default> + <control type="toggle"/> + </setting> + <setting id="ignore_docker_v4" type="boolean" label="33014" help="33015"> + <level>0</level> + <default>true</default> + <control type="toggle"/> + </setting> + <setting id="honor_plextv_dnsrebind" type="boolean" label="33645" help="33646"> + <level>0</level> + <default>true</default> + <control type="toggle"/> + </setting> + <setting id="honor_plextv_pam" type="boolean" label="33647" help="33648"> + <level>0</level> + <default>true</default> + <control type="toggle"/> + </setting> + <setting id="use_cert_bundle" type="string" label="33051" help="33052"> + <level>0</level> + <default>acme</default> + <constraints> + <options> + <option label="33053">system</option> + <option label="33054">acme</option> + <option label="33055">custom</option> + </options> + <allowempty>false</allowempty> + </constraints> + <control type="list" format="string"/> + </setting> + <setting id="requests_timeout_connect" type="number" label="33620" help="33621"> <level>0</level> <default>5</default> <constraints> - <minimum>0.1</minimum> - <step>0.1</step> - <maximum>20</maximum> + <minimum>0.5</minimum> + <step>0.5</step> + <maximum>60</maximum> + </constraints> + <control type="slider" format="number"> + <popup>false</popup> + </control> + </setting> + <setting id="requests_timeout_read" type="number" label="33636" help="33637"> + <level>0</level> + <default>10</default> + <constraints> + <minimum>0.5</minimum> + <step>0.5</step> + <maximum>60</maximum> + </constraints> + <control type="slider" format="number"> + <popup>false</popup> + </control> + </setting> + <setting id="plextv_timeout_connect" type="number" label="33638" help="33639"> + <level>0</level> + <default>1</default> + <constraints> + <minimum>0.5</minimum> + <step>0.5</step> + <maximum>60</maximum> + </constraints> + <control type="slider" format="number"> + <popup>false</popup> + </control> + </setting> + <setting id="plextv_timeout_read" type="number" label="33640" help="33641"> + <level>0</level> + <default>2</default> + <constraints> + <minimum>0.5</minimum> + <step>0.5</step> + <maximum>60</maximum> </constraints> <control type="slider" format="number"> <popup>false</popup> @@ -340,8 +476,8 @@ <level>0</level> <default>2.5</default> <constraints> - <minimum>0.1</minimum> - <step>0.1</step> + <minimum>0.5</minimum> + <step>0.5</step> <maximum>20</maximum> </constraints> <control type="slider" format="number"> @@ -360,6 +496,42 @@ <popup>false</popup> </control> </setting> + <setting id="max_retries1" type="number" label="33049" help="33050"> + <level>0</level> + <default>3</default> + <constraints> + <minimum>0</minimum> + <step>1</step> + <maximum>20</maximum> + </constraints> + <control type="slider" format="number"> + <popup>false</popup> + </control> + </setting> + <setting id="tickrate" type="number" label="33098" help="33099"> + <level>0</level> + <default>1.0</default> + <constraints> + <minimum>0.5</minimum> + <step>0.5</step> + <maximum>10</maximum> + </constraints> + <control type="slider" format="number"> + <popup>false</popup> + </control> + </setting> + <setting id="worker_count" type="number" label="32981" help="32982"> + <level>0</level> + <default>3</default> + <constraints> + <minimum>2</minimum> + <step>1</step> + <maximum>32</maximum> + </constraints> + <control type="slider" format="number"> + <popup>false</popup> + </control> + </setting> </group> </category> </section> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-album.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-album.xml deleted file mode 100644 index f32092dc3c..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-album.xml +++ /dev/null @@ -1,636 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>5</posy> - <width>420</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(artist.title)]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>60</posy> - <width>420</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(album.title)]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>142</posy> - <width>630</width> - <height>630</height> - <texture>$INFO[Window.Property(album.thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - </control> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <defaultcontrol>301</defaultcontrol> - <posx>50</posx> - <posy>784</posy> - <width>650</width> - <height>145</height> - <onup>200</onup> - <onright>101</onright> - <itemgap>-50</itemgap> - <orientation>horizontal</orientation> - <align>center</align> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>750</posx> - <posy>0</posy> - <width>1170</width> - <height>945</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1380</width> - <height>945</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="list" id="101"> - <hitrect x="40" y="0" w="1090" h="945" /> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>945</height> - <onup>200</onup> - <onright>152</onright> - <onleft>300</onleft> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="76"> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(is.header))</visible> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>76</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>2</posx> - <posy>21</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="group"> - <posx>90</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>723</width> - <height>76</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - <control type="label"> - <posx>730</posx> - <posy>0</posy> - <width>200</width> - <height>76</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>73</posy> - <width>930</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.header))</visible> - <posx>120</posx> - <posy>24</posy> - <width>400</width> - <height>76</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B][UPPERCASE]$INFO[ListItem.Label][/UPPERCASE][/B]</label> - </control> - - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="76"> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(is.header))</visible> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>76</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>2</posx> - <posy>21</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="group"> - <posx>90</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>723</width> - <height>76</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - <control type="label"> - <posx>730</posx> - <posy>0</posy> - <width>200</width> - <height>76</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>73</posy> - <width>930</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1130</width> - <height>156</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1044</width> - <height>76</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="label"> - <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>48</posx> - <posy>0</posy> - <width>50</width> - <height>76</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>36</posx> - <posy>21</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="group"> - <posx>140</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>738</width> - <height>76</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - <control type="label"> - <posx>796</posx> - <posy>0</posy> - <width>200</width> - <height>76</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - </control> - </control> - - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.header))</visible> - <posx>120</posx> - <posy>24</posy> - <width>400</width> - <height>76</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B][UPPERCASE]$INFO[ListItem.Label][/UPPERCASE][/B]</label> - </control> - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1088" y="33" w="110" h="874" /> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>874</height> - <onleft>101</onleft> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - </control> - </control> - - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <visible>ControlGroup(200).HasFocus(0) + false</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <!-- <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]MUSIC[/UPPERCASE]</label> - </control> --> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-artist.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-artist.xml deleted file mode 100644 index 8d1dac581d..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-artist.xml +++ /dev/null @@ -1,776 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>400</defaultcontrol> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <defaultcontrol>301</defaultcontrol> - <posx>594</posx> - <posy>418</posy> - <width>600</width> - <height>145</height> - <onup>200</onup> - <ondown>400</ondown> - <itemgap>-50</itemgap> - <orientation>horizontal</orientation> - <align>center</align> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/info-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/info.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <width>1920</width> - <height>200</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>519</width> - <height>519</height> - <texture background="true" fallback="script.plex/thumb_fallbacks/music.png">$INFO[Window.Property(thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>579</posx> - <posy>5</posy> - <width>1190</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(artist.title)]</label> - </control> - <control type="label"> - <posx>579</posx> - <posy>55</posy> - <width>1190</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Window.Property(artist.genre)]</label> - </control> - <control type="textbox"> - <posx>579</posx> - <posy>158</posy> - <width>1221</width> - <height>250</height> - <font>font13</font> - <align>left</align> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Window.Property(summary)]</label> - <pagecontrol>152</pagecontrol> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>400</defaultcontrol> - <posx>0</posx> - <posy>585</posy> - <width>1920</width> - <height>360</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>360</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="list" id="400"> - <posx>0</posx> - <posy>-20</posy> - <width>1920</width> - <height>700</height> - <onup>300</onup> - <ondown>401</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>2</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="260"> - <control type="group"> - <posx>60</posx> - <posy>60</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>220</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>30</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Property(year)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="260"> - <control type="group"> - <posx>60</posx> - <posy>60</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="107.5,107.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="107.5,107.5" reversible="false">UnFocus</animation> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>295</width> - <height>295</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>220</posy> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>30</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Property(year)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>-5</posx> - <posy>-5</posy> - <width>225</width> - <height>225</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <!-- similar artists --> - <control type="group" id="500"> - <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>401</defaultcontrol> - <width>1920</width> - <height>520</height> - <posx>0</posx> - <posy>945</posy> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(divider.401))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> - </control> - <control type="list" id="401"> - <posx>0</posx> - <posy>16</posy> - <width>1920</width> - <height>520</height> - <onup>400</onup> - <ondown>false</ondown> - <onleft>false</onleft> - <onright>false</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="260"> - <control type="group"> - <posx>60</posx> - <posy>60</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>220</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>30</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Property(year)]</label> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>77</posx> - <posy>57.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>77</posx> - <posy>57.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>43.5</posx> - <posy>43.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="260"> - <control type="group"> - <posx>60</posx> - <posy>60</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="107.5,107.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="107.5,107.5" reversible="false">UnFocus</animation> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>295</width> - <height>295</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>220</posy> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>30</posy> - <width>215</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Property(year)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>-5</posx> - <posy>-5</posy> - <width>225</width> - <height>225</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>215</width> - <height>215</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>77</posx> - <posy>57.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>77</posx> - <posy>57.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>43.5</posx> - <posy>43.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - </control> - - <control type="group" id="200"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras)) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window.Property(on.extras))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <!-- <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE][/UPPERCASE]</label> - </control> --> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-background.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-background.xml deleted file mode 100644 index 7d28bf2fbc..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-background.xml +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>0xff111111</backgroundcolor> - <controls> - <control type="image"> - <visible>!String.IsEmpty(Window(10000).Property(script.plex.background.splash))</visible> - <posx>710</posx> - <posy>459</posy> - <width>500</width> - <height>162</height> - <texture>script.plex/splash.png</texture> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window(10000).Property(script.plex.background.busy))</visible> - <control type="image"> - <posx>812</posx> - <posy>135</posy> - <width>300</width> - <height>97</height> - <texture>script.plex/user_select/plex.png</texture> - </control> - <control type="image"> - <posx>840</posx> - <posy>465</posy> - <width>240</width> - <height>150</height> - <texture>script.plex/busy-back.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>915</posx> - <posy>521</posy> - <width>90</width> - <height>38</height> - <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window(10000).Property(script.plex.background.shutdown))</visible> - <control type="image"> - <posx>840</posx> - <posy>465</posy> - <width>240</width> - <height>150</height> - <texture>script.plex/busy-back.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>915</posx> - <posy>521</posy> - <width>90</width> - <height>38</height> - <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-blank.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-blank.xml deleted file mode 100644 index 2f887866c6..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-blank.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-busy.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-busy.xml deleted file mode 100644 index 31b167f2b7..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-busy.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <controls> - <control type="group"> - <animation effect="fade" start="0" end="100">WindowOpen</animation> - <control type="image"> - <posx>840</posx> - <posy>465</posy> - <width>240</width> - <height>150</height> - <texture>script.plex/busy-back.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>915</posx> - <posy>521</posy> - <width>90</width> - <height>38</height> - <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-busy_msg.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-busy_msg.xml deleted file mode 100644 index 5fc2a6bb5b..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-busy_msg.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <controls> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <animation effect="fade" start="0" end="100">WindowOpen</animation> - <control type="image"> - <posx>840</posx> - <posy>465</posy> - <width>240</width> - <height>150</height> - <texture>script.plex/busy-back.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - <control type="label"> - <posx>840</posx> - <posy>465</posy> - <width>240</width> - <height>150</height> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(message)]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-dropdown.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-dropdown.xml deleted file mode 100644 index 8ace797b8b..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-dropdown.xml +++ /dev/null @@ -1,201 +0,0 @@ -<window> - <onload>SetProperty(dropdown,1)</onload> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <zorder>100</zorder> - <controls> - <control type="button" id="700"> - <!-- dummy for clicks off list --> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - </control> - <control type="group" id="100"> - <defaultcontrol>250</defaultcontrol> - <visible>!String.IsEmpty(Window.Property(show))</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image" id="110"> - <posx>-40</posx> - <posy>-40</posy> - <width>380</width> - <height>146</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="list" id="250"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>924</height> - <onup condition="String.IsEqual(Window.Property(close.direction),top)">Close</onup> - <onup condition="!String.IsEqual(Window.Property(close.direction),top)">noop</onup> - <onleft condition="String.IsEqual(Window.Property(close.direction),left)">Close</onleft> - <onright condition="String.IsEqual(Window.Property(close.direction),right)">Close</onright> - <ondown condition="String.IsEqual(Window.Property(close.direction),down)">Close</ondown> - <ondown condition="!String.IsEqual(Window.Property(close.direction),down)">noop</ondown> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="66"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FF323232">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture flipy="true" colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FF323232" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(with.indicator))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> - <control type="label"> - <posx>20</posx> - <posy>0</posy> - <width>280</width> - <height>66</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <posx>254</posx> - <posy>20</posy> - <width>26</width> - <height>26</height> - <texture colordiffuse="FFFFFFFF">$INFO[ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(separator))</visible> - <posx>0</posx> - <posy>64</posy> - <width>300</width> - <height>2</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - </itemlayout> - <focusedlayout height="66"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(with.indicator))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> - <control type="label"> - <posx>20</posx> - <posy>0</posy> - <width>280</width> - <height>66</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <posx>254</posx> - <posy>20</posy> - <width>26</width> - <height>26</height> - <texture colordiffuse="FF000000">$INFO[ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(separator))</visible> - <posx>0</posx> - <posy>64</posy> - <width>300</width> - <height>2</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - </focusedlayout> - </control> - </control> - </controls> -</window> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-dropdown_header.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-dropdown_header.xml deleted file mode 100644 index 3c623d851a..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-dropdown_header.xml +++ /dev/null @@ -1,247 +0,0 @@ -<window> - <onload>SetProperty(dropdown,1)</onload> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <controls> - <control type="button" id="700"> - <!-- dummy for clicks off list --> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - </control> - <control type="group" id="100"> - <defaultcontrol>250</defaultcontrol> - <visible>!String.IsEmpty(Window.Property(show))</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image" id="110"> - <posx>-60</posx> - <posy>-106</posy> - <width>720</width> - <height>146</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(header))</visible> - <posx>-20</posx> - <posy>-66</posy> - <control type="image" id="111"> - <posx>0</posx> - <posy>0</posy> - <width>640</width> - <height>132</height> - <texture colordiffuse="FF000000" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>20</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Window.Property(header)][/B]</label> - </control> - </control> - <control type="list" id="250"> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>924</height> - <onup condition="String.IsEqual(Window.Property(close.direction),top)">Close</onup> - <onup condition="!String.IsEqual(Window.Property(close.direction),top)">noop</onup> - <onleft condition="String.IsEqual(Window.Property(close.direction),left)">Close</onleft> - <onright condition="String.IsEqual(Window.Property(close.direction),right)">Close</onright> - <ondown condition="String.IsEqual(Window.Property(close.direction),down)">Close</ondown> - <ondown condition="!String.IsEqual(Window.Property(close.direction),down)">noop</ondown> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="66"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture colordiffuse="FF323232">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture flipy="true" colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture colordiffuse="FF323232" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),center)</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),left)</visible> - <posx>20</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>520</width> - <height>66</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <posx>20</posx> - <posy>20</posy> - <width>26</width> - <height>26</height> - <texture colordiffuse="FFFFFFFF">$INFO[ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(separator))</visible> - <posx>0</posx> - <posy>64</posy> - <width>600</width> - <height>2</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - </itemlayout> - <focusedlayout height="66"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),center)</visible> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),left)</visible> - <posx>20</posx> - <posy>0</posy> - <width>600</width> - <height>66</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>520</width> - <height>66</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <posx>20</posx> - <posy>20</posy> - <width>26</width> - <height>26</height> - <texture colordiffuse="FF000000">$INFO[ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(separator))</visible> - <posx>0</posx> - <posy>64</posy> - <width>600</width> - <height>2</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - </focusedlayout> - </control> - </control> - </controls> -</window> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-episodes.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-episodes.xml deleted file mode 100644 index 38fe38352e..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-episodes.xml +++ /dev/null @@ -1,1962 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" end="0,-125" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),3) + Control.IsVisible(503)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <posx>0</posx> - <posy>155</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <visible allowhiddenfocus="!String.IsEmpty(Container(400).ListItem.Property(media.multiple))">String.IsEmpty(Container(400).ListItem.Property(media.multiple)) + !String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol always="true">301</defaultcontrol> - <posx>30</posx> - <posy>405</posy> - <width>717</width> - <height>200</height> - <onup>200</onup> - <ondown>400</ondown> - <align>center</align> - <itemgap>-50</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="304"> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/info-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/info.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="301"> - <visible allowhiddenfocus="true">!String.IsEmpty(Window.Property(current_item.loaded))</visible> - <enable>!String.IsEmpty(Window.Property(current_item.loaded))</enable> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <onleft>304</onleft> - <onright>305</onright> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="306"> - <visible>String.IsEmpty(Window.Property(current_item.loaded))</visible> - <hitrect x="40" y="40" w="96" h="60" /> - <onleft>304</onleft> - <onright>305</onright> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="44FFFFFF">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="33FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="305"> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/settings-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/settings.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="grouplist" id="1300"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(media.multiple)) + !String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol always="true">1301</defaultcontrol> - <posx>30</posx> - <posy>412.5</posy> - <width>717</width> - <height>200</height> - <onup>200</onup> - <ondown>400</ondown> - <align>center</align> - <itemgap>-50</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="1304"> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>161</width> - <height>125</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/info-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/info.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="1301"> - <visible allowhiddenfocus="true">!String.IsEmpty(Window.Property(current_item.loaded))</visible> - <enable>!String.IsEmpty(Window.Property(current_item.loaded))</enable> - <hitrect x="40" y="40" w="96" h="60" /> - <onleft>1304</onleft> - <onright>1307</onright> - <posx>0</posx> - <posy>0</posy> - <width>161</width> - <height>125</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="1306"> - <visible>String.IsEmpty(Window.Property(current_item.loaded))</visible> - <hitrect x="40" y="40" w="96" h="60" /> - <onleft>1304</onleft> - <onright>1307</onright> - <posx>0</posx> - <posy>0</posy> - <width>161</width> - <height>125</height> - <font>font12</font> - <onleft>304</onleft> - <onright>305</onright> - <texturefocus colordiffuse="44FFFFFF">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="33FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="1307"> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>161</width> - <height>125</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/media-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/media.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="1305"> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>161</width> - <height>125</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/settings-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/settings.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="1303"> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>161</width> - <height>125</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="1302"> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>161</width> - <height>125</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>600</height> - <control type="group"> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>657</width> - <height>393</height> - <texture background="true">script.plex/thumb_fallbacks/show.png</texture> - <animation effect="fade" start="0" end="100" time="0" delay="500">WindowOpen</animation> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>657</width> - <height>393</height> - <texture background="true">$INFO[Container(400).ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(unwatched))</visible> - <posx>682</posx> - <posy>0</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - </control> - - <control type="grouplist"> - <posx>776</posx> - <posy>0</posy> - <width>880</width> - <height>60</height> - <align>left</align> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="label"> - <width min="200" max="880">auto</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>top</aligny> - <textcolor>FFFFFFFF</textcolor> - <scroll>true</scroll> - <scrollspeed>5</scrollspeed> - <label>$INFO[Container(400).ListItem.Property(title)]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(remainingTime))</visible> - <posx>10</posx> - <posy>6</posy> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFE5A00D</focusedcolor> - <textcolor>FFE5A00D</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturenofocus> - <label>$INFO[Container(400).ListItem.Property(remainingTime)]</label> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(rating.stars))</visible> - <posx>1726</posx> - <posy>6</posy> - <width>134</width> - <height>22</height> - <texture>script.plex/stars/$INFO[Container(400).ListItem.Property(rating.stars)].png</texture> - </control> - <control type="label"> - <posx>776</posx> - <posy>50</posy> - <width>714</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>top</aligny> - <scroll>true</scroll> - <scrollspeed>5</scrollspeed> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(show.title)]</label> - </control> - - <control type="grouplist"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(rating)) | !String.IsEmpty(Container(400).ListItem.Property(rating2))</visible> - <posx>1560</posx> - <posy>50</posy> - <width>300</width> - <height>32</height> - <align>right</align> - <itemgap>15</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="image"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(rating))</visible> - <posy>2</posy> - <width>63</width> - <height>30</height> - <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Container(400).ListItem.Property(rating.image)]</texture> - <aspectratio align="right">keep</aspectratio> - </control> - <control type="label"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(rating))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(rating)]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(rating2))</visible> - <posy>2</posy> - <width>40</width> - <height>30</height> - <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Container(400).ListItem.Property(rating2.image)]</texture> - <aspectratio align="right">keep</aspectratio> - </control> - <control type="label"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(rating2))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(rating2)]</label> - </control> - </control> - - <control type="grouplist"> - <posx>776</posx> - <posy>100</posy> - <width>1360</width> - <height>30</height> - <align>left</align> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="label"> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(season)]$INFO[Container(400).ListItem.Property(episode), • , / ]$INFO[Container(400).ListItem.Property(date)]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(unavailable))</visible> - <posx>10</posx> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="FFAC3223" border="12">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus colordiffuse="FFAC3223" border="12">script.plex/white-square-rounded.png</texturenofocus> - <label>$ADDON[script.plexmod 32312]</label> - </control> - </control> - <control type="grouplist"> - <posx>776</posx> - <posy>148</posy> - <width>1360</width> - <height>34</height> - <align>left</align> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="label"> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(duration)]$INFO[Container(400).ListItem.Property(genre), • ]$INFO[Container(400).ListItem.Property(year), • ]$INFO[Container(400).ListItem.Property(content.rating), • ]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(video.res))</visible> - <posx>10</posx> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>$INFO[Container(400).ListItem.Property(video.res)]$INFO[Container(400).ListItem.Property(video.rendering), • ]$INFO[Container(400).ListItem.Property(video.codec), • ]$INFO[Container(400).ListItem.Property(audio.codec), • ]$INFO[Container(400).ListItem.Property(audio.channels), • ]</label> - </control> - </control> - - <control type="label"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(directors)) | !String.IsEmpty(Container(400).ListItem.Property(writers))</visible> - <posx>776</posx> - <posy>194</posy> - <width>1360</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(directors)]$INFO[Container(400).ListItem.Property(writers)]</label> - </control> - - <control type="grouplist"> - <posx>776</posx> - <posy>263</posy> - <width>1360</width> - <height>34</height> - <align>left</align> - <itemgap>15</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="button"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(audio))</visible> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>[UPPERCASE]$ADDON[script.plexmod 32395][/UPPERCASE]</label> - </control> - <control type="label"> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(audio)]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(subtitles))</visible> - <left>34</left> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>[UPPERCASE]$ADDON[script.plexmod 32396][/UPPERCASE]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Container(400).ListItem.Property(subtitles))</visible> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(subtitles)]</label> - </control> - </control> - <control type="textbox"> - <posx>776</posx> - <posy>340</posy> - <width>1084</width> - <height>172</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Container(400).ListItem.Property(summary)]</label> - </control> - - <control type="image" id="250"> - <animation effect="zoom" start="0,100" end="100,100" time="1000" center="-1,561" reversible="false" tween="circle" easing="out">WindowOpen</animation> - <posx>-1</posx> - <posy>557</posy> - <width>1</width> - <height>8</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="image"> - <visible>!Control.IsVisible(500)</visible> - <posx>0</posx> - <posy>565</posy> - <width>1920</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - </control> - - <!-- EPISODES --> - <control type="grouplist" id="60"> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <posx>0</posx> - <posy>565</posy> - <width>1920</width> - <height>1800</height> - - <onup condition="Control.IsVisible(300)">300</onup> - <onup condition="Control.IsVisible(1300)">1300</onup> - <itemgap>0</itemgap> - - <!-- EPISODES --> - <control type="group" id="500"> - <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <height>360</height> - <width>1920</width> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>800</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>AAFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(episodes.header)][/UPPERCASE]</label> - </control> - <control type="list" id="400"> - <posx>0</posx> - <posy>18</posy> - <width>1920</width> - <height>360</height> - <onup condition="Control.IsVisible(300)">300</onup> - <onup condition="Control.IsVisible(1300)">1300</onup> - <ondown>401</ondown> - <onleft>noop</onleft> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>158</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>299</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>264</posx> - <posy>0</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>175</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>210</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>85.5</posx> - <posy>20</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="154.5,87.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="154.5,87.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>389</width> - <height>258</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>158</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>299</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>264</posx> - <posy>0</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>Control.HasFocus(400)</visible> - <control type="label"> - <scroll>true</scroll> - <posx>0</posx> - <posy>175</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>true</scroll> - <posx>0</posx> - <posy>210</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="group"> - <visible>!Control.HasFocus(400)</visible> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>175</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>FFCC7B19</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>210</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>FFCC7B19</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>85.5</posx> - <posy>20</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>0</posx> - <posy>0</posy> - <width>309</width> - <height>178</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- EPISODES --> - - <!-- Seasons --> - <control type="group" id="501"> - <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <height>380</height> - <width>1920</width> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>800</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(seasons.header)][/UPPERCASE]</label> - </control> - <control type="list" id="401"> - <posx>0</posx> - <posy>36</posy> - <width>1920</width> - <height>380</height> - <onup>400</onup> - <ondown>402</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="218"> - <control type="group"> - <posx>55</posx> - <posy>29</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>113</posx> - <posy>0</posy> - <width>45</width> - <height>40</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>230</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>158</width> - <height>4</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>240</posy> - <width>158</width> - <height>54</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="218"> - <control type="group"> - <posx>55</posx> - <posy>29</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="84,123" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="84,123" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>248</width> - <height>326</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>113</posx> - <posy>0</posy> - <width>45</width> - <height>40</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>230</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>158</width> - <height>4</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(401)</scroll> - <posx>0</posx> - <posy>240</posy> - <width>158</width> - <height>54</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>0</posx> - <posy>0</posy> - <width>168</width> - <height>246</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- Seasons --> - - <!-- ROLES --> - <control type="group" id="502"> - <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>402</defaultcontrol> - <width>1920</width> - <height>400</height> - <control type="label"> - <posx>60</posx> - <posy>-20</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32419][/UPPERCASE]</label> - </control> - <control type="list" id="402"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>400</height> - <onup>401</onup> - <ondown>403</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>253</posy> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>30</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>253</posy> - <control type="label"> - <scroll>Control.HasFocus(402)</scroll> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(402)</scroll> - <posx>0</posx> - <posy>30</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- ROLES --> - - <!-- EXTRAS --> - <control type="group" id="503"> - <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <height>360</height> - <width>1920</width> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>800</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>AAFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(extras.header)][/UPPERCASE]</label> - </control> - <control type="list" id="403"> - <posx>0</posx> - <posy>18</posy> - <width>1920</width> - <height>430</height> - <onup>402</onup> - <ondown>404</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>175</posy> - <width>299</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>205</posy> - <width>299</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="154.5,87.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="154.5,87.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>389</width> - <height>258</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <control type="label"> - <scroll>Control.HasFocus(403)</scroll> - <posx>0</posx> - <posy>175</posy> - <width>299</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(403)</scroll> - <posx>0</posx> - <posy>205</posy> - <width>299</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>0</posx> - <posy>0</posy> - <width>309</width> - <height>178</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- EXTRAS --> - - <!-- RELATED --> - <control type="group" id="504"> - <visible>Integer.IsGreater(Container(404).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>404</defaultcontrol> - <width>1920</width> - <height>520</height> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> - </control> - <control type="list" id="404"> - <posx>0</posx> - <posy>16</posy> - <width>1920</width> - <height>520</height> - <onup>403</onup> - <ondown>404</ondown> - <onleft>noop</onleft> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(404)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>441</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(404)</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(404)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- RELATED --> - - </control> - </control> - - <control type="group" id="200"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras)) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window.Property(on.extras))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-home.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-home.xml deleted file mode 100644 index 2817f0deb4..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-home.xml +++ /dev/null @@ -1,8678 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="grouplist" id="50"> - <animation effect="slide" end="0,-135" time="200" tween="sine" easing="inout" condition="!String.IsEmpty(Window(10000).Property(script.plex.off.sections))">Conditional</animation> - - <!-- 501 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> - <effect type="slide" end="0,-345" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 502 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 503 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 504 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),3) + Control.IsVisible(503)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 505 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),4) + Control.IsVisible(504)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 506 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),5) + Control.IsVisible(505)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 507 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),6) + Control.IsVisible(506)" reversible="true"> - <effect type="slide" end="0,-440" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 508 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),7) + Control.IsVisible(507)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 509 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),8) + Control.IsVisible(508)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 510 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),9) + Control.IsVisible(509)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 511 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),10) + Control.IsVisible(510)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 512 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),11) + Control.IsVisible(511)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 520 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),12) + Control.IsVisible(512)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 521 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),13) + Control.IsVisible(520)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 522 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),14) + Control.IsVisible(521)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 513 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),15) + Control.IsVisible(522)" reversible="true"> - <effect type="slide" end="0,-400" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 514 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),16) + Control.IsVisible(513)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 515 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),17) + Control.IsVisible(514)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 516 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),18) + Control.IsVisible(515)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 517 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),19) + Control.IsVisible(516)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 518 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),20) + Control.IsVisible(517)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 519 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),21) + Control.IsVisible(518)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - <!-- 523 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),22) + Control.IsVisible(519)" reversible="true"> - <effect type="slide" end="0,-540" time="200" tween="sine" easing="inout"/> - </animation> - - - <defaultcontrol>101</defaultcontrol> - <posx>0</posx> - <posy>96</posy> - <width>2130</width> - <height>5540</height> - <itemgap>20</itemgap> - <orientation>vertical</orientation> - <usecontrolcoords>true</usecontrolcoords> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <control type="group" id="100"> - <width>2130</width> - <height>200</height> - <control type="fixedlist" id="101"> - <animation effect="slide" end="-110,0" time="200" tween="sine" easing="inout" condition="Integer.IsGreater(Container(101).Position,3)">Conditional</animation> - <animation effect="slide" end="-110,0" time="200" tween="sine" easing="inout" condition="Integer.IsGreater(Container(101).Position,4)">Conditional</animation> - <posx>-300</posx> - <posy>0</posy> - <width>2430</width> - <height>240</height> - <onleft>101</onleft> - <onup condition="!Player.HasAudio">203</onup> - <onup condition="Player.HasAudio">204</onup> - <ondown>400</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <focusposition>4</focusposition> - <movement>3</movement> - <pagecontrol>102</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="298"> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(item))</visible> - <posx>60</posx> - <posy>40</posy> - <width>298</width> - <height>200</height> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>117</height> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.home))</visible> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>117</height> - <texture border="10">script.plex/white-square-rounded.png</texture> - <colordiffuse>FF1F1F1F</colordiffuse> - </control> - - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.home))</visible> - <posx>84</posx> - <posy>23.5</posy> - <width>70</width> - <height>70</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.home))</visible> - <posx>74</posx> - <posy>13.5</posy> - <width>90</width> - <height>90</height> - <texture>script.plex/home/type/home.png</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>125</posy> - <width>238</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="298"> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(item))</visible> - <posx>60</posx> - <posy>40</posy> - <control type="group"> - <animation effect="zoom" start="100" end="120" time="100" center="119,58.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="119,58.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(is.home))</visible> - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>318</width> - <height>197</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <animation effect="fade" end="100" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>117</height> - <texture border="10">script.plex/white-square-rounded.png</texture> - <colordiffuse>FF1F1F1F</colordiffuse> - </control> - <control type="image"> - <animation effect="fade" end="0" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>117</height> - <texture border="10">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!Control.HasFocus(101)</visible> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>117</height> - <texture border="10">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="image"> - <posx>84</posx> - <posy>23.5</posy> - <width>70</width> - <height>70</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.home))</visible> - <posx>74</posx> - <posy>13.5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>90</width> - <height>90</height> - <texture>script.plex/home/type/home.png</texture> - <aspectratio>keep</aspectratio> - </control> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <animation effect="fade" end="0" reversible="false">UnFocus</animation> - <posx>-40</posx> - <posy>-40</posy> - <width>170</width> - <height>170</height> - <texture>script.plex/home/type/home-selected.png</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(100)</scroll> - <posx>0</posx> - <posy>125</posy> - <width>238</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="500"> - <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1920</width> - <height>440</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.400)][/UPPERCASE]</label> - </control> - <control type="list" id="400"> - <posx>0</posx> - <posy>30</posy> - <width>1920</width> - <height>440</height> - <onup>101</onup> - <ondown>401</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.400))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="271,152" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="271,152" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>622</width> - <height>389</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(400)</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(400)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.400))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>0</posx> - <posy>0</posy> - <width>542</width> - <height>309</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="600"> - <visible>Integer.IsGreater(Container(400).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.400))</visible> - <width>10</width> - <height>12</height> - </control> - - <control type="group" id="501"> - <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>401</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.401)][/UPPERCASE]</label> - </control> - <control type="list" id="401"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>400</onup> - <ondown>402</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.401))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(401)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(401)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.401))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="601"> - <visible>Integer.IsGreater(Container(401).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.401))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="502"> - <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>402</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.402)][/UPPERCASE]</label> - </control> - <control type="list" id="402"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>401</onup> - <ondown>403</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.402))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(402)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(402)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.402))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="602"> - <visible>Integer.IsGreater(Container(402).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.402))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="503"> - <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>403</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.403)][/UPPERCASE]</label> - </control> - <control type="list" id="403"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>402</onup> - <ondown>404</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.403))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(403)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(403)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.403))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="603"> - <visible>Integer.IsGreater(Container(403).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.403))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="504"> - <visible>Integer.IsGreater(Container(404).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>404</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.404)][/UPPERCASE]</label> - </control> - <control type="list" id="404"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>403</onup> - <ondown>405</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.404))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(404)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(404)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(404)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.404))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(404)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="604"> - <visible>Integer.IsGreater(Container(404).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.404))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="505"> - <visible>Integer.IsGreater(Container(405).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>405</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.405)][/UPPERCASE]</label> - </control> - <control type="list" id="405"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>404</onup> - <ondown>406</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.405))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(405)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(405)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(405)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.405))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(405)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="605"> - <visible>Integer.IsGreater(Container(405).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.405))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="506"> - <visible>Integer.IsGreater(Container(406).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1920</width> - <height>440</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.406)][/UPPERCASE]</label> - </control> - <control type="list" id="406"> - <posx>0</posx> - <posy>30</posy> - <width>1920</width> - <height>440</height> - <onup>405</onup> - <ondown>407</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.406))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="271,152" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="271,152" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(406)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>622</width> - <height>389</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(406)</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(406)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.406))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(406)</visible> - <posx>0</posx> - <posy>0</posy> - <width>542</width> - <height>309</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="606"> - <visible>Integer.IsGreater(Container(406).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.406))</visible> - <width>10</width> - <height>12</height> - </control> - - <control type="group" id="507"> - <visible>Integer.IsGreater(Container(407).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>407</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.407)][/UPPERCASE]</label> - </control> - <control type="list" id="407"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>406</onup> - <ondown>408</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.407))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(407)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(407)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(407)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.407))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(407)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="607"> - <visible>Integer.IsGreater(Container(407).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.407))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="508"> - <visible>Integer.IsGreater(Container(408).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>408</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.408)][/UPPERCASE]</label> - </control> - <control type="list" id="408"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>407</onup> - <ondown>409</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.408))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(408)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(408)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(408)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.408))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(408)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="608"> - <visible>Integer.IsGreater(Container(408).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.408))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="509"> - <visible>Integer.IsGreater(Container(409).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>409</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.409)][/UPPERCASE]</label> - </control> - <control type="list" id="409"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>408</onup> - <ondown>410</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.409))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(409)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(409)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(409)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.409))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(409)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="609"> - <visible>Integer.IsGreater(Container(409).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.409))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="510"> - <visible>Integer.IsGreater(Container(410).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>410</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.410)][/UPPERCASE]</label> - </control> - <control type="list" id="410"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>409</onup> - <ondown>411</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.410))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(410)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(410)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(410)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.410))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(410)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="610"> - <visible>Integer.IsGreater(Container(410).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.410))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="511"> - <visible>Integer.IsGreater(Container(411).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>411</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.411)][/UPPERCASE]</label> - </control> - <control type="list" id="411"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>410</onup> - <ondown>412</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.411))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(411)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(411)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(411)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.411))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(411)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="611"> - <visible>Integer.IsGreater(Container(411).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.411))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="512"> - <visible>Integer.IsGreater(Container(412).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>412</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.412)][/UPPERCASE]</label> - </control> - <control type="list" id="412"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>411</onup> - <ondown>420</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.412))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(412)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(412)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(412)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.412))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(412)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="612"> - <visible>Integer.IsGreater(Container(412).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.412))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="520"> - <visible>Integer.IsGreater(Container(420).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>420</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.420)][/UPPERCASE]</label> - </control> - <control type="list" id="420"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>412</onup> - <ondown>421</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.420))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(420)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(420)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(420)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.420))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(420)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="620"> - <visible>Integer.IsGreater(Container(420).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.420))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="521"> - <visible>Integer.IsGreater(Container(421).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>421</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.421)][/UPPERCASE]</label> - </control> - <control type="list" id="421"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>420</onup> - <ondown>422</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.421))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(421)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(421)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(421)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.421))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(421)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="621"> - <visible>Integer.IsGreater(Container(421).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.421))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="522"> - <visible>Integer.IsGreater(Container(422).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>422</defaultcontrol> - <width>1920</width> - <height>392</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.422)][/UPPERCASE]</label> - </control> - <control type="list" id="422"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>392</height> - <onup>421</onup> - <ondown>413</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.422))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="122,122" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="122,122" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(422)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>324</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>72</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>58</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>234</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(422)</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(422)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.422))</visible> - <posx>0</posx> - <posy>281</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="622"> - <visible>Integer.IsGreater(Container(422).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.422))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="513"> - <visible>Integer.IsGreater(Container(413).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>413</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.413)][/UPPERCASE]</label> - </control> - <control type="list" id="413"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>422</onup> - <ondown>414</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.413))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(413)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(413)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(413)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.413))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(413)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="613"> - <visible>Integer.IsGreater(Container(413).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.413))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="514"> - <visible>Integer.IsGreater(Container(414).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>414</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.414)][/UPPERCASE]</label> - </control> - <control type="list" id="414"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>413</onup> - <ondown>415</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.414))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(414)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(414)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(414)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.414))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(414)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="614"> - <visible>Integer.IsGreater(Container(414).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.414))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="515"> - <visible>Integer.IsGreater(Container(415).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>415</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.415)][/UPPERCASE]</label> - </control> - <control type="list" id="415"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>414</onup> - <ondown>416</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.415))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(415)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(415)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(415)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.415))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(415)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="615"> - <visible>Integer.IsGreater(Container(415).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.415))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="516"> - <visible>Integer.IsGreater(Container(416).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>416</defaultcontrol> - <width>1920</width> - <height>515</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.416)][/UPPERCASE]</label> - </control> - <control type="list" id="416"> - <posx>0</posx> - <posy>29</posy> - <width>1920</width> - <height>515</height> - <onup>415</onup> - <ondown>417</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.416))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(416)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(416)</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(416)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.416))</visible> - <posx>0</posx> - <posy>398</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(416)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="616"> - <visible>Integer.IsGreater(Container(416).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.416))</visible> - <width>10</width> - <height>7</height> - </control> - - <control type="group" id="517"> - <visible>Integer.IsGreater(Container(417).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1920</width> - <height>440</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.417)][/UPPERCASE]</label> - </control> - <control type="list" id="417"> - <posx>0</posx> - <posy>30</posy> - <width>1920</width> - <height>440</height> - <onup>416</onup> - <ondown>418</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.417))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="271,152" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="271,152" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(417)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>622</width> - <height>389</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(417)</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(417)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.417))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(417)</visible> - <posx>0</posx> - <posy>0</posy> - <width>542</width> - <height>309</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="617"> - <visible>Integer.IsGreater(Container(417).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.417))</visible> - <width>10</width> - <height>12</height> - </control> - - <control type="group" id="518"> - <visible>Integer.IsGreater(Container(418).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1920</width> - <height>440</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.418)][/UPPERCASE]</label> - </control> - <control type="list" id="418"> - <posx>0</posx> - <posy>30</posy> - <width>1920</width> - <height>440</height> - <onup>417</onup> - <ondown>419</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.418))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="271,152" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="271,152" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(418)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>622</width> - <height>389</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(418)</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(418)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.418))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(418)</visible> - <posx>0</posx> - <posy>0</posy> - <width>542</width> - <height>309</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="618"> - <visible>Integer.IsGreater(Container(418).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.418))</visible> - <width>10</width> - <height>12</height> - </control> - - <control type="group" id="519"> - <visible>Integer.IsGreater(Container(419).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1920</width> - <height>440</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.419)][/UPPERCASE]</label> - </control> - <control type="list" id="419"> - <posx>0</posx> - <posy>30</posy> - <width>1920</width> - <height>440</height> - <onup>418</onup> - <ondown>423</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.419))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="271,152" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="271,152" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(419)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>622</width> - <height>389</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(419)</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(419)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.419))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(419)</visible> - <posx>0</posx> - <posy>0</posy> - <width>542</width> - <height>309</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="619"> - <visible>Integer.IsGreater(Container(419).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.419))</visible> - <width>10</width> - <height>12</height> - </control> - - <control type="group" id="523"> - <visible>Integer.IsGreater(Container(423).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1920</width> - <height>440</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> - <posx>60</posx> - <posy>12</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.423)][/UPPERCASE]</label> - </control> - <control type="list" id="423"> - <posx>0</posx> - <posy>30</posy> - <width>1920</width> - <height>440</height> - <onup>419</onup> - <ondown>423</ondown> - <onright>noop</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.423))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="592"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="271,152" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="271,152" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(423)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>622</width> - <height>389</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>235.5</posx> - <posy>99.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>202</posx> - <posy>85.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>299</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>289</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>532</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>532</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>484</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>481</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>1</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(423)</scroll> - <posx>0</posx> - <posy>309</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(423)</scroll> - <visible>!String.IsEmpty(Window.Property(hub.text2lines.423))</visible> - <posx>0</posx> - <posy>337</posy> - <width>532</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(423)</visible> - <posx>0</posx> - <posy>0</posy> - <width>542</width> - <height>309</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <control type="group" id="623"> - <visible>Integer.IsGreater(Container(423).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.423))</visible> - <width>10</width> - <height>12</height> - </control> - - <control type="label"> - <!-- DUMMY --> - <width>1920</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>00FFFFFF</textcolor> - <label> </label> - </control> - </control> - - - - <control type="group" id="200"> - <animation effect="slide" end="0,-135" time="200" tween="sine" easing="inout" condition="!String.IsEmpty(Window(10000).Property(script.plex.off.sections)) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window(10000).Property(script.plex.off.sections))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="group"> - <visible>String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="button" id="203"> - <animation effect="zoom" start="100" end="177" time="100" center="80,67.5" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="80,67.5" reversible="false">UnFocus</animation> - <posx>60</posx> - <posy>47.5</posy> - <width>40</width> - <height>40</height> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - <control type="label"> - <posx>160</posx> - <posy>35</posy> - <width>500</width> - <height>65</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32430][/UPPERCASE]</label> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>203</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - <control type="group"> - <posx>576</posx> - <posy>34</posy> - <width>1000</width> - <height>1046</height> - <control type="grouplist"> - <posx>0</posx> - <posy>0</posy> - <width>1000</width> - <height>1046</height> - <ondown>50</ondown> - <onleft>204</onleft> - <align>right</align> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="201"> - <width max="500">auto</width> - <height>66</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label>$INFO[Window.Property(server.name)]</label> - <onunfocus condition="!String.IsEmpty(Window.Property(show.servers))">SetFocus(260)</onunfocus> - </control> - <!-- server control --> - <control type="group"> - <posx>-93</posx> - <width>93</width> - <height>66</height> - <control type="image"> - <posx>6</posx> - <posy>14</posy> - <width>40</width> - <height>39</height> - <texture>$INFO[Window.Property(server.icon)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>38</posy> - <width>16</width> - <height>15</height> - <texture>$INFO[Window.Property(server.iconmod)]</texture> - </control> - <!-- secure + local --> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(server.iconmod))</visible> - <posx>0</posx> - <posy>20</posy> - <width>16</width> - <height>14</height> - <texture>$INFO[Window.Property(server.iconmod2)]</texture> - <colordiffuse>FFEEEEEE</colordiffuse> - </control> - <!-- local --> - <control type="image"> - <visible>String.IsEmpty(Window.Property(server.iconmod))</visible> - <posx>0</posx> - <posy>38</posy> - <width>16</width> - <height>14</height> - <texture>$INFO[Window.Property(server.iconmod2)]</texture> - <colordiffuse>FFEEEEEE</colordiffuse> - </control> - <control type="image"> - <visible>!Control.HasFocus(201)</visible> - <posx>59</posx> - <posy>27</posy> - <width>15</width> - <height>13</height> - <texture>script.plex/indicators/dropdown-triangle.png</texture> - <colordiffuse>99FFFFFF</colordiffuse> - </control> - <control type="image"> - <visible>Control.HasFocus(201)</visible> - <posx>59</posx> - <posy>27</posy> - <width>15</width> - <height>13</height> - <texture>script.plex/indicators/dropdown-triangle.png</texture> - <colordiffuse>FF222222</colordiffuse> - </control> - <control type="group"> - <visible>Control.HasFocus(260) | !String.IsEmpty(Window.Property(show.servers))</visible> - <posx>-413</posx> - <posy>70</posy> - <control type="image" id="800"> - <posx>-40</posx> - <posy>-40</posy> - <width>580</width> - <height>146</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <posx>432</posx> - <posy>-13</posy> - <width>15</width> - <height>13</height> - <texture flipy="true">script.plex/indicators/dropdown-triangle.png</texture> - <colordiffuse>FF1F1F1F</colordiffuse> - </control> - <control type="list" id="260"> - <hitrect x="0" y="-10" w="500" h="910" /> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>900</height> - <onup>201</onup> - <onleft>203</onleft> - <onright>202</onright> - <onunfocus>SetProperty(show.servers,)</onunfocus> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <pagecontrol>261</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="100"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture flipy="true" colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Label2)</visible> - <control type="label"> - <posx>20</posx> - <posy>20</posy> - <width>400</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>20</posx> - <posy>50</posy> - <width>400</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFA0A0A0</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>0</posy> - <width>400</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - - <!-- not status + not current + local --> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>456</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <!-- not status + current + local --> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>415</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <!-- status + not current + local --> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>415</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <!-- status + current + local --> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>374</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <!-- status + not current --> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current))</visible> - <posx>456</posx> - <posy>38</posy> - <width>24</width> - <height>24</height> - <texture>script.plex/home/device/$INFO[ListItem.Property(status)]</texture> - </control> - <!-- status + current --> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current))</visible> - <posx>415</posx> - <posy>38</posy> - <width>24</width> - <height>24</height> - <texture>script.plex/home/device/$INFO[ListItem.Property(status)]</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(current))</visible> - <posx>449</posx> - <posy>38</posy> - <width>31</width> - <height>24</height> - <texture colordiffuse="FFFFFFFF">script.plex/home/device/check.png</texture> - </control> - - </itemlayout> - <focusedlayout height="100"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>100</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Label2)</visible> - <control type="label"> - <posx>20</posx> - <posy>20</posy> - <width>400</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>20</posx> - <posy>50</posy> - <width>400</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>0</posy> - <width>400</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - - <!-- not status + not current + local --> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>456</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <!-- not status + current + local --> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>415</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <!-- status + not current + local --> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>415</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <!-- status + current + local --> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> - <posx>374</posx> - <posy>38</posy> - <width>24</width> - <height>21</height> - <texture>script.plex/home/device/home.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current))</visible> - <posx>456</posx> - <posy>38</posy> - <width>24</width> - <height>24</height> - <texture>script.plex/home/device/focus-$INFO[ListItem.Property(status)]</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current))</visible> - <posx>415</posx> - <posy>38</posy> - <width>24</width> - <height>24</height> - <texture>script.plex/home/device/focus-$INFO[ListItem.Property(status)]</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(current))</visible> - <posx>449</posx> - <posy>38</posy> - <width>31</width> - <height>24</height> - <texture colordiffuse="FF000000">script.plex/home/device/check.png</texture> - </control> - - </focusedlayout> - </control> - - <control type="scrollbar" id="261"> - <posx>492</posx> - <posy>20</posy> - <width>8</width> - <height>860</height> - <texturesliderbackground>-</texturesliderbackground> - <texturesliderbar colordiffuse="20FFFFFF" border="4">script.plex/white-square.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="20E5A00D" border="4">script.plex/white-square.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>250</onleft> - </control> - - </control> - </control> - <control type="button" id="202"> - <width max="500">auto</width> - <height>66</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label>$INFO[Window.Property(user.name)]</label> - <onunfocus condition="!String.IsEmpty(Window.Property(show.options))">SetFocus(250)</onunfocus> - </control> - <control type="group"> - <posx>-87</posx> - <width>87</width> - <height>66</height> - <control type="image"> - <posx>0</posx> - <posy>14</posy> - <width>40</width> - <height>39</height> - <texture diffuse="script.plex/home/avatar-diffuse.png" fallback="script.plex/gray-square.png">$INFO[Window.Property(user.avatar)]</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(Window.Property(user.avatar))</visible> - <posx>0</posx> - <posy>14</posy> - <width>40</width> - <height>39</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Window.Property(user.avatar.letter)][/B]</label> - </control> - <control type="image"> - <visible>!Control.HasFocus(202)</visible> - <posx>53</posx> - <posy>27</posy> - <width>15</width> - <height>13</height> - <texture>script.plex/indicators/dropdown-triangle.png</texture> - <colordiffuse>99FFFFFF</colordiffuse> - </control> - <control type="image"> - <visible>Control.HasFocus(202)</visible> - <posx>53</posx> - <posy>27</posy> - <width>15</width> - <height>13</height> - <texture>script.plex/indicators/dropdown-triangle.png</texture> - <colordiffuse>FF222222</colordiffuse> - </control> - <control type="group"> - <visible>Control.HasFocus(250) | !String.IsEmpty(Window.Property(show.options))</visible> - <posx>-213</posx> - <posy>70</posy> - <control type="image" id="801"> - <posx>-40</posx> - <posy>-40</posy> - <width>380</width> - <height>146</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <posx>226</posx> - <posy>-13</posy> - <width>15</width> - <height>13</height> - <texture flipy="true">script.plex/indicators/dropdown-triangle.png</texture> - <colordiffuse>FF1F1F1F</colordiffuse> - </control> - <control type="list" id="250"> - <hitrect x="0" y="-10" w="300" h="208" /> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>198</height> - <onup>202</onup> - <ondown>noop</ondown> - <onleft>201</onleft> - <onunfocus>SetProperty(show.options,)</onunfocus> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="66"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture flipy="true" colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </itemlayout> - <focusedlayout height="66"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(first))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(last))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(only))</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>66</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </focusedlayout> - </control> - </control> - </control> - <control type="image"> - <!-- dummy image to allow shadow --> - <width>40</width> - <height>10</height> - <texture>-</texture> - </control> - </control> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - <control type="group"> - <visible>String.IsEmpty(Window.Property(busy)) + !String.IsEmpty(Window.Property(no.content))</visible> - <posx>0</posx> - <posy>465</posy> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$ADDON[script.plexmod 32452][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>60</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFCCCCCC</textcolor> - <label>$ADDON[script.plexmod 32453]</label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(busy))</visible> - <animation effect="fade" start="0" end="100" delay="500">Visible</animation> - <posx>840</posx> - <posy>465</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>240</width> - <height>150</height> - <texture>script.plex/busy-back.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>75</posx> - <posy>56</posy> - <width>90</width> - <height>38</height> - <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-info.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-info.xml deleted file mode 100644 index b4d1deef78..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-info.xml +++ /dev/null @@ -1,289 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>152</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>135</posy> - - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(is.poster))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>519</width> - <height>769</height> - <texture>$INFO[Window.Property(thumb.fallback)]</texture> - <aspectratio aligny="top">scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>519</width> - <height>769</height> - <texture>$INFO[Window.Property(thumb)]</texture> - <aspectratio aligny="top">scale</aspectratio> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(is.square))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>519</width> - <height>519</height> - <texture>$INFO[Window.Property(thumb.fallback)]</texture> - <aspectratio aligny="top">keep</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>519</width> - <height>519</height> - <texture>$INFO[Window.Property(thumb)]</texture> - <aspectratio aligny="top">scale</aspectratio> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(is.16x9))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>519</width> - <height>292</height> - <texture>$INFO[Window.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>519</width> - <height>292</height> - <texture>$INFO[Window.Property(thumb)]</texture> - <aspectratio aligny="top">scale</aspectratio> - </control> - </control> - <control type="label"> - <posx>579</posx> - <posy>5</posy> - <width>1190</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(title.main)]</label> - </control> - <control type="label"> - <posx>579</posx> - <posy>55</posy> - <width>1190</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Window.Property(title.sub)]</label> - </control> - <control type="textbox"> - <posx>579</posx> - <posy>157</posy> - <pagecontrol>152</pagecontrol> - <width>1190</width> - <height>718</height> - <font>font13</font> - <align>left</align> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Window.Property(info)]</label> - </control> - <control type="scrollbar" id="152"> - <hitrect x="1754" y="157" w="126" h="718" /> - <left>1794</left> - <top>157</top> - <width>6</width> - <height>718</height> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>204</onleft> - </control> - </control> - </control> - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <ondown>152</ondown> - <onright>152</onright> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9-chunked.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9-chunked.xml deleted file mode 100644 index b209ee4612..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9-chunked.xml +++ /dev/null @@ -1,879 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture fallback="script.plex/home/background-fallback.png" background="true">$INFO[Window.Property(background)]</texture> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>750</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="wraplist" id="101"> - <hitrect x="60" y="0" w="1010" h="945" /> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>945</height> - <onup>600</onup> - <onright>151</onright> - <onleft>304</onleft> - <scrolltime>0</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <focusposition>5</focusposition> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="76"> - <control type="group"> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-3</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer)) + !String.IsEmpty(ListItem.Label)</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="76"> - <control type="group"> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-2</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer)) + !String.IsEmpty(ListItem.Label)</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1085</width> - <height>156</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1005</width> - <height>76</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>957</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched-rounded.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>933</posx> - <posy>15</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>23</posy> - <width>915</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),episode)</visible> - <hitrect x="1108" y="33" w="90" h="879" /> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>879</height> - <onleft>101</onleft> - <onright>951</onright> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - <control type="group"> - <visible>String.IsEqual(Window(10000).Property(script.plex.item.type),episode)</visible> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>879</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>879</height> - <texture colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texture> - </control> - <control type="group" id="950"> - <posx>0</posx> - <posy>0</posy> - <control type="image" id="952"> - <visible>!Control.HasFocus(951) + String.IsEmpty(Window.Property(dragging))</visible> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>10</height> - <texture colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texture> - </control> - <control type="image" id="953"> - <visible>Control.HasFocus(951) | !String.IsEmpty(Window.Property(dragging))</visible> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>10</height> - <texture colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texture> - </control> - </control> - <control type="button" id="951"> - <hitrect x="-20" y="0" w="90" h="879" /> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>879</height> - <onleft>152</onleft> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - </control> - </control> - - <control type="image"> - <posx>0</posx> - <posy>-135</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture fallback="script.plex/home/background-fallback.png" background="true" diffuse="script.plex/masks/listview-16x9-backgroundmask.png">$INFO[Window.Property(background)]</texture> - </control> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <defaultcontrol>301</defaultcontrol> - <posx>30</posx> - <posy>-25</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>101</ondown> - <onright>101</onright> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="button" id="301"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(no.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <hitrect x="20" y="20" w="86" h="60" /> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/chapters-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/chapters.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - - <control type="group"> - <posx>60</posx> - <posy>248</posy> - <control type="image"> - <visible>!String.IsEqual(Window.Property(media),show) + !String.IsEqual(Window.Property(media),movie)</visible> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/movie.png">$INFO[Container(101).ListItem.Property(art)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)</visible> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/show.png">$INFO[Container(101).ListItem.Property(art)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>0</posx> - <posy>355</posy> - <width>440</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>630</posx> - <posy>355</posy> - <width>180</width> - <height>80</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label2][/B]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>435</posy> - <width>630</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>463</posy> - <width>630</width> - <height>307</height> - <font>font12</font> - <align>left</align> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Container(101).ListItem.Property(summary)]</label> - </control> - </control> - - <control type="group" id="150"> - <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>151</defaultcontrol> - <posx>1830</posx> - <posy>150</posy> - <width>20</width> - <height>920</height> - <control type="list" id="151"> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>1050</height> - <onleft>100</onleft> - <onright>152</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>34</height> - <colordiffuse>FFE5A00D</colordiffuse> - <texture border="12">script.plex/white-outline-rounded.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <onright>211</onright> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="grouplist" id="600"> - <defaultcontrol>311</defaultcontrol> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <right>340</right> - <posy>35</posy> - <width>1000</width> - <height>65</height> - <align>right</align> - <itemgap>30</itemgap> - <orientation>horizontal</orientation> - <onleft>204</onleft> - <onright>210</onright> - <ondown>50</ondown> - <control type="button" id="311"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> - </control> - <control type="button" id="211"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="500">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> - </control> - <control type="button" id="310"> - <visible>!String.IsEqual(Window.Property(media),show) + !String.IsEqual(Window.Property(media),movie)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturenofocus>-</texturenofocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="312"> - <visible>String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="210"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9.xml deleted file mode 100644 index 26fe1b8a11..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-16x9.xml +++ /dev/null @@ -1,850 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group"> - <posx>60</posx> - <posy>248</posy> - <control type="image"> - <visible>!String.IsEqual(Window.Property(media),show) + !String.IsEqual(Window.Property(media),movie)</visible> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/movie.png">$INFO[Container(101).ListItem.Property(art)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)</visible> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/show.png">$INFO[Container(101).ListItem.Property(art)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>0</posx> - <posy>355</posy> - <width>440</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>630</posx> - <posy>355</posy> - <width>180</width> - <height>80</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label2][/B]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>435</posy> - <width>630</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>463</posy> - <width>630</width> - <height>307</height> - <font>font12</font> - <align>left</align> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Container(101).ListItem.Property(summary)]</label> - </control> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <defaultcontrol>301</defaultcontrol> - <posx>30</posx> - <posy>-25</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>101</ondown> - <onright>101</onright> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="button" id="301"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(no.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <hitrect x="20" y="20" w="86" h="60" /> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/chapters-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/chapters.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>750</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="list" id="101"> - <hitrect x="60" y="0" w="1010" h="945" /> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>945</height> - <onup>600</onup> - <onright>151</onright> - <onleft>304</onleft> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="76"> - <control type="group"> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-3</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="76"> - <control type="group"> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-2</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1085</width> - <height>156</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1005</width> - <height>76</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>957</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched-rounded.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>933</posx> - <posy>15</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>510</width> - <height>72</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1108" y="33" w="90" h="879" /> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>879</height> - <onleft>101</onleft> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - </control> - </control> - - <control type="group" id="150"> - <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>151</defaultcontrol> - <posx>1830</posx> - <posy>150</posy> - <width>20</width> - <height>920</height> - <control type="list" id="151"> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>1050</height> - <onleft>100</onleft> - <onright>152</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>34</height> - <colordiffuse>FFE5A00D</colordiffuse> - <texture border="12">script.plex/white-outline-rounded.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE][COLOR=gray]$INFO[Window.Property(items.count), (,)][/COLOR]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <onright>211</onright> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="grouplist" id="600"> - <defaultcontrol>311</defaultcontrol> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <right>340</right> - <posy>35</posy> - <width>1000</width> - <height>65</height> - <align>right</align> - <itemgap>30</itemgap> - <orientation>horizontal</orientation> - <onleft>204</onleft> - <onright>210</onright> - <ondown>50</ondown> - <control type="button" id="311"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> - </control> - <control type="button" id="211"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="500">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> - </control> - <control type="button" id="310"> - <visible>!String.IsEqual(Window.Property(media),show) + !String.IsEqual(Window.Property(media),movie)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturenofocus>-</texturenofocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="312"> - <visible>String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="210"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-square-chunked.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-listview-square-chunked.xml deleted file mode 100644 index b3aab30787..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-square-chunked.xml +++ /dev/null @@ -1,943 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture fallback="script.plex/home/background-fallback.png" background="true">$INFO[Window.Property(background)]</texture> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>750</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="wraplist" id="101"> - <hitrect x="60" y="0" w="1010" h="945" /> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>945</height> - <onup>600</onup> - <onright>151</onright> - <onleft>304</onleft> - <scrolltime>0</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <focusposition>5</focusposition> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="76"> - <control type="group"> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-3</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][COLOR FFE5A00D]/[/COLOR][/B]</label> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer)) + !String.IsEmpty(ListItem.Label)</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="76"> - <control type="group"> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-2</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][COLOR FFE5A00D]/[/COLOR][/B]</label> - </control> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer)) + !String.IsEmpty(ListItem.Label)</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1085</width> - <height>156</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1005</width> - <height>76</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>957</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched-rounded.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>933</posx> - <posy>15</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>23</posy> - <width>885</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>23</posy> - <width>885</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>[B]$INFO[ListItem.Label]/[/B]</label> - </control> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),album)</visible> - <hitrect x="1108" y="33" w="90" h="879" /> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>879</height> - <onleft>101</onleft> - <onright>951</onright> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - <control type="group"> - <visible>String.IsEqual(Window(10000).Property(script.plex.item.type),album)</visible> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>879</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>879</height> - <texture colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texture> - </control> - <control type="group" id="950"> - <posx>0</posx> - <posy>0</posy> - <control type="image" id="952"> - <visible>!Control.HasFocus(951) + String.IsEmpty(Window.Property(dragging))</visible> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>10</height> - <texture colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texture> - </control> - <control type="image" id="953"> - <visible>Control.HasFocus(951) | !String.IsEmpty(Window.Property(dragging))</visible> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>10</height> - <texture colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texture> - </control> - </control> - <control type="button" id="951"> - <hitrect x="-20" y="0" w="90" h="879" /> - <posx>0</posx> - <posy>0</posy> - <width>10</width> - <height>879</height> - <onleft>152</onleft> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - </control> - </control> - - <control type="image"> - <posx>0</posx> - <posy>-135</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture fallback="script.plex/home/background-fallback.png" background="true" diffuse="script.plex/masks/listview-16x9-backgroundmask.png">$INFO[Window.Property(background)]</texture> - </control> - - <control type="grouplist" id="300"> - <defaultcontrol>301</defaultcontrol> - <posx>30</posx> - <posy>-25</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>101</ondown> - <onright>101</onright> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(no.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/chapters-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/chapters.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - - <control type="group"> - <posx>60</posx> - <posy>248</posy> - <control type="group"> - <visible>String.IsEqual(Window.Property(media),photo) | String.IsEqual(Window.Property(media),photodirectory)</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <texture colordiffuse="A0000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/photo.png">$INFO[Container(101).ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(media),artist)</visible> - <posx>0</posx> - <posy>0</posy> - <width>355</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/music.png">$INFO[Container(101).ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(Container(101).ListItem.Label2)</visible> - <control type="label"> - <posx>0</posx> - <posy>355</posy> - <width>510</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>630</posx> - <posy>355</posy> - <width>110</width> - <height>80</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label2][/B]</label> - </control> - </control> - <control type="group"> - <visible>String.IsEmpty(Container(101).ListItem.Label2)</visible> - <control type="label"> - <posx>0</posx> - <posy>355</posy> - <width>630</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>435</posy> - <width>630</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>463</posy> - <width>630</width> - <height>307</height> - <font>font12</font> - <align>left</align> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Container(101).ListItem.Property(camera.model),,[CR]]$INFO[Container(101).ListItem.Property(camera.lens),,[CR]]$INFO[Container(101).ListItem.Property(photo.dims),,[CR]]$INFO[Container(101).ListItem.Property(camera.settings),,[CR]]$INFO[Container(101).ListItem.Property(photo.summary),[CR],[CR]]$INFO[Container(101).ListItem.Property(summary)]</label> - </control> - </control> - - <control type="group" id="150"> - <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>151</defaultcontrol> - <posx>1830</posx> - <posy>150</posy> - <width>20</width> - <height>920</height> - <control type="list" id="151"> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>1050</height> - <onleft>100</onleft> - <onright>152</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>34</height> - <colordiffuse>FFE5A00D</colordiffuse> - <texture border="12">script.plex/white-outline-rounded.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <onright>211</onright> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="grouplist" id="600"> - <defaultcontrol>311</defaultcontrol> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <right>340</right> - <posy>35</posy> - <width>1000</width> - <height>65</height> - <align>right</align> - <itemgap>30</itemgap> - <orientation>horizontal</orientation> - <onleft>204</onleft> - <onright>210</onright> - <ondown>50</ondown> - <control type="button" id="311"> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> - </control> - <control type="button" id="211"> - <width max="500">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> - </control> - <control type="button" id="310"> - <visible>!String.IsEqual(Window.Property(media),artist)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturenofocus>-</texturenofocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="312"> - <visible>String.IsEqual(Window.Property(media),artist)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="210"> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-square.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-listview-square.xml deleted file mode 100644 index b5349dbb0b..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-listview-square.xml +++ /dev/null @@ -1,916 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group"> - <posx>60</posx> - <posy>248</posy> - <control type="group"> - <visible>String.IsEqual(Window.Property(media),photo) | String.IsEqual(Window.Property(media),photodirectory)</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <texture colordiffuse="A0000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>630</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/photo.png">$INFO[Container(101).ListItem.Thumb]</texture> - <aspectratio>keep</aspectratio> - </control> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(media),artist)</visible> - <posx>0</posx> - <posy>0</posy> - <width>355</width> - <height>355</height> - <fadetime>500</fadetime> - <texture background="true" fallback="script.plex/thumb_fallbacks/music.png">$INFO[Container(101).ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(Container(101).ListItem.Label2)</visible> - <control type="label"> - <posx>0</posx> - <posy>355</posy> - <width>310</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>630</posx> - <posy>355</posy> - <width>310</width> - <height>80</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label2][/B]</label> - </control> - </control> - <control type="group"> - <visible>String.IsEmpty(Container(101).ListItem.Label2)</visible> - <control type="label"> - <posx>0</posx> - <posy>355</posy> - <width>630</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>435</posy> - <width>630</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>463</posy> - <width>630</width> - <height>307</height> - <font>font12</font> - <align>left</align> - <textcolor>FFDDDDDD</textcolor> - <label>$INFO[Container(101).ListItem.Property(camera.model),,[CR]]$INFO[Container(101).ListItem.Property(camera.lens),,[CR]]$INFO[Container(101).ListItem.Property(photo.dims),,[CR]]$INFO[Container(101).ListItem.Property(camera.settings),,[CR]]$INFO[Container(101).ListItem.Property(photo.summary),[CR],[CR]]$INFO[Container(101).ListItem.Property(summary)]</label> - </control> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <defaultcontrol>301</defaultcontrol> - <posx>30</posx> - <posy>-25</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>101</ondown> - <onright>101</onright> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="button" id="301"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(no.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/chapters-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/chapters.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>750</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="list" id="101"> - <hitrect x="60" y="0" w="1010" h="945" /> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>945</height> - <onup>600</onup> - <onright>151</onright> - <onleft>304</onleft> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="76"> - <control type="group"> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-3</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][COLOR FFE5A00D]/[/COLOR][/B]</label> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="76"> - <control type="group"> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>880</posx> - <posy>-2</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>861</posx> - <posy>14</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>42</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>915</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][COLOR FFE5A00D]/[/COLOR][/B]</label> - </control> - </control> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>72</posy> - <width>915</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1085</width> - <height>156</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1005</width> - <height>76</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>957</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched-rounded.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>933</posx> - <posy>15</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square-rounded.png</texture> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>57</width> - <height>46</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>885</width> - <height>72</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>885</width> - <height>72</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>[B]$INFO[ListItem.Label]/[/B]</label> - </control> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1108" y="33" w="90" h="879" /> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>879</height> - <onleft>101</onleft> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - </control> - </control> - - <control type="group" id="150"> - <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>151</defaultcontrol> - <posx>1830</posx> - <posy>150</posy> - <width>20</width> - <height>920</height> - <control type="list" id="151"> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>1050</height> - <onleft>100</onleft> - <onright>152</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>34</height> - <colordiffuse>FFE5A00D</colordiffuse> - <texture border="12">script.plex/white-outline-rounded.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE][COLOR=gray]$INFO[Window.Property(items.count), (,)][/COLOR]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <onright>211</onright> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="grouplist" id="600"> - <defaultcontrol>311</defaultcontrol> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <right>340</right> - <posy>35</posy> - <width>1000</width> - <height>65</height> - <align>right</align> - <itemgap>30</itemgap> - <orientation>horizontal</orientation> - <onleft>204</onleft> - <onright>210</onright> - <ondown>50</ondown> - <control type="button" id="311"> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> - </control> - <control type="button" id="211"> - <width max="500">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> - </control> - <control type="button" id="310"> - <visible>!String.IsEqual(Window.Property(media),artist)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturenofocus>-</texturenofocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="312"> - <visible>String.IsEqual(Window.Property(media),artist)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="210"> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-music_current_playlist.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-music_current_playlist.xml deleted file mode 100644 index 28881da16a..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-music_current_playlist.xml +++ /dev/null @@ -1,790 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + !String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="group"> - <visible>false</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Player.Art(fanart)]</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Player.Art(fanart))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>D0404040</colordiffuse> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Player.Art(landscape)]</texture> - </control> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>0</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="group"> - <posx>90</posx> - <posy>0</posy> - <control type="image"> - <posx>-15</posx> - <posy>75</posy> - <width>669</width> - <height>669</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>90</posy> - <width>639</width> - <height>639</height> - <texture>$INFO[Player.Art(thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>0</posx> - <posy>764</posy> - <width>639</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[MusicPlayer.Artist]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>799</posy> - <width>639</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[MusicPlayer.Album]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>834</posy> - <width>639</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[MusicPlayer.Title][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>869</posy> - <width>639</width> - <height>35</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Player.Time]$INFO[MusicPlayer.Duration, / ]</label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>819</posx> - <posy>0</posy> - <width>1101</width> - <height>1080</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1101</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="list" id="101"> - <posx>0</posx> - <posy>0</posy> - <width>1101</width> - <height>1080</height> - <onup>200</onup> - <onright>152</onright> - <onleft>411</onleft> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="100"> - <control type="group"> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>2</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>74</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>168</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>723</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>723</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="label"> - <posx>661</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>97</posy> - <width>861</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="100"> - <control type="group"> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>0</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>74</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>168</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>723</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>723</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="label"> - <posx>669</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>97</posy> - <width>861</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1055</width> - <height>180</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>975</width> - <height>100</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="label"> - <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>24</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>36</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>103</posx> - <posy>0</posy> - <width>100</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>235</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>16</posy> - <width>669</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>51</posy> - <width>669</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>98000000</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="label"> - <posx>735</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - </control> - </control> - - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1039" y="33" w="90" h="1014" /> - <left>1059</left> - <top>33</top> - <width>10</width> - <height>1014</height> - <onleft>101</onleft> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - </control> - </control> - - <control type="grouplist" id="400"> - <defaultcontrol>406</defaultcontrol> - <hitrect x="460" y="998" w="1000" h="55" /> - <posx>0</posx> - <posy>964</posy> - <width>819</width> - - <height>124</height> - <align>center</align> - <onup>500</onup> - <onright>100</onright> - <itemgap>-40</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>false</usecontrolcoords> - <control type="group" id="421"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false" condition="Control.HasFocus(401)">Conditional</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false" condition="!Control.HasFocus(401)">Conditional</animation> - <width>125</width> - <height>101</height> - <control type="button" id="401"> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <onup>100</onup> - <onright>402</onright> - <onleft>411</onleft> - <font>font12</font> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - <control type="group"> - <visible>!Control.HasFocus(401)</visible> - <control type="image"> - <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/repeat.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeatOne</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-one.png</texture> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(401)</visible> - <control type="image"> - <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFE5A00D">script.plex/buttons/repeat-focus.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-focus.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeatOne</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-one-focus.png</texture> - </control> - </control> - </control> - - <control type="togglebutton" id="402"> - <visible>String.IsEmpty(Window.Property(pq.isremote))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <usealttexture>Playlist.IsRandom</usealttexture> - <alttexturefocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle.png</alttexturenofocus> - <onclick>PlayerControl(RandomOn)</onclick> - <altclick>PlayerControl(RandomOff)</altclick> - <label> </label> - </control> - - <control type="group" id="432"> - <visible>!String.IsEmpty(Window.Property(pq.isremote))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false" condition="Control.HasFocus(422)">Conditional</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false" condition="!Control.HasFocus(422)">Conditional</animation> - <width>125</width> - <height>101</height> - <control type="button" id="422"> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <onup>100</onup> - <onright>404</onright> - <onleft>401</onleft> - <font>font12</font> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - <control type="group"> - <visible>String.IsEmpty(Window.Property(pq.shuffled))</visible> - <control type="image"> - <visible>!Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texture> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(pq.shuffled))</visible> - <control type="image"> - <visible>!Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/shuffle.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/shuffle-focus.png</texture> - </control> - </control> - </control> - - <control type="button" id="404"> - <enable>MusicPlayer.HasPrevious | !String.IsEmpty(Window.Property(pq.hasprevious))</enable> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="togglebutton" id="406"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/pause-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pause.png</texturenofocus> - <usealttexture>Player.Paused | Player.Forwarding | Player.Rewinding</usealttexture> - <alttexturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</alttexturenofocus> - <!-- <enable>Player.PauseEnabled</enable> --> - <onclick>PlayerControl(Play)</onclick> - <label> </label> - </control> - <control type="button" id="407"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/stop-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/stop.png</texturenofocus> - <onclick>PlayerControl(Stop)</onclick> - <label> </label> - </control> - <control type="button" id="409"> - <enable>MusicPlayer.HasNext | !String.IsEmpty(Window.Property(pq.hasnext))</enable> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - - <control type="button" id="410"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/pqueue-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pqueue.png</texturenofocus> - <label> </label> - <onclick>Close</onclick> - </control> - <control type="button" id="411"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>940</posy> - <control type="button" id="500"> - <enable>Player.HasAudio</enable> - <hitrect x="0" y="-19" w="819" h="48" /> - <posx>0</posx> - <posy>0</posy> - <width>819</width> - <height>10</height> - <onup>100</onup> - <ondown>400</ondown> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image" id="510"> - <visible>Control.HasFocus(500)</visible> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>0</posx> - <posy>1</posy> - <width>1</width> - <height>8</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="progress"> - <visible>!Control.HasFocus(500)</visible> - <description>Progressbar</description> - <posx>0</posx> - <posy>2</posy> - <width>819</width> - <height>6</height> - <texturebg>script.plex/transparent-6px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-6px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - <control type="progress"> - <visible>Control.HasFocus(500)</visible> - <description>Progressbar</description> - <posx>0</posx> - <posy>2</posy> - <width>819</width> - <height>6</height> - <texturebg>script.plex/transparent-6px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFAC5B00">script.plex/white-square-6px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - - <!-- <control type="slider"> - <posx>0</posx> - <posy>942</posy> - <width>819</width> - <height>6</height> - <visible>true</visible> - <texturesliderbar>-</texturesliderbar> - <textureslidernib colordiffuse="FFE5A00D">script.plex/white-square-6px.png</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <action>seek</action> - </control> --> - - <!-- <control type="image" id="201"> - <visible>!Control.HasFocus(100) + !Control.HasFocus(500)</visible> - <animation effect="fade" time="100" delay="100" end="0">Hidden</animation> - <posx>0</posx> - <posy>942</posy> - <width>1</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> --> - - <control type="group" id="202"> - <visible>Control.HasFocus(500)</visible> - <posx>0</posx> - <posy>896</posy> - <control type="group" id="203"> - <posx>-50</posx> - <posy>0</posy> - <control type="image"> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>0</posx> - <posy>0</posy> - <width>101</width> - <height>39</height> - <texture>script.plex/indicators/player-selection-time_box.png</texture> - <colordiffuse>D0000000</colordiffuse> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>101</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(time.selection)]</label> - </control> - </control> - <control type="image"> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>-6</posx> - <posy>39</posy> - <width>15</width> - <height>7</height> - <texture>script.plex/indicators/player-selection-time_arrow.png</texture> - <colordiffuse>D0000000</colordiffuse> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-music_player.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-music_player.xml deleted file mode 100644 index 18926cfc26..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-music_player.xml +++ /dev/null @@ -1,578 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <defaultcontrol>406</defaultcontrol> - <controls> - <control type="group"> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + !String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="group"> - <visible>false</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Player.Art(fanart)]</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Player.Art(fanart))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>D0404040</colordiffuse> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Player.Art(landscape)]</texture> - </control> - </control> - - <control type="image"> - <posx>75</posx> - <posy>75</posy> - <width>786</width> - <height>786</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>90</posx> - <posy>90</posy> - <width>756</width> - <height>756</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <posx>939</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>305</posy> - <width>1000</width> - <height>54</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[MusicPlayer.Artist]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>359</posy> - <width>1000</width> - <height>54</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[MusicPlayer.Album]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>470</posy> - <width>1000</width> - <height>54</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[MusicPlayer.Title][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>580</posy> - <width>1000</width> - <height>54</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Player.Time]$INFO[MusicPlayer.Duration, / ]</label> - </control> - </control> - - <control type="group"> - <posx>1845</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>738</posy> - <width>1000</width> - <height>54</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>80FFFFFF</textcolor> - <label>$INFO[MusicPlayer.offset(1).Artist]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>794</posy> - <width>1000</width> - <height>54</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>80FFFFFF</textcolor> - <label>$INFO[MusicPlayer.offset(1).Title]</label> - </control> - </control> - - <!-- <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>140</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - - <control type="group"> - <posx>0</posx> - <posy>940</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>140</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>965</posy> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(time.current)]</label> - </control> - <control type="label"> - <posx>1860</posx> - <posy>0</posy> - <width>800</width> - <height>60</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(time.duration)]</label> - </control> - <control type="label"> - <posx>1860</posx> - <posy>40</posy> - <width>800</width> - <height>60</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>A0FFFFFF</textcolor> - <label>$INFO[Window.Property(time.end)]</label> - </control> - </control> --> - - <control type="grouplist" id="400"> - <defaultcontrol>406</defaultcontrol> - <hitrect x="460" y="998" w="1000" h="55" /> - <posx>360</posx> - <posy>964</posy> - <width>1200</width> - - <height>124</height> - <align>center</align> - <onup>100</onup> - <itemgap>-40</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="group" id="421"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false" condition="Control.HasFocus(401)">Conditional</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false" condition="!Control.HasFocus(401)">Conditional</animation> - <width>125</width> - <height>101</height> - <control type="button" id="401"> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <onup>100</onup> - <onright>402</onright> - <onleft>411</onleft> - <font>font12</font> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - <control type="group"> - <visible>!Control.HasFocus(401)</visible> - <control type="image"> - <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/repeat.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeatOne</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-one.png</texture> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(401)</visible> - <control type="image"> - <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFE5A00D">script.plex/buttons/repeat-focus.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-focus.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeatOne</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-one-focus.png</texture> - </control> - </control> - </control> - - <control type="togglebutton" id="402"> - <visible>String.IsEmpty(Window.Property(pq.isremote))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <usealttexture>Playlist.IsRandom</usealttexture> - <alttexturefocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle.png</alttexturenofocus> - <onclick>PlayerControl(RandomOn)</onclick> - <altclick>PlayerControl(RandomOff)</altclick> - <label> </label> - </control> - - <control type="group" id="432"> - <visible>!String.IsEmpty(Window.Property(pq.isremote))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false" condition="Control.HasFocus(422)">Conditional</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false" condition="!Control.HasFocus(422)">Conditional</animation> - <width>125</width> - <height>101</height> - <control type="button" id="422"> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <onup>100</onup> - <onright>404</onright> - <onleft>401</onleft> - <font>font12</font> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - <control type="group"> - <visible>String.IsEmpty(Window.Property(pq.shuffled))</visible> - <control type="image"> - <visible>!Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texture> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(pq.shuffled))</visible> - <control type="image"> - <visible>!Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/shuffle.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(422)</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/shuffle-focus.png</texture> - </control> - </control> - </control> - - <control type="button" id="404"> - <enable>MusicPlayer.HasPrevious | !String.IsEmpty(Window.Property(pq.hasprevious))</enable> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="togglebutton" id="406"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/pause-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pause.png</texturenofocus> - <usealttexture>Player.Paused | Player.Forwarding | Player.Rewinding</usealttexture> - <alttexturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</alttexturenofocus> - <!-- <enable>Player.PauseEnabled</enable> --> - <onclick>PlayerControl(Play)</onclick> - <label> </label> - </control> - <control type="button" id="407"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/stop-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/stop.png</texturenofocus> - <onclick>PlayerControl(Stop)</onclick> - <label> </label> - </control> - <control type="button" id="409"> - <enable>MusicPlayer.HasNext | !String.IsEmpty(Window.Property(pq.hasnext))</enable> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - - - <control type="button" id="410"> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/pqueue-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pqueue.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="411"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>940</posy> - <control type="button" id="100"> - <enable>Player.HasAudio</enable> - <hitrect x="0" y="-19" w="1920" h="48" /> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>10</height> - <ondown>400</ondown> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image" id="200"> - <visible>Control.HasFocus(100)</visible> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>0</posx> - <posy>1</posy> - <width>1</width> - <height>8</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="progress"> - <visible>!Control.HasFocus(100)</visible> - <description>Progressbar</description> - <posx>0</posx> - <posy>2</posy> - <width>1920</width> - <height>6</height> - <texturebg>script.plex/transparent-6px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-6px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - <control type="progress"> - <visible>Control.HasFocus(100)</visible> - <description>Progressbar</description> - <posx>0</posx> - <posy>2</posy> - <width>1920</width> - <height>6</height> - <texturebg>script.plex/transparent-6px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFAC5B00">script.plex/white-square-6px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - - <!-- <control type="slider"> - <posx>0</posx> - <posy>942</posy> - <width>1920</width> - <height>6</height> - <visible>true</visible> - <texturesliderbar>-</texturesliderbar> - <textureslidernib colordiffuse="FFE5A00D">script.plex/white-square-6px.png</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <action>seek</action> - </control> --> - - <!-- <control type="image" id="201"> - <visible>!Control.HasFocus(100) + !Control.HasFocus(500)</visible> - <animation effect="fade" time="100" delay="100" end="0">Hidden</animation> - <posx>0</posx> - <posy>942</posy> - <width>1</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> --> - - <control type="group" id="202"> - <visible>Control.HasFocus(100)</visible> - <posx>0</posx> - <posy>896</posy> - <control type="group" id="203"> - <posx>-50</posx> - <posy>0</posy> - <control type="image"> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>0</posx> - <posy>0</posy> - <width>101</width> - <height>39</height> - <texture>script.plex/indicators/player-selection-time_box.png</texture> - <colordiffuse>D0000000</colordiffuse> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>101</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(time.selection)]</label> - </control> - </control> - <control type="image"> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>-6</posx> - <posy>39</posy> - <width>15</width> - <height>7</height> - <texture>script.plex/indicators/player-selection-time_arrow.png</texture> - <colordiffuse>D0000000</colordiffuse> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-options_dialog.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-options_dialog.xml deleted file mode 100644 index 3c0ab818fc..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-options_dialog.xml +++ /dev/null @@ -1,136 +0,0 @@ -<window> - <defaultcontrol>1001</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <controls> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060" border="10">script.plex/white-square.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <posx>585</posx> - <posy>360</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>830</width> - <height>440</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>750</width> - <height>360</height> - <texture colordiffuse="EE323232" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>750</width> - <height>80</height> - <texture colordiffuse="99000000" border="10">script.plex/white-square-top-rounded.png</texture> - </control> - - <control type="image"> - <posx>48</posx> - <posy>31</posy> - <width>19</width> - <height>19</height> - <texture colordiffuse="FFE5A00D">script.plex/indicators/circle-19.png</texture> - </control> - - <control type="label"> - <posx>115</posx> - <posy>0</posy> - <width>575</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[Window.Property(header)]</label> - </control> - - <control type="textbox"> - <posx>115</posx> - <posy>105</posy> - <width>575</width> - <height>125</height> - <font>font10</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(info)]</label> - </control> - - <control type="grouplist" id="100"> - <defaultcontrol always="true">1001</defaultcontrol> - <posx>-10</posx> - <posy>220</posy> - <width>770</width> - <height>155</height> - <align>center</align> - <itemgap>-50</itemgap> - <orientation>horizontal</orientation> - <scrolltime>0</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="1001"> - <visible allowhiddenfocus="true">!String.IsEmpty(Window.Property(button.0))</visible> - <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> - <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width min="120">auto</width> - <height>143</height> - <font>font10</font> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> - <textoffsetx>70</textoffsetx> - <textcolor>FF000000</textcolor> - <focusedcolor>FF000000</focusedcolor> - <label>$INFO[Window.Property(button.0)]</label> - </control> - <control type="button" id="1002"> - <visible>!String.IsEmpty(Window.Property(button.1))</visible> - <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> - <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width min="120">auto</width> - <height>143</height> - <font>font10</font> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> - <textoffsetx>70</textoffsetx> - <textcolor>FF000000</textcolor> - <focusedcolor>FF000000</focusedcolor> - <label>$INFO[Window.Property(button.1)]</label> - </control> - <control type="button" id="1003"> - <visible>!String.IsEmpty(Window.Property(button.2))</visible> - <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> - <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width min="120">auto</width> - <height>143</height> - <font>font10</font> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> - <textoffsetx>70</textoffsetx> - <textcolor>FF000000</textcolor> - <focusedcolor>FF000000</focusedcolor> - <label>$INFO[Window.Property(button.2)]</label> - </control> - </control> - - </control> - </controls> -</window> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-photo.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-photo.xml deleted file mode 100644 index 57e2c151b2..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-photo.xml +++ /dev/null @@ -1,725 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <defaultcontrol>250</defaultcontrol> - <zorder>100</zorder> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - <control type="image" id="600"> - <!-- Doesn't work for all aspects --> - <!-- <animation effect="zoom" start="56" end="100" time="200" center="960,540" reversible="false" condition="String.IsEqual(Window.Property(rotate),90) | String.IsEqual(Window.Property(rotate),270)">Conditional</animation> - <animation effect="zoom" start="178" end="100" time="200" center="960,540" reversible="false" condition="String.IsEqual(Window.Property(rotate),0) | String.IsEqual(Window.Property(rotate),180)">Conditional</animation> --> - <animation effect="rotate" time="200" start="0" end="90" center="960,540" reversible="false" condition="Integer.IsGreater(Window.Property(rotate),89)">Conditional</animation> - <animation effect="rotate" time="200" start="0" end="90" center="960,540" reversible="false" condition="Integer.IsGreater(Window.Property(rotate),179)">Conditional</animation> - <animation effect="rotate" time="200" start="0" end="90" center="960,540" reversible="false" condition="Integer.IsGreater(Window.Property(rotate),269)">Conditional</animation> - <animation effect="rotate" time="200" start="270" end="360" center="960,540" reversible="false" condition="!Integer.IsGreater(Window.Property(rotate),89)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(photo)]</texture> - <aspectratio>keep</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(is.updating))</visible> - <animation effect="fade" time="500" delay="500">VisibleChange</animation> - <control type="image"> - <posx>840</posx> - <posy>465</posy> - <width>240</width> - <height>150</height> - <texture>script.plex/busy-back.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>915</posx> - <posy>521</posy> - <width>90</width> - <height>38</height> - <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> - </control> - </control> - </control> - <control type="togglebutton" id="250"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <usealttexture>!String.IsEmpty(Window.Property(OSD))</usealttexture> - <alttexturefocus>-</alttexturefocus> - <alttexturenofocus>-</alttexturenofocus> - <label> </label> - <onclick>SetProperty(OSD,1)</onclick> - <onclick>SetFocus(400)</onclick> - <altclick>SetProperty(OSD,)</altclick> - <ondown>SetProperty(OSD,1)</ondown> - <ondown>SetFocus(400)</ondown> - <onfocus condition="!String.IsEmpty(Window.Property(show.pqueue))">SetFocus(501)</onfocus> - <onfocus condition="!String.IsEmpty(Window.Property(OSD))">SetFocus(400)</onfocus> - </control> - <control type="group" id="200"> - <animation effect="slide" start="0,0" end="0,-135" time="100" condition="!String.IsEmpty(Window.Property(show.pqueue))">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <visible allowhiddenfocus="true">!String.IsEmpty(Window.Property(OSD))</visible> - <control type="image"> - <posx>0</posx> - <posy>940</posy> - <width>1920</width> - <height>140</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="grouplist" id="400"> - <defaultcontrol>406</defaultcontrol> - <hitrect x="460" y="998" w="1000" h="55" /> - <posx>360</posx> - <posy>964</posy> - <width>1200</width> - - <height>124</height> - <align>center</align> - <onup>250</onup> - <onup>SetProperty(OSD,)</onup> - <ondown>250</ondown> - <onup>SetProperty(OSD,)</onup> - <itemgap>-40</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - - <control type="togglebutton" id="401"> - <visible>String.IsEmpty(Window.Property(no.playlist))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/repeat-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/repeat.png</texturenofocus> - <usealttexture>!String.IsEmpty(Window.Property(pq.repeat))</usealttexture> - <alttexturefocus colordiffuse="FFCC7B19">script.plex/buttons/repeat-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="FFCC7B19">script.plex/buttons/repeat.png</alttexturenofocus> - <label> </label> - </control> - <control type="button" id="421"> - <enable>false</enable> - <visible>!String.IsEmpty(Window.Property(no.playlist))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="40FFFFFF">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="40FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - - <control type="togglebutton" id="402"> - <visible>String.IsEmpty(Window.Property(no.playlist))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <usealttexture>!String.IsEmpty(Window.Property(pq.shuffled))</usealttexture> - <alttexturefocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle.png</alttexturenofocus> - <label> </label> - </control> - <control type="button" id="422"> - <enable>false</enable> - <visible>!String.IsEmpty(Window.Property(no.playlist))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="40FFFFFF">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="40FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - - <control type="button" id="403"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/rotate-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/rotate.png</texturenofocus> - <label> </label> - </control> - - - <control type="button" id="404"> - <visible>String.IsEmpty(Window.Property(hide.prev))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="58" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="424"> - <enable>false</enable> - <visible>!String.IsEmpty(Window.Property(hide.prev))</visible> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="40FFFFFF">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="40FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="togglebutton" id="406"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <usealttexture>!String.IsEmpty(Window.Property(playing))</usealttexture> - <alttexturefocus colordiffuse="FFE5A00D">script.plex/buttons/pause-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pause.png</alttexturenofocus> - <label> </label> - </control> - <control type="button" id="407"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/stop-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/stop.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="409"> - <visible>String.IsEmpty(Window.Property(hide.next))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="419"> - <enable>false</enable> - <visible>!String.IsEmpty(Window.Property(hide.next))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texturefocus colordiffuse="40FFFFFF">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus colordiffuse="40FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - - - <control type="togglebutton" id="412"> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="58" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/square2x2-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/square2x2.png</texturenofocus> - <usealttexture>!String.IsEmpty(Window.Property(show.pqueue))</usealttexture> - <alttexturefocus colordiffuse="FFCC7B19">script.plex/buttons/square2x2-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="FFCC7B19">script.plex/buttons/square2x2-focus.png</alttexturenofocus> - <onclick>SetProperty(show.pqueue,1)</onclick> - <altclick>SetProperty(show.pqueue,)</altclick> - <label> </label> - </control> - <control type="togglebutton" id="413"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/info-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/info.png</texturenofocus> - <usealttexture>!String.IsEmpty(Window.Property(show.info))</usealttexture> - <alttexturefocus colordiffuse="FFCC7B19">script.plex/buttons/info-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="FFCC7B19">script.plex/buttons/info-focus.png</alttexturenofocus> - <onclick>SetProperty(show.info,1)</onclick> - <altclick>SetProperty(show.info,)</altclick> - <label> </label> - </control> - <control type="button" id="414"> - <visible>false</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/tags-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/tags.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="411"> - <visible>false</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - - <control type="button" id="501"> - <posx>0</posx> - <posy>1080</posy> - <width>1920</width> - <height>135</height> - <onup>SetProperty(OSD,1)</onup> - <onup>400</onup> - <font>font12</font> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - <onclick>SetProperty(OSD,1)</onclick> - <onclick>SetFocus(400)</onclick> - </control> - - <control type="image"> - <posx>0</posx> - <posy>1080</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="fixedlist" id="500"> - <posx>0</posx> - <posy>1080</posy> - <width>1920</width> - <height>135</height> - <hitrect x="28" y="28" w="69" h="45" /> - - <scrolltime>0</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <focusposition>7</focusposition> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="128"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>2.5</posx> - <posy>6</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>123</width> - <height>123</height> - <texture>script.plex/thumb_fallbacks/photo.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>123</width> - <height>123</height> - <texture fallback="script.plex/thumb_fallbacks/broken-photo-thumb.png" background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="128"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>2.5</posx> - <posy>6</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>123</width> - <height>123</height> - <texture>script.plex/thumb_fallbacks/photo.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>123</width> - <height>123</height> - <texture fallback="script.plex/thumb_fallbacks/broken-photo-thumb.png" background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - </control> - </control> - </focusedlayout> - </control> - <control type="image"> - <posx>892.5</posx> - <posy>1080</posy> - <width>135</width> - <height>135</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(show.info))</visible> - <posx>1470</posx> - <posy>0</posy> - <width>450</width> - <height>1080</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>450</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>4C000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>0</posx> - <posy>0</posy> - <width>450</width> - <height>1080</height> - <itemgap>0</itemgap> - <orientation>vertical</orientation> - - <control type="button"> - <!-- margin --> - <width>450</width> - <height>21</height> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <colordiffuse>00000000</colordiffuse> - <label> </label> - </control> - <control type="button" id="650"> - <width>450</width> - <height>37</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>00000000</colordiffuse> - <align>left</align> - <align>center</align> - <textoffsetx>28</textoffsetx> - <font>font12</font> - <label>[B]$INFO[Window.Property(photo.title)][/B]</label> - </control> - <control type="button" id="659"> - <width>450</width> - <height>37</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>00000000</colordiffuse> - <align>left</align> - <align>center</align> - <textoffsetx>28</textoffsetx> - <font>font12</font> - <label>$INFO[Window.Property(photo.date)]</label> - </control> - <control type="button"> - <!-- margin --> - <width>450</width> - <height>21</height> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <colordiffuse>00000000</colordiffuse> - <label> </label> - </control> - - <control type="button"> - <!-- margin --> - <width>450</width> - <height>21</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <label> </label> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(camera.model))</visible> - <width>450</width> - <height>37</height> - <control type="button"> - <posx>0</posx> - <posy>0</posy> - <width>450</width> - <height>37</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <align>left</align> - <align>center</align> - <textoffsetx>28</textoffsetx> - <font>font12</font> - <label>$INFO[Window.Property(camera.model)]</label> - </control> - <control type="image"> - <posx>393</posx> - <posy>6</posy> - <width>29</width> - <height>24</height> - <texture>script.plex/indicators/camera.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - </control> - <control type="button"> - <visible>!String.IsEmpty(Window.Property(camera.lens))</visible> - <width>450</width> - <height>37</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <align>left</align> - <align>center</align> - <textoffsetx>28</textoffsetx> - <font>font12</font> - <label>$INFO[Window.Property(camera.lens)]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(photo.container))</visible> - <posx>0</posx> - <posy>0</posy> - <width>450</width> - <height>37</height> - <control type="button"> - <posx>0</posx> - <posy>0</posy> - <width>450</width> - <height>37</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <align>left</align> - <align>center</align> - <textoffsetx>28</textoffsetx> - <font>font12</font> - <label>$INFO[Window.Property(photo.dims)]</label> - </control> - <control type="grouplist"> - <right>28</right> - <posy>5</posy> - <width>200</width> - <height>26</height> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <align>right</align> - <control type="button"> - <width>auto</width> - <height>26</height> - <font>font10</font> - <align>center</align> - <aligny>top</aligny> - <focusedcolor>FF000000</focusedcolor> - <textcolor>FF000000</textcolor> - <textoffsetx>5</textoffsetx> - <textoffsety>-3</textoffsety> - <texturefocus colordiffuse="A0FFFFFF" border="12">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus colordiffuse="A0FFFFFF" border="12">script.plex/white-square-rounded.png</texturenofocus> - <label>[UPPERCASE]$INFO[Window.Property(photo.container)][/UPPERCASE]</label> - </control> - </control> - </control> - <control type="button"> - <!-- margin --> - <width>450</width> - <height>21</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <label> </label> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(camera.settings))</visible> - <width>450</width> - <height>80</height> - <!-- sep --> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>450</width> - <height>1</height> - <texture border="30,0,30,0">script.plex/indicators/info-sep.png</texture> - <colordiffuse>99000000</colordiffuse> - </control> - <control type="image"> - <posx>28</posx> - <posy>0</posy> - <width>394</width> - <height>1</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>999B9B9B</colordiffuse> - </control> - <control type="button"> - <!-- margin --> - <posx>0</posx> - <posy>1</posy> - <width>450</width> - <height>21</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <label> </label> - </control> - <control type="button"> - <posx>0</posx> - <posy>22</posy> - <width>450</width> - <height>37</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <align>left</align> - <align>center</align> - <textoffsetx>28</textoffsetx> - <font>font12</font> - <label>$INFO[Window.Property(camera.settings)]</label> - </control> - <control type="button"> - <!-- margin --> - <posx>0</posx> - <posy>59</posy> - <width>450</width> - <height>21</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>99000000</colordiffuse> - <label> </label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(photo.summary))</visible> - <width>450</width> - <height>152</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>450</width> - <height>152</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>661F1F1F</colordiffuse> - </control> - <control type="textbox"> - <posx>28</posx> - <posy>24</posy> - <width>394</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <label>$INFO[Window.Property(photo.summary)]</label> - </control> - </control> - - <!-- <control type="button"> - <width>450</width> - <height>147</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>66000000</colordiffuse> - <font>font12</font> - </control> - <control type="button"> - <width>450</width> - <height>150</height> - <texturefocus>script.plex/white-square.png</texturefocus> - <texturenofocus>script.plex/white-square.png</texturenofocus> - <colordiffuse>661F1F1F</colordiffuse> - <font>font12</font> - </control> --> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-pin_login.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-pin_login.xml deleted file mode 100644 index 6dcac7f4ab..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-pin_login.xml +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - - <control type="image"> - <visible>!String.IsEmpty(Window.Property(pin.image.0))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/pin-display.jpg</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(pin.image.0)) + String.IsEmpty(Window.Property(linking))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/generating-code.jpg</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(linking))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/linking-account.jpg</texture> - </control> - - <control type="label"> - <posx>270</posx> - <posy>738</posy> - <width>800</width> - <height>153</height> - <font>WeatherTemp</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(pin)]</label> - </control> - - <control type="grouplist" id="400"> - <defaultcontrol>406</defaultcontrol> - <posx>265</posx> - <posy>708</posy> - <width>1000</width> - - <height>200</height> - <align>left</align> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <control type="image"> - <width>200</width> - <height>200</height> - <texture>$INFO[Window.Property(pin.image.0)]</texture> - </control> - <control type="image"> - <width>200</width> - <height>200</height> - <texture>$INFO[Window.Property(pin.image.1)]</texture> - </control> - <control type="image"> - <width>200</width> - <height>200</height> - <texture>$INFO[Window.Property(pin.image.2)]</texture> - </control> - <control type="image"> - <width>200</width> - <height>200</height> - <texture>$INFO[Window.Property(pin.image.3)]</texture> - </control> - - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-playlist.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-playlist.xml deleted file mode 100644 index 5c642c0c34..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-playlist.xml +++ /dev/null @@ -1,891 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="group"> - <posx>60</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>5</posy> - <width>420</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(playlist.title)]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>60</posy> - <width>420</width> - <height>40</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(playlist.duration)]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>142</posy> - <width>630</width> - <height>630</height> - <texture>$INFO[Window.Property(playlist.thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - </control> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <defaultcontrol always="true">303</defaultcontrol> - <posx>50</posx> - <posy>784</posy> - <width>650</width> - <height>145</height> - <onup>200</onup> - <onright>101</onright> - <itemgap>-50</itemgap> - <orientation>horizontal</orientation> - <align>center</align> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <visible>!String.IsEmpty(Window.Property(show.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="120" time="100" center="87,69.5" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="87,69.5" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="94" h="59" /> - <posx>0</posx> - <posy>0</posy> - <width>174</width> - <height>139</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>750</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>1080</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>20000000</colordiffuse> - </control> - <control type="list" id="101"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>945</height> - <onup>200</onup> - <onright>152</onright> - <onleft>300</onleft> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="100"> - <control type="group"> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(track.ID)) | !String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(track.ID)) + String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>2</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>74</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>168</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>132</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(watched))</visible> - <posx>895</posx> - <posy>-1</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <posx>226</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="label"> - <posx>730</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="group"> - <!-- Don't show the progress bar in the playlist because we don't start from the resume point so why show it --> - <visible>False <!-- !String.IsEmpty(ListItem.Property(progress)) --></visible> - <posx>63</posx> - <posy>85</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>870</width> - <height>8</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>870</width> - <height>6</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>97</posy> - <width>930</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="100"> - <control type="group"> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(track.ID)) | !String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(track.ID)) + String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>0</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>74</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>168</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>132</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(watched))</visible> - <posx>895</posx> - <posy>-1</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <posx>226</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="label"> - <posx>730</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>63</posx> - <posy>88</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>870</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>870</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>97</posy> - <width>930</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1124</width> - <height>180</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1044</width> - <height>100</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <!-- comment the previous and uncomment the following for re-enabling options button --> - <!--<control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>999</width> - <height>100</height> - <texture border="12">script.plex/white-square-left-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="image"> - <posx>999</posx> - <posy>0</posy> - <width>45</width> - <height>100</height> - <texture>script.plex/buttons/more-vertical.png</texture> - <colordiffuse>99FFFFFF</colordiffuse> - </control>--> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(track.ID)) | !String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>24</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(track.ID)) + String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> - <posx>36</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <posx>103</posx> - <posy>0</posy> - <width>100</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>235</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>16</posy> - <width>638</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>51</posy> - <width>638</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>98000000</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>103</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(watched))</visible> - <posx>951</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <posx>313</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>16</posy> - <width>510</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>51</posy> - <width>510</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>98000000</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="label"> - <posx>802</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>103</posx> - <posy>91</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>899</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>899</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - </control> - </control> - - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1108" y="33" w="90" h="879" /> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>879</height> - <onleft>101</onleft> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - </control> - </control> - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + false</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32333][/UPPERCASE]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-playlists.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-playlists.xml deleted file mode 100644 index f53b7f4779..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-playlists.xml +++ /dev/null @@ -1,575 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <posx>0</posx> - <posy>115</posy> - <defaultcontrol always="true">101</defaultcontrol> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>360</height> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32048][/UPPERCASE]</label> - </control> - <control type="list" id="101"> - <posx>0</posx> - <posy>30</posy> - <width>1920</width> - <height>390</height> - <onup>200</onup> - <ondown>301</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>2</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="298"> - <control type="group"> - <posx>40</posx> - <posy>40</posy> - <control type="group"> - <posx>21</posx> - <posy>21</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>238</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>238</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>-30</posx> - <posy>248</posy> - <width>298</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>-30</posx> - <posy>278</posy> - <width>298</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="298"> - <control type="group"> - <posx>40</posx> - <posy>40</posy> - <control type="group"> - <animation effect="zoom" start="100" end="116" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="116" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>-19</posx> - <posy>-19</posy> - <width>318</width> - <height>318</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>21</posx> - <posy>21</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>238</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>238</width> - <height>238</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>-30</posx> - <posy>248</posy> - <width>298</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>-30</posx> - <posy>278</posy> - <width>298</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>16</posx> - <posy>16</posy> - <width>248</width> - <height>248</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="300"> - <visible>Integer.IsGreater(Container(301).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <animation effect="slide" end="0,-420" condition="!Control.IsVisible(100)">Conditional</animation> - <defaultcontrol>301</defaultcontrol> - <posx>0</posx> - <posy>445</posy> - <width>1920</width> - <height>360</height> - <control type="image"> - <visible>Control.IsVisible(100)</visible> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>661F1F1F</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32053][/UPPERCASE]</label> - </control> - <control type="list" id="301"> - <posx>-21.5</posx> - <posy>30</posy> - <width>1941.5</width> - <height>700</height> - <onup>101</onup> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>2</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="602"> - <control type="group"> - <posx>40</posx> - <posy>40</posy> - <control type="group"> - <posx>41.5</posx> - <posy>25.5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>537</width> - <height>303</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>537</width> - <height>303</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>-30</posx> - <posy>313</posy> - <width>597</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>-30</posx> - <posy>343</posy> - <width>597</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="602"> - <control type="group"> - <posx>40</posx> - <posy>40</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="310,177" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="310,177" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(301)</visible> - <posx>1.5</posx> - <posy>-15.5</posy> - <width>617</width> - <height>383</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>41.5</posx> - <posy>25.5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>537</width> - <height>303</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>537</width> - <height>303</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <posx>-30</posx> - <posy>313</posy> - <width>597</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>-30</posx> - <posy>343</posy> - <width>597</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(301)</visible> - <posx>36.5</posx> - <posy>20.5</posy> - <width>547</width> - <height>313</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - </control> - - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + false</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32333][/UPPERCASE]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-plex_pass.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-plex_pass.xml deleted file mode 100644 index d4c0be6d5c..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-plex_pass.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/plexpass.jpg</texture> - </control> - - <control type="button" id="100"> - <posx>1436</posx> - <posy>802</posy> - <width>275</width> - <height>100</height> - <onup>200</onup> - <font>font13</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-posters-small.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-posters-small.xml deleted file mode 100644 index e8f7380773..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-posters-small.xml +++ /dev/null @@ -1,885 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" time="200" end="0,-218" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),9)">Conditional</animation> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <visible>!Integer.IsGreater(Container(101).ListItem.Property(index),9) + String.IsEmpty(Window.Property(no.content)) + String.IsEmpty(Window.Property(no.content.filtered)) + !String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol>301</defaultcontrol> - <posx>30</posx> - <posy>-25</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>101</ondown> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(no.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <hitrect x="20" y="20" w="86" h="60" /> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/chapters-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/chapters.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>0</posx> - <posy>-35</posy> - <width>1920</width> - <height>1080</height> - <control type="panel" id="101"> - <hitrect x="0" y="95" w="1780" h="1185" /> - <posx>0</posx> - <posy>0</posy> - <width>1800</width> - <height>1190</height> - <onup>300</onup> - <onright>151</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>2</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="170" height="262"> - <control type="group"> - <posx>55</posx> - <posy>137</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>144</width> - <height>213</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>144</width> - <height>213</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>203</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>144</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>144</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>115</posx> - <posy>0</posy> - <width>29</width> - <height>29</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>93</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>94</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>94</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(subtitle))</visible> - <scroll>false</scroll> - <posx>0</posx> - <posy>218</posy> - <width>144</width> - <height>72</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(subtitle))</visible> - <scroll>false</scroll> - <posx>0</posx> - <posy>218</posy> - <width>144</width> - <height>72</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Property(subtitle)]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="170" height="262"> - <control type="group"> - <posx>55</posx> - <posy>137</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,185" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,185" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>234</width> - <height>316</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>144</width> - <height>213</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>144</width> - <height>213</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>203</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>144</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>144</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>115</posx> - <posy>0</posy> - <width>29</width> - <height>29</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>93</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>94</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>94</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(subtitle))</visible> - <scroll>true</scroll> - <posx>0</posx> - <posy>218</posy> - <width>144</width> - <height>72</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Property(subtitle))</visible> - <scroll>true</scroll> - <posx>0</posx> - <posy>218</posy> - <width>144</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Property(subtitle)] - $INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>0</posx> - <posy>0</posy> - <width>154</width> - <height>225</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - </control> - - <control type="group" id="150"> - <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>151</defaultcontrol> - <posx>1780</posx> - <posy>150</posy> - <width>20</width> - <height>920</height> - <control type="list" id="151"> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>1050</height> - <onleft>100</onleft> - <onright>152</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>34</height> - <colordiffuse>FFE5A00D</colordiffuse> - <texture border="12">script.plex/white-outline-rounded.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1820" y="150" w="100" h="910" /> - <left>1860</left> - <top>150</top> - <width>12</width> - <height>910</height> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - - - <control type="group" id="200"> - <animation effect="slide" end="0,-135" time="200" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),9) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + Integer.IsGreater(Container(101).ListItem.Property(index),9)</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE][COLOR=gray]$INFO[Window.Property(items.count), (,)][/COLOR]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <onright>211</onright> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="grouplist"> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <right>340</right> - <posy>35</posy> - <width>870</width> - <height>65</height> - <align>right</align> - <itemgap>30</itemgap> - <orientation>horizontal</orientation> - <onleft>204</onleft> - <onright>210</onright> - <ondown>50</ondown> - <control type="button" id="311"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font10</font> - <textcolor>A0FFFFFF</textcolor> - <focusedcolor>A0FFFFFF</focusedcolor> - <disabledcolor>A0FFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> - </control> - <control type="button" id="211"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="400">auto</width> - <height>65</height> - <font>font10</font> - <textcolor>A0FFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> - </control> - <control type="button" id="310"> - <visible>String.IsEqual(Window.Property(subDir),1) | ![String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)]</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturenofocus>-</texturenofocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="312"> - <visible>!String.IsEqual(Window.Property(subDir),1) + [String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)]</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="210"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font10</font> - <textcolor>A0FFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(no.content))</visible> - <posx>0</posx> - <posy>465</posy> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$ADDON[script.zidooplexmod 32452][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>60</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFCCCCCC</textcolor> - <label>$ADDON[script.zidooplexmod 32453]</label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(no.content.filtered))</visible> - <posx>0</posx> - <posy>465</posy> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$ADDON[script.zidooplexmod 32454][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>60</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFCCCCCC</textcolor> - <label>$ADDON[script.zidooplexmod 32455]</label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-posters.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-posters.xml deleted file mode 100644 index afc001480b..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-posters.xml +++ /dev/null @@ -1,859 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" time="200" end="0,-115" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5)">Conditional</animation> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <visible>!Integer.IsGreater(Container(101).ListItem.Property(index),5) + String.IsEmpty(Window.Property(no.content)) + String.IsEmpty(Window.Property(no.content.filtered)) + !String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol>301</defaultcontrol> - <posx>30</posx> - <posy>-25</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>101</ondown> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(no.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <hitrect x="20" y="20" w="86" h="60" /> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/chapters-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/chapters.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>0</posx> - <posy>-35</posy> - <width>1920</width> - <height>1080</height> - <control type="panel" id="101"> - <hitrect x="0" y="95" w="1780" h="1185" /> - <posx>0</posx> - <posy>0</posy> - <width>1800</width> - <height>1190</height> - <onup>300</onup> - <onright>151</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>2</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287" height="460"> - <control type="group"> - <posx>55</posx> - <posy>137</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>199</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>72</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287" height="460"> - <control type="group"> - <posx>55</posx> - <posy>137</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,185" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,185" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>451</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="group"> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>199</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - </control> - <control type="label"> - <scroll>true</scroll> - <posx>0</posx> - <posy>371</posy> - <width>244</width> - <height>72</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - </control> - - <control type="group" id="150"> - <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>151</defaultcontrol> - <posx>1780</posx> - <posy>150</posy> - <width>20</width> - <height>920</height> - <control type="list" id="151"> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>1050</height> - <onleft>100</onleft> - <onright>152</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>34</height> - <colordiffuse>FFE5A00D</colordiffuse> - <texture border="12">script.plex/white-outline-rounded.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1820" y="150" w="100" h="910" /> - <left>1860</left> - <top>150</top> - <width>12</width> - <height>910</height> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - - - <control type="group" id="200"> - <animation effect="slide" end="0,-135" time="200" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + Integer.IsGreater(Container(101).ListItem.Property(index),5)</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE][COLOR=gray]$INFO[Window.Property(items.count), (,)][/COLOR]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <onright>211</onright> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="grouplist"> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <right>340</right> - <posy>35</posy> - <width>870</width> - <height>65</height> - <align>right</align> - <itemgap>30</itemgap> - <orientation>horizontal</orientation> - <onleft>204</onleft> - <onright>210</onright> - <ondown>50</ondown> - <control type="button" id="311"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font10</font> - <textcolor>A0FFFFFF</textcolor> - <focusedcolor>A0FFFFFF</focusedcolor> - <disabledcolor>A0FFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> - </control> - <control type="button" id="211"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="400">auto</width> - <height>65</height> - <font>font10</font> - <textcolor>A0FFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> - </control> - <control type="button" id="310"> - <visible>String.IsEqual(Window.Property(subDir),1) | ![String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)]</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturenofocus>-</texturenofocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="312"> - <visible>!String.IsEqual(Window.Property(subDir),1) + [String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)]</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="210"> - <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font10</font> - <textcolor>A0FFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(no.content))</visible> - <posx>0</posx> - <posy>465</posy> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$ADDON[script.plexmod 32452][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>60</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFCCCCCC</textcolor> - <label>$ADDON[script.plexmod 32453]</label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(no.content.filtered))</visible> - <posx>0</posx> - <posy>465</posy> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$ADDON[script.plexmod 32454][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>60</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFCCCCCC</textcolor> - <label>$ADDON[script.plexmod 32455]</label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-pre_play.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-pre_play.xml deleted file mode 100644 index 6cfca6581c..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-pre_play.xml +++ /dev/null @@ -1,1486 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <posx>0</posx> - <posy>155</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol>302</defaultcontrol> - <posx>428</posx> - <posy>410</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>400</ondown> - <itemgap>-50</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="304"> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/info-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/info.png</texturenofocus> - <label> </label> - </control> - <!-- <control type="button" id="301"> - <visible>String.IsEmpty(Window(10000).Property(script.plex.hide.resume))</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/resume-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/resume.png</texturenofocus> - <label> </label> - </control> --> - <control type="button" id="302"> - <visible>String.IsEmpty(Window.Property(unavailable))</visible> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <visible>!String.IsEmpty(Window.Property(trailer.button))</visible> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/trailer-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/trailer.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="307"> - <visible>!String.IsEmpty(Window.Property(media.multiple))</visible> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/media-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/media.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="305"> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/settings-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/settings.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="306"> - <animation effect="zoom" start="100" end="132" time="100" center="88,70" reversible="false">Focus</animation> - <animation effect="zoom" start="132" end="100" time="100" center="88,70" reversible="false">UnFocus</animation> - <hitrect x="40" y="40" w="96" h="60" /> - <posx>0</posx> - <posy>0</posy> - <width>176</width> - <height>140</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>600</height> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(preview.no))</visible> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>347</width> - <height>518</height> - <texture background="true">script.plex/thumb_fallbacks/movie.png</texture> - <animation effect="fade" start="0" end="100" time="0" delay="500">WindowOpen</animation> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>347</width> - <height>518</height> - <texture background="true">$INFO[Window.Property(thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(unwatched))</visible> - <posx>359</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(preview.yes))</visible> - <posx>60</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>347</width> - <height>315</height> - <texture background="true">script.plex/thumb_fallbacks/show.png</texture> - <animation effect="fade" start="0" end="100" time="0" delay="500">WindowOpen</animation> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>323</posy> - <width>347</width> - <height>195</height> - <texture colordiffuse="FF111111">script.plex/white-square.png</texture> - <aspectratio>scale</aspectratio> - </control> - - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>347</width> - <height>315</height> - <texture background="true">$INFO[Window.Property(thumb)]</texture> - <aspectratio aligny="top">scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>323</posy> - <width>347</width> - <height>195</height> - <texture background="true">$INFO[Window.Property(preview)]</texture> - <aspectratio>scale</aspectratio> - </control> - </control> - <control type="grouplist"> - <posx>466</posx> - <posy>0</posy> - <width>1226</width> - <height>60</height> - <align>left</align> - <itemgap>0</itemgap> - <scroll>true</scroll> - <scrollspeed>5</scrollspeed> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="label"> - <width>auto</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(title)]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Window.Property(remainingTime))</visible> - <posx>10</posx> - <posy>6</posy> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFE5A00D</focusedcolor> - <textcolor>FFE5A00D</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>$INFO[Window.Property(remainingTime)]</label> - </control> - </control> - <control type="grouplist"> - <posx>466</posx> - <posy>68</posy> - <width>1360</width> - <height>34</height> - <align>left</align> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="label"> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(duration)]$INFO[Window.Property(info), • ]$INFO[Window.Property(date), • ]$INFO[Window.Property(content.rating), • ]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Window.Property(video.res))</visible> - <posx>10</posx> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>$INFO[Window.Property(video.res)]$INFO[Window.Property(video.rendering), • ]$INFO[Window.Property(video.codec), • ]$INFO[Window.Property(audio.codec), • ]$INFO[Window.Property(audio.channels), • ]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Window.Property(unavailable))</visible> - <posx>10</posx> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="FFAC3223" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="FFAC3223" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>$ADDON[script.plexmod 32312]</label> - </control> - </control> - - <control type="grouplist"> - <visible>!String.IsEmpty(Window.Property(rating)) | !String.IsEmpty(Window.Property(rating2))</visible> - <posx>1426</posx> - <posy>4</posy> - <width>434</width> - <height>32</height> - <align>right</align> - <itemgap>15</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(rating))</visible> - <posy>2</posy> - <width>63</width> - <height>30</height> - <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating.image)]</texture> - <aspectratio align="right">keep</aspectratio> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(rating))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(rating)]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(rating2))</visible> - <posy>2</posy> - <width>40</width> - <height>30</height> - <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating2.image)]</texture> - <aspectratio align="right">keep</aspectratio> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(rating2))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(rating2)]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(rating.stars))</visible> - <posy>6</posy> - <width>134</width> - <height>22</height> - <texture>script.plex/stars/$INFO[Window.Property(rating.stars)].png</texture> - </control> - </control> - - <control type="label"> - <visible>!String.IsEmpty(Window.Property(directors)) | !String.IsEmpty(Window.Property(writers))</visible> - <posx>466</posx> - <posy>130</posy> - <width>1360</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[Window.Property(directors)]$INFO[Window.Property(writers)]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(cast))</visible> - <posx>466</posx> - <posy>165</posy> - <width>1360</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[Window.Property(cast)]</label> - </control> - <control type="grouplist"> - <posx>466</posx> - <posy>223</posy> - <width>1360</width> - <height>34</height> - <align>left</align> - <itemgap>15</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="button"> - <visible>!String.IsEmpty(Window.Property(audio))</visible> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>[UPPERCASE]$ADDON[script.plexmod 32048][/UPPERCASE]</label> - </control> - <control type="label"> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(audio)]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Window.Property(subtitles))</visible> - <left>30</left> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> - <label>[UPPERCASE]$ADDON[script.plexmod 32396][/UPPERCASE]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(subtitles))</visible> - <width>auto</width> - <height>34</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(subtitles)]</label> - </control> - </control> - <control type="textbox"> - <posx>466</posx> - <posy>290</posy> - <width>1360</width> - <height>102</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(summary)]</label> - </control> - <control type="image" id="250"> - <animation effect="zoom" start="0,100" end="100,100" time="1000" center="-1,561" reversible="false" tween="circle" easing="out">WindowOpen</animation> - <posx>-1</posx> - <posy>557</posy> - <width>1</width> - <height>8</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="image"> - <visible>!Control.IsVisible(500)</visible> - <posx>0</posx> - <posy>565</posy> - <width>1920</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - </control> - - <control type="grouplist" id="60"> - <posx>0</posx> - <posy>540</posy> - <width>1920</width> - <height>1800</height> - - <onup>300</onup> - <itemgap>0</itemgap> - - <!-- ROLES --> - <control type="group" id="500"> - <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>400</defaultcontrol> - <width>1920</width> - <height>446</height> - <control type="list" id="400"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>410</height> - <onup>300</onup> - <ondown>401</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>253</posy> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>30</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>253</posy> - <control type="label"> - <scroll>Control.HasFocus(400)</scroll> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(400)</scroll> - <posx>0</posx> - <posy>30</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- /ROLES --> - - <!-- REVIEWS --> - <control type="group" id="501"> - <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>401</defaultcontrol> - <width>1920</width> - <height>446</height> - <control type="label"> - <posx>60</posx> - <posy>20</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32953][/UPPERCASE]</label> - </control> - <control type="list" id="401"> - <posx>0</posx> - <posy>36</posy> - <width>1920</width> - <height>410</height> - <onup>400</onup> - <ondown>402</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="540"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>520</width> - <height>310</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>60000000</colordiffuse> - </control> - <control type="group"> - <posx>20</posx> - <posy>20</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>10</posx> - <posy>-5</posy> - <width>70</width> - <height>70</height> - <texture>script.plex/reviews/$INFO[ListItem.Thumb].png</texture> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>100</posx> - <posy>0</posy> - <width>400</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <textcolor>DDFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>100</posx> - <posy>30</posy> - <width>400</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <textcolor>66FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>80</posy> - <width>480</width> - <height>190</height> - <font>font10</font> - <align>left</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Property(text)]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="540"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>520</width> - <height>310</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>80000000</colordiffuse> - </control> - <control type="group"> - <posx>20</posx> - <posy>20</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>10</posx> - <posy>-5</posy> - <width>70</width> - <height>70</height> - <texture>script.plex/reviews/$INFO[ListItem.Thumb].png</texture> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>100</posx> - <posy>0</posy> - <width>400</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <textcolor>DDFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>100</posx> - <posy>30</posy> - <width>400</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <textcolor>66FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>80</posy> - <width>480</width> - <height>190</height> - <font>font10</font> - <align>left</align> - <textcolor>DDFFFFFF</textcolor> - <label>$INFO[ListItem.Property(text)]</label> - <autoscroll delay="6000" time="3000" repeat="12000">Control.HasFocus(401)</autoscroll> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>-5</posx> - <posy>-5</posy> - <width>530</width> - <height>320</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- /REVIEWS --> - - <!-- EXTRAS --> - <control type="group" id="502"> - <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <height>360</height> - <width>1920</width> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>360</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>800</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32305][/UPPERCASE]</label> - </control> - <control type="list" id="402"> - <posx>0</posx> - <posy>18</posy> - <width>1920</width> - <height>430</height> - <onup>401</onup> - <ondown>403</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>180</posy> - <width>299</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="154.5,87.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="154.5,87.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>389</width> - <height>258</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>180</posy> - <width>299</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>0</posx> - <posy>0</posy> - <width>309</width> - <height>178</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- /EXTRAS --> - - <!-- RELATED --> - <control type="group" id="503"> - <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>403</defaultcontrol> - <width>1920</width> - <height>520</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(divider.403))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> - </control> - <control type="list" id="403"> - <posx>0</posx> - <posy>16</posy> - <width>1920</width> - <height>520</height> - <onup>402</onup> - <onleft>false</onleft> - <onright>false</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>441</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(403)</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- /RELATED --> - </control> - </control> - - <control type="group" id="200"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras)) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window.Property(on.extras))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-pre_signin.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-pre_signin.xml deleted file mode 100644 index 9c8b5d3910..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-pre_signin.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/pre-signin.jpg</texture> - </control> - - <control type="button" id="100"> - <posx>1437</posx> - <posy>801</posy> - <width>275</width> - <height>104</height> - <onup>200</onup> - <font>font13</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-refresh_code.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-refresh_code.xml deleted file mode 100644 index 4826223894..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-refresh_code.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/refresh-code.jpg</texture> - </control> - - <control type="button" id="100"> - <posx>1383</posx> - <posy>802</posy> - <width>335</width> - <height>102</height> - <onup>200</onup> - <font>font13</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-search.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-search.xml deleted file mode 100644 index 95db79fb57..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-search.xml +++ /dev/null @@ -1,8839 +0,0 @@ -<window> - <onload>SetProperty(dropdown,1)</onload> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <controls> - <!-- BACKGROUNDS --> - <control type="group"> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>564</width> - <height>1080</height> - <texture colordiffuse="4C000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>135</posy> - <width>564</width> - <height>810</height> - <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> - <texture colordiffuse="FF2D2D2D">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>135</posy> - <width>564</width> - <height>248</height> - <visible>!String.IsEmpty(Window.Property(hide.kbd))</visible> - <texture colordiffuse="FF2D2D2D">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>945</posy> - <width>564</width> - <height>135</height> - <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> - <texture colordiffuse="66000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>383</posy> - <width>564</width> - <height>697</height> - <visible>!String.IsEmpty(Window.Property(hide.kbd))</visible> - <texture colordiffuse="66000000">script.plex/white-square.png</texture> - </control> - </control> - - <control type="button" id="999"> - <animation effect="zoom" start="100" end="177" time="100" center="80,67.5" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="80,67.5" reversible="false">UnFocus</animation> - <posx>60</posx> - <posy>47.5</posy> - <width>40</width> - <height>40</height> - <ondown>900</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="FFCC7B19">script.plex/buttons/search.png</texturenofocus> - <onclick>Close</onclick> - <label> </label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>160</posx> - <posy>35</posy> - <width>500</width> - <height>65</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32431][/UPPERCASE]</label> - </control> - - <control type="group" id="899"> - <!-- SECTIONS --> - <control type="group"> - <posx>60</posx> - <posy>186</posy> - <width>459</width> - <height>60</height> - - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>151</width> - <height>60</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="group"> - <visible>String.IsEqual(Window.Property(search.section),all)</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>151</width> - <height>60</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>0</posy> - <width>151</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>All</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <visible>!String.IsEqual(Window.Property(search.section),all)</visible> - <posx>0</posx> - <posy>0</posy> - <width>151</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$ADDON[script.plexmod 32345]</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(search.section),movie)</visible> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(search.section),show)</visible> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(search.section),artist)</visible> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> - </control> - </control> - <control type="group"> - <posx>384</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEqual(Window.Property(search.section),photo)</visible> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> - </control> - </control> - - <control type="group" id="900"> - <defaultcontrol>901</defaultcontrol> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="901"> - <animation effect="zoom" start="100" end="120" time="100" center="75.5,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="75.5,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="151" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>231</width> - <height>140</height> - <onright>902</onright> - <onup>999</onup> - <ondown>650</ondown> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <textcolor>00000000</textcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>$ADDON[script.plexmod 32345]</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="902"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="74" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>140</height> - <onleft>901</onleft> - <onright>903</onright> - <onup>999</onup> - <ondown>650</ondown> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="button" id="903"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="74" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>140</height> - <onleft>902</onleft> - <onright>904</onright> - <onup>999</onup> - <ondown>650</ondown> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="904"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="74" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>140</height> - <onleft>903</onleft> - <onright>905</onright> - <onup>999</onup> - <ondown>650</ondown> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="button" id="905"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="74" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>140</height> - <onleft>904</onleft> - <onright>3000</onright> - <onup>999</onup> - <ondown>650</ondown> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - </control> - </control> - - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="group"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="true" condition="Control.HasFocus(902)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <control type="image"> - <posx>26</posx> - <posy>20</posy> - <width>22</width> - <height>20</height> - <texture colordiffuse="FFFFFFFF">script.plex/home/type/movie.png</texture> - </control> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="group"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="true" condition="Control.HasFocus(903)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <control type="image"> - <posx>26</posx> - <posy>20</posy> - <width>24</width> - <height>20</height> - <texture colordiffuse="FFFFFFFF">script.plex/home/type/show.png</texture> - </control> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="group"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="true" condition="Control.HasFocus(904)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <control type="image"> - <posx>26</posx> - <posy>20</posy> - <width>18</width> - <height>20</height> - <texture colordiffuse="FFFFFFFF">script.plex/home/type/artist.png</texture> - </control> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="group"> - <animation effect="zoom" start="100" end="120" time="100" center="37,30" reversible="true" condition="Control.HasFocus(905)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>60</height> - <control type="image"> - <posx>26</posx> - <posy>20</posy> - <width>22</width> - <height>20</height> - <texture colordiffuse="FFFFFFFF">script.plex/home/type/photo.png</texture> - </control> - </control> - </control> - </control> - - <!-- ENTRY --> - <control type="group"> - <posx>60</posx> - <posy>276</posy> - <width>459</width> - <height>60</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>459</width> - <height>60</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="edit" id="650"> - <posx>0</posx> - <posy>0</posy> - <width>459</width> - <height>60</height> - <align>left</align> - <aligny>center</aligny> - <onup>900</onup> - <ondown>1001</ondown> - <onright>3000</onright> - <textcolor>00000000</textcolor> - <label> </label> - <hinttext> </hinttext> - <font>font13</font> - <textoffsetx>30</textoffsetx> - <texturefocus border="10">script.plex/home/selected.png</texturefocus> - <texturenofocus>-</texturenofocus> - <pulseonselect>no</pulseonselect> - </control> - <control type="label" id="651"> - <scroll>false</scroll> - <posx>30</posx> - <posy>0</posy> - <width>399</width> - <height>60</height> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <font>font13</font> - <label> </label> - </control> - </control> - - <!-- KEYBOARD --> - <control type="group"> - <posx>60</posx> - <posy>360</posy> - <width>459</width> - <height>439</height> - <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> - - <!-- IMAGES ROW 1 --> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>77</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>154</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>231</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>308</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>385</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - </control> - <!-- IMAGES ROW 2 --> - <control type="group"> - <posx>0</posx> - <posy>77</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>77</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>154</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>231</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>308</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>385</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - </control> - <!-- IMAGES ROW 3 --> - <control type="group"> - <posx>0</posx> - <posy>154</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>77</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>154</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>231</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>308</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>385</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - </control> - <!-- IMAGES ROW 4 --> - <control type="group"> - <posx>0</posx> - <posy>231</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>77</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>154</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>231</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>308</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>385</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - </control> - <!-- IMAGES ROW 5 --> - <control type="group"> - <posx>0</posx> - <posy>308</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>77</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>154</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>231</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>308</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>385</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - </control> - <!-- IMAGES ROW 6 --> - <control type="group"> - <posx>0</posx> - <posy>385</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>77</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>154</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>231</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>308</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>385</posx> - <posy>0</posy> - <width>74</width> - <height>74</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - </control> - - <!-- BUTTONS ROW 1 --> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="1001"> - <visible allowhiddenfocus="true">true</visible> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>650</onup> - <ondown>1007</ondown> - <onright>1002</onright> - <onleft>1006</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>A</label> - </control> - </control> - <control type="group"> - <posx>77</posx> - <posy>0</posy> - <control type="button" id="1002"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>650</onup> - <ondown>1008</ondown> - <onright>1003</onright> - <onleft>1001</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>B</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="1003"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>650</onup> - <ondown>1009</ondown> - <onright>1004</onright> - <onleft>1002</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>C</label> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="button" id="1004"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>650</onup> - <ondown>1010</ondown> - <onright>1005</onright> - <onleft>1003</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>D</label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="1005"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>650</onup> - <ondown>1011</ondown> - <onright>1006</onright> - <onleft>1004</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>E</label> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="button" id="1006"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>650</onup> - <ondown>1012</ondown> - <onright>3000</onright> - <onleft>1005</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>F</label> - </control> - </control> - </control> - <!-- BUTTONS ROW 2 --> - <control type="group"> - <posx>0</posx> - <posy>77</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="1007"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1001</onup> - <ondown>1013</ondown> - <onright>1008</onright> - <onleft>1012</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>G</label> - </control> - </control> - <control type="group"> - <posx>77</posx> - <posy>0</posy> - <control type="button" id="1008"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1002</onup> - <ondown>1014</ondown> - <onright>1009</onright> - <onleft>1007</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>H</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="1009"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1003</onup> - <ondown>1015</ondown> - <onright>1010</onright> - <onleft>1008</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>I</label> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="button" id="1010"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1004</onup> - <ondown>1016</ondown> - <onright>1011</onright> - <onleft>1009</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>J</label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="1011"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1005</onup> - <ondown>1017</ondown> - <onright>1012</onright> - <onleft>1010</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>K</label> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="button" id="1012"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1006</onup> - <ondown>1018</ondown> - <onright>3000</onright> - <onleft>1011</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>L</label> - </control> - </control> - </control> - <!-- BUTTONS ROW 3 --> - <control type="group"> - <posx>0</posx> - <posy>154</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="1013"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1007</onup> - <ondown>1019</ondown> - <onright>1014</onright> - <onleft>1018</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>M</label> - </control> - </control> - <control type="group"> - <posx>77</posx> - <posy>0</posy> - <control type="button" id="1014"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1008</onup> - <ondown>1020</ondown> - <onright>1015</onright> - <onleft>1013</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>N</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="1015"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1009</onup> - <ondown>1021</ondown> - <onright>1016</onright> - <onleft>1014</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>O</label> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="button" id="1016"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1010</onup> - <ondown>1022</ondown> - <onright>1017</onright> - <onleft>1015</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>P</label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="1017"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1011</onup> - <ondown>1023</ondown> - <onright>1018</onright> - <onleft>1016</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>Q</label> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="button" id="1018"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1012</onup> - <ondown>1024</ondown> - <onright>3000</onright> - <onleft>1017</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>R</label> - </control> - </control> - </control> - <!-- BUTTONS ROW 4 --> - <control type="group"> - <posx>0</posx> - <posy>231</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="1019"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1013</onup> - <ondown>1025</ondown> - <onright>1020</onright> - <onleft>1024</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>S</label> - </control> - </control> - <control type="group"> - <posx>77</posx> - <posy>0</posy> - <control type="button" id="1020"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1014</onup> - <ondown>1026</ondown> - <onright>1021</onright> - <onleft>1019</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>T</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="1021"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1015</onup> - <ondown>1027</ondown> - <onright>1022</onright> - <onleft>1020</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>U</label> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="button" id="1022"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1016</onup> - <ondown>1028</ondown> - <onright>1023</onright> - <onleft>1021</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>V</label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="1023"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1017</onup> - <ondown>1029</ondown> - <onright>1024</onright> - <onleft>1022</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>W</label> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="button" id="1024"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1018</onup> - <ondown>1030</ondown> - <onright>3000</onright> - <onleft>1023</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>X</label> - </control> - </control> - </control> - <!-- BUTTONS ROW 5 --> - <control type="group"> - <posx>0</posx> - <posy>308</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="1025"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1019</onup> - <ondown>1031</ondown> - <onright>1026</onright> - <onleft>1030</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>Y</label> - </control> - </control> - <control type="group"> - <posx>77</posx> - <posy>0</posy> - <control type="button" id="1026"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1020</onup> - <ondown>1032</ondown> - <onright>1027</onright> - <onleft>1025</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>Z</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="1027"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1021</onup> - <ondown>1033</ondown> - <onright>1028</onright> - <onleft>1026</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>0[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="button" id="1028"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1022</onup> - <ondown>1034</ondown> - <onright>1029</onright> - <onleft>1027</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>1[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="1029"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1023</onup> - <ondown>1035</ondown> - <onright>1030</onright> - <onleft>1028</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>2[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="button" id="1030"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1024</onup> - <ondown>1036</ondown> - <onright>3000</onright> - <onleft>1029</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>3[B][/B]</label> - </control> - </control> - </control> - <!-- BUTTONS ROW 6 --> - <control type="group"> - <posx>0</posx> - <posy>385</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="1031"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1025</onup> - <ondown>951</ondown> - <onright>1032</onright> - <onleft>1036</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>4[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>77</posx> - <posy>0</posy> - <control type="button" id="1032"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1026</onup> - <ondown>951</ondown> - <onright>1033</onright> - <onleft>1031</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>5[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="1033"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1027</onup> - <ondown>952</ondown> - <onright>1034</onright> - <onleft>1032</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>6[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>231</posx> - <posy>0</posy> - <control type="button" id="1034"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1028</onup> - <ondown>952</ondown> - <onright>1035</onright> - <onleft>1033</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>7[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="1035"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1029</onup> - <ondown>953</ondown> - <onright>1036</onright> - <onleft>1034</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>8[B][/B]</label> - </control> - </control> - <control type="group"> - <posx>385</posx> - <posy>0</posy> - <control type="button" id="1036"> - <animation effect="zoom" start="100" end="120" time="100" center="37,37" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="37,37" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="75" h="75" /> - <posx>-40</posx> - <posy>-40</posy> - <width>154</width> - <height>154</height> - <onup>1030</onup> - <ondown>953</ondown> - <onright>3000</onright> - <onleft>1035</onleft> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>9[B][/B]</label> - </control> - </control> - </control> - </control> - - <!-- DELETE-ETC --> - <control type="group" id="950"> - <posx>60</posx> - <posy>840</posy> - <width>459</width> - <height>60</height> - <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>151</width> - <height>60</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>154</posx> - <posy>0</posy> - <width>151</width> - <height>60</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - <control type="image"> - <posx>308</posx> - <posy>0</posy> - <width>151</width> - <height>60</height> - <texture colordiffuse="FF000000">script.plex/white-square.png</texture> - </control> - - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="button" id="951"> - <animation effect="zoom" start="100" end="120" time="100" center="75.5,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="75.5,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="151" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>231</width> - <height>140</height> - <onleft>953</onleft> - <onright>952</onright> - <onup>1031</onup> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>$ADDON[script.plexmod 32322]</label> - </control> - </control> - <control type="group"> - <posx>154</posx> - <posy>0</posy> - <control type="button" id="952"> - <animation effect="zoom" start="100" end="120" time="100" center="75.5,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="75.5,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="151" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>231</width> - <height>140</height> - <onleft>951</onleft> - <onright>953</onright> - <onup>1033</onup> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>$ADDON[script.plexmod 32432]</label> - </control> - </control> - <control type="group"> - <posx>308</posx> - <posy>0</posy> - <control type="button" id="953"> - <animation effect="zoom" start="100" end="120" time="100" center="75.5,30" reversible="false">Focus</animation> - <animation effect="zoom" start="120" end="100" time="100" center="75.5,30" reversible="false">UnFocus</animation> - <hitrect x="0" y="0" w="151" h="60" /> - <posx>-40</posx> - <posy>-40</posy> - <width>231</width> - <height>140</height> - <onleft>952</onleft> - <onright>3000</onright> - <onup>1036</onup> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label>$ADDON[script.plexmod 32433]</label> - </control> - </control> - </control> - - <control type="group"> - <animation effect="fade" start="0" end="100" time="100" condition="!String.IsEmpty(Window.Property(searching))">Visible</animation> - <visible>!String.IsEmpty(Window.Property(searching))</visible> - <posx>0</posx> - <posy>993</posy> - <control type="label"> - <scroll>false</scroll> - <posx>420</posx> - <posy>0</posy> - <width>434</width> - <height>39</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32434][/UPPERCASE]</label> - </control> - <control type="group"> - <posx>480</posx> - <posy>0</posy> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(searching))</visible> - <animation effect="rotate" start="0" end="-36000" time="100000" center="19.5,19.5" reversible="false">Visible</animation> - <posx>0</posx> - <posy>0</posy> - <width>39</width> - <height>39</height> - <texture colordiffuse="FFE5A00D">script.plex/indicators/spinner.png</texture> - </control> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(no.results)) + String.IsEmpty(Window.Property(searching))</visible> - <posx>0</posx> - <posy>993</posy> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>0</posy> - <width>564</width> - <height>39</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32435][/UPPERCASE]</label> - </control> - </control> - </control> - - <control type="grouplist" id="3000"> - <!-- 2108 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),8) + Control.IsVisible(2008)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2109 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),9) + Control.IsVisible(2009)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2110 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),10) + Control.IsVisible(2010)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2111 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),11) + Control.IsVisible(2011)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2112 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),12) + Control.IsVisible(2012)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2113 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),13) + Control.IsVisible(2013)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2114 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),14) + Control.IsVisible(2014)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2115 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),15) + Control.IsVisible(2015)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2116 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),16) + Control.IsVisible(2016)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2117 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),17) + Control.IsVisible(2017)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2118 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),18) + Control.IsVisible(2018)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2119 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),19) + Control.IsVisible(2019)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2120 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),20) + Control.IsVisible(2020)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2121 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),21) + Control.IsVisible(2021)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2122 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),22) + Control.IsVisible(2022)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2123 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),23) + Control.IsVisible(2023)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2124 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),24) + Control.IsVisible(2024)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2125 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),25) + Control.IsVisible(2025)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2126 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),26) + Control.IsVisible(2026)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2127 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),27) + Control.IsVisible(2027)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2128 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),28) + Control.IsVisible(2028)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2129 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),29) + Control.IsVisible(2029)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2130 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),30) + Control.IsVisible(2030)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2131 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),31) + Control.IsVisible(2031)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2132 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),32) + Control.IsVisible(2032)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2133 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),33) + Control.IsVisible(2033)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2134 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),34) + Control.IsVisible(2034)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2135 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),35) + Control.IsVisible(2035)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2136 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),36) + Control.IsVisible(2036)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2137 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),37) + Control.IsVisible(2037)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2138 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),38) + Control.IsVisible(2038)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2139 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),39) + Control.IsVisible(2039)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2140 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),40) + Control.IsVisible(2040)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2141 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),41) + Control.IsVisible(2041)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2142 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),42) + Control.IsVisible(2042)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2143 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),43) + Control.IsVisible(2043)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2144 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),44) + Control.IsVisible(2044)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2145 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),45) + Control.IsVisible(2045)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2146 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),46) + Control.IsVisible(2046)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - <!-- 2147 Focus animation --> - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),47) + Control.IsVisible(2047)" reversible="true"> - <effect type="slide" end="0,-420" time="200" tween="quadratic" easing="out"/> - </animation> - - - <defaultcontrol always="true">2000</defaultcontrol> - <posx>564</posx> - <posy>20</posy> - <width>2130</width> - <height>5540</height> - <itemgap>20</itemgap> - <orientation>vertical</orientation> - <usecontrolcoords>true</usecontrolcoords> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - - <control type="group" id="2000"> - <defaultcontrol>2100</defaultcontrol> - <visible>Integer.IsGreater(Container(2100).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2100)][/UPPERCASE]</label> - </control> - <control type="list" id="2100"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <ondown>2101</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2100)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2100)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2001"> - <visible>Integer.IsGreater(Container(2101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2101)][/UPPERCASE]</label> - </control> - <control type="list" id="2101"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2100</onup> - <ondown>2102</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2101)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2101)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2002"> - <visible>Integer.IsGreater(Container(2102).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2102)][/UPPERCASE]</label> - </control> - <control type="list" id="2102"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2101</onup> - <ondown>2103</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2102)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2102)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2003"> - <visible>Integer.IsGreater(Container(2103).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2103)][/UPPERCASE]</label> - </control> - <control type="list" id="2103"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2102</onup> - <ondown>2104</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2103)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2103)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2004"> - <visible>Integer.IsGreater(Container(2104).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2104)][/UPPERCASE]</label> - </control> - <control type="list" id="2104"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2103</onup> - <ondown>2105</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2104)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2104)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2005"> - <visible>Integer.IsGreater(Container(2105).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2105)][/UPPERCASE]</label> - </control> - <control type="list" id="2105"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2104</onup> - <ondown>2106</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2105)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2105)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2006"> - <visible>Integer.IsGreater(Container(2106).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2106)][/UPPERCASE]</label> - </control> - <control type="list" id="2106"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2105</onup> - <ondown>2107</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2106)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2106)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2007"> - <visible>Integer.IsGreater(Container(2107).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2107)][/UPPERCASE]</label> - </control> - <control type="list" id="2107"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2106</onup> - <ondown>2108</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2107)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2107)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2008"> - <visible>Integer.IsGreater(Container(2108).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2108)][/UPPERCASE]</label> - </control> - <control type="list" id="2108"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2107</onup> - <ondown>2109</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2108)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2108)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2009"> - <visible>Integer.IsGreater(Container(2109).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2109)][/UPPERCASE]</label> - </control> - <control type="list" id="2109"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2108</onup> - <ondown>2110</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2109)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2109)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2010"> - <visible>Integer.IsGreater(Container(2110).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2110)][/UPPERCASE]</label> - </control> - <control type="list" id="2110"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2109</onup> - <ondown>2111</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2110)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2110)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2011"> - <visible>Integer.IsGreater(Container(2111).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2111)][/UPPERCASE]</label> - </control> - <control type="list" id="2111"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2110</onup> - <ondown>2112</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2111)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2111)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2012"> - <visible>Integer.IsGreater(Container(2112).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2112)][/UPPERCASE]</label> - </control> - <control type="list" id="2112"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2111</onup> - <ondown>2113</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2112)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2112)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2013"> - <visible>Integer.IsGreater(Container(2113).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2113)][/UPPERCASE]</label> - </control> - <control type="list" id="2113"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2112</onup> - <ondown>2114</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2113)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2113)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2014"> - <visible>Integer.IsGreater(Container(2114).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2114)][/UPPERCASE]</label> - </control> - <control type="list" id="2114"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2113</onup> - <ondown>2115</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2114)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2114)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2015"> - <visible>Integer.IsGreater(Container(2115).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2115)][/UPPERCASE]</label> - </control> - <control type="list" id="2115"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2114</onup> - <ondown>2116</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2115)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2115)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2016"> - <visible>Integer.IsGreater(Container(2116).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2116)][/UPPERCASE]</label> - </control> - <control type="list" id="2116"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2115</onup> - <ondown>2117</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2116)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2116)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2017"> - <visible>Integer.IsGreater(Container(2117).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2117)][/UPPERCASE]</label> - </control> - <control type="list" id="2117"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2116</onup> - <ondown>2118</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2117)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2117)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2018"> - <visible>Integer.IsGreater(Container(2118).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2118)][/UPPERCASE]</label> - </control> - <control type="list" id="2118"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2117</onup> - <ondown>2119</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2118)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2118)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2019"> - <visible>Integer.IsGreater(Container(2119).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2119)][/UPPERCASE]</label> - </control> - <control type="list" id="2119"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2118</onup> - <ondown>2120</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2119)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2119)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2020"> - <visible>Integer.IsGreater(Container(2120).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2120)][/UPPERCASE]</label> - </control> - <control type="list" id="2120"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2119</onup> - <ondown>2121</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2120)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2120)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2021"> - <visible>Integer.IsGreater(Container(2121).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2121)][/UPPERCASE]</label> - </control> - <control type="list" id="2121"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2120</onup> - <ondown>2122</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2121)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2121)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2022"> - <visible>Integer.IsGreater(Container(2122).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2122)][/UPPERCASE]</label> - </control> - <control type="list" id="2122"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2121</onup> - <ondown>2123</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2122)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2122)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2023"> - <visible>Integer.IsGreater(Container(2123).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2123)][/UPPERCASE]</label> - </control> - <control type="list" id="2123"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2122</onup> - <ondown>2124</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2123)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2123)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2024"> - <visible>Integer.IsGreater(Container(2124).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2124)][/UPPERCASE]</label> - </control> - <control type="list" id="2124"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2123</onup> - <ondown>2125</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2124)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2124)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2025"> - <visible>Integer.IsGreater(Container(2125).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2125)][/UPPERCASE]</label> - </control> - <control type="list" id="2125"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2124</onup> - <ondown>2126</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2125)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2125)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2026"> - <visible>Integer.IsGreater(Container(2126).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2126)][/UPPERCASE]</label> - </control> - <control type="list" id="2126"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2125</onup> - <ondown>2127</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2126)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2126)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2027"> - <visible>Integer.IsGreater(Container(2127).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2127)][/UPPERCASE]</label> - </control> - <control type="list" id="2127"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2126</onup> - <ondown>2128</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2127)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2127)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2028"> - <visible>Integer.IsGreater(Container(2128).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2128)][/UPPERCASE]</label> - </control> - <control type="list" id="2128"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2127</onup> - <ondown>2129</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2128)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2128)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2029"> - <visible>Integer.IsGreater(Container(2129).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2129)][/UPPERCASE]</label> - </control> - <control type="list" id="2129"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2128</onup> - <ondown>2130</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2129)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2129)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2030"> - <visible>Integer.IsGreater(Container(2130).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2130)][/UPPERCASE]</label> - </control> - <control type="list" id="2130"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2129</onup> - <ondown>2131</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2130)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2130)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2031"> - <visible>Integer.IsGreater(Container(2131).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2131)][/UPPERCASE]</label> - </control> - <control type="list" id="2131"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2130</onup> - <ondown>2132</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2131)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2131)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2032"> - <visible>Integer.IsGreater(Container(2132).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2132)][/UPPERCASE]</label> - </control> - <control type="list" id="2132"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2131</onup> - <ondown>2133</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2132)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2132)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2033"> - <visible>Integer.IsGreater(Container(2133).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2133)][/UPPERCASE]</label> - </control> - <control type="list" id="2133"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2132</onup> - <ondown>2134</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2133)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2133)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2034"> - <visible>Integer.IsGreater(Container(2134).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2134)][/UPPERCASE]</label> - </control> - <control type="list" id="2134"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2133</onup> - <ondown>2135</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2134)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2134)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2035"> - <visible>Integer.IsGreater(Container(2135).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2135)][/UPPERCASE]</label> - </control> - <control type="list" id="2135"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2134</onup> - <ondown>2136</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2135)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2135)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2036"> - <visible>Integer.IsGreater(Container(2136).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2136)][/UPPERCASE]</label> - </control> - <control type="list" id="2136"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2135</onup> - <ondown>2137</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2136)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2136)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2037"> - <visible>Integer.IsGreater(Container(2137).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2137)][/UPPERCASE]</label> - </control> - <control type="list" id="2137"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2136</onup> - <ondown>2138</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2137)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2137)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2038"> - <visible>Integer.IsGreater(Container(2138).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2138)][/UPPERCASE]</label> - </control> - <control type="list" id="2138"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2137</onup> - <ondown>2139</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2138)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2138)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2039"> - <visible>Integer.IsGreater(Container(2139).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2139)][/UPPERCASE]</label> - </control> - <control type="list" id="2139"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2138</onup> - <ondown>2140</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2139)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2139)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2040"> - <visible>Integer.IsGreater(Container(2140).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2140)][/UPPERCASE]</label> - </control> - <control type="list" id="2140"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2139</onup> - <ondown>2141</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2140)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2140)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2041"> - <visible>Integer.IsGreater(Container(2141).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2141)][/UPPERCASE]</label> - </control> - <control type="list" id="2141"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2140</onup> - <ondown>2142</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2141)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2141)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2042"> - <visible>Integer.IsGreater(Container(2142).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2142)][/UPPERCASE]</label> - </control> - <control type="list" id="2142"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2141</onup> - <ondown>2143</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2142)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2142)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2043"> - <visible>Integer.IsGreater(Container(2143).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2143)][/UPPERCASE]</label> - </control> - <control type="list" id="2143"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2142</onup> - <ondown>2144</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2143)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2143)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2044"> - <visible>Integer.IsGreater(Container(2144).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2144)][/UPPERCASE]</label> - </control> - <control type="list" id="2144"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2143</onup> - <ondown>2145</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="240"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="95,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="95,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2144)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>270</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>180</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>180</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2144)</visible> - <posx>0</posx> - <posy>0</posy> - <width>190</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2045"> - <visible>Integer.IsGreater(Container(2145).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2145)][/UPPERCASE]</label> - </control> - <control type="list" id="2145"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2144</onup> - <ondown>2146</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="140,140" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="140,140" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2145)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>360</width> - <height>360</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>270</width> - <height>270</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>280</posy> - <width>270</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2145)</visible> - <posx>0</posx> - <posy>0</posy> - <width>280</width> - <height>280</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2046"> - <visible>Integer.IsGreater(Container(2146).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>320</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2146)][/UPPERCASE]</label> - </control> - <control type="list" id="2146"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2145</onup> - <ondown>2147</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="360"> - <control type="group"> - <posx>55</posx> - <posy>64</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="155,89.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="155,89.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2146)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>390</width> - <height>259</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>169</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>179</posy> - <width>300</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2146)</visible> - <posx>0</posx> - <posy>0</posy> - <width>310</width> - <height>179</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="2047"> - <visible>Integer.IsGreater(Container(2147).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <width>1356</width> - <height>420</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1236</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF282828</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>87</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(hub.2147)][/UPPERCASE]</label> - </control> - <control type="list" id="2147"> - <posx>0</posx> - <posy>30</posy> - <width>1356</width> - <height>440</height> - <onleft>899</onleft> - <onup>2146</onup> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(2147)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>254</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>282</posy> - <width>244</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(2147)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - </control> - </controls> -</window> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-seasons.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-seasons.xml deleted file mode 100644 index 114dafa312..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-seasons.xml +++ /dev/null @@ -1,1437 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> - <effect type="slide" end="0,-360" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <posx>0</posx> - <posy>155</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol>302</defaultcontrol> - <posx>440</posx> - <posy>445</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>400</ondown> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/info-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/info.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>600</height> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>347</width> - <height>518</height> - <texture background="true">script.plex/thumb_fallbacks/movie.png</texture> - <animation effect="fade" start="0" end="100" time="0" delay="500">WindowOpen</animation> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>347</width> - <height>518</height> - <texture background="true">$INFO[Window.Property(thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - - <control type="label"> - <posx>466</posx> - <posy>0</posy> - <width>1360</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(title)]</label> - </control> - <control type="grouplist"> - <posx>466</posx> - <posy>70</posy> - <width>1360</width> - <height>30</height> - <align>left</align> - <itemgap>0</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="label"> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(duration)]$INFO[Window.Property(info), • ]$INFO[Window.Property(date), • ]$INFO[Window.Property(content.rating), • ]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(rating.stars))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label> • </label> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(rating.stars))</visible> - <posy>4</posy> - <width>134</width> - <height>22</height> - <texture>script.plex/stars/$INFO[Window.Property(rating.stars)].png</texture> - </control> - </control> - - <control type="grouplist"> - <visible>!String.IsEmpty(Window.Property(rating)) | !String.IsEmpty(Window.Property(rating2))</visible> - <posx>1660</posx> - <posy>70</posy> - <width>200</width> - <height>32</height> - <align>right</align> - <itemgap>15</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(rating))</visible> - <posy>2</posy> - <width>63</width> - <height>30</height> - <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating.image)]</texture> - <aspectratio align="right">keep</aspectratio> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(rating))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(rating)]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(rating2))</visible> - <posy>2</posy> - <width>63</width> - <height>30</height> - <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating2.image)]</texture> - <aspectratio align="right">keep</aspectratio> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(rating2))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(rating2)]</label> - </control> - </control> - - - <control type="label"> - <visible>!String.IsEmpty(Window.Property(directors))</visible> - <posx>466</posx> - <posy>130</posy> - <width>1360</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[Window.Property(directors)]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(writers))</visible> - <posx>466</posx> - <posy>165</posy> - <width>1360</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[Window.Property(writers)]</label> - </control> - <!-- <control type="grouplist"> - <posx>466</posx> - <posy>225</posy> - <width>1360</width> - <height>30</height> - <align>left</align> - <itemgap>15</itemgap> - <orientation>horizontal</orientation> - <usecontrolcoords>true</usecontrolcoords> - <control type="button"> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturenofocus> - <label>AUDIO</label> - </control> - <control type="label"> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(audio)]</label> - </control> - <control type="button"> - <visible>!String.IsEmpty(Window.Property(subtitles))</visible> - <left>30</left> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <focusedcolor>FFFFFFFF</focusedcolor> - <textcolor>FFFFFFFF</textcolor> - <textoffsetx>15</textoffsetx> - <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturenofocus> - <label>SUBTITLES</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(subtitles))</visible> - <width>auto</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(subtitles)]</label> - </control> - </control> - <control type="textbox"> - <posx>466</posx> - <posy>300</posy> - <width>1360</width> - <height>113</height> - <font>font13</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(summary)]</label> - </control> --> - <control type="textbox"> - <posx>466</posx> - <posy>234</posy> - <width>1360</width> - <height>179</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(summary)]</label> - </control> - <control type="image" id="250"> - <animation effect="zoom" start="0,100" end="100,100" time="1000" center="-1,561" reversible="false" tween="circle" easing="out">WindowOpen</animation> - <posx>-1</posx> - <posy>557</posy> - <width>1</width> - <height>8</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="image"> - <visible>!Control.IsVisible(500)</visible> - <posx>0</posx> - <posy>565</posy> - <width>1920</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - </control> - - <control type="grouplist" id="60"> - <posx>0</posx> - <posy>565</posy> - <width>1920</width> - <height>1600</height> - - <onup>300</onup> - <itemgap>0</itemgap> - - <!-- Seasons --> - <control type="group" id="500"> - <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <height>380</height> - <width>1920</width> - <control type="list" id="400"> - <posx>0</posx> - <posy>36</posy> - <width>1920</width> - <height>380</height> - <onup>300</onup> - <ondown>401</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="218"> - <control type="group"> - <posx>55</posx> - <posy>29</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>113</posx> - <posy>0</posy> - <width>45</width> - <height>40</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>230</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>158</width> - <height>4</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>240</posy> - <width>158</width> - <height>54</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="218"> - <control type="group"> - <posx>55</posx> - <posy>29</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="84,123" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="84,123" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>248</width> - <height>326</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>236</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>113</posx> - <posy>0</posy> - <width>45</width> - <height>40</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>114</posx> - <posy>0</posy> - <width>44</width> - <height>39</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>230</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>158</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>158</width> - <height>4</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(400)</scroll> - <posx>0</posx> - <posy>240</posy> - <width>158</width> - <height>54</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>0</posx> - <posy>0</posy> - <width>168</width> - <height>246</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- Seasons --> - - <!-- ROLES --> - <control type="group" id="501"> - <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>401</defaultcontrol> - <width>1920</width> - <height>400</height> - <control type="label"> - <posx>60</posx> - <posy>-20</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32419][/UPPERCASE]</label> - </control> - <control type="list" id="401"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>400</height> - <onup>400</onup> - <ondown>402</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>253</posy> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>30</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="group"> - <posx>0</posx> - <posy>253</posy> - <control type="label"> - <scroll>Control.HasFocus(401)</scroll> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(401)</scroll> - <posx>0</posx> - <posy>30</posy> - <width>244</width> - <height>60</height> - <font>font10</font> - <align>center</align> - <textcolor>AAFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- ROLES --> - - <!-- EXTRAS --> - <control type="group" id="502"> - <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <height>360</height> - <width>1920</width> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>800</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(extras.header)][/UPPERCASE]</label> - </control> - <control type="list" id="402"> - <posx>0</posx> - <posy>18</posy> - <width>1920</width> - <height>430</height> - <onup>401</onup> - <ondown>403</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>175</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>210</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="154.5,87.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="154.5,87.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>389</width> - <height>258</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <control type="label"> - <scroll>Control.HasFocus(402)</scroll> - <posx>0</posx> - <posy>175</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>Control.HasFocus(402)</scroll> - <posx>0</posx> - <posy>210</posy> - <width>299</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(402)</visible> - <posx>0</posx> - <posy>0</posy> - <width>309</width> - <height>178</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- EXTRAS --> - - <!-- RELATED --> - <control type="group" id="503"> - <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>403</defaultcontrol> - <width>1920</width> - <height>520</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(divider.403))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> - </control> - <control type="list" id="403"> - <posx>0</posx> - <posy>16</posy> - <width>1920</width> - <height>520</height> - <onup>402</onup> - <ondown>403</ondown> - <onleft>false</onleft> - <onright>false</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>441</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>Control.HasFocus(403)</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - <!-- RELATED --> - - </control> - </control> - - <control type="group" id="200"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras)) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window.Property(on.extras))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-seek_dialog.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-seek_dialog.xml deleted file mode 100644 index 818fb6904f..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-seek_dialog.xml +++ /dev/null @@ -1,1101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <zorder>100</zorder> - <defaultcontrol>800</defaultcontrol> - <controls> - <control type="group" id="802"> - <visible>[!String.IsEmpty(Window.Property(show.OSD)) | Window.IsVisible(seekbar) | !String.IsEmpty(Window.Property(button.seek))] + !Window.IsVisible(osdvideosettings) + !Window.IsVisible(osdaudiosettings) + !Window.IsVisible(osdsubtitlesettings) + !Window.IsVisible(subtitlesearch) + !Window.IsActive(playerprocessinfo) + !Window.IsActive(selectdialog) + !Window.IsVisible(osdcmssettings)</visible> - <animation effect="fade" time="200" delay="200" end="0">Hidden</animation> - <control type="group"> - <visible>String.IsEmpty(Window.Property(settings.visible)) + [Window.IsVisible(seekbar) | Window.IsVisible(videoosd) | Player.ShowInfo]</visible> - <animation effect="fade" start="100" end="0">Hidden</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/player-fade.png</texture> - <colordiffuse>FF080808</colordiffuse> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>140</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>940</posy> - <width>1920</width> - <height>140</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>40</posy> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(is.show))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1720</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <scroll>true</scroll> - <scrollspeed>15</scrollspeed> - <label>[B]$INFO[VideoPlayer.TVShowTitle][/B]$INFO[VideoPlayer.Title, • ]$INFO[VideoPlayer.Season, • Season ]$INFO[VideoPlayer.Episode, Episode ]$INFO[Window.Property(ep.year), • ]</label> - </control> - <control type="label"> - <visible>String.IsEmpty(Window.Property(is.show))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1720</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <scroll>true</scroll> - <scrollspeed>15</scrollspeed> - <label>[B]$INFO[VideoPlayer.Title][/B]$INFO[VideoPlayer.Year, • ]</label> - </control> - <control type="label"> - <posx>1860</posx> - <posy>0</posy> - <width>300</width> - <height>60</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>965</posy> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(direct.play))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Player.Time($INFO[Window.Property(time.fmt)])]</label> - </control> - <control type="label"> - <visible>String.IsEmpty(Window.Property(direct.play))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(time.current)]</label> - </control> - <control type="label"> - <visible>Player.IsTempo</visible> - <posx>60</posx> - <posy>40</posy> - <width>1000</width> - <height>60</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>A0FFFFFF</textcolor> - <label>$INFO[Player.PlaySpeed]x</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(direct.play))</visible> - <posx>1860</posx> - <posy>0</posy> - <width>800</width> - <height>60</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Player.TimeRemaining($INFO[Window.Property(time.fmt)])]$INFO[Window.Property(time.add)]</label> - </control> - <control type="label"> - <visible>String.IsEmpty(Window.Property(direct.play))</visible> - <posx>1860</posx> - <posy>0</posy> - <width>800</width> - <height>60</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(time.left)]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(media.show_ends)) + !String.IsEmpty(Window.Property(direct.play))</visible> - <posx>1860</posx> - <posy>40</posy> - <width>800</width> - <height>60</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>A0FFFFFF</textcolor> - <label>$INFO[Window.Property(time.ends_label)] $INFO[Player.FinishTime($INFO[Window.Property(time.fmt.ends)])]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Window.Property(media.show_ends)) + String.IsEmpty(Window.Property(direct.play))</visible> - <posx>1860</posx> - <posy>40</posy> - <width>800</width> - <height>60</height> - <font>font13</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>A0FFFFFF</textcolor> - <label>$INFO[Window.Property(time.ends_label)] $INFO[Window.Property(time.end)]</label> - </control> - <control type="label"> - <visible>Player.Paused + String.IsEmpty(Window.Property(show.OSD))</visible> - <animation effect="fade" time="200" delay="200" end="100">Visible</animation> - <posx>0</posx> - <posy>20</posy> - <width>1920</width> - <height>60</height> - <font>font13</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFCC7B19</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32436][/UPPERCASE]</label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>940</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image" id="206"> - <visible>!String.IsEmpty(Window.Property(show.buffer))</visible> - <posx>0</posx> - <posy>2</posy> - <width>1</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>EE4E4842</colordiffuse> - </control> - <control type="image" id="201"> - <posx>0</posx> - <posy>2</posy> - <width>1</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFAC5B00</colordiffuse> - </control> - <control type="image" id="200"> - <visible>Control.HasFocus(100) | !String.IsEmpty(Window.Property(button.seek))</visible> - <posx>0</posx> - <posy>2</posy> - <width>1</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - </control> - </control> - <control type="button" id="800"> - <visible allowhiddenfocus="true">String.IsEmpty(Window.Property(show.OSD))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - <onclick condition="String.IsEmpty(Window.Property(button.seek)) + String.IsEmpty(Window.Property(marker.countdown))">SetProperty(show.OSD,1)</onclick> - </control> - - <!-- PPI --> - <control type="group" id="803"> - <bottom>0</bottom> - <height>350</height> - <visible>!String.IsEmpty(Window.Property(show.PPI)) + String.IsEmpty(Window.Property(settings.visible)) + String.IsEmpty(Window.Property(playlist.visible))</visible> - <animation effect="fade" start="0" end="100" time="300">Visible</animation> - <animation effect="fade" start="100" end="0" time="200">Hidden</animation> - <control type="image"> - <left>10</left> - <top>-220</top> - <right>10</right> - <height>420</height> - <texture border="40">buttons/dialogbutton-nofo.png</texture> - </control> - <control type="grouplist"> - <left>52</left> - <top>-184</top> - <width>1786</width> - <height>350</height> - <orientation>horizontal</orientation> - <itemgap>10</itemgap> - <control type="grouplist"> - <left>0</left> - <top>0</top> - <width>793</width> - <control type="label"> - <width>793</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[Player.Process(videodecoder),[COLOR FFE5A00D]$LOCALIZE[31139]:[/COLOR] ]$VAR[VideoHWDecoder, (,)]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo</visible> - </control> - <control type="label"> - <width>793</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[Player.Process(pixformat),[COLOR FFE5A00D]$LOCALIZE[31140]:[/COLOR] ]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo</visible> - </control> - <control type="label"> - <width>793</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[Player.Process(deintmethod),[COLOR FFE5A00D]$LOCALIZE[16038]:[/COLOR] ]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo</visible> - </control> - <control type="label"> - <width>793</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[Player.Process(videowidth),[COLOR FFE5A00D]$LOCALIZE[38031]:[/COLOR] ,x]$INFO[Player.Process(videoheight),, px]$INFO[Player.Process(videodar),$COMMA , AR]$INFO[Player.Process(videofps),$COMMA , FPS]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo</visible> - </control> - <control type="textbox"> - <width>793</width> - <height>50</height> - <aligny>bottom</aligny> - <autoscroll delay="1000" time="1000" repeat="2000"></autoscroll> - <label>[COLOR FFE5A00D]$LOCALIZE[460]:[/COLOR] $INFO[Player.Process(audiochannels),,$COMMA ]$INFO[Player.Process(audiodecoder)]$INFO[Player.Process(audiobitspersample),$COMMA , bits]$INFO[Player.Process(audiosamplerate),$COMMA , Hz]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - </control> - <control type="label"> - <width>793</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[System.Memory(used.percent),[COLOR FFE5A00D]$LOCALIZE[31030]:[/COLOR] ,]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - </control> - </control> - <control type="grouplist"> - <left>0</left> - <top>0</top> - <width>993</width> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[Window.Property(ppi.Status)]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Status))</visible> - </control> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>[COLOR FFE5A00D]Mode:[/COLOR] $INFO[Window.Property(ppi.Mode)]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Mode))</visible> - </control> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>[COLOR FFE5A00D]Container:[/COLOR] $INFO[Window.Property(ppi.Container)]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Container))</visible> - </control> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>[COLOR FFE5A00D]Video:[/COLOR] $INFO[Window.Property(ppi.Video)]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Video))</visible> - </control> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[Window.Property(ppi.Audio),[COLOR FFE5A00D]Audio:[/COLOR] ]$INFO[Window.Property(ppi.Subtitles), [COLOR FFE5A00D]Subtitle:[/COLOR] ]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + [!String.IsEmpty(Window.Property(ppi.Audio)) | !String.IsEmpty(Window.Property(ppi.Subtitles))]</visible> - </control> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>[COLOR FFE5A00D]Server:[/COLOR] $INFO[Window.Property(ppi.User)]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.User))</visible> - </control> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>[COLOR FFE5A00D]Buffer:[/COLOR] $INFO[Player.CacheLevel]%</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + String.IsEmpty(Window.Property(ppi.Buffered))</visible> - </control> - <control type="label"> - <width>893</width> - <height>50</height> - <aligny>bottom</aligny> - <label>[COLOR FFE5A00D]Buffer:[/COLOR] $INFO[Window.Property(ppi.Buffered)]% (% of Video cached)</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Buffered))</visible> - </control> - </control> - </control> - <control type="label"> - <left>52</left> - <top>120</top> - <width>1786</width> - <height>50</height> - <aligny>bottom</aligny> - <label>$INFO[System.CpuUsage,[COLOR FFE5A00D]$LOCALIZE[13271][/COLOR] ]</label> - <font>font14</font> - <shadowcolor>black</shadowcolor> - </control> - </control> - <control type="group" id="801"> - <visible>!String.IsEmpty(Window.Property(show.OSD)) + !Window.IsVisible(osdvideosettings) + !Window.IsVisible(osdaudiosettings) + !Window.IsVisible(osdsubtitlesettings) + !Window.IsVisible(subtitlesearch) + !Window.IsActive(playerprocessinfo) + !Window.IsActive(selectdialog) + !Window.IsVisible(osdcmssettings)</visible> - <animation effect="fade" time="200" delay="200" end="0">Hidden</animation> - <control type="group" id="300"> - <visible>!String.IsEmpty(Window.Property(has.bif)) + [Control.HasFocus(100) | Control.HasFocus(501) | !String.IsEmpty(Window.Property(button.seek))]</visible> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>0</posx> - <posy>752</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>324</width> - <height>184</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>2</posx> - <posy>2</posy> - <width>320</width> - <height>180</height> - <fadetime>10</fadetime> - <texture>$INFO[Window.Property(bif.image)]</texture> - </control> - </control> - - <control type="grouplist" id="400"> - <defaultcontrol>406</defaultcontrol> - <hitrect x="460" y="998" w="1000" h="55" /> - <posx>360</posx> - <posy>964</posy> - <width>1200</width> - - <height>124</height> - <align>center</align> - <onup>100</onup> - <itemgap>-40</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="group" id="421"> - <visible>!String.IsEmpty(Window.Property(nav.repeat))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false" condition="Control.HasFocus(401)">Conditional</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false" condition="!Control.HasFocus(401)">Conditional</animation> - <width>125</width> - <height>101</height> - <control type="button" id="401"> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <onup>100</onup> - <onright>402</onright> - <onleft>412</onleft> - <font>font12</font> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - <control type="group"> - <visible>!Control.HasFocus(401)</visible> - <control type="image"> - <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/repeat.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeatOne | !String.IsEmpty(Window.Property(pq.repeat.one))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-one.png</texture> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(401)</visible> - <control type="image"> - <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFE5A00D">script.plex/buttons/repeat-focus.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-focus.png</texture> - </control> - <control type="image"> - <visible>Playlist.IsRepeatOne | !String.IsEmpty(Window.Property(pq.repeat.one))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFCC7B19">script.plex/buttons/repeat-one-focus.png</texture> - </control> - </control> - </control> - - <control type="togglebutton" id="402"> - <visible>!String.IsEmpty(Window.Property(has.playlist)) + !String.IsEmpty(Window.Property(nav.shuffle))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <usealttexture>!String.IsEmpty(Window.Property(pq.shuffled))</usealttexture> - <alttexturefocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="FFCC7B19">script.plex/buttons/shuffle.png</alttexturenofocus> - <label> </label> - </control> - <control type="button" id="422"> - <enable>false</enable> - <visible>String.IsEmpty(Window.Property(has.playlist)) + !String.IsEmpty(Window.Property(nav.shuffle))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="40FFFFFF">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="40FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - - <control type="button" id="403"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/settings-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/settings.png</texturenofocus> - <label> </label> - </control> - - - <control type="button" id="404"> - <visible>!String.IsEmpty(Window.Property(pq.hasprev)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="58" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="424"> - <enable>false</enable> - <visible>String.IsEmpty(Window.Property(pq.hasprev)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="40FFFFFF">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="40FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="405"> - <visible>!String.IsEmpty(Window.Property(nav.ffwdrwd))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="FFE5A00D">script.plex/buttons/skip-forward-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="99FFFFFF">script.plex/buttons/skip-forward.png</texturenofocus> - <label> </label> - </control> - - <control type="group" id="426"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false" condition="Control.HasFocus(406)">Conditional</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false" condition="!Control.HasFocus(406)">Conditional</animation> - <width>125</width> - <height>101</height> - <control type="button" id="406"> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <onup>100</onup> - <onright>407</onright> - <onleft>405</onleft> - <font>font12</font> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - <onclick>PlayerControl(Play)</onclick> - </control> - <control type="group"> - <visible>!Control.HasFocus(406)</visible> - <control type="image"> - <visible>!Player.Paused + !Player.Forwarding + !Player.Rewinding</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/pause.png</texture> - </control> - <control type="image"> - <visible>Player.Paused | Player.Forwarding | Player.Rewinding</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/play.png</texture> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(406)</visible> - <control type="image"> - <visible>!Player.Paused + !Player.Forwarding + !Player.Rewinding</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFE5A00D">script.plex/buttons/pause-focus.png</texture> - </control> - <control type="image"> - <visible>Player.Paused | Player.Forwarding | Player.Rewinding</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texture colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texture> - </control> - </control> - </control> - - <control type="button" id="407"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/stop-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/stop.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="408"> - <visible>!String.IsEmpty(Window.Property(nav.ffwdrwd))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/skip-forward-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/skip-forward.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="409"> - <visible>!String.IsEmpty(Window.Property(pq.hasnext)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="419"> - <enable>false</enable> - <visible>String.IsEmpty(Window.Property(pq.hasnext)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <texturefocus colordiffuse="40FFFFFF">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus colordiffuse="40FFFFFF">script.plex/buttons/next.png</texturenofocus> - <label> </label> - </control> - - - <control type="button" id="410"> - <visible>[!String.IsEmpty(Window.Property(pq.hasnext)) | !String.IsEmpty(Window.Property(pq.hasprev))] + !String.IsEmpty(Window.Property(nav.playlist))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="58" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/pqueue-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pqueue.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="430"> - <enable>false</enable> - <visible>String.IsEmpty(Window.Property(pq.hasnext)) + String.IsEmpty(Window.Property(pq.hasprev)) + !String.IsEmpty(Window.Property(nav.playlist))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="40FFFFFF">script.plex/buttons/pqueue-focus.png</texturefocus> - <texturenofocus colordiffuse="40FFFFFF">script.plex/buttons/pqueue.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="412"> - <visible>!String.IsEmpty(Window.Property(nav.quick_subtitles))</visible> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/subtitle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/subtitle.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group"> - <posx>0</posx> - <posy>940</posy> - <control type="button" id="100"> - <hitrect x="0" y="-19" w="1920" h="48" /> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>10</height> - <onup>501</onup> - <ondown>400</ondown> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - </control> - </control> - - <control type="group" id="500"> - <animation effect="slide" time="100" start="0,0" end="0,20" reversible="true" condition="Control.HasFocus(501) + String.IsEmpty(Window.Property(has.chapters))">Conditional</animation> - - <!-- CHAPTERS --> - <animation effect="slide" time="100" start="0,0" end="0,-60" reversible="true" condition="Control.HasFocus(501) + !String.IsEmpty(Window.Property(has.chapters)) + !String.IsEmpty(Window.Property(show.chapters))">Conditional</animation> - <!-- /CHAPTERS --> - - <visible>String.IsEmpty(Window.Property(mouse.mode)) + String.IsEmpty(Window.Property(hide.bigseek)) + [Control.HasFocus(501) | Control.HasFocus(100)] + [!String.IsEmpty(Window.Property(show.chapters)) | String.IsEmpty(Window.Property(has.chapters))]</visible> - <posx>-8</posx> - <posy>917</posy> - <control type="image"> - <posx>-200</posx> - <posy>5</posy> - <width>2320</width> - <height>6</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - <visible>String.IsEmpty(Window.Property(has.chapters))</visible> - </control> - <!-- CHAPTERS --> - <control type="image"> - <posx>0</posx> - <posy>-175</posy> - <width>1928</width> - <height>200</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - <visible>!String.IsEmpty(Window.Property(has.chapters))</visible> - </control> - <control type="label"> - <posx>40</posx> - <posy>-162</posy> - <width>auto</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>CC606060</textcolor> - <label>$INFO[Window.Property(chapters.label)]</label> - <visible>!String.IsEmpty(Window.Property(has.chapters)) + !Control.HasFocus(501)</visible> - </control> - <control type="label"> - <posx>40</posx> - <posy>-162</posy> - <width>auto</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(chapters.label)]</label> - <visible>!String.IsEmpty(Window.Property(has.chapters)) + Control.HasFocus(501)</visible> - </control> - <!-- /CHAPTERS --> - <control type="list" id="501"> - <hitrect x="-20" y="-20" w="10" h="10" /> - <posx>0</posx> - <posy>0</posy> - <width>1928</width> - <height>16</height> - <ondown>100</ondown> - <onfocus>SetProperty(hide.bigseek,)</onfocus> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="160" condition="String.IsEmpty(Window.Property(has.chapters))"> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>16</width> - <height>16</height> - <texture>script.plex/indicators/seek-selection-marker.png</texture> - <colordiffuse>FF606060</colordiffuse> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="160" condition="String.IsEmpty(Window.Property(has.chapters))"> - <control type="image"> - <visible>!Control.HasFocus(501)</visible> - <posx>0</posx> - <posy>0</posy> - <width>16</width> - <height>16</height> - <texture>script.plex/indicators/seek-selection-marker.png</texture> - <colordiffuse>FF606060</colordiffuse> - </control> - <control type="image"> - <visible>Control.HasFocus(501)</visible> - <posx>0</posx> - <posy>0</posy> - <width>16</width> - <height>16</height> - <texture>script.plex/indicators/seek-selection-marker.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - </focusedlayout> - - <!-- ITEM LAYOUT CHAPTERS ########################################## --> - <itemlayout width="218" condition="!String.IsEmpty(Window.Property(has.chapters))"> - <control type="group"> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> - <aspectratio>scale</aspectratio> - <colordiffuse>CC606060</colordiffuse> - <visible>!Control.HasFocus(501)</visible> - </control> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - <colordiffuse>DDAAAAAA</colordiffuse> - <visible>!Control.HasFocus(501)</visible> - </control> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> - <aspectratio>scale</aspectratio> - <colordiffuse>FFAAAAAA</colordiffuse> - <visible>Control.HasFocus(501)</visible> - </control> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - <colordiffuse>FFAAAAAA</colordiffuse> - <visible>Control.HasFocus(501)</visible> - </control> - <control type="label"> - <posx>40</posx> - <posy>120</posy> - <width>auto</width> - <height>10</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>CC606060</textcolor> - <label>$INFO[ListItem.Label]</label> - <visible>!Control.HasFocus(501)</visible> - </control> - <control type="label"> - <posx>40</posx> - <posy>120</posy> - <width>auto</width> - <height>10</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFAAAAAA</textcolor> - <label>$INFO[ListItem.Label]</label> - <visible>Control.HasFocus(501)</visible> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT CHAPTERS ####################################### --> - <focusedlayout width="218" condition="!String.IsEmpty(Window.Property(has.chapters))"> - <control type="group"> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> - <aspectratio>scale</aspectratio> - <colordiffuse>CC909090</colordiffuse> - <visible>!Control.HasFocus(501)</visible> - </control> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - <colordiffuse>FFAAAAAA</colordiffuse> - <visible>!Control.HasFocus(501)</visible> - </control> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> - <aspectratio>scale</aspectratio> -<!-- <colordiffuse>FF606060</colordiffuse>--> - <visible>Control.HasFocus(501)</visible> - </control> - <control type="image"> - <posx>40</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> -<!-- <colordiffuse>FFFFFFFF</colordiffuse>--> - <visible>Control.HasFocus(501)</visible> - </control> - <control type="label"> - <posx>40</posx> - <posy>120</posy> - <width>auto</width> - <height>10</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFAAAAAA</textcolor> - <label>$INFO[ListItem.Label]</label> - <visible>!Control.HasFocus(501)</visible> - </control> - <control type="label"> - <posx>40</posx> - <posy>120</posy> - <width>auto</width> - <height>10</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> -<!-- <textcolor>FFFFFFFF</textcolor>--> - <label>[B]$INFO[ListItem.Label][/B]</label> - <visible>Control.HasFocus(501)</visible> - </control> - </control> - </focusedlayout> - </control> - </control> - </control> - <control type="group" id="202"> - <visible>Control.HasFocus(100) | Control.HasFocus(501) | !String.IsEmpty(Window.Property(button.seek))</visible> - <posx>0</posx> - <posy>896</posy> - <control type="group" id="203"> - <posx>-50</posx> - <posy>0</posy> - <control type="image" id="204"> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>0</posx> - <posy>0</posy> - <width>101</width> - <height>39</height> - <texture>script.plex/indicators/player-selection-time_box.png</texture> - <colordiffuse>D0000000</colordiffuse> - </control> - <control type="label" id="205"> - <posx>0</posx> - <posy>0</posy> - <width>101</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(time.selection)]</label> - </control> - </control> - <control type="image"> - <animation effect="fade" time="100" delay="100" end="100">Visible</animation> - <posx>-6</posx> - <posy>39</posy> - <width>15</width> - <height>7</height> - <texture>script.plex/indicators/player-selection-time_arrow.png</texture> - <colordiffuse>D0000000</colordiffuse> - </control> - </control> - - <!-- SKIP MARKER BUTTON --> - <control type="grouplist" id="790"> - <right>30</right> - <top>797</top> - <width>1670</width> - <height>143</height> - <align>right</align> - <orientation>horizontal</orientation> - <control type="button" id="791"> - <visible>[!String.IsEmpty(Window.Property(show.markerSkip)) + String.IsEmpty(Window.Property(show.markerSkip_OSDOnly))] | [!String.IsEmpty(Window.Property(show.markerSkip_OSDOnly)) + !String.IsEmpty(Window.Property(show.OSD))]</visible> - <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> - <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> - <animation type="Conditional" condition="String.IsEmpty(Window.Property(show.OSD)) + !Window.IsVisible(seekbar)" reversible="false"> - <effect type="slide" end="0,100" time="100" delay="100"></effect> - </animation> - <width min="200">auto</width> - <height>143</height> - <align>center</align> - <right>0</right> - <top>0</top> - <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> - <textoffsetx>70</textoffsetx> - <textcolor>FF000000</textcolor> - <focusedcolor>FF000000</focusedcolor> - <label>$INFO[Window.Property(skipMarkerName)]</label> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-settings.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-settings.xml deleted file mode 100644 index 35321b29b7..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-settings.xml +++ /dev/null @@ -1,684 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>300</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - - <control type="group"> - <animation effect="slide" end="-582,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <control type="group"> - <animation effect="slide" end="-297,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> - <control type="image"> - <posx>843</posx> - <posy>135</posy> - <width>1077</width> - <height>945</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>32111111</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>810</posy> - <width>1920</width> - <height>270</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>32000000</colordiffuse> - </control> - </control> - <control type="image"> - <posx>843</posx> - <posy>810</posy> - <width>1077</width> - <height>270</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>32111111</colordiffuse> - </control> - <control type="image"> - <animation effect="slide" end="-297,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> - <posx>1920</posx> - <posy>135</posy> - <width>879</width> - <height>945</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>66111111</colordiffuse> - </control> - </control> - - <control type="textbox"> - <visible>Control.HasFocus(100) | Control.HasFocus(125)</visible> - <posx>903</posx> - <posy>870</posy> - <width>1017</width> - <height>170</height> - <font>font10</font> - <textcolor>FFFFFFFF</textcolor> - <align>left</align> - <scrolltime>200</scrolltime> - <autoscroll delay="5000" time="4000" repeat="15000"></autoscroll> - <label>$INFO[Container(100).ListItem.Property(description)]</label> - </control> - - <control type="group" id="50"> - <posx>248</posx> - <posy>168</posy> - <defaultcontrol always="true">75</defaultcontrol> - <control type="list" id="75"> - <posx>0</posx> - <posy>0</posy> - <width>590</width> - <height>666</height> - <onleft>201</onleft> - <onright>100</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="75"> - <control type="group"> - <posx>88</posx> - <posy>40</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>414</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>75</posy> - <width>414</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>661F1F1F</colordiffuse> - </control> - </control> - </itemlayout> - <focusedlayout height="75"> - <control type="group"> - <visible>ControlGroup(50).HasFocus(0)</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>590</width> - <height>155</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(75)</visible> - <posx>40</posx> - <posy>40</posy> - <width>510</width> - <height>75</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="image"> - <visible>!Control.HasFocus(75)</visible> - <posx>40</posx> - <posy>40</posy> - <width>510</width> - <height>75</height> - <texture colordiffuse="FFCC7B19" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="image"> - <visible>!Control.HasFocus(75)</visible> - <posx>512</posx> - <posy>66</posy> - <width>16</width> - <height>23</height> - <texture>script.plex/settings/expanded.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="label"> - <posx>88</posx> - <posy>40</posy> - <width>414</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="label"> - <visible>!ControlGroup(50).HasFocus(0)</visible> - <posx>88</posx> - <posy>40</posy> - <width>414</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </focusedlayout> - </control> - - <control type="list" id="100"> - <visible>Integer.IsGreater(Container(100).NumItems,0)</visible> - <enable>String.IsEmpty(Window.Property(section.about))</enable> - <posx>604</posx> - <posy>0</posy> - <width>776</width> - <height>640</height> - <onleft>75</onleft> - <onright>150</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <pagecontrol>101</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="75"> - <control type="group"> - <posx>88</posx> - <posy>40</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>200</posx> - <posy>0</posy> - <width>400</width> - <scroll>true</scroll> - <scrollspeed>25</scrollspeed> - <height>75</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>75</posy> - <width>600</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>661F1F1F</colordiffuse> - </control> - </control> - <control type="group"> - <posx>643</posx> - <posy>55</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(checkbox))</visible> - <posx>0</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture colordiffuse="EE000000" border="10">script.plex/settings/checkbox.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> - <posx>0</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture>script.plex/settings/checkmark.png</texture> - </control> - </control> - </itemlayout> - <focusedlayout height="75"> - <control type="group"> - <visible>Control.HasFocus(100) | Control.HasFocus(125)</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>776</width> - <height>155</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <visible>!Control.HasFocus(125)</visible> - <posx>40</posx> - <posy>40</posy> - <width>696</width> - <height>75</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(125)</visible> - <posx>40</posx> - <posy>40</posy> - <width>696</width> - <height>75</height> - <texture colordiffuse="FFCC7B19" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(125)</visible> - <posx>698</posx> - <posy>66</posy> - <width>16</width> - <height>23</height> - <texture>script.plex/settings/expanded.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="group"> - <posx>88</posx> - <posy>40</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>500</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>200</posx> - <posy>0</posy> - <width>400</width> - <height>75</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="group"> - <visible>!Control.HasFocus(100) + !Control.HasFocus(125)</visible> - <posx>88</posx> - <posy>40</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>400</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>200</posx> - <posy>0</posy> - <width>400</width> - <height>75</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>75</posy> - <width>600</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>661F1F1F</colordiffuse> - </control> - </control> - <control type="group"> - <posx>643</posx> - <posy>55</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(checkbox))</visible> - <posx>0</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture colordiffuse="EE000000" border="10">script.plex/settings/checkbox.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> - <posx>0</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture>script.plex/settings/checkmark.png</texture> - </control> - </control> - </focusedlayout> - </control> - - <control type="scrollbar" id="101"> - <visible>Control.IsVisible(100) + !Control.IsVisible(125)</visible> - <left>1388</left> - <top>40</top> - <width>9</width> - <height>600</height> - <visible>true</visible> - <texturesliderbackground colordiffuse="66000000" border="4">script.plex/white-square-rounded-4r.png</texturesliderbackground> - <texturesliderbar colordiffuse="66FFFFFF" border="4">script.plex/white-square-rounded-4r.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="4">script.plex/white-square-rounded-4r.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - - <control type="button" id="150"> - <visible>Integer.IsGreater(Container(100).NumItems,0) + String.IsEmpty(Window.Property(section.about))</visible> - <width>10</width> - <height>10</height> - <onright>125</onright> - <onleft>100</onleft> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - <onfocus>SetFocus(100)</onfocus> - </control> - - <control type="list" id="125"> - <visible allowhiddenfocus="true">Control.HasFocus(125) + Integer.IsGreater(Container(100).NumItems,0)</visible> - <enable>Integer.IsGreater(Container(100).NumItems,0) + String.IsEmpty(Window.Property(section.about))</enable> - - <posx>1383</posx> - <posy>0</posy> - <width>845</width> - <height>566</height> - <onleft>100</onleft> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <pagecontrol>126</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="75"> - <control type="group"> - <posx>88</posx> - <posy>40</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>594</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>75</posy> - <width>594</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>661F1F1F</colordiffuse> - </control> - </control> - <control type="group"> - <posx>637</posx> - <posy>55</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> - <posx>0</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture>script.plex/settings/checkmark.png</texture> - </control> - </control> - </itemlayout> - <focusedlayout height="75"> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>610</width> - <height>155</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <posx>40</posx> - <posy>40</posy> - <width>690</width> - <height>75</height> - <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="group"> - <posx>88</posx> - <posy>40</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>594</width> - <height>75</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="group"> - <posx>637</posx> - <posy>55</posy> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> - <posx>0</posx> - <posy>0</posy> - <width>45</width> - <height>45</height> - <texture>script.plex/settings/checkmark.png</texture> - </control> - </control> - </focusedlayout> - </control> - - <control type="scrollbar" id="126"> - <visible>Control.IsVisible(125)</visible> - <left>2161</left> - <top>40</top> - <width>9</width> - <height>525</height> - <visible>true</visible> - <texturesliderbackground colordiffuse="66000000" border="4">script.plex/white-square-rounded-4r.png</texturesliderbackground> - <texturesliderbar colordiffuse="66FFFFFF" border="4">script.plex/white-square-rounded-4r.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="4">script.plex/white-square-rounded-4r.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - - </control> - </control> - - - <control type="group" id="200"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(heading)][/UPPERCASE]</label> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-settings_select_dialog.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-settings_select_dialog.xml deleted file mode 100644 index 7e93be5c07..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-settings_select_dialog.xml +++ /dev/null @@ -1,142 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <!-- <zorder>102</zorder> --> - <controls> - <control type="group"> - <posx>660</posx> - <posy>145</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>680</width> - <height>870</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>80</height> - <texture border="10">script.plex/white-square-top-rounded.png</texture> - <colordiffuse>F21F1F1F</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>80</posy> - <width>600</width> - <height>710</height> - <texture flipy="true" border="10">script.plex/white-square-top-rounded.png</texture> - <colordiffuse>F2606060</colordiffuse> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>80</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B][UPPERCASE]$INFO[Window.Property(heading)][/UPPERCASE][/B]</label> - </control> - <control type="list" id="100"> - <posx>0</posx> - <posy>80</posy> - <width>600</width> - <height>700</height> - <onup>noop</onup> - <ondown>noop</ondown> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="100"> - <control type="label"> - <visible>String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>0</posy> - <width>560</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>15</posy> - <width>560</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>40</posy> - <width>560</width> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFBBBBBB</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </itemlayout> - <focusedlayout height="100"> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>600</width> - <height>100</height> - <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>0</posy> - <width>560</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>15</posy> - <width>560</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(ListItem.Label2)</visible> - <posx>20</posx> - <posy>40</posy> - <width>560</width> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF222222</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </focusedlayout> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-signin_background.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-signin_background.xml deleted file mode 100644 index 4747d54736..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-signin_background.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/back.jpg</texture> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-signin_blank.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-signin_blank.xml deleted file mode 100644 index 91e3fae5ee..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-signin_blank.xml +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/sign_in/back.jpg</texture> - </control> - - <control type="textbox"> - <posx>210</posx> - <posy>375</posy> - <width>1502</width> - <height>530</height> - <font>font13</font> - <textcolor>FFFFFFFF</textcolor> - <align>left</align> - <label>[B]$INFO[Window.Property(message)][/B]</label> - </control> - - <control type="button" id="100"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <font>font20</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-slideshow.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-slideshow.xml deleted file mode 100644 index 869b7255bc..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-slideshow.xml +++ /dev/null @@ -1,63 +0,0 @@ -<window> - <zorder>6</zorder> - <controls> - <control type="group"> - <control type="image" id="1"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true"></texture> - <aspectratio>keep</aspectratio> - <fadetime>1000</fadetime> - <texture>$INFO[Window.Property(thumb)]</texture> - </control> - <control type="group" id="100"> - <posx>20</posx> - <posy>20</posy> - <height>100</height> - <width>1880</width> - <control type="label" id="101"> - <visible>String.IsEqual(Window.Property(align),0)</visible> - <posy>0</posy> - <height>50</height> - <font>font45</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <shadowcolor>FF000000</shadowcolor> - <label>$INFO[Window.Property(clock)]</label> - </control> - <control type="label" id="105"> - <visible>String.IsEqual(Window.Property(align),0)</visible> - <posy>50</posy> - <height>20</height> - <font>font13</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <shadowcolor>FF000000</shadowcolor> - <label>$INFO[Window.Property(title)]</label> - </control> - <control type="label" id="111"> - <visible>String.IsEqual(Window.Property(align),1)</visible> - <posy>0</posy> - <height>50</height> - <font>font45</font> - <align>right</align> - <textcolor>FFFFFFFF</textcolor> - <shadowcolor>FF000000</shadowcolor> - <label>$INFO[Window.Property(clock)]</label> - </control> - <control type="label" id="115"> - <visible>String.IsEqual(Window.Property(align),1)</visible> - <posy>50</posy> - <height>20</height> - <font>font13</font> - <align>right</align> - <textcolor>FFFFFFFF</textcolor> - <shadowcolor>FF000000</shadowcolor> - <label>$INFO[Window.Property(title)]</label> - </control> - </control> - </control> - </controls> -</window> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-squares.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-squares.xml deleted file mode 100644 index c6eab7662a..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-squares.xml +++ /dev/null @@ -1,777 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" time="200" end="0,-135" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5)">Conditional</animation> - <animation effect="slide" time="200" end="0,-200" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5) + Integer.IsGreater(Container(101).Position,5)">Conditional</animation> - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>101</defaultcontrol> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <visible>!Integer.IsGreater(Container(101).ListItem.Property(index),5) + String.IsEmpty(Window.Property(no.content)) + String.IsEmpty(Window.Property(no.content.filtered)) + !String.IsEmpty(Window.Property(initialized))</visible> - <defaultcontrol>301</defaultcontrol> - <posx>30</posx> - <posy>-25</posy> - <width>1000</width> - <height>145</height> - <onup>200</onup> - <ondown>101</ondown> - <itemgap>-20</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - <control type="button" id="301"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="302"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/shuffle-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/shuffle.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="303"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(no.options)) | Player.HasAudio</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/more-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/more.png</texturenofocus> - <label> </label> - </control> - <control type="button" id="304"> - <hitrect x="20" y="20" w="86" h="60" /> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <animation effect="zoom" start="100" end="143" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="143" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <width>126</width> - <height>100</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/chapters-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/chapters.png</texturenofocus> - <label> </label> - </control> - </control> - - <control type="group" id="100"> - <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>101</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <control type="panel" id="101"> - <hitrect x="0" y="95" w="1780" h="1185" /> - <posx>0</posx> - <posy>0</posy> - <width>1800</width> - <height>1280</height> - <onup>300</onup> - <onright>151</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>2</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="287" height="343"> - <control type="group"> - <posx>55</posx> - <posy>97</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>244</posy> - <width>244</width> - <height>40</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>80000000</colordiffuse> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>260</posy> - <width>244</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="287" height="343"> - <control type="group"> - <posx>55</posx> - <posy>97</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>374</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>244</posy> - <width>244</width> - <height>40</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>80000000</colordiffuse> - </control> - <control type="label"> - <scroll>Control.HasFocus(101)</scroll> - <posx>0</posx> - <posy>260</posy> - <width>244</width> - <height>40</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>294</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - </control> - - <control type="group" id="150"> - <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>151</defaultcontrol> - <posx>1780</posx> - <posy>150</posy> - <width>20</width> - <height>920</height> - <control type="list" id="151"> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>1050</height> - <onleft>100</onleft> - <onright>152</onright> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="34"> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="label"> - <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>99FFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>32</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFE5A00D</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(151)</visible> - <posx>0</posx> - <posy>0</posy> - <width>34</width> - <height>34</height> - <colordiffuse>FFE5A00D</colordiffuse> - <texture border="12">script.plex/white-outline-rounded.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1820" y="150" w="100" h="910" /> - <left>1860</left> - <top>150</top> - <width>12</width> - <height>910</height> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - - - <control type="group" id="200"> - <animation effect="slide" end="0,-135" time="200" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <visible>!String.IsEmpty(Window.Property(initialized))</visible> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + Integer.IsGreater(Container(101).ListItem.Property(index),5)</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE][COLOR=gray]$INFO[Window.Property(items.count), (,)][/COLOR]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <onright>211</onright> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="grouplist"> - <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> - <right>340</right> - <posy>35</posy> - <width>1000</width> - <height>65</height> - <align>right</align> - <itemgap>30</itemgap> - <orientation>horizontal</orientation> - <onleft>204</onleft> - <onright>210</onright> - <ondown>50</ondown> - <control type="button" id="311"> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> - </control> - <control type="button" id="211"> - <width max="500">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> - </control> - <control type="button" id="310"> - <visible>!String.IsEqual(Window.Property(media),artist)</visible> - <enable>false</enable> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturenofocus>-</texturenofocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="312"> - <visible>String.IsEqual(Window.Property(media),artist)</visible> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <disabledcolor>FFFFFFFF</disabledcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> - </control> - <control type="button" id="210"> - <width max="300">auto</width> - <height>65</height> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>20</textoffsetx> - <textoffsety>0</textoffsety> - <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(no.content))</visible> - <posx>0</posx> - <posy>465</posy> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$ADDON[script.plexmod 32452][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>60</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFCCCCCC</textcolor> - <label>$ADDON[script.plexmod 32453]</label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(no.content.filtered))</visible> - <posx>0</posx> - <posy>465</posy> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$ADDON[script.plexmod 32454][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>60</posy> - <width>1800</width> - <height>35</height> - <font>font13</font> - <align>center</align> - <textcolor>FFCCCCCC</textcolor> - <label>$ADDON[script.plexmod 32455]</label> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-track_context.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-track_context.xml deleted file mode 100644 index 1597a70534..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-track_context.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true" fallback="script.plex/home/background-fallback.png">$INFO[Window.Property(background)]</texture> - </control> - - <control type="image"> - <posx>236</posx> - <posy>131</posy> - <width>638</width> - <height>638</height> - <texture>$INFO[Window.Property(track.thumb)]</texture> - </control> - - <control type="textbox"> - <posx>236</posx> - <posy>131</posy> - <width>1502</width> - <height>530</height> - <font>font13</font> - <textcolor>FFFFFFFF</textcolor> - <align>left</align> - <label>[B]$INFO[Window.Property(message)][/B]</label> - </control> - - <control type="grouplist" id="300"> - <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> - <defaultcontrol>301</defaultcontrol> - <posx>965</posx> - <posy>131</posy> - <width>750</width> - <height>638</height> - <itemgap>30</itemgap> - <orientation>vertical</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <control type="button" id="100"> - <posx>30</posx> - <posy>30</posy> - <width>1920</width> - <height>1080</height> - <font>font20</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FFFFFFFF</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-user_select.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-user_select.xml deleted file mode 100644 index 0ab23658bd..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-user_select.xml +++ /dev/null @@ -1,941 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour_opaque)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - </control> - - <control type="group"> - <animation effect="fade" time="100" start="100" end="20" condition="ControlGroup(400).HasFocus(0)">Conditional</animation> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>441</posx> - <posy>780</posy> - - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>225</width> - <height>225</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <posx>255</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>783</width> - <height>40</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>0</posx> - <posy>40</posy> - <width>783</width> - <height>40</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Album</info> - </control> - <control type="label"> - <posx>0</posx> - <posy>80</posy> - <width>783</width> - <height>40</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[MusicPlayer.Title][/B]</label> - </control> - </control> - - <control type="grouplist" id="600"> - <defaultcontrol>406</defaultcontrol> - <hitrect x="460" y="998" w="1000" h="55" /> - <posx>255</posx> - <posy>134</posy> - <width>783</width> - <height>124</height> - <align>center</align> - <onup>101</onup> - <itemgap>-40</itemgap> - <orientation>horizontal</orientation> - <scrolltime tween="quadratic" easing="out">200</scrolltime> - <usecontrolcoords>true</usecontrolcoords> - - <control type="button" id="404"> - <enable>MusicPlayer.HasPrevious</enable> - <animation effect="zoom" start="100" end="124" time="100" center="93,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="93,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>30</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus flipx="true" colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus flipx="true" colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <onclick>PlayerControl(Previous)</onclick> - <label> </label> - </control> - <control type="togglebutton" id="406"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/pause-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pause.png</texturenofocus> - <usealttexture>Player.Paused | Player.Forwarding | Player.Rewinding</usealttexture> - <alttexturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</alttexturefocus> - <alttexturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</alttexturenofocus> - <onclick>PlayerControl(Play)</onclick> - <label> </label> - </control> - <control type="button" id="409"> - <enable>MusicPlayer.HasNext</enable> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> - <onclick>PlayerControl(Next)</onclick> - <label> </label> - </control> - <control type="button" id="407"> - <animation effect="zoom" start="100" end="124" time="100" center="63,50" reversible="false">Focus</animation> - <animation effect="zoom" start="124" end="100" time="100" center="63,50" reversible="false">UnFocus</animation> - <hitrect x="28" y="28" w="69" h="45" /> - <posx>0</posx> - <posy>0</posy> - <width>125</width> - <height>101</height> - <font>font12</font> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/stop-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/stop.png</texturenofocus> - <onclick>PlayerControl(Stop)</onclick> - <label> </label> - </control> - </control> - - <control type="label"> - <posx>255</posx> - <posy>177</posy> - <width>783</width> - <height>40</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Time</info> - </control> - <control type="label"> - <posx>1038</posx> - <posy>177</posy> - <width>783</width> - <height>40</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.TimeRemaining</info> - </control> - - - <control type="progress"> - <description>Progressbar</description> - <posx>255</posx> - <posy>222</posy> - <width>783</width> - <height>3</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - - <control type="image" id="110"> - <visible>ControlGroup(400).HasFocus(0) + String.IsEmpty(Window.Property(busy))</visible> - <posx>770</posx> - <posy>275</posy> - <width>380</width> - <height>695</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - - <control type="group" id="100"> - <posx>0</posx> - <posy>315</posy> - <defaultcontrol always="true">101</defaultcontrol> - - <control type="fixedlist" id="101"> - <posx>-180</posx> - <posy>-40</posy> - <width>2100</width> - <height>455</height> - <scrolltime>200</scrolltime> - <onup>500</onup> - <ondown condition="Player.HasAudio">600</ondown> - <ondown condition="!String.IsEmpty(Container(101).ListItem.Property(protected))">400</ondown> - <orientation>horizontal</orientation> - <focusposition>3</focusposition> - - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="330"> - - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(empty))</visible> - <posx>0</posx> - <posy>40</posy> - <control type="image"> - <visible>Control.HasFocus(101) | ControlGroup(400).HasFocus(0)</visible> - <posx>75</posx> - <posy>75</posy> - <width>150</width> - <height>150</height> - <texture>script.plex/user_select/refresh.png</texture> - <colordiffuse>FFA0A0A0</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(empty))</visible> - <posx>0</posx> - <posy>40</posy> - <width>300</width> - <height>300</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <texture diffuse="script.plex/user_select/item-background.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> - <colordiffuse>FFA0A0A0</colordiffuse> - </control> - - <control type="image"> - <posx>45</posx> - <posy>45</posy> - <width>210</width> - <height>210</height> - <texture>script.plex/user_select/avatar-background.png</texture> - <colordiffuse>E0C0C0C0</colordiffuse> - </control> - <control type="image"> - <posx>54</posx> - <posy>54</posy> - <width>192</width> - <height>192</height> - <texture diffuse="script.plex/user_select/avatar-diffuse.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Thumb]</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Thumb)</visible> - <posx>54</posx> - <posy>54</posy> - <width>192</width> - <height>192</height> - <font>WeatherTemp</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(protected))</visible> - <posx>15</posx> - <posy>231</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/protected-back.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/protected-icon.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(admin))</visible> - <posx>231</posx> - <posy>231</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/admin-back.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/admin-icon.png</texture> - </control> - </control> - </control> - - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="330"> - - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(empty))</visible> - <posx>0</posx> - <posy>40</posy> - <control type="image"> - <visible>Control.HasFocus(101) | ControlGroup(400).HasFocus(0)</visible> - <posx>75</posx> - <posy>75</posy> - <width>150</width> - <height>150</height> - <texture>script.plex/user_select/refresh.png</texture> - <colordiffuse>FFFFFFFF</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(empty))</visible> - <posx>0</posx> - <posy>40</posy> - <control type="image" id="110"> - <visible>Control.HasFocus(101)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>380</width> - <height>455</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <visible>Control.HasFocus(101) | ControlGroup(400).HasFocus(0)</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>300</height> - <texture diffuse="script.plex/user_select/item-background-top.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> - <colordiffuse>FFA0A0A0</colordiffuse> - </control> - <control type="image"> - <visible>!Control.HasFocus(101) + !ControlGroup(400).HasFocus(0)</visible> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>300</height> - <texture diffuse="script.plex/user_select/item-background.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> - <colordiffuse>FFA0A0A0</colordiffuse> - </control> - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <control type="image"> - <posx>0</posx> - <posy>300</posy> - <width>300</width> - <height>75</height> - <texture>script.plex/user_select/item-background-bottom.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>300</posy> - <width>300</width> - <height>75</height> - <texture diffuse="script.plex/user_select/item-background-bottom.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> - <aspectratio scalediffuse="false">stretch</aspectratio> - <colordiffuse>40FFFFFF</colordiffuse> - </control> - </control> - - <control type="image"> - <visible>!Control.HasFocus(101) + !ControlGroup(400).HasFocus(0)</visible> - <posx>45</posx> - <posy>45</posy> - <width>210</width> - <height>210</height> - <texture>script.plex/user_select/avatar-background.png</texture> - <colordiffuse>E0C0C0C0</colordiffuse> - </control> - <control type="image"> - <visible>ControlGroup(400).HasFocus(0)</visible> - <posx>45</posx> - <posy>45</posy> - <width>210</width> - <height>210</height> - <texture>script.plex/user_select/avatar-background.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>45</posx> - <posy>45</posy> - <width>210</width> - <height>210</height> - <texture>script.plex/user_select/avatar-background.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - - <control type="image"> - <posx>54</posx> - <posy>54</posy> - <width>192</width> - <height>192</height> - <texture diffuse="script.plex/user_select/avatar-diffuse.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Thumb]</texture> - </control> - <control type="label"> - <visible>String.IsEmpty(ListItem.Thumb)</visible> - <posx>54</posx> - <posy>54</posy> - <width>192</width> - <height>192</height> - <font>WeatherTemp</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(protected))</visible> - <posx>15</posx> - <posy>231</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/protected-back.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/protected-icon.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(admin))</visible> - <posx>231</posx> - <posy>231</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/admin-back.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>54</width> - <height>54</height> - <texture>script.plex/user_select/admin-icon.png</texture> - </control> - </control> - - <control type="label"> - <visible>Control.HasFocus(101)</visible> - <posx>10</posx> - <posy>300</posy> - <width>280</width> - <height>75</height> - <font>font13</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFCC7B19</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - - </focusedlayout> - </control> - - <control type="group" id="400"> - <defaultcontrol always="true">205</defaultcontrol> - <visible allowhiddenfocus="true">!String.IsEmpty(Container(101).ListItem.Property(protected)) + ControlGroup(400).HasFocus(0) + !String.IsEmpty(Window.Property(initialized))</visible> - <posx>810</posx> - <posy>375</posy> - <control type="button"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>239</height> - <onleft>400</onleft> - <onright>400</onright> - <onup>400</onup> - <ondown>400</ondown> - <texturefocus>-</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>-75</posy> - <width>300</width> - <height>75</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>-75</posy> - <width>300</width> - <height>75</height> - <texture fallback="script.plex/gray-square.png">$INFO[Container(101).ListItem.Property(back.image)]</texture> - <colordiffuse>40FFFFFF</colordiffuse> - </control> - <control type="label"> - <visible>String.IsEmpty(Container(101).ListItem.Property(editing.pin))</visible> - <posx>0</posx> - <posy>-75</posy> - <width>300</width> - <height>75</height> - <font>font13</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFCC7B19</textcolor> - <label>$INFO[Container(101).ListItem.Label]</label> - </control> - <control type="label"> - <visible>!String.IsEmpty(Container(101).ListItem.Property(editing.pin))</visible> - <posx>0</posx> - <posy>-75</posy> - <width>300</width> - <height>75</height> - <font>font13</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFCC7B19</textcolor> - <label>[B]$INFO[Container(101).ListItem.Property(pin)][/B]</label> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>300</width> - <height>239</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="group" id="300"> - <defaultcontrol>205</defaultcontrol> - <control type="group" id="200"> - <defaultcontrol>205</defaultcontrol> - <control type="button" id="201"> - <posx>0</posx> - <posy>0</posy> - <width>73</width> - <height>58</height> - <onright>202</onright> - <onup>101</onup> - <ondown>204</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]1[/B]</label> - </control> - <control type="button" id="202"> - <posx>75</posx> - <posy>0</posy> - <width>73</width> - <height>58</height> - <onright>203</onright> - <onleft>201</onleft> - <onup>101</onup> - <ondown>205</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]2[/B]</label> - </control> - <control type="button" id="203"> - <posx>150</posx> - <posy>0</posy> - <width>73</width> - <height>58</height> - <onright>211</onright> - <onleft>202</onleft> - <onup>101</onup> - <ondown>206</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]3[/B]</label> - </control> - <control type="button" id="204"> - <posx>0</posx> - <posy>60</posy> - <width>73</width> - <height>58</height> - <onright>205</onright> - <ondown>207</ondown> - <onup>201</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]4[/B]</label> - </control> - <control type="button" id="205"> - <posx>75</posx> - <posy>60</posy> - <width>73</width> - <height>58</height> - <onright>206</onright> - <onleft>204</onleft> - <ondown>208</ondown> - <onup>202</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]5[/B]</label> - </control> - <control type="button" id="206"> - <posx>150</posx> - <posy>60</posy> - <width>73</width> - <height>58</height> - <onright>211</onright> - <onleft>205</onleft> - <ondown>209</ondown> - <onup>203</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]6[/B]</label> - </control> - <control type="button" id="207"> - <posx>0</posx> - <posy>120</posy> - <width>73</width> - <height>58</height> - <onright>208</onright> - <ondown>210</ondown> - <onup>204</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]7[/B]</label> - </control> - <control type="button" id="208"> - <posx>75</posx> - <posy>120</posy> - <width>73</width> - <height>58</height> - <onright>209</onright> - <onleft>207</onleft> - <ondown>210</ondown> - <onup>205</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]8[/B]</label> - </control> - <control type="button" id="209"> - <posx>150</posx> - <posy>120</posy> - <width>73</width> - <height>58</height> - <onright>211</onright> - <onleft>208</onleft> - <ondown>210</ondown> - <onup>206</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]9[/B]</label> - </control> - </control> - <control type="button" id="210"> - <posx>0</posx> - <posy>180</posy> - <width>223</width> - <height>59</height> - <onright>211</onright> - <onup>200</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> - <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label>[B]0[/B]</label> - </control> - </control> - <control type="button" id="211"> - <posx>225</posx> - <posy>0</posy> - <width>75</width> - <height>239</height> - <onleft>300</onleft> - <onup>101</onup> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>center</align> - <aligny>center</aligny> - <texturefocus>script.plex/user_select/backspace.png</texturefocus> - <texturenofocus>script.plex/user_select/backspace_nf.png</texturenofocus> - <textoffsetx>0</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - </control> - - </control> - - <control type="group"> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>19000000</colordiffuse> - </control> - - <control type="grouplist"> - <posx>60</posx> - <posy>34.5</posy> - <width>1000</width> - <height>66</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>101</ondown> - <usecontrolcoords>true</usecontrolcoords> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <width>124</width> - <height>66</height> - <control type="button" id="500"> - <posx>0</posx> - <posy>0</posy> - <width>124</width> - <height>66</height> - <ondown>101</ondown> - <onright>101</onright> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <label> </label> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(dropdown))</visible> - <posx>0</posx> - <posy>0</posy> - <width>124</width> - <height>66</height> - <texture colordiffuse="FFCC7B19" border="10">script.plex/white-square-rounded.png</texture> - </control> - <control type="group"> - <posx>27</posx> - <posy>13</posy> - <control type="group"> - <visible>!Control.HasFocus(500) + String.IsEmpty(Window.Property(dropdown))</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>40</width> - <height>40</height> - <texture colordiffuse="99FFFFFF">script.plex/buttons/power.png</texture> - </control> - <control type="image"> - <posx>55</posx> - <posy>13.5</posy> - <width>15</width> - <height>13</height> - <texture colordiffuse="99FFFFFF">script.plex/indicators/dropdown-triangle.png</texture> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(500) | !String.IsEmpty(Window.Property(dropdown))</visible> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>40</width> - <height>40</height> - <texture colordiffuse="FF000000">script.plex/buttons/power.png</texture> - </control> - <control type="image"> - <posx>55</posx> - <posy>13.5</posy> - <width>15</width> - <height>13</height> - <texture colordiffuse="FF000000">script.plex/indicators/dropdown-triangle.png</texture> - </control> - </control> - </control> - </control> - <control type="label"> - <posx>-27</posx> - <posy>0</posy> - <width max="500">auto</width> - <height>66</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32437][/UPPERCASE]</label> - </control> - </control> - - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(busy))</visible> - <animation effect="fade" start="0" end="100">Visible</animation> - <control type="image"> - <posx>840</posx> - <posy>465</posy> - <width>240</width> - <height>150</height> - <texture>script.plex/busy-back.png</texture> - <colordiffuse>A0FFFFFF</colordiffuse> - </control> - <control type="image"> - <posx>915</posx> - <posy>521</posy> - <width>90</width> - <height>38</height> - <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-video_current_playlist.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-video_current_playlist.xml deleted file mode 100644 index 796140288d..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-video_current_playlist.xml +++ /dev/null @@ -1,480 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <defaultcontrol>100</defaultcontrol> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <control type="group" id="100"> - <!-- <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> --> - <defaultcontrol>101</defaultcontrol> - <posx>750</posx> - <posy>140</posy> - <width>1170</width> - <height>800</height> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>800</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>B3111111</colordiffuse> - </control> - <control type="list" id="101"> - <posx>0</posx> - <posy>0</posy> - <width>1170</width> - <height>800</height> - <onup>200</onup> - <onright>152</onright> - <onleft>300</onleft> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <preloaditems>4</preloaditems> - <pagecontrol>152</pagecontrol> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="101"> - <control type="group"> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(playing))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(playing))</visible> - <posx>2</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>74</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>168</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>132</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(watched))</visible> - <posx>895</posx> - <posy>-1</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <posx>226</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="label"> - <posx>730</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>98</posy> - <width>930</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout height="100"> - <control type="group"> - <control type="group"> - <visible>!Control.HasFocus(101)</visible> - <posx>120</posx> - <posy>24</posy> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(playing))</visible> - <posx>-10</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font10</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(playing))</visible> - <posx>0</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>74</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>168</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>692</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>63</posx> - <posy>11</posy> - <width>132</width> - <height>74</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(watched))</visible> - <posx>895</posx> - <posy>-1</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <posx>226</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>15</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>50</posy> - <width>584</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>B8FFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="label"> - <posx>756</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font10</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>D8FFFFFF</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> - <posx>0</posx> - <posy>97</posy> - <width>930</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - </control> - - <control type="group"> - <visible>Control.HasFocus(101)</visible> - <posx>63</posx> - <posy>21</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1124</width> - <height>180</height> - <texture border="40">script.plex/square-rounded-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1044</width> - <height>100</height> - <texture border="12">script.plex/white-square-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <!-- comment the previous and uncomment the following for re-enabling options button --> - <!--<control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>999</width> - <height>100</height> - <texture border="12">script.plex/white-square-left-rounded.png</texture> - <colordiffuse>FFE5A00D</colordiffuse> - </control> - <control type="image"> - <posx>999</posx> - <posy>0</posy> - <width>45</width> - <height>100</height> - <texture>script.plex/buttons/more-vertical.png</texture> - <colordiffuse>99FFFFFF</colordiffuse> - </control>--> - <control type="label"> - <visible>String.IsEmpty(ListItem.Property(playing))</visible> - <posx>24</posx> - <posy>0</posy> - <width>60</width> - <height>100</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(playing))</visible> - <posx>36</posx> - <posy>32.5</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/playing-circle.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="group"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(video))</visible> - <posx>103</posx> - <posy>0</posy> - <width>100</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>235</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>16</posy> - <width>638</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>51</posy> - <width>638</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>98000000</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(video))</visible> - <control type="image"> - <posx>103</posx> - <posy>0</posy> - <width>178</width> - <height>100</height> - <texture>$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(watched))</visible> - <posx>951</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <posx>313</posx> - <posy>0</posy> - <control type="label"> - <posx>0</posx> - <posy>16</posy> - <width>510</width> - <height>30</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>DF000000</textcolor> - <label>[B]$INFO[ListItem.Label][/B]</label> - </control> - <control type="label"> - <posx>0</posx> - <posy>51</posy> - <width>510</width> - <height>30</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>98000000</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - <control type="label"> - <posx>802</posx> - <posy>0</posy> - <width>200</width> - <height>100</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>B8000000</textcolor> - <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> - </control> - </control> - </control> - - </focusedlayout> - </control> - - <control type="scrollbar" id="152"> - <hitrect x="1108" y="33" w="90" h="734" /> - <left>1128</left> - <top>33</top> - <width>10</width> - <height>734</height> - <onleft>101</onleft> - <visible>true</visible> - <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>151</onleft> - </control> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-video_player.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-video_player.xml deleted file mode 100644 index b9abc3a73c..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-video_player.xml +++ /dev/null @@ -1,1351 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor> - <controls> - <control type="group"> - <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback_black.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background_static)]</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <fadetime>1000</fadetime> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(post.play))</visible> - <control type="group"> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(post.play.background)]</texture> - </control> - </control> - - <control type="group" id="50"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> - <effect type="slide" end="0,-500" time="200" tween="quadratic" easing="out"/> - </animation> - - <posx>0</posx> - <posy>135</posy> - <defaultcontrol>102</defaultcontrol> - - <control type="image"> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - - <control type="label"> - <scroll>false</scroll> - <posx>60</posx> - <posy>57</posy> - <width>462</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>A0FFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32438][/UPPERCASE]</label> - </control> - - <control type="group" id="100"> - <defaultcontrol>102</defaultcontrol> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>580</height> - <control type="group"> - <posx>60</posx> - <posy>131</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="231,129.5" reversible="true" condition="Control.HasFocus(101)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(101)</visible> - <posx>-45</posx> - <posy>-45</posy> - <width>552</width> - <height>349</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>462</width> - <height>259</height> - <texture>$INFO[Window.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>462</width> - <height>259</height> - <texture background="true">$INFO[Window.Property(prev.thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <posx>193</posx> - <posy>91.5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>76</width> - <height>76</height> - <texture colordiffuse="99000000">script.plex/indicators/circle-152.png</texture> - </control> - <control type="image"> - <posx>15</posx> - <posy>15</posy> - <width>46</width> - <height>46</height> - <texture>script.plex/indicators/replay.png</texture> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>269</posy> - <width>462</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(prev.title)]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>301</posy> - <width>462</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(prev.subtitle)]</label> - </control> - </control> - <control type="button" id="101"> - <posx>-5</posx> - <posy>-5</posy> - <width>472</width> - <height>269</height> - <onup>200</onup> - <ondown>400</ondown> - <onright>102</onright> - <texturefocus border="10">script.plex/home/selected.png</texturefocus> - <texturenofocus>-</texturenofocus> - </control> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(has.next))</visible> - <control type="label"> - <scroll>false</scroll> - <posx>572</posx> - <posy>57</posy> - <width>462</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32439][/UPPERCASE]</label> - </control> - <control type="group"> - <posx>582</posx> - <posy>131</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="268.5,151.5" reversible="true" condition="Control.HasFocus(102)">Conditional</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(102)</visible> - <posx>-45</posx> - <posy>-45</posy> - <width>627</width> - <height>393</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>537</width> - <height>303</height> - <texture>$INFO[Window.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>537</width> - <height>303</height> - <texture background="true">$INFO[Window.Property(next.thumb)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(countdown)) + Integer.IsGreaterOrEqual(Window.Property(countdown), 0)</visible> - <posx>192.5</posx> - <posy>75.5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>152</width> - <height>152</height> - <texture colordiffuse="99000000">script.plex/indicators/circle-152.png</texture> - </control> - <control type="image"> - <posx>8</posx> - <posy>8</posy> - <width>136</width> - <height>136</height> - <texture colordiffuse="FFCC7B19">script.plex/circle-progress/$INFO[Window.Property(countdown)].png</texture> - </control> - <control type="image"> - <posx>59.5</posx> - <posy>57</posy> - <width>33</width> - <height>38</height> - <texture>script.plex/indicators/pause.png</texture> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>313</posy> - <width>537</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(next.title)]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>345</posy> - <width>537</width> - <height>30</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(next.subtitle)]</label> - </control> - </control> - <control type="button" id="102"> - <posx>-5</posx> - <posy>-5</posy> - <width>547</width> - <height>313</height> - <onup>200</onup> - <ondown>400</ondown> - <onleft>101</onleft> - <texturefocus border="10">script.plex/home/selected.png</texturefocus> - <texturenofocus>-</texturenofocus> - </control> - </control> - </control> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(has.next))</visible> - <control type="label"> - <scroll>false</scroll> - <posx>1177</posx> - <posy>131</posy> - <width>683</width> - <height>43</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Window.Property(info.title)][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>1177</posx> - <posy>189</posy> - <width>683</width> - <height>32</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>A0FFFFFF</textcolor> - <label>$INFO[Window.Property(info.date)]$INFO[Window.Property(info.duration), • ]</label> - </control> - <control type="textbox"> - <scroll>false</scroll> - <posx>1177</posx> - <posy>300</posy> - <width>683</width> - <height>215</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(info.summary)]</label> - </control> - </control> - - <control type="group"> - <visible>String.IsEmpty(Window.Property(has.next))</visible> - <control type="label"> - <scroll>false</scroll> - <posx>580</posx> - <posy>131</posy> - <width>1280</width> - <height>43</height> - <font>font13</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B]$INFO[Window.Property(prev.info.title)][/B]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>580</posx> - <posy>189</posy> - <width>1280</width> - <height>32</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>A0FFFFFF</textcolor> - <label>$INFO[Window.Property(prev.info.date)]$INFO[Window.Property(prev.info.duration), • ]</label> - </control> - <control type="textbox"> - <scroll>false</scroll> - <posx>580</posx> - <posy>300</posy> - <width>1280</width> - <height>225</height> - <font>font12</font> - <align>left</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[Window.Property(prev.info.summary)]</label> - </control> - </control> - </control> - - <control type="grouplist" id="60"> - <posx>0</posx> - <posy>585</posy> - <width>1920</width> - <height>1610</height> - - <onup>300</onup> - <itemgap>0</itemgap> - - <control type="group" id="500"> - <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <height>360</height> - <width>1920</width> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>360</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>40000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>800</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32440][/UPPERCASE]</label> - </control> - <control type="list" id="400"> - <posx>0</posx> - <posy>18</posy> - <width>1920</width> - <height>430</height> - <onup>100</onup> - <ondown>401</ondown> - <onleft>false</onleft> - <onright>false</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>158</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>299</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>264</posx> - <posy>0</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>180</posy> - <width>299</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>212</posy> - <width>299</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>85.5</posx> - <posy>20</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="359"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="154.5,87.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="154.5,87.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>389</width> - <height>258</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>158</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>299</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>264</posx> - <posy>0</posy> - <width>35</width> - <height>35</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>180</posy> - <width>299</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>212</posy> - <width>299</width> - <height>35</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>299</width> - <height>168</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>119</posx> - <posy>34</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>85.5</posx> - <posy>20</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(400)</visible> - <posx>0</posx> - <posy>0</posy> - <width>309</width> - <height>178</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="501"> - <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>401</defaultcontrol> - <width>1920</width> - <height>520</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(divider.401))</visible> - <posx>60</posx> - <posy>0</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>0</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> - </control> - <control type="list" id="401"> - <posx>0</posx> - <posy>16</posy> - <width>1920</width> - <height>520</height> - <onup>400</onup> - <ondown>403</ondown> - <onleft>false</onleft> - <onright>false</onright> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>72</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,180.5" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,180.5" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>324</width> - <height>441</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture colordiffuse="FF404040">script.plex/white-square.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> - </control> - <control type="image"> - <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> - <posx>91.5</posx> - <posy>130.5</posy> - <width>61</width> - <height>100</height> - <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> - <posx>58</posx> - <posy>116.5</posy> - <width>128</width> - <height>128</height> - <texture>script.plex/home/busy.gif</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>361</height> - <texture background="true">$INFO[ListItem.Thumb]</texture> - <aspectratio>scale</aspectratio> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(progress))</visible> - <posx>0</posx> - <posy>351</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>10</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>1</posy> - <width>244</width> - <height>8</height> - <texture>$INFO[ListItem.Property(progress)]</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - </control> - <control type="image"> - <visible>!String.IsEmpty(ListItem.Property(unwatched))</visible> - <posx>196</posx> - <posy>0</posy> - <width>48</width> - <height>48</height> - <texture>script.plex/indicators/unwatched.png</texture> - </control> - <control type="group"> - <visible>!String.IsEmpty(ListItem.Property(unwatched.count))</visible> - <control type="image"> - <posx>193</posx> - <posy>0</posy> - <width>51</width> - <height>39</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FF000000</colordiffuse> - </control> - <control type="image"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>FFCC7B19</colordiffuse> - </control> - <control type="label"> - <posx>194</posx> - <posy>0</posy> - <width>50</width> - <height>38</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Property(unwatched.count)]</label> - </control> - </control> - <control type="label"> - <scroll>false</scroll> - <posx>0</posx> - <posy>369</posy> - <width>244</width> - <height>38</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(401)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>371</height> - <texture border="10">script.plex/home/selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - - <control type="group" id="503"> - <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> - <defaultcontrol>403</defaultcontrol> - <width>1920</width> - <height>410</height> - <control type="image"> - <visible>!String.IsEmpty(Window.Property(divider.403))</visible> - <posx>60</posx> - <posy>20</posy> - <width>1800</width> - <height>2</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>A0000000</colordiffuse> - </control> - <control type="label"> - <posx>60</posx> - <posy>20</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32419][/UPPERCASE]</label> - </control> - <control type="list" id="403"> - <posx>0</posx> - <posy>36</posy> - <width>1920</width> - <height>410</height> - <onup>401</onup> - <ondown>404</ondown> - <scrolltime>200</scrolltime> - <orientation>horizontal</orientation> - <preloaditems>4</preloaditems> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>253</posy> - <width>244</width> - <height>90</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label][CR]$INFO[ListItem.Label2]</label> - </control> - </control> - </control> - </itemlayout> - - <!-- FOCUSED LAYOUT ####################################### --> - <focusedlayout width="304"> - <control type="group"> - <posx>55</posx> - <posy>61</posy> - <control type="group"> - <animation effect="zoom" start="100" end="110" time="100" center="127,127" reversible="false">Focus</animation> - <animation effect="zoom" start="110" end="100" time="100" center="127,127" reversible="false">UnFocus</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>-40</posx> - <posy>-40</posy> - <width>334</width> - <height>334</height> - <texture border="42">script.plex/buttons/role-shadow.png</texture> - </control> - <control type="group"> - <posx>5</posx> - <posy>5</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>244</width> - <height>244</height> - <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> - <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> - </control> - <control type="textbox"> - <posx>0</posx> - <posy>253</posy> - <width>244</width> - <height>90</height> - <font>font10</font> - <align>center</align> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label][CR]$INFO[ListItem.Label2]</label> - </control> - </control> - <control type="image"> - <visible>Control.HasFocus(403)</visible> - <posx>0</posx> - <posy>0</posy> - <width>254</width> - <height>254</height> - <texture>script.plex/buttons/role-selected.png</texture> - </control> - </control> - </control> - </focusedlayout> - </control> - </control> - </control> - </control> - - <control type="group" id="200"> - <animation effect="slide" end="0,-300" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras)) + !ControlGroup(200).HasFocus(0)">Conditional</animation> - <defaultcontrol always="true">201</defaultcontrol> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <control type="image"> - <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> - <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window.Property(on.extras))</visible> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>135</height> - <texture>script.plex/white-square.png</texture> - <colordiffuse>C0000000</colordiffuse> - </control> - <control type="grouplist"> - <posx>60</posx> - <posy>47.5</posy> - <width>1000</width> - <height>40</height> - <align>left</align> - <itemgap>60</itemgap> - <orientation>horizontal</orientation> - <ondown>50</ondown> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="201"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>202</onright> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> - <label> </label> - </control> - </control> - <control type="label"> - <width max="500">auto</width> - <height>40</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[UPPERCASE]$ADDON[script.plexmod 32439][/UPPERCASE]</label> - </control> - <control type="group"> - <width>40</width> - <height>40</height> - <control type="button" id="202"> - <animation effect="zoom" start="100" end="177" time="100" center="20,20" reversible="false">Focus</animation> - <animation effect="zoom" start="177" end="100" time="100" center="20,20" reversible="false">UnFocus</animation> - <width>40</width> - <height>40</height> - <onright>204</onright> - <onleft>201</onleft> - <ondown>50</ondown> - <font>font12</font> - <focusedcolor>FF000000</focusedcolor> - <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> - <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> - <label> </label> - </control> - </control> - </control> - <control type="group"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>438</posx> - <posy>0</posy> - <control type="button" id="204"> - <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> - <posx>-10</posx> - <posy>38</posy> - <width>260</width> - <height>75</height> - <onleft>202</onleft> - <ondown>50</ondown> - <font>font12</font> - <textcolor>FFFFFFFF</textcolor> - <focusedcolor>FF000000</focusedcolor> - <align>right</align> - <aligny>center</aligny> - <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> - <texturenofocus>-</texturenofocus> - <textoffsetx>100</textoffsetx> - <textoffsety>0</textoffsety> - <label> </label> - </control> - <control type="image"> - <posx>0</posx> - <posy>48</posy> - <width>42</width> - <height>42</height> - <texture>$INFO[Player.Art(thumb)]</texture> - </control> - - <control type="group"> - <visible>!Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - <control type="group"> - <visible>Control.HasFocus(204)</visible> - <control type="label"> - <posx>53</posx> - <posy>48</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Artist</info> - </control> - <control type="label"> - <posx>53</posx> - <posy>72</posy> - <width>187</width> - <height>20</height> - <font>font10</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <info>MusicPlayer.Title</info> - </control> - </control> - - <control type="progress"> - <description>Progressbar</description> - <posx>0</posx> - <posy>102</posy> - <width>240</width> - <height>1</height> - <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> - <lefttexture>-</lefttexture> - <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> - <righttexture>-</righttexture> - <overlaytexture>-</overlaytexture> - <info>Player.Progress</info> - </control> - </control> - <control type="label"> - <right>213</right> - <posy>35</posy> - <width>200</width> - <height>65</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[System.Time]</label> - </control> - <control type="image"> - <posx>153r</posx> - <posy>54</posy> - <width>93</width> - <height>30</height> - <texture>script.plex/home/plex.png</texture> - </control> - </control> - - <control type="group"> - <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> - <control type="group" > - <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/home/background-fallback.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture background="true">$INFO[Window.Property(background)]</texture> - </control> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture colordiffuse="99606060">script.plex/white-square.png</texture> - </control> - </control> - </control> - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/script-plex-video_settings_dialog.xml b/script.plexmod/resources/skins/Main/1080i/script-plex-video_settings_dialog.xml deleted file mode 100644 index 39d399a927..0000000000 --- a/script.plexmod/resources/skins/Main/1080i/script-plex-video_settings_dialog.xml +++ /dev/null @@ -1,159 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<window> - <coordinates> - <system>1</system> - <posx>0</posx> - <posy>0</posy> - </coordinates> - <!-- <zorder>101</zorder> --> - <controls> - <control type="group"> - <visible>!String.IsEmpty(Window.Property(via.OSD))</visible> - <animation effect="fade" start="100" end="0">Hidden</animation> - <posx>0</posx> - <posy>0</posy> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1920</width> - <height>1080</height> - <texture>script.plex/player-fade.png</texture> - <colordiffuse>FF080808</colordiffuse> - </control> - </control> - <control type="group"> - <visible>!Window.IsVisible(sliderdialog) + !Window.IsVisible(osdvideosettings) + !Window.IsVisible(osdaudiosettings) + !Window.IsVisible(osdsubtitlesettings) + !Window.IsVisible(subtitlesearch) + !Window.IsActive(selectdialog) + !Window.IsVisible(osdcmssettings)</visible> - <posx>460</posx> - <posy>200</posy> - <control type="image"> - <posx>-40</posx> - <posy>-40</posy> - <width>1080</width> - <height>770</height> - <texture border="42">script.plex/drop-shadow.png</texture> - </control> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1000</width> - <height>80</height> - <texture border="10">script.plex/white-square-top-rounded.png</texture> - <colordiffuse>F21F1F1F</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>80</posy> - <width>1000</width> - <height>610</height> - <texture flipy="true" border="10">script.plex/white-square-top-rounded.png</texture> - <colordiffuse>F2606060</colordiffuse> - </control> - <control type="image"> - <posx>0</posx> - <posy>80</posy> - <width>400</width> - <height>610</height> - <texture flipy="true" border="10">script.plex/white-square-tl-rounded.png</texture> - <colordiffuse>30000000</colordiffuse> - </control> - <control type="label"> - <posx>0</posx> - <posy>0</posy> - <width>1000</width> - <height>80</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>[B][UPPERCASE]$INFO[Window.Property(heading)][/UPPERCASE][/B]</label> - </control> - <control type="list" id="100"> - <posx>0</posx> - <posy>80</posy> - <width>990</width> - <height>600</height> - <onup>noop</onup> - <ondown>noop</ondown> - <scrolltime>200</scrolltime> - <orientation>vertical</orientation> - <pagecontrol>101</pagecontrol> - <onright>101</onright> - <!-- ITEM LAYOUT ########################################## --> - <itemlayout height="100"> - <control type="label"> - <posx>20</posx> - <posy>0</posy> - <width>300</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>320</posx> - <posy>0</posy> - <width>650</width> - <height>100</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FFFFFFFF</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </itemlayout> - <focusedlayout height="100"> - <control type="image"> - <posx>0</posx> - <posy>0</posy> - <width>1000</width> - <height>100</height> - <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> - </control> - <control type="label"> - <posx>20</posx> - <posy>0</posy> - <width>300</width> - <height>100</height> - <font>font12</font> - <align>left</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label]</label> - </control> - <control type="label"> - <posx>320</posx> - <posy>0</posy> - <width>650</width> - <height>100</height> - <font>font12</font> - <align>right</align> - <aligny>center</aligny> - <textcolor>FF000000</textcolor> - <label>$INFO[ListItem.Label2]</label> - </control> - </focusedlayout> - </control> - </control> - <control type="scrollbar" id="101"> - <hitrect x="1108" y="33" w="90" h="734" /> - <left>1450</left> - <top>280</top> - <width>10</width> - <height>600</height> - <onleft>100</onleft> - <visible>true</visible> - <texturesliderbackground colordiffuse="30000000" border="5">script.plex/white-square.png</texturesliderbackground> - <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square.png</texturesliderbar> - <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square.png</texturesliderbarfocus> - <textureslidernib>-</textureslidernib> - <textureslidernibfocus>-</textureslidernibfocus> - <pulseonselect>false</pulseonselect> - <orientation>vertical</orientation> - <showonepage>false</showonepage> - <onleft>100</onleft> - </control> - - </controls> -</window> diff --git a/script.plexmod/resources/skins/Main/1080i/templates/base.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/base.xml.tpl new file mode 100644 index 0000000000..3545a0ac0f --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/base.xml.tpl @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<window>{# this is the basic window/dialog structure #} + {% block headers %}{% endblock %} + {% block coordinates %} + <coordinates> + <system>1</system> + <posx>0</posx> + <posy>0</posy> + </coordinates> + {% endblock coordinates %} + {% block backgroundcolor %}<backgroundcolor>$INFO[Window.Property(background_colour)]</backgroundcolor>{% endblock %} + <controls> + {% block controls %}{% endblock %} + <control type="label" id="666"><visible>false</visible></control><!-- sanity check dummy --> + </controls> +</window> diff --git a/script.plexmod/resources/skins/Main/1080i/templates/default.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/default.xml.tpl new file mode 100644 index 0000000000..46c2e11671 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/default.xml.tpl @@ -0,0 +1,221 @@ +{% extends "base.xml.tpl" %}{# this extends base and adds background and default header blocks #} +{% block controls %} + {% block background %} + {% include "includes/default_background.xml.tpl" %} + {% endblock %} + <!-- block content --> + {% block content %}{% endblock %} + + {% block header %} + <control type="group" id="200"> + {% block header_anim %}<animation effect="slide" end="0,{{ vscale(-300) }}" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras)) + !ControlGroup(200).HasFocus(0)">Conditional</animation>{% endblock %} + <defaultcontrol always="true">201</defaultcontrol> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + {% block header_bgfade %} + <control type="image"> + <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> + <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window.Property(on.extras))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + {% endblock %} + <control type="grouplist"> + <posx>60</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>1000</width> + <height>{{ vscale(40) }}</height> + <align>left</align> + <itemgap>60</itemgap> + <orientation>horizontal</orientation> + <ondown>50</ondown> + <control type="group"> + <width>40</width> + <height>{{ vscale(40) }}</height> + <control type="button" id="201"> + <animation effect="zoom" start="100" end="144" time="100" center="20,{{ vscale(20) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="144" end="100" time="100" center="20,{{ vscale(20) }}" reversible="false">UnFocus</animation> + <width>40</width> + <height>{{ vscale(40) }}</height> + <onright>202</onright> + <ondown>50</ondown> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> + <label> </label> + </control> + </control> + {% block topleft_add %}{% endblock %} + <control type="group"> + <width>40</width> + <height>{{ vscale(40) }}</height> + <control type="button" id="202"> + <animation effect="zoom" start="100" end="144" time="100" center="20,{{ vscale(20) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="144" end="100" time="100" center="20,{{ vscale(20) }}" reversible="false">UnFocus</animation> + <width>40</width> + <height>{{ vscale(40) }}</height> + <onright>204</onright> + <onleft>201</onleft> + <ondown>50</ondown> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> + <label> </label> + </control> + </control> + </control> + <control type="group"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>438</posx> + <posy>0</posy> + <control type="button" id="204"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>-10</posx> + <posy>{{ vscale(38) }}</posy> + <width>260</width> + <height>{{ vscale(75) }}</height> + <onleft>202</onleft> + <ondown>50</ondown> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>right</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>100</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(48) }}</posy> + <width>42</width> + <height>{{ vscale(42) }}</height> + <texture>$INFO[Player.Art(thumb)]</texture> + </control> + + <control type="group"> + <visible>!Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + + <control type="progress"> + <description>Progressbar</description> + <posx>0</posx> + <posy>{{ vscale(102) }}</posy> + <width>240</width> + <height>{{ vscale(1) }}</height> + <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> + </control> + <control type="label"> + <right>213</right> + <posy>{{ vscale(35) }}</posy> + <width>200</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[System.Time]</label> + </control> + <control type="image"> + <posx>153r</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>93</width> + <height>{{ vscale(43) }}</height> + <texture>script.plex/home/plex.png</texture> + </control> + </control> + + <control type="group"> + <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> + <control type="group" > + <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/home/background-fallback.png</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">$INFO[Window.Property(background)]</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture colordiffuse="99606060">script.plex/white-square.png</texture> + </control> + </control> + {% endblock header %} +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/includes/default_background.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/includes/default_background.xml.tpl new file mode 100644 index 0000000000..470b12980d --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/includes/default_background.xml.tpl @@ -0,0 +1,39 @@ +<control type="group"> + <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback.png</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(dynamic_backgrounds))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true" fallback="script.plex/home/background-fallback_black.png">$INFO[Window.Property(background_static)]</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(dynamic_backgrounds))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <fadetime>1000</fadetime> + <texture background="true">{{ background_source|default("$INFO[Window.Property(background)]") }}</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> +</control> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/includes/music_player_buttons.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/includes/music_player_buttons.xml.tpl new file mode 100644 index 0000000000..3575d87422 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/includes/music_player_buttons.xml.tpl @@ -0,0 +1,238 @@ + <control type="group" id="421"> + <width>125</width> + <height>{{ vscale(101) }}</height> + <control type="button" id="401"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <onup>100</onup> + <onright>402</onright> + <onleft>411</onleft> + <font>font12</font> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + <control type="group"> + <visible>!Control.HasFocus(401)</visible> + <control type="image"> + <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}repeat.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}repeat.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeatOne</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}repeat-one.png</texture> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(401)</visible> + <control type="image"> + <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeatOne</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat-one{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + </control> + </control> + + <control type="togglebutton" id="402"> + <visible>String.IsEmpty(Window.Property(pq.isremote))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle.png</texturenofocus> + <usealttexture>Playlist.IsRandom</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}shuffle.png</alttexturenofocus> + <onclick>PlayerControl(RandomOn)</onclick> + <altclick>PlayerControl(RandomOff)</altclick> + <label> </label> + </control> + + <control type="group" id="432"> + <visible>!String.IsEmpty(Window.Property(pq.isremote))</visible> + <width>125</width> + <height>{{ vscale(101) }}</height> + <control type="button" id="422"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <onup>100</onup> + <onright>404</onright> + <onleft>401</onleft> + <font>font12</font> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + <control type="group"> + <visible>String.IsEmpty(Window.Property(pq.shuffled))</visible> + <control type="image"> + <visible>!Control.HasFocus(422)</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle.png</texture> + </control> + <control type="image"> + <visible>Control.HasFocus(422)</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(pq.shuffled))</visible> + <control type="image"> + <visible>!Control.HasFocus(422)</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}shuffle.png</texture> + </control> + <control type="image"> + <visible>Control.HasFocus(422)</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + </control> + </control> + + <control type="button" id="404"> + <visible>MusicPlayer.HasPrevious | !String.IsEmpty(Window.Property(pq.hasprevious))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true"{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus flipx="true"{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="424"> + <enable>false</enable> + <visible>!MusicPlayer.HasPrevious + String.IsEmpty(Window.Property(pq.hasprevious))</visible> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true" colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturefocus> + <texturenofocus flipx="true" colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="togglebutton" id="406"> + <hitrect x="28" y="28" w="69" h="45" /> + {% if theme.buttons.zoomPlayButton %} + <animation effect="zoom" start="100" end="124" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="Control.HasFocus(406)">Conditional</animation> + <animation effect="zoom" start="124" end="100" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="!Control.HasFocus(406)">Conditional</animation> + {% endif %} + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}pause{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}pause.png</texturenofocus> + <usealttexture>Player.Paused | Player.Forwarding | Player.Rewinding</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}play{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}play.png</alttexturenofocus> + <!-- <enable>Player.PauseEnabled</enable> --> + <onclick>PlayerControl(Play)</onclick> + <label> </label> + </control> + <control type="button" id="407"> + <hitrect x="28" y="28" w="69" h="45" /> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}stop{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}stop.png</texturenofocus> + <onclick>PlayerControl(Stop)</onclick> + <label> </label> + </control> + <control type="button" id="409"> + <visible>MusicPlayer.HasNext | !String.IsEmpty(Window.Property(pq.hasnext))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="419"> + <enable>false</enable> + <visible>!MusicPlayer.HasNext + String.IsEmpty(Window.Property(pq.hasnext))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texturefocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturefocus> + <texturenofocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + + <control type="button" id="410"> + <hitrect x="28" y="28" w="69" h="45" /> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}pqueue{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}pqueue.png</texturenofocus> + <label> </label> + <onclick>Close</onclick> + </control> + <control type="button" id="411"> + <hitrect x="28" y="28" w="69" h="45" /> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}more{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}more.png</texturenofocus> + <label> </label> + </control> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/includes/scale_background.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/includes/scale_background.xml.tpl new file mode 100644 index 0000000000..cfb7eb6820 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/includes/scale_background.xml.tpl @@ -0,0 +1 @@ +{% if core.needs_scaling %}<aspectratio align="center" aligny="top">scale</aspectratio>{% endif %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/includes/themed_button.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/includes/themed_button.xml.tpl new file mode 100644 index 0000000000..f97d459905 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/includes/themed_button.xml.tpl @@ -0,0 +1,28 @@ +<control type="button" id="{{ id }}"> + {% if visible %}<visible{% if allowhiddenfocus %} allowhiddenfocus="true"{% endif %}>{{ visible }}</visible>{% endif %} + <hitrect x="{{ hitrect.x|default(40) }}" y="{{ hitrect.y|default(40)|vscale }}" w="{{ hitrect.w|default(96) }}" h="{{ hitrect.h|default(60)|vscale }}" /> + {% if enable %}<enable>{{ enable }}</enable>{% endif %} + {% if elements %}{% spaceless %} {# simple key/value elements #} + {% for var, value in elements %}<{{ var }}>{{ value }}</{{ var }}>{% endfor %}{% endspaceless %} + {% endif %} + {% if name == "play" and theme.buttons.zoomPlayButton %} + <animation effect="zoom" start="100" end="124" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="Control.HasFocus({{ id }})">Conditional</animation> + <animation effect="zoom" start="124" end="100" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="!Control.HasFocus({{ id }})">Conditional</animation> + {% endif %} + {% for direction in ("onleft", "onright", "onup", "ondown") %}{% spaceless %} + {% if resolve("direction") %}<{{ direction }}>{{ resolve("direction") }}</{{ direction }}>{% endif %} + {% endspaceless %}{% endfor %} + <posx>{{ attr.posx|default(0) }}</posx> + <posy>{{ attr.posy|default(0)|vscale }}</posy> + <width>{{ attr.width }}</width> + <height>{{ attr.height|vscale }}</height> + <font>{{ font|default("font12") }}</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}{{ name }}{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}{{ name }}.png</texturenofocus> + <label> </label> + {% if xml %}{% spaceless %} {# complex elements #} + {% for element in xml %} + <{{ element.type}}{% if element.attrs %} {% for name, value in attrs %}{{ name }}="{{ value }}"{% if not loop.is_last %} {% endif %}{% endfor %}{% endif %}>{{ element.value }}</{{ element.type }}> + {% endfor %} + {% endspaceless %}{% endif %} +</control> \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/includes/watched_indicator.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/includes/watched_indicator.xml.tpl new file mode 100644 index 0000000000..4d2d0d24ba --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/includes/watched_indicator.xml.tpl @@ -0,0 +1,81 @@ +{% with xoff = xoff|default(158) & yoff = yoff|default(0) & uw_size = uw_size|default(32) & wbg_w = wbg_w|default(32) & wbg_h = wbg_h|default(32) & scale_fac = indicators.scale|get(scale, "small", 1.0) %} + {% if indicators.use_unwatched %} + <control type="image"> + <visible>!String.IsEmpty({{ itemref|default("ListItem") }}.Property(unwatched)) + String.IsEmpty({{ itemref|default("ListItem") }}.Property(watched))</visible> + <posx>{{ xoff - uw_size }}</posx> + <posy>{{ uw_posy|default(0)|vscale }}</posy> + <width>{{ uw_size }}</width> + <height>{{ uw_size|vscale }}</height> + <texture fallback="script.plex/indicators/{{ indicators.assets.unwatched }}">special://profile/addon_data/script.plexmod/media/{{ indicators.assets.unwatched }}</texture> + </control> + {% else %} + <control type="group"> + <visible>!String.IsEmpty({{ itemref|default("ListItem") }}.Property(watched)) + String.IsEmpty({{ itemref|default("ListItem") }}.Property(unwatched.count))</visible> + {% if indicators.use_scaling and scale_fac != 1.0 %}<animation effect="zoom" start="{{ scale_fac|mul(100)|int }}" end="{{ scale_fac|mul(100)|int }}" time="0" reversible="false" center="{{ xoff }}" condition="true">Conditional</animation>{% endif %} + <posx>{{ xoff - wbg_w }}</posx> + <posy>{{ yoff|vscale }}</posy> + {% if not indicators.hide_aw_bg and not force_nowbg %} + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>{{ wbg_w }}</width> + <height>{{ wbg_h|vscale }}</height> + <texture>{{ wbg|default("script.plex/white-square-bl-rounded_w.png") }}</texture> + <colordiffuse>{{ indicators.watched_bg|default("CC000000") }}</colordiffuse> + </control> + {% endif %} + <control type="image"> + <posx>{{ wbg_w / 2 - 8 }}</posx> + <posy>{{ (wbg_h / 2 - 8)|vscale }}</posy> + <width>16</width> + <height>{{ vscale(16) }}</height> + <texture fallback="script.plex/indicators/{{ indicators.assets.watched }}">special://profile/addon_data/script.plexmod/media/{{ indicators.assets.watched }}</texture> + </control> + </control> + {% endif %} + {% if with_count %} + <control type="group"> + <visible>!String.IsEmpty({{ itemref|default("ListItem") }}.Property(unwatched.count))</visible> + {% if indicators.use_scaling and scale_fac != 1.0 %}<animation effect="zoom" start="{{ scale_fac|mul(100)|int }}" end="{{ scale_fac|mul(100)|int }}" time="0" reversible="false" center="{{ xoff }}" condition="true">Conditional</animation>{% endif %} + {% if indicators.style == "classic" %} + <control type="image"> + <posx>{{ xoff - wbg_w - 1 }}</posx> + <posy>{{ yoff|vscale }}</posy> + <width>{{ wbg_w + 1 }}</width> + <height>{{ (wbg_h + 1)|vscale }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="image"> + <posx>{{ xoff - wbg_w }}</posx> + <posy>{{ yoff|vscale }}</posy> + <width>{{ wbg_w }}</width> + <height>{{ wbg_h|vscale }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>{{ indicators.unwatched_count_bg|default("FFCC7B19") }}</colordiffuse> + </control> + {% else %} + <control type="image"> + <posx>{{ xoff - wbg_w }}</posx> + <posy>{{ yoff|vscale }}</posy> + <width>{{ wbg_w }}</width> + <height>{{ wbg_h|vscale }}</height> + <texture>{{ wbg|default("script.plex/white-square-bl-rounded_w.png") }}</texture> + <colordiffuse>{{ indicators.unwatched_count_bg|default("FFCC7B19") }}</colordiffuse> + </control> + {% endif %} + <control type="label">{# this label uses a nasty hack to get a smaller fitting font size: use a larger font, increase the label size, then zoom it down #} + <animation effect="zoom" start="40" end="40" time="0" reversible="false" center="auto" condition="true">Conditional</animation> + <posx>{{ xoff - wbg_w - 16 }}</posx> + <posy>{{ (yoff - 8)|vscale }}</posy> + <width>{{ wbg_w + 32 }}</width> + <height>{{ (wbg_h + 16)|vscale }}</height> + <font>font32_title</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>{{ indicators.textcolor|default("FF000000") }}</textcolor> + <label>$INFO[{{ itemref|default("ListItem") }}.Property(unwatched.count)]</label> + </control> + </control> + {% endif %} +{% endwith %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/library.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/library.xml.tpl new file mode 100644 index 0000000000..f09ed452e1 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/library.xml.tpl @@ -0,0 +1,373 @@ +{% extends "default.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} + +{% block header %} +<control type="group" id="200"> + {% block header_animation %}<animation effect="slide" end="0,{{ vscale(-135) }}" time="200" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5) + !ControlGroup(200).HasFocus(0)">Conditional</animation>{% endblock %} + <defaultcontrol always="true">201</defaultcontrol> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <visible>!String.IsEmpty(Window.Property(initialized))</visible> + {% block header_bg %} + <control type="image"> + <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> + <visible>ControlGroup(200).HasFocus(0) + Integer.IsGreater(Container(101).ListItem.Property(index),5)</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + {% endblock %} + <control type="grouplist"> + <posx>60</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>1000</width> + <height>{{ vscale(40) }}</height> + <align>left</align> + <itemgap>60</itemgap> + <orientation>horizontal</orientation> + <ondown>50</ondown> + <control type="group"> + <width>40</width> + <height>{{ vscale(40) }}</height> + <control type="button" id="201"> + <animation effect="zoom" start="100" end="144" time="100" center="20,{{ vscale(20) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="144" end="100" time="100" center="20,{{ vscale(20) }}" reversible="false">UnFocus</animation> + <width>40</width> + <height>{{ vscale(40) }}</height> + <onright>202</onright> + <ondown>50</ondown> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> + <label> </label> + </control> + </control> + <control type="label"> + <width max="500">auto</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(screen.title)][/UPPERCASE][COLOR=gray]$INFO[Window.Property(items.count), (,)][/COLOR]</label> + </control> + <control type="group"> + <width>40</width> + <height>{{ vscale(40) }}</height> + <control type="button" id="202"> + <animation effect="zoom" start="100" end="144" time="100" center="20,{{ vscale(20) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="144" end="100" time="100" center="20,{{ vscale(20) }}" reversible="false">UnFocus</animation> + <width>40</width> + <height>{{ vscale(40) }}</height> + <onright>204</onright> + <onleft>201</onleft> + <ondown>50</ondown> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> + <label> </label> + </control> + </control> + </control> + <control type="group"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>438</posx> + <posy>0</posy> + <control type="button" id="204"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>-10</posx> + <posy>{{ vscale(38) }}</posy> + <width>260</width> + <height>{{ vscale(75) }}</height> + <onleft>202</onleft> + <onright>211</onright> + <ondown>50</ondown> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>right</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>100</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(48) }}</posy> + <width>42</width> + <height>{{ vscale(42) }}</height> + <texture>$INFO[Player.Art(thumb)]</texture> + </control> + + <control type="group"> + <visible>!Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + + <control type="progress"> + <description>Progressbar</description> + <posx>0</posx> + <posy>{{ vscale(102) }}</posy> + <width>240</width> + <height>{{ vscale(1) }}</height> + <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> + </control> + {% block filteropts_grouplist %} + <control type="grouplist"{% block filteropts_grouplist_attrs %}{% endblock %}> + <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> + <right>340</right> + <posy>{{ vscale(35) }}</posy> + <width>1000</width> + <height>{{ vscale(65) }}</height> + <align>right</align> + <itemgap>30</itemgap> + <orientation>horizontal</orientation> + <onleft>204</onleft> + <onright>210</onright> + <ondown>50</ondown> + <control type="button" id="311"> + <enable>false</enable> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> + </control> + <control type="button" id="211"> + <width max="500">auto</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> + </control> + <control type="button" id="310"> + <visible>!String.IsEqual(Window.Property(media),artist)</visible> + <enable>false</enable> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturenofocus>-</texturenofocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> + </control> + <control type="button" id="312"> + <visible>String.IsEqual(Window.Property(media),artist)</visible> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> + </control> + <control type="button" id="210"> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> + </control> + </control> + {% endblock filteropts_grouplist %} + <control type="label"> + <right>213</right> + <posy>{{ vscale(35) }}</posy> + <width>200</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[System.Time]</label> + </control> + <control type="image"> + <posx>153r</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>93</width> + <height>{{ vscale(43) }}</height> + <texture>script.plex/home/plex.png</texture> + </control> +</control> + +{% block no_content %} +<control type="group"> + <visible>!String.IsEmpty(Window.Property(no.content))</visible> + <posx>0</posx> + <posy>{{ vscale(465) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(35) }}</height> + <font>font13</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$ADDON[script.plexmod 32452][/B]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>{{ vscale(60) }}</posy> + <width>1800</width> + <height>{{ vscale(35) }}</height> + <font>font13</font> + <align>center</align> + <textcolor>FFCCCCCC</textcolor> + <label>$ADDON[script.plexmod 32453]</label> + </control> +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window.Property(no.content.filtered))</visible> + <posx>0</posx> + <posy>{{ vscale(465) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(35) }}</height> + <font>font13</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$ADDON[script.plexmod 32454][/B]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>{{ vscale(60) }}</posy> + <width>1800</width> + <height>{{ vscale(35) }}</height> + <font>font13</font> + <align>center</align> + <textcolor>FFCCCCCC</textcolor> + <label>$ADDON[script.plexmod 32455]</label> + </control> +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> + <control type="group" > + <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/home/background-fallback.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">$INFO[Window.Property(background)]</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture colordiffuse="99606060">script.plex/white-square.png</texture> + </control> +</control> +{% endblock %} +{% endblock header %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/library_posters.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/library_posters.xml.tpl new file mode 100644 index 0000000000..9aa14dda78 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/library_posters.xml.tpl @@ -0,0 +1,96 @@ +{% extends "library.xml.tpl" %} +{% block filteropts_grouplist %} +<control type="grouplist"> + <visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> + <right>340</right> + <posy>{{ vscale(35) }}</posy> + <width>870</width> + <height>{{ vscale(65) }}</height> + <align>right</align> + <itemgap>30</itemgap> + <orientation>horizontal</orientation> + <onleft>204</onleft> + <onright>210</onright> + <ondown>50</ondown> + <control type="button" id="311"> + <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> + <enable>false</enable> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font10</font> + <textcolor>A0FFFFFF</textcolor> + <focusedcolor>A0FFFFFF</focusedcolor> + <disabledcolor>A0FFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> + </control> + <control type="button" id="211"> + <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> + <width max="400">auto</width> + <height>{{ vscale(65) }}</height> + <font>font10</font> + <textcolor>A0FFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> + </control> + <control type="button" id="310"> + <visible>String.IsEqual(Window.Property(subDir),1) | ![String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)]</visible> + <enable>false</enable> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturenofocus>-</texturenofocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> + </control> + <control type="button" id="312"> + <visible>!String.IsEqual(Window.Property(subDir),1) + [String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)]</visible> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> + </control> + <control type="button" id="210"> + <visible>!String.IsEqual(Window.Property(media.itemType),folder)</visible> + <width max="300">auto</width> + <height>{{ vscale(65) }}</height> + <font>font10</font> + <textcolor>A0FFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> + </control> +</control> +{% endblock filteropts_grouplist %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-album.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-album.xml.tpl new file mode 100644 index 0000000000..83f98c7f25 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-album.xml.tpl @@ -0,0 +1,346 @@ +{% extends "default.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block content %} + <control type="group" id="50"> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>101</defaultcontrol> + + <control type="group"> + <posx>60</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>5</posy> + <width>420</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(artist.title)]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(60) }}</posy> + <width>420</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(album.title)]</label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(142) }}</posy> + <width>630</width> + <height>{{ vscale(630) }}</height> + <texture>$INFO[Window.Property(album.thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + </control> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <defaultcontrol>301</defaultcontrol> + <posx>50</posx> + <posy>{{ vscale(784) }}</posy> + <width>650</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <onright>101</onright> + <itemgap>-50</itemgap> + <orientation>horizontal</orientation> + <align>center</align> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = {"width": 174, "height": 139} & template = "includes/themed_button.xml.tpl" & hitrect = {"w": 94, "h": 59} %} + {% include template with name="play" & id=301 %} + {% include template with name="shuffle" & id=302 %} + {% include template with name="more" & id=303 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>750</posx> + <posy>0</posy> + <width>1170</width> + <height>{{ vscale(945) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1380</width> + <height>{{ vscale(945) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20000000</colordiffuse> + </control> + <control type="list" id="101"> + <hitrect x="40" y="0" w="1090" h="945" /> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>{{ vscale(945) }}</height> + <onup>200</onup> + <onright>152</onright> + <onleft>300</onleft> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>4</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(76) }}"> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(is.header))</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>2</posx> + <posy>{{ vscale(21) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="group"> + <posx>90</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>723</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + </control> + <control type="label"> + <posx>730</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(73) }}</posy> + <width>930</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(is.header))</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <width>400</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B][UPPERCASE]$INFO[ListItem.Label][/UPPERCASE][/B]</label> + </control> + + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="{{ vscale(76) }}"> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(is.header))</visible> + <control type="group"> + <visible>!Control.HasFocus(101)</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>2</posx> + <posy>{{ vscale(21) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="group"> + <posx>90</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>723</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + </control> + <control type="label"> + <posx>730</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(73) }}</posy> + <width>930</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <posx>63</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>1130</width> + <height>{{ vscale(156) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1044</width> + <height>{{ vscale(76) }}</height> + <texture border="12">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="label"> + <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>48</posx> + <posy>0</posy> + <width>50</width> + <height>{{ vscale(76) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>36</posx> + <posy>{{ vscale(21) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="group"> + <posx>140</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>738</width> + <height>{{ vscale(76) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + </control> + <control type="label"> + <posx>796</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(76) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + </control> + </control> + + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(is.header))</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <width>400</width> + <height>{{ vscale(76) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B][UPPERCASE]$INFO[ListItem.Label][/UPPERCASE][/B]</label> + </control> + </focusedlayout> + </control> + + <control type="scrollbar" id="152"> + <hitrect x="1088" y="33" w="110" h="874" /> + <left>1128</left> + <top>33</top> + <width>10</width> + <height>{{ vscale(874) }}</height> + <onleft>101</onleft> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + </control> + </control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-artist.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-artist.xml.tpl new file mode 100644 index 0000000000..8dc370d54b --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-artist.xml.tpl @@ -0,0 +1,472 @@ +{% extends "default.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block content %} +<control type="group" id="50"> + <animation effect="slide" end="0,{{ vscale(-300) }}" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>400</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <defaultcontrol>301</defaultcontrol> + <posx>594</posx> + <posy>{{ vscale(418) }}</posy> + <width>600</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>400</ondown> + <itemgap>-50</itemgap> + <orientation>horizontal</orientation> + <align>center</align> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = {"width": 174, "height": 139} & template = "includes/themed_button.xml.tpl" & hitrect = {"w": 94, "h": 59} %} + {% include template with name="info" & id=301 %} + {% include template with name="play" & id=302 %} + {% include template with name="shuffle" & id=303 %} + {% include template with name="more" & id=304 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group"> + <posx>60</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(200) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>519</width> + <height>{{ vscale(519) }}</height> + <texture background="true" fallback="script.plex/thumb_fallbacks/music.png">$INFO[Window.Property(thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <posx>579</posx> + <posy>5</posy> + <width>1190</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(artist.title)]</label> + </control> + <control type="label"> + <posx>579</posx> + <posy>{{ vscale(55) }}</posy> + <width>1190</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFDDDDDD</textcolor> + <label>$INFO[Window.Property(artist.genre)]</label> + </control> + <control type="textbox"> + <posx>579</posx> + <posy>{{ vscale(158) }}</posy> + <width>1221</width> + <height>{{ vscale(250) }}</height> + <font>font13</font> + <align>left</align> + <textcolor>FFDDDDDD</textcolor> + <label>$INFO[Window.Property(summary)]</label> + <pagecontrol>152</pagecontrol> + </control> + </control> + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>400</defaultcontrol> + <posx>0</posx> + <posy>{{ vscale(585) }}</posy> + <width>1920</width> + <height>{{ vscale(360) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(360) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20000000</colordiffuse> + </control> + <control type="list" id="400"> + <posx>0</posx> + <posy>{{ vscale(-20) }}</posy> + <width>1920</width> + <height>{{ vscale(700) }}</height> + <onup>300</onup> + <ondown>401</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>2</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="260"> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(60) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(220) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(year)]</label> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="260"> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(60) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="107.5,{{ vscale(107.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="107.5,{{ vscale(107.5) }}" reversible="false">UnFocus</animation> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>295</width> + <height>{{ vscale(295) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(220) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(year)]</label> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>-5</posx> + <posy>{{ vscale(-5) }}</posy> + <width>225</width> + <height>{{ vscale(225) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <!-- similar artists --> + <control type="group" id="500"> + <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>401</defaultcontrol> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <posx>0</posx> + <posy>{{ vscale(945) }}</posy> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(divider.401))</visible> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> + </control> + <control type="list" id="401"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <onup>400</onup> + <ondown>false</ondown> + <onleft>false</onleft> + <onright>false</onright> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="260"> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(60) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(220) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(year)]</label> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>77</posx> + <posy>{{ vscale(57.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>77</posx> + <posy>{{ vscale(57.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>43.5</posx> + <posy>{{ vscale(43.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="260"> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(60) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="107.5,{{ vscale(107.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="107.5,{{ vscale(107.5) }}" reversible="false">UnFocus</animation> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>295</width> + <height>{{ vscale(295) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(220) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>215</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(year)]</label> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>-5</posx> + <posy>{{ vscale(-5) }}</posy> + <width>225</width> + <height>{{ vscale(225) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>215</width> + <height>{{ vscale(215) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>77</posx> + <posy>{{ vscale(57.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>77</posx> + <posy>{{ vscale(57.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>43.5</posx> + <posy>{{ vscale(43.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-background.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-background.xml.tpl new file mode 100644 index 0000000000..a291e2600d --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-background.xml.tpl @@ -0,0 +1,59 @@ +{% extends "base.xml.tpl" %} +{% block headers %}{% endblock %} +{% block backgroundcolor %}<backgroundcolor>0xff111111</backgroundcolor>{% endblock %} + +{% block controls %} +<control type="image"> + <visible>!String.IsEmpty(Window(10000).Property(script.plex.background.splash))</visible> + <posx>710</posx> + <posy>{{ vperc(vscale(232.5)) }}</posy> + <width>500</width> + <height>{{ vscale(232.5) }}</height> + <texture>script.plex/splash.png</texture> +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window(10000).Property(script.plex.background.busy))</visible> + <control type="image"> + <posx>812</posx> + <posy>{{ vperc(vscale(139)) }}</posy> + <width>300</width> + <height>{{ vscale(139) }}</height> + <texture>script.plex/user_select/plex.png</texture> + </control> + <control type="image"> + <posx>840</posx> + <posy>{{ vperc(vscale(150)) }}</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/busy-back.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + <control type="image"> + <posx>915</posx> + <posy>{{ vperc(vscale(38)) }}</posy> + <width>90</width> + <height>{{ vscale(38) }}</height> + <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> + </control> +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window(10000).Property(script.plex.background.shutdown))</visible> + <control type="image"> + <posx>840</posx> + <posy>{{ vperc(vscale(150)) }}</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/busy-back.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + <control type="image"> + <posx>915</posx> + <posy>{{ vperc(vscale(38)) }}</posy> + <width>90</width> + <height>{{ vscale(38) }}</height> + <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-blank.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-blank.xml.tpl new file mode 100644 index 0000000000..9c833cb685 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-blank.xml.tpl @@ -0,0 +1 @@ +{% extends "base.xml.tpl" %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy.xml.tpl new file mode 100644 index 0000000000..cebcedd780 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy.xml.tpl @@ -0,0 +1,22 @@ +{% extends "base.xml.tpl" %} +{% block backgroundcolor %}{% endblock %} +{% block controls %} +<control type="group"> + <animation effect="fade" start="0" end="100">WindowOpen</animation> + <control type="image"> + <posx>840</posx> + <posy>{{ vperc(vscale(150)) }}</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/busy-back.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + <control type="image"> + <posx>915</posx> + <posy>{{ vperc(vscale(38)) }}</posy> + <width>90</width> + <height>{{ vscale(38) }}</height> + <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy_msg.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy_msg.xml.tpl new file mode 100644 index 0000000000..8dc7b77f58 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-busy_msg.xml.tpl @@ -0,0 +1,29 @@ +{% extends "base.xml.tpl" %} +{% block backgroundcolor %}{% endblock %} +{% block controls %} +<control type="group"> + <posx>0</posx> + <posy>0</posy> + <animation effect="fade" start="0" end="100">WindowOpen</animation> + <control type="image"> + <posx>840</posx> + <posy>{{ vperc(vscale(150)) }}</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/busy-back.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + <control type="label"> + <posx>840</posx> + <posy>{{ vperc(vscale(150)) }}</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(message)]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown.xml.tpl new file mode 100644 index 0000000000..3342519d96 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown.xml.tpl @@ -0,0 +1,206 @@ +{% extends "base.xml.tpl" %} +{% block backgroundcolor %}{% endblock %} +{% block headers %} +<onload>SetProperty(dropdown,1)</onload> +<defaultcontrol>100</defaultcontrol> +<zorder>100</zorder> +{% endblock %} +{% block controls %} +<control type="button" id="700"> + <!-- dummy for clicks off list --> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> +</control> +<control type="group" id="100"> + <defaultcontrol>250</defaultcontrol> + <visible>!String.IsEmpty(Window.Property(show))</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image" id="110"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>380</width> + <height>{{ vscale(146) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="list" id="250"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(924) }}</height> + <onup condition="String.IsEqual(Window.Property(close.direction),top)">Close</onup> + <onup condition="!String.IsEqual(Window.Property(close.direction),top)">noop</onup> + <onleft condition="String.IsEqual(Window.Property(close.direction),left)">Close</onleft> + <onright condition="String.IsEqual(Window.Property(close.direction),right)">Close</onright> + <ondown condition="String.IsEqual(Window.Property(close.direction),down)">Close</ondown> + <ondown condition="!String.IsEqual(Window.Property(close.direction),down)">noop</ondown> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(66) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF323232">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture flipy="true" colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF323232" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(with.indicator))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> + <control type="label"> + <posx>20</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <posx>254</posx> + <posy>{{ vscale(20) }}</posy> + <width>26</width> + <height>{{ vscale(26) }}</height> + <texture colordiffuse="FFFFFFFF">$INFO[ListItem.Thumb]</texture> + <aspectratio>keep</aspectratio> + </control> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(separator))</visible> + <posx>0</posx> + <posy>{{ vscale(64) }}</posy> + <width>300</width> + <height>{{ vscale(2) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(66) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(with.indicator))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> + <control type="label"> + <posx>20</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <posx>254</posx> + <posy>{{ vscale(20) }}</posy> + <width>26</width> + <height>{{ vscale(26) }}</height> + <texture colordiffuse="FF000000">$INFO[ListItem.Thumb]</texture> + <aspectratio>keep</aspectratio> + </control> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(separator))</visible> + <posx>0</posx> + <posy>{{ vscale(64) }}</posy> + <width>300</width> + <height>{{ vscale(2) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + </focusedlayout> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown_header.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown_header.xml.tpl new file mode 100644 index 0000000000..6f3cb0796c --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-dropdown_header.xml.tpl @@ -0,0 +1,256 @@ +{% extends "base.xml.tpl" %} +{% block backgroundcolor %}{% endblock %} +{% block headers %} +<onload>SetProperty(dropdown,1)</onload> +<defaultcontrol>100</defaultcontrol> +{% endblock %} +{% block controls %} +<control type="button" id="700"> + <!-- dummy for clicks off list --> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> +</control> +<control type="group" id="100"> + <defaultcontrol>250</defaultcontrol> + <visible>!String.IsEmpty(Window.Property(show))</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image" id="110"> + <posx>-60</posx> + <posy>{{ vperc(vscale(-106)) }}</posy> + <width>720</width> + <height>{{ vscale(146) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(header))</visible> + <posx>-20</posx> + <posy>{{ vscale(-66) }}</posy> + <control type="image" id="111"> + <posx>0</posx> + <posy>0</posy> + <width>640</width> + <height>{{ vscale(132) }}</height> + <texture colordiffuse="FF000000" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="label"> + <posx>20</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Window.Property(header)][/B]</label> + </control> + </control> + <control type="list" id="250"> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(528) }}</height> + <onup condition="String.IsEqual(Window.Property(close.direction),top)">Close</onup> + <onup condition="!String.IsEqual(Window.Property(close.direction),top)">noop</onup> + <onleft condition="String.IsEqual(Window.Property(close.direction),left)">Close</onleft> + <onright condition="String.IsEqual(Window.Property(close.direction),right)">Close</onright> + <ondown condition="String.IsEqual(Window.Property(close.direction),down)">Close</ondown> + <ondown condition="!String.IsEqual(Window.Property(close.direction),down)">noop</ondown> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(66) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF323232">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture flipy="true" colordiffuse="FF323232" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF323232" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),center)</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),left)</visible> + <posx>20</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>520</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <posx>20</posx> + <posy>{{ vscale(20) }}</posy> + <width>26</width> + <height>{{ vscale(26) }}</height> + <texture colordiffuse="FFFFFFFF">$INFO[ListItem.Thumb]</texture> + <aspectratio>keep</aspectratio> + </control> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(separator))</visible> + <posx>0</posx> + <posy>{{ vscale(64) }}</posy> + <width>600</width> + <height>{{ vscale(2) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(66) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),center)</visible> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(with.indicator)) + String.IsEqual(ListItem.Property(align),left)</visible> + <posx>20</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(with.indicator))</visible> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>520</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <scroll>true</scroll> + <scrollspeed>60</scrollspeed> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <posx>20</posx> + <posy>{{ vscale(20) }}</posy> + <width>26</width> + <height>{{ vscale(26) }}</height> + <texture colordiffuse="FF000000">$INFO[ListItem.Thumb]</texture> + <aspectratio>keep</aspectratio> + </control> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(separator))</visible> + <posx>0</posx> + <posy>{{ vscale(64) }}</posy> + <width>600</width> + <height>{{ vscale(2) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + </focusedlayout> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-episodes.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-episodes.xml.tpl new file mode 100644 index 0000000000..226cc7792a --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-episodes.xml.tpl @@ -0,0 +1,1437 @@ +{% extends "default.xml.tpl" %} +{% block content %} +<control type="group" id="50"> + <animation effect="slide" end="0,{{ vscale(-125) }}" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),3) + Control.IsVisible(503)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <posx>0</posx> + <posy>{{ vscale(155) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + {% if theme.episodes.use_button_bg %} + <control type="image"> + <posx>60</posx> + <posy>{{ vscale(369) }}</posy> + <width>657</width> + <height>{{ vscale(104) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>{{ theme.episodes.button_bg_color|default(66000000) }}</colordiffuse> + </control> + {% endif %} + <control type="grouplist" id="300"> + <visible allowhiddenfocus="!String.IsEmpty(Container(400).ListItem.Property(media.multiple))">String.IsEmpty(Container(400).ListItem.Property(media.multiple)) + !String.IsEmpty(Window.Property(initialized))</visible> + <defaultcontrol always="true">301</defaultcontrol> + <posx>30</posx> + <posy>{{ theme.episodes.buttongroup.posy|vscale }}</posy> + <width>717</width> + <height>{{ vscale(200) }}</height> + <onup>200</onup> + <ondown>400</ondown> + <align>center</align> + <itemgap>{{ theme.episodes.buttongroup.itemgap }}</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = theme.episodes.buttons & template = "includes/themed_button.xml.tpl" %} + {% include template with name="info" & id=304 %} + {% include template with name="play" & id=301 & onleft=304 & onright=305 & + enable="!String.IsEmpty(Window.Property(current_item.loaded))" & visible="!String.IsEmpty(Window.Property(current_item.loaded))" & + allowhiddenfocus=True + %} + {% include template with name="play" & id=306 & onleft=304 & onright=305 & + visible="String.IsEmpty(Window.Property(current_item.loaded))" + %} + {% include template with name="settings" & id=305 %} + {% include template with name="more" & id=303 %} + {% include template with name="shuffle" & id=302 %} + {% endwith %} + </control> + <control type="grouplist" id="1300"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(media.multiple)) + !String.IsEmpty(Window.Property(initialized))</visible> + <defaultcontrol always="true">1301</defaultcontrol> + <posx>30</posx> + <posy>{{ theme.episodes.buttongroup_1300.posy|vscale }}</posy> + <width>717</width> + <height>{{ vscale(200) }}</height> + <onup>200</onup> + <ondown>400</ondown> + <align>center</align> + <itemgap>{{ theme.episodes.buttongroup_1300.itemgap }}</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = theme.episodes.buttons_1300 & template = "includes/themed_button.xml.tpl" %} + {% include template with name="info" & id=1304 %} + {% include template with name="play" & id=1301 & onleft=1304 & onright=1305 & + enable="!String.IsEmpty(Window.Property(current_item.loaded))" & visible="!String.IsEmpty(Window.Property(current_item.loaded))" & + allowhiddenfocus=True + %} + {% include template with name="play" & id=1306 & onleft=1304 & onright=1307 & + visible="String.IsEmpty(Window.Property(current_item.loaded))" + %} + {% include template with name="media" & id=1307 %} + {% include template with name="settings" & id=1305 %} + {% include template with name="more" & id=1303 %} + {% include template with name="shuffle" & id=1302 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(600) }}</height> + <control type="group"> + <control type="image"> + <visible>false</visible> + <posx>60</posx> + <posy>0</posy> + <width>656</width> + <height>{{ vscale(369) }}</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>656</width> + <height>{{ vscale(369) }}</height> + <texture background="true" fallback="script.plex/thumb_fallbacks/show.png">$INFO[Container(400).ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with itemref="Container(400).ListItem" & xoff=656+60 & uw_size=35 & scale="large" %} + </control> + + <control type="grouplist"> + <posx>776</posx> + <posy>0</posy> + <width>880</width> + <height>{{ vscale(60) }}</height> + <align>left</align> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="label"> + <width max="880">auto</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>top</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>5</scrollspeed> + <label>$INFO[Container(400).ListItem.Property(title)]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(remainingTime))</visible> + <posx>10</posx> + <posy>6</posy> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFE5A00D</focusedcolor> + <textcolor>FFE5A00D</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturenofocus> + <label>$INFO[Container(400).ListItem.Property(remainingTime)]</label> + </control> + </control> + <control type="image"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(rating.stars))</visible> + <posx>1726</posx> + <posy>6</posy> + <width>134</width> + <height>{{ vscale(22) }}</height> + <texture>script.plex/stars/$INFO[Container(400).ListItem.Property(rating.stars)].png</texture> + </control> + <control type="label"> + <posx>776</posx> + <posy>{{ vscale(50) }}</posy> + <width>714</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>top</aligny> + <scroll>true</scroll> + <scrollspeed>5</scrollspeed> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(show.title)]</label> + </control> + + <control type="grouplist"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(rating)) | !String.IsEmpty(Container(400).ListItem.Property(rating2))</visible> + <posx>1560</posx> + <posy>{{ vscale(50) }}</posy> + <width>300</width> + <height>{{ vscale(32) }}</height> + <align>right</align> + <itemgap>15</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="image"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(rating))</visible> + <posy>2</posy> + <width>63</width> + <height>{{ vscale(30) }}</height> + <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Container(400).ListItem.Property(rating.image)]</texture> + <aspectratio align="right">keep</aspectratio> + </control> + <control type="label"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(rating))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(rating)]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(rating2))</visible> + <posy>2</posy> + <width>40</width> + <height>{{ vscale(30) }}</height> + <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Container(400).ListItem.Property(rating2.image)]</texture> + <aspectratio align="right">keep</aspectratio> + </control> + <control type="label"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(rating2))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(rating2)]</label> + </control> + </control> + + <control type="grouplist"> + <posx>776</posx> + <posy>{{ vscale(100) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <align>left</align> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="label"> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(season)]$INFO[Container(400).ListItem.Property(episode), • , / ]$INFO[Container(400).ListItem.Property(date)]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(unavailable))</visible> + <posx>10</posx> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="FFAC3223" border="12">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus colordiffuse="FFAC3223" border="12">script.plex/white-square-rounded.png</texturenofocus> + <label>$ADDON[script.plexmod 32312]</label> + </control> + </control> + <control type="grouplist"> + <posx>776</posx> + <posy>{{ vscale(148) }}</posy> + <width>1360</width> + <height>{{ vscale(34) }}</height> + <align>left</align> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="label"> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(duration)]$INFO[Container(400).ListItem.Property(genre), • ]$INFO[Container(400).ListItem.Property(year), • ]$INFO[Container(400).ListItem.Property(content.rating), • ]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(video.res))</visible> + <posx>10</posx> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>$INFO[Container(400).ListItem.Property(video.res)]$INFO[Container(400).ListItem.Property(video.rendering), • ]$INFO[Container(400).ListItem.Property(video.codec), • ]$INFO[Container(400).ListItem.Property(audio.codec), • ]$INFO[Container(400).ListItem.Property(audio.channels), • ]</label> + </control> + </control> + + <control type="label"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(directors)) | !String.IsEmpty(Container(400).ListItem.Property(writers))</visible> + <posx>776</posx> + <posy>{{ vscale(194) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(directors)]$INFO[Container(400).ListItem.Property(writers)]</label> + </control> + + <control type="grouplist"> + <posx>776</posx> + <posy>{{ vscale(263) }}</posy> + <width>1360</width> + <height>{{ vscale(34) }}</height> + <align>left</align> + <itemgap>15</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="button"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(audio))</visible> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>[UPPERCASE]$ADDON[script.plexmod 32395][/UPPERCASE]</label> + </control> + <control type="label"> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(audio)]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(subtitles))</visible> + <left>34</left> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>[UPPERCASE]$ADDON[script.plexmod 32396][/UPPERCASE]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Container(400).ListItem.Property(subtitles))</visible> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Container(400).ListItem.Property(subtitles)]</label> + </control> + </control> + <control type="textbox"> + <posx>776</posx> + <posy>{{ vscale(340) }}</posy> + <width>1084</width> + <height>{{ vscale(172) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <scrolltime>200</scrolltime> + <autoscroll delay="2000" time="2000" repeat="10000">!Control.HasFocus(13)</autoscroll> + <label>$INFO[Container(400).ListItem.Property(summary)]</label> + </control> + + <control type="image" id="250"> + <animation effect="zoom" start="0,100" end="100,100" time="1000" center="-1,561" reversible="false" tween="circle" easing="out">WindowOpen</animation> + <posx>-1</posx> + <posy>{{ vscale(557) }}</posy> + <width>1</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + <control type="image"> + <visible>!Control.IsVisible(500)</visible> + <posx>0</posx> + <posy>{{ vscale(565) }}</posy> + <width>1920</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + </control> + + <!-- EPISODES --> + <control type="grouplist" id="60"> + <visible>!String.IsEmpty(Window.Property(initialized))</visible> + <posx>0</posx> + <posy>{{ vscale(565) }}</posy> + <width>1920</width> + <height>{{ vscale(1800) }}</height> + + <onup condition="Control.IsVisible(300)">300</onup> + <onup condition="Control.IsVisible(1300)">1300</onup> + <itemgap>0</itemgap> + + <!-- EPISODES --> + <control type="group" id="500"> + <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <height>{{ vscale(360) }}</height> + <width>1920</width> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>AAFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(episodes.header)][/UPPERCASE]</label> + </control> + <control type="list" id="400"> + <posx>0</posx> + <posy>{{ vscale(18) }}</posy> + <width>1920</width> + <height>{{ vscale(360) }}</height> + <onup condition="Control.IsVisible(300)">300</onup> + <onup condition="Control.IsVisible(1300)">1300</onup> + <ondown>401</ondown> + <onleft>noop</onleft> + <onright>noop</onright> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(158) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>299</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=299 & uw_size=35 & wbw_w=40 %} + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(175) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(210) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>85.5</posx> + <posy>{{ vscale(20) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>389</width> + <height>{{ vscale(258) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(158) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>299</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=299 & uw_size=35 & wbw_w=40 %} + + <control type="group"> + <visible>Control.HasFocus(400)</visible> + <control type="label"> + <scroll>true</scroll> + <posx>0</posx> + <posy>{{ vscale(175) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>true</scroll> + <posx>0</posx> + <posy>{{ vscale(210) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="group"> + <visible>!Control.HasFocus(400)</visible> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(175) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>FFCC7B19</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(210) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>FFCC7B19</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>85.5</posx> + <posy>{{ vscale(20) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>0</posx> + <posy>0</posy> + <width>309</width> + <height>{{ vscale(178) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- EPISODES --> + + <!-- Seasons --> + <control type="group" id="501"> + <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <height>{{ vscale(380) }}</height> + <width>1920</width> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(seasons.header)][/UPPERCASE]</label> + </control> + <control type="list" id="401"> + <posx>0</posx> + <posy>{{ vscale(36) }}</posy> + <width>1920</width> + <height>{{ vscale(380) }}</height> + <onup>400</onup> + <ondown>402</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="218"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(29) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with with_count=True %} + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(230) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>158</width> + <height>{{ vscale(4) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(240) }}</posy> + <width>158</width> + <height>{{ vscale(54) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="218"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(29) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="84,{{ vscale(123) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="84,{{ vscale(123) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>248</width> + <height>{{ vscale(326) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with with_count=True %} + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(230) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>158</width> + <height>{{ vscale(4) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(401)</scroll> + <posx>0</posx> + <posy>{{ vscale(240) }}</posy> + <width>158</width> + <height>{{ vscale(54) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>0</posx> + <posy>0</posy> + <width>168</width> + <height>{{ vscale(246) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- Seasons --> + + <!-- ROLES --> + <control type="group" id="502"> + <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>402</defaultcontrol> + <width>1920</width> + <height>{{ vscale(400) }}</height> + <control type="label"> + <posx>60</posx> + <posy>{{ vscale(-20) }}</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32419][/UPPERCASE]</label> + </control> + <control type="list" id="402"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(400) }}</height> + <onup>401</onup> + <ondown>403</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <control type="label"> + <scroll>Control.HasFocus(402)</scroll> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(402)</scroll> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- ROLES --> + + <!-- EXTRAS --> + <control type="group" id="503"> + <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <height>{{ vscale(360) }}</height> + <width>1920</width> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>AAFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(extras.header)][/UPPERCASE]</label> + </control> + <control type="list" id="403"> + <posx>0</posx> + <posy>{{ vscale(18) }}</posy> + <width>1920</width> + <height>{{ vscale(430) }}</height> + <onup>402</onup> + <ondown>404</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(175) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(205) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>389</width> + <height>{{ vscale(258) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <control type="label"> + <scroll>Control.HasFocus(403)</scroll> + <posx>0</posx> + <posy>{{ vscale(175) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(403)</scroll> + <posx>0</posx> + <posy>{{ vscale(205) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>0</posx> + <posy>0</posy> + <width>309</width> + <height>{{ vscale(178) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- EXTRAS --> + + <!-- RELATED --> + <control type="group" id="504"> + <visible>Integer.IsGreater(Container(404).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>404</defaultcontrol> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> + </control> + <control type="list" id="404"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <onup>403</onup> + <ondown>404</ondown> + <onleft>noop</onleft> + <onright>noop</onright> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(404)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(441) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + <control type="label"> + <scroll>Control.HasFocus(404)</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(404)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- / RELATED --> + + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-home.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-home.xml.tpl new file mode 100644 index 0000000000..c9f6cda368 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-home.xml.tpl @@ -0,0 +1,7496 @@ +{% extends "default.xml.tpl" %} +{% block content %} +<control type="grouplist" id="50"> + <animation effect="slide" end="0,{{ vscale(-135) }}" time="200" tween="sine" easing="inout" condition="!String.IsEmpty(Window(10000).Property(script.plex.off.sections))">Conditional</animation> + + <!-- 501 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-345) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 502 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 503 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 504 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),3) + Control.IsVisible(503)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 505 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),4) + Control.IsVisible(504)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 506 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),5) + Control.IsVisible(505)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 507 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),6) + Control.IsVisible(506)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-440) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 508 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),7) + Control.IsVisible(507)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 509 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),8) + Control.IsVisible(508)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 510 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),9) + Control.IsVisible(509)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 511 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),10) + Control.IsVisible(510)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 512 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),11) + Control.IsVisible(511)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 520 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),12) + Control.IsVisible(512)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 521 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),13) + Control.IsVisible(520)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 522 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),14) + Control.IsVisible(521)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 513 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),15) + Control.IsVisible(522)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-400) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 514 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),16) + Control.IsVisible(513)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 515 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),17) + Control.IsVisible(514)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 516 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),18) + Control.IsVisible(515)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 517 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),19) + Control.IsVisible(516)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 518 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),20) + Control.IsVisible(517)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 519 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),21) + Control.IsVisible(518)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + <!-- 523 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),22) + Control.IsVisible(519)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-540) }}" time="200" tween="sine" easing="inout"/> + </animation> + + + <defaultcontrol>101</defaultcontrol> + <posx>0</posx> + <posy>{{ vscale(96) }}</posy> + <width>2130</width> + <height>{{ vscale(5540) }}</height> + <itemgap>20</itemgap> + <orientation>vertical</orientation> + <usecontrolcoords>true</usecontrolcoords> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <control type="group" id="100"> + <width>2130</width> + <height>{{ vscale(200) }}</height> + <control type="fixedlist" id="101"> + <animation effect="slide" end="-110,0" time="200" tween="sine" easing="inout" condition="Integer.IsGreater(Container(101).Position,3)">Conditional</animation> + <animation effect="slide" end="-110,0" time="200" tween="sine" easing="inout" condition="Integer.IsGreater(Container(101).Position,4)">Conditional</animation>--> + <posx>-300</posx> + <posy>0</posy> + <width>2430</width> + <height>{{ vscale(240) }}</height> + <onup condition="!Player.HasAudio">203</onup> + <onup condition="Player.HasAudio">204</onup> + <ondown>400</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <focusposition>4</focusposition> + <movement>3</movement> + <pagecontrol>102</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="298"> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(item))</visible> + <posx>60</posx> + <posy>{{ vscale(40) }}</posy> + <width>298</width> + <height>{{ vscale(200) }}</height> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(117) }}</height> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.home))</visible> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(117) }}</height> + <texture border="10">script.plex/white-square-rounded.png</texture> + <colordiffuse>FF1F1F1F</colordiffuse> + </control> + + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.home))</visible> + <posx>84</posx> + <posy>{{ vscale(23.5) }}</posy> + <width>70</width> + <height>{{ vscale(70) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>keep</aspectratio> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.home))</visible> + <posx>74</posx> + <posy>{{ vscale(13.5) }}</posy> + <width>90</width> + <height>{{ vscale(90) }}</height> + <texture>script.plex/home/type/home.png</texture> + <aspectratio>keep</aspectratio> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.mapped))</visible> + <posx>230</posx> + <posy>0</posy> + <width>8</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square-rounded-4r.png</texture> + <colordiffuse>FF666666</colordiffuse> + </control> + </control> + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(125) }}</posy> + <width>238</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="298"> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(item))</visible> + <posx>60</posx> + <posy>{{ vscale(40) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="120" time="100" center="119,{{ vscale(58.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="119,{{ vscale(58.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(is.home))</visible> + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>318</width> + <height>{{ vscale(197) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(moving))</visible> + <animation effect="fade" end="100" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(117) }}</height> + <texture border="10">script.plex/white-square-rounded.png</texture> + <colordiffuse>FF1F1F1F</colordiffuse> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(moving))</visible> + <animation effect="fade" end="0" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(117) }}</height> + <texture border="10">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(moving))</visible> + <animation effect="fade" end="100" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(117) }}</height> + <texture border="10">script.plex/white-square-rounded.png</texture> + <colordiffuse>66777777</colordiffuse> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(moving))</visible> + <animation effect="fade" end="0" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(117) }}</height> + <texture border="10">script.plex/white-square-rounded.png</texture> + <colordiffuse>66777777</colordiffuse> + </control> + </control> + <control type="image"> + <visible>!Control.HasFocus(101)</visible> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(117) }}</height> + <texture border="10">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + <control type="image"> + <posx>84</posx> + <posy>{{ vscale(23.5) }}</posy> + <width>70</width> + <height>{{ vscale(70) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>keep</aspectratio> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.mapped))</visible> + <posx>230</posx> + <posy>0</posy> + <width>8</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square-rounded-4r.png</texture> + <colordiffuse>AAFFFFFFF</colordiffuse> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.home))</visible> + <posx>74</posx> + <posy>{{ vscale(13.5) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>90</width> + <height>{{ vscale(90) }}</height> + <texture>script.plex/home/type/home.png</texture> + <aspectratio>keep</aspectratio> + </control> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <animation effect="fade" end="0" reversible="false">UnFocus</animation> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>170</width> + <height>{{ vscale(170) }}</height> + <texture>script.plex/home/type/home-selected.png</texture> + <aspectratio>keep</aspectratio> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(100)</scroll> + <posx>0</posx> + <posy>{{ vscale(125) }}</posy> + <width>238</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="500"> + <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.400)][/UPPERCASE]</label> + </control> + <control type="list" id="400"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <onup>101</onup> + <ondown>401</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.400))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="271,{{ vscale(152) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="271,{{ vscale(152) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>622</width> + <height>{{ vscale(389) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + + <control type="label"> + <scroll>Control.HasFocus(400)</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(400)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.400))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>0</posx> + <posy>0</posy> + <width>542</width> + <height>{{ vscale(309) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="600"> + <visible>Integer.IsGreater(Container(400).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.400))</visible> + <width>10</width> + <height>{{ vscale(12) }}</height> + </control> + + <control type="group" id="501"> + <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>401</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.401)][/UPPERCASE]</label> + </control> + <control type="list" id="401"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>400</onup> + <ondown>402</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.401))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(401)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(401)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.401))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="601"> + <visible>Integer.IsGreater(Container(401).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.401))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="502"> + <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>402</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.402)][/UPPERCASE]</label> + </control> + <control type="list" id="402"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>401</onup> + <ondown>403</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.402))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(402)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(402)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.402))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="602"> + <visible>Integer.IsGreater(Container(402).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.402))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="503"> + <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>403</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.403)][/UPPERCASE]</label> + </control> + <control type="list" id="403"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>402</onup> + <ondown>404</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.403))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(403)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(403)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.403))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="603"> + <visible>Integer.IsGreater(Container(403).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.403))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="504"> + <visible>Integer.IsGreater(Container(404).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>404</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.404)][/UPPERCASE]</label> + </control> + <control type="list" id="404"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>403</onup> + <ondown>405</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.404))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(404)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(404)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(404)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.404))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(404)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="604"> + <visible>Integer.IsGreater(Container(404).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.404))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="505"> + <visible>Integer.IsGreater(Container(405).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>405</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.405)][/UPPERCASE]</label> + </control> + <control type="list" id="405"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>404</onup> + <ondown>406</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.405))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(405)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(405)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(405)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.405))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(405)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="605"> + <visible>Integer.IsGreater(Container(405).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.405))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="506"> + <visible>Integer.IsGreater(Container(406).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.406)][/UPPERCASE]</label> + </control> + <control type="list" id="406"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <onup>405</onup> + <ondown>407</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.406))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="271,{{ vscale(152) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="271,{{ vscale(152) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(406)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>622</width> + <height>{{ vscale(389) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>Control.HasFocus(406)</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(406)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.406))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(406)</visible> + <posx>0</posx> + <posy>0</posy> + <width>542</width> + <height>{{ vscale(309) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="606"> + <visible>Integer.IsGreater(Container(406).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.406))</visible> + <width>10</width> + <height>{{ vscale(12) }}</height> + </control> + + <control type="group" id="507"> + <visible>Integer.IsGreater(Container(407).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>407</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.407)][/UPPERCASE]</label> + </control> + <control type="list" id="407"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>406</onup> + <ondown>408</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.407))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(407)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(407)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(407)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.407))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(407)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="607"> + <visible>Integer.IsGreater(Container(407).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.407))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="508"> + <visible>Integer.IsGreater(Container(408).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>408</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.408)][/UPPERCASE]</label> + </control> + <control type="list" id="408"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>407</onup> + <ondown>409</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.408))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(408)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(408)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(408)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.408))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(408)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="608"> + <visible>Integer.IsGreater(Container(408).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.408))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="509"> + <visible>Integer.IsGreater(Container(409).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>409</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.409)][/UPPERCASE]</label> + </control> + <control type="list" id="409"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>408</onup> + <ondown>410</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.409))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(409)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(409)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(409)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.409))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(409)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="609"> + <visible>Integer.IsGreater(Container(409).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.409))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="510"> + <visible>Integer.IsGreater(Container(410).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>410</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.410)][/UPPERCASE]</label> + </control> + <control type="list" id="410"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>409</onup> + <ondown>411</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.410))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(410)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(410)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(410)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.410))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(410)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="610"> + <visible>Integer.IsGreater(Container(410).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.410))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="511"> + <visible>Integer.IsGreater(Container(411).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>411</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.411)][/UPPERCASE]</label> + </control> + <control type="list" id="411"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>410</onup> + <ondown>412</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.411))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(411)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(411)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(411)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.411))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(411)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="611"> + <visible>Integer.IsGreater(Container(411).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.411))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="512"> + <visible>Integer.IsGreater(Container(412).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>412</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.412)][/UPPERCASE]</label> + </control> + <control type="list" id="412"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>411</onup> + <ondown>420</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.412))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(412)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(412)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(412)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.412))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(412)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="612"> + <visible>Integer.IsGreater(Container(412).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.412))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="520"> + <visible>Integer.IsGreater(Container(420).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>420</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.420)][/UPPERCASE]</label> + </control> + <control type="list" id="420"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>412</onup> + <ondown>421</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.420))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(420)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(420)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(420)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.420))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(420)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="620"> + <visible>Integer.IsGreater(Container(420).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.420))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="521"> + <visible>Integer.IsGreater(Container(421).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>421</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.421)][/UPPERCASE]</label> + </control> + <control type="list" id="421"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>420</onup> + <ondown>422</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.421))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(421)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(421)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(421)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.421))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(421)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="621"> + <visible>Integer.IsGreater(Container(421).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.421))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="522"> + <visible>Integer.IsGreater(Container(422).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>422</defaultcontrol> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.422)][/UPPERCASE]</label> + </control> + <control type="list" id="422"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(392) }}</height> + <onup>421</onup> + <ondown>413</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.422))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="122,{{ vscale(122) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="122,{{ vscale(122) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(422)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(324) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(72) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(58) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(234) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(422)</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(422)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.422))</visible> + <posx>0</posx> + <posy>{{ vscale(281) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(422)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="622"> + <visible>Integer.IsGreater(Container(422).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.422))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="513"> + <visible>Integer.IsGreater(Container(413).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>413</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.413)][/UPPERCASE]</label> + </control> + <control type="list" id="413"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>422</onup> + <ondown>414</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.413))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(413)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(413)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(413)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.413))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(413)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="613"> + <visible>Integer.IsGreater(Container(413).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.413))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="514"> + <visible>Integer.IsGreater(Container(414).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>414</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.414)][/UPPERCASE]</label> + </control> + <control type="list" id="414"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>413</onup> + <ondown>415</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.414))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(414)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(414)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(414)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.414))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(414)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="614"> + <visible>Integer.IsGreater(Container(414).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.414))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="515"> + <visible>Integer.IsGreater(Container(415).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>415</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.415)][/UPPERCASE]</label> + </control> + <control type="list" id="415"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>414</onup> + <ondown>416</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.415))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(415)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(415)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(415)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.415))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(415)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="615"> + <visible>Integer.IsGreater(Container(415).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.415))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="516"> + <visible>Integer.IsGreater(Container(416).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>416</defaultcontrol> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.416)][/UPPERCASE]</label> + </control> + <control type="list" id="416"> + <posx>0</posx> + <posy>{{ vscale(29) }}</posy> + <width>1920</width> + <height>{{ vscale(515) }}</height> + <onup>415</onup> + <ondown>417</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.416))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(416)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(416)</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(416)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.416))</visible> + <posx>0</posx> + <posy>{{ vscale(398) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + </control> + <control type="image"> + <visible>Control.HasFocus(416)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="616"> + <visible>Integer.IsGreater(Container(416).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.416))</visible> + <width>10</width> + <height>{{ vscale(7) }}</height> + </control> + + <control type="group" id="517"> + <visible>Integer.IsGreater(Container(417).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.417)][/UPPERCASE]</label> + </control> + <control type="list" id="417"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <onup>416</onup> + <ondown>418</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.417))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="271,{{ vscale(152) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="271,{{ vscale(152) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(417)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>622</width> + <height>{{ vscale(389) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>Control.HasFocus(417)</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(417)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.417))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(417)</visible> + <posx>0</posx> + <posy>0</posy> + <width>542</width> + <height>{{ vscale(309) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="617"> + <visible>Integer.IsGreater(Container(417).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.417))</visible> + <width>10</width> + <height>{{ vscale(12) }}</height> + </control> + + <control type="group" id="518"> + <visible>Integer.IsGreater(Container(418).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.418)][/UPPERCASE]</label> + </control> + <control type="list" id="418"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <onup>417</onup> + <ondown>419</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.418))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="271,{{ vscale(152) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="271,{{ vscale(152) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(418)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>622</width> + <height>{{ vscale(389) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>Control.HasFocus(418)</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(418)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.418))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(418)</visible> + <posx>0</posx> + <posy>0</posy> + <width>542</width> + <height>{{ vscale(309) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="618"> + <visible>Integer.IsGreater(Container(418).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.418))</visible> + <width>10</width> + <height>{{ vscale(12) }}</height> + </control> + + <control type="group" id="519"> + <visible>Integer.IsGreater(Container(419).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.419)][/UPPERCASE]</label> + </control> + <control type="list" id="419"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <onup>418</onup> + <ondown>423</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.419))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="271,{{ vscale(152) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="271,{{ vscale(152) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(419)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>622</width> + <height>{{ vscale(389) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>Control.HasFocus(419)</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(419)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.419))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(419)</visible> + <posx>0</posx> + <posy>0</posy> + <width>542</width> + <height>{{ vscale(309) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="619"> + <visible>Integer.IsGreater(Container(419).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.419))</visible> + <width>10</width> + <height>{{ vscale(12) }}</height> + </control> + + <control type="group" id="523"> + <visible>Integer.IsGreater(Container(423).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(bifurcation_lines))</visible> + <posx>60</posx> + <posy>{{ vscale(12) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.423)][/UPPERCASE]</label> + </control> + <control type="list" id="423"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>{{ vscale(440) }}</height> + <onup>419</onup> + <ondown>423</ondown> + <onright>noop</onright> + <onleft>noop</onleft> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.423))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="592"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="271,{{ vscale(152) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="271,{{ vscale(152) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(423)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>622</width> + <height>{{ vscale(389) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.end))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>235.5</posx> + <posy>{{ vscale(99.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>202</posx> + <posy>{{ vscale(85.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(299) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(289) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>532</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>532</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=532 & uw_size=48 & with_count=True %} + <control type="label"> + <scroll>Control.HasFocus(423)</scroll> + <posx>0</posx> + <posy>{{ vscale(309) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(423)</scroll> + <visible>!String.IsEmpty(Window.Property(hub.text2lines.423))</visible> + <posx>0</posx> + <posy>{{ vscale(337) }}</posy> + <width>532</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(423)</visible> + <posx>0</posx> + <posy>0</posy> + <width>542</width> + <height>{{ vscale(309) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <control type="group" id="623"> + <visible>Integer.IsGreater(Container(423).NumItems,0) + !String.IsEmpty(Window.Property(hub.text2lines.423))</visible> + <width>10</width> + <height>{{ vscale(12) }}</height> + </control> + + <control type="label"> + <!-- DUMMY --> + <width>1920</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>00FFFFFF</textcolor> + <label> </label> + </control> +</control> +{% endblock content %} + +{% block header %} +<control type="group" id="200"> + <animation effect="slide" end="0,{{ vscale(-135) }}" time="200" tween="sine" easing="inout" condition="!String.IsEmpty(Window(10000).Property(script.plex.off.sections)) + !ControlGroup(200).HasFocus(0)">Conditional</animation> + <defaultcontrol always="true">201</defaultcontrol> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <control type="image"> + <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> + <visible>ControlGroup(200).HasFocus(0) + !String.IsEmpty(Window(10000).Property(script.plex.off.sections))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="group"> + <visible>String.IsEmpty(Window.Property(search.dialog))</visible> + <control type="button" id="203"> + <animation effect="zoom" start="100" end="144" time="100" center="80,{{ vscale(67.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="144" end="100" time="100" center="80,{{ vscale(67.5) }}" reversible="false">UnFocus</animation> + <posx>60</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>40</width> + <height>{{ vscale(40) }}</height> + <ondown>50</ondown> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/search.png</texturenofocus> + <label> </label> + </control> + <control type="label"> + <posx>160</posx> + <posy>{{ vscale(35) }}</posy> + <width>500</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32430][/UPPERCASE]</label> + </control> + </control> + <control type="group"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>438</posx> + <posy>0</posy> + <control type="button" id="204"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>-10</posx> + <posy>{{ vscale(38) }}</posy> + <width>260</width> + <height>{{ vscale(75) }}</height> + <onleft>203</onleft> + <ondown>50</ondown> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>right</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>100</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(48) }}</posy> + <width>42</width> + <height>{{ vscale(42) }}</height> + <texture>$INFO[Player.Art(thumb)]</texture> + </control> + + <control type="group"> + <visible>!Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + + <control type="progress"> + <description>Progressbar</description> + <posx>0</posx> + <posy>{{ vscale(102) }}</posy> + <width>240</width> + <height>{{ vscale(1) }}</height> + <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> + </control> + <control type="label"> + <right>213</right> + <posy>{{ vscale(35) }}</posy> + <width>200</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[System.Time]</label> + </control> + <control type="image"> + <posx>153r</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>93</width> + <height>{{ vscale(43) }}</height> + <texture>script.plex/home/plex.png</texture> + </control> + <control type="group"> + <posx>576</posx> + <posy>{{ vscale(34) }}</posy> + <width>1000</width> + <height>{{ vscale(1046) }}</height> + <control type="grouplist"> + <posx>0</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(1046) }}</height> + <ondown>50</ondown> + <onleft>204</onleft> + <align>right</align> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + <control type="button" id="201"> + <width max="500">auto</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>right</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>100</textoffsetx> + <textoffsety>0</textoffsety> + <label>$INFO[Window.Property(server.name)]</label> + <onunfocus condition="!String.IsEmpty(Window.Property(show.servers))">SetFocus(260)</onunfocus> + </control> + <!-- server control --> + <control type="group"> + <posx>-93</posx> + <width>93</width> + <height>{{ vscale(66) }}</height> + <control type="image"> + <posx>6</posx> + <posy>{{ vscale(14) }}</posy> + <width>40</width> + <height>{{ vscale(39) }}</height> + <texture>$INFO[Window.Property(server.icon)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(38) }}</posy> + <width>16</width> + <height>{{ vscale(15) }}</height> + <texture>$INFO[Window.Property(server.iconmod)]</texture> + </control> + <!-- secure + local --> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(server.iconmod))</visible> + <posx>0</posx> + <posy>{{ vscale(20) }}</posy> + <width>16</width> + <height>{{ vscale(14) }}</height> + <texture>$INFO[Window.Property(server.iconmod2)]</texture> + <colordiffuse>FFEEEEEE</colordiffuse> + </control> + <!-- local --> + <control type="image"> + <visible>String.IsEmpty(Window.Property(server.iconmod))</visible> + <posx>0</posx> + <posy>{{ vscale(38) }}</posy> + <width>16</width> + <height>{{ vscale(14) }}</height> + <texture>$INFO[Window.Property(server.iconmod2)]</texture> + <colordiffuse>FFEEEEEE</colordiffuse> + </control> + <control type="image"> + <visible>!Control.HasFocus(201)</visible> + <posx>59</posx> + <posy>{{ vscale(27) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture>script.plex/indicators/dropdown-triangle.png</texture> + <colordiffuse>99FFFFFF</colordiffuse> + </control> + <control type="image"> + <visible>Control.HasFocus(201)</visible> + <posx>59</posx> + <posy>{{ vscale(27) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture>script.plex/indicators/dropdown-triangle.png</texture> + <colordiffuse>FF222222</colordiffuse> + </control> + <control type="group"> + <visible>Control.HasFocus(260) | !String.IsEmpty(Window.Property(show.servers))</visible> + <posx>-413</posx> + <posy>{{ vscale(70) }}</posy> + <control type="image" id="800"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>580</width> + <height>{{ vscale(146) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <posx>432</posx> + <posy>{{ vscale(-13) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture flipy="true">script.plex/indicators/dropdown-triangle.png</texture> + <colordiffuse>FF1F1F1F</colordiffuse> + </control> + <control type="list" id="260"> + <hitrect x="0" y="-10" w="500" h="910" /> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(900) }}</height> + <onup>201</onup> + <onleft>203</onleft> + <onright>202</onright> + <onunfocus>SetProperty(show.servers,)</onunfocus> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <pagecontrol>261</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(100) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture flipy="true" colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Label2)</visible> + <control type="label"> + <posx>20</posx> + <posy>{{ vscale(20) }}</posy> + <width>400</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>20</posx> + <posy>{{ vscale(50) }}</posy> + <width>400</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFA0A0A0</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>0</posy> + <width>400</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + + <!-- not status + not current + local --> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>456</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <!-- not status + current + local --> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>415</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <!-- status + not current + local --> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>415</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <!-- status + current + local --> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>374</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <!-- status + not current --> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current))</visible> + <posx>456</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(24) }}</height> + <texture>script.plex/home/device/$INFO[ListItem.Property(status)]</texture> + </control> + <!-- status + current --> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current))</visible> + <posx>415</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(24) }}</height> + <texture>script.plex/home/device/$INFO[ListItem.Property(status)]</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(current))</visible> + <posx>449</posx> + <posy>{{ vscale(38) }}</posy> + <width>31</width> + <height>{{ vscale(24) }}</height> + <texture colordiffuse="FFFFFFFF">script.plex/home/device/check.png</texture> + </control> + + </itemlayout> + <focusedlayout height="{{ vscale(100) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Label2)</visible> + <control type="label"> + <posx>20</posx> + <posy>{{ vscale(20) }}</posy> + <width>400</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>20</posx> + <posy>{{ vscale(50) }}</posy> + <width>400</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>0</posy> + <width>400</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + + <!-- not status + not current + local --> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>456</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <!-- not status + current + local --> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>415</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <!-- status + not current + local --> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>415</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <!-- status + current + local --> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current)) + !String.IsEmpty(ListItem.Property(local)) </visible> + <posx>374</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(21) }}</height> + <texture>script.plex/home/device/home.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + String.IsEmpty(ListItem.Property(current))</visible> + <posx>456</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(24) }}</height> + <texture>script.plex/home/device/focus-$INFO[ListItem.Property(status)]</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(status)) + !String.IsEmpty(ListItem.Property(current))</visible> + <posx>415</posx> + <posy>{{ vscale(38) }}</posy> + <width>24</width> + <height>{{ vscale(24) }}</height> + <texture>script.plex/home/device/focus-$INFO[ListItem.Property(status)]</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(current))</visible> + <posx>449</posx> + <posy>{{ vscale(38) }}</posy> + <width>31</width> + <height>{{ vscale(24) }}</height> + <texture colordiffuse="FF000000">script.plex/home/device/check.png</texture> + </control> + + </focusedlayout> + </control> + + <control type="scrollbar" id="261"> + <posx>492</posx> + <posy>{{ vscale(20) }}</posy> + <width>8</width> + <height>{{ vscale(860) }}</height> + <texturesliderbackground>-</texturesliderbackground> + <texturesliderbar colordiffuse="20FFFFFF" border="4">script.plex/white-square.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="20E5A00D" border="4">script.plex/white-square.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>250</onleft> + </control> + + </control> + </control> + <control type="button" id="202"> + <width max="500">auto</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>right</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>100</textoffsetx> + <textoffsety>0</textoffsety> + <label>$INFO[Window.Property(user.name)]</label> + <onunfocus condition="!String.IsEmpty(Window.Property(show.options))">SetFocus(250)</onunfocus> + </control> + <control type="group"> + <posx>-87</posx> + <width>87</width> + <height>{{ vscale(66) }}</height> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(14) }}</posy> + <width>40</width> + <height>{{ vscale(39) }}</height> + <texture diffuse="script.plex/home/avatar-diffuse.png" fallback="script.plex/gray-square.png">$INFO[Window.Property(user.avatar)]</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(Window.Property(user.avatar))</visible> + <posx>0</posx> + <posy>{{ vscale(14) }}</posy> + <width>40</width> + <height>{{ vscale(39) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Window.Property(user.avatar.letter)][/B]</label> + </control> + <control type="image"> + <visible>!Control.HasFocus(202)</visible> + <posx>53</posx> + <posy>{{ vscale(27) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture>script.plex/indicators/dropdown-triangle.png</texture> + <colordiffuse>99FFFFFF</colordiffuse> + </control> + <control type="image"> + <visible>Control.HasFocus(202)</visible> + <posx>53</posx> + <posy>{{ vscale(27) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture>script.plex/indicators/dropdown-triangle.png</texture> + <colordiffuse>FF222222</colordiffuse> + </control> + <control type="group"> + <visible>Control.HasFocus(250) | !String.IsEmpty(Window.Property(show.options))</visible> + <posx>-213</posx> + <posy>{{ vscale(70) }}</posy> + <control type="image" id="801"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>380</width> + <height>{{ vscale(146) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <posx>226</posx> + <posy>{{ vscale(-13) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture flipy="true">script.plex/indicators/dropdown-triangle.png</texture> + <colordiffuse>FF1F1F1F</colordiffuse> + </control> + <control type="list" id="250"> + <hitrect x="0" y="-10" w="300" h="208" /> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(198) }}</height> + <onup>202</onup> + <ondown>noop</ondown> + <onleft>201</onleft> + <onunfocus>SetProperty(show.options,)</onunfocus> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(66) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture flipy="true" colordiffuse="FF1F1F1F" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FF1F1F1F" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(66) }}"> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(first))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(first)) + String.IsEmpty(ListItem.Property(last)) + String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(last))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture flipy="true" colordiffuse="FFE5A00D" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(only))</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </focusedlayout> + </control> + </control> + </control> + <control type="image"> + <!-- dummy image to allow shadow --> + <width>40</width> + <height>{{ vscale(10) }}</height> + <texture>-</texture> + </control> + </control> + </control> +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window.Property(search.dialog))</visible> + <control type="group" > + <visible>!String.IsEmpty(Window.Property(search.dialog.hasresults))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/home/background-fallback.png</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">$INFO[Window.Property(background)]</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture colordiffuse="99606060">script.plex/white-square.png</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> +</control> + +<control type="group"> + <visible>String.IsEmpty(Window.Property(busy)) + !String.IsEmpty(Window.Property(no.content))</visible> + <posx>0</posx> + <posy>{{ vscale(465) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(35) }}</height> + <font>font13</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$ADDON[script.plexmod 32452][/B]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>{{ vscale(60) }}</posy> + <width>1800</width> + <height>{{ vscale(35) }}</height> + <font>font13</font> + <align>center</align> + <textcolor>FFCCCCCC</textcolor> + <label>$ADDON[script.plexmod 32453]</label> + </control> +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window.Property(busy))</visible> + <animation effect="fade" start="0" end="100" delay="500">Visible</animation> + <posx>840</posx> + <posy>{{ vscale(465) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/busy-back.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + <control type="image"> + <posx>75</posx> + <posy>{{ vscale(56) }}</posy> + <width>90</width> + <height>{{ vscale(38) }}</height> + <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> + </control> +</control> +{% endblock header %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-info.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-info.xml.tpl new file mode 100644 index 0000000000..6e98f0a429 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-info.xml.tpl @@ -0,0 +1,158 @@ +{% extends "default.xml.tpl" %} +{% block headers %}<defaultcontrol>152</defaultcontrol>{% endblock %} + +{% block content %} +<control type="group"> + <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true" fallback="script.plex/home/background-fallback_black.png">$INFO[Window.Property(background_static)]</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <fadetime>1000</fadetime> + <texture background="true">$INFO[Window.Property(background)]</texture> + </control> +</control> + +<control type="group" id="50"> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + + <control type="group"> + <posx>60</posx> + <posy>0</posy> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(is.poster))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>519</width> + <height>{{ vscale(769) }}</height> + <texture>$INFO[Window.Property(thumb.fallback)]</texture> + <aspectratio aligny="top">scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>519</width> + <height>{{ vscale(769) }}</height> + <texture>$INFO[Window.Property(thumb)]</texture> + <aspectratio aligny="top">scale</aspectratio> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(is.square))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>519</width> + <height>{{ vscale(519) }}</height> + <texture>$INFO[Window.Property(thumb.fallback)]</texture> + <aspectratio aligny="top">keep</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>519</width> + <height>{{ vscale(519) }}</height> + <texture>$INFO[Window.Property(thumb)]</texture> + <aspectratio aligny="top">scale</aspectratio> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(is.16x9))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>519</width> + <height>{{ vscale(292) }}</height> + <texture>$INFO[Window.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>519</width> + <height>{{ vscale(292) }}</height> + <texture>$INFO[Window.Property(thumb)]</texture> + <aspectratio aligny="top">scale</aspectratio> + </control> + </control> + <control type="label"> + <posx>579</posx> + <posy>5</posy> + <width>1190</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(title.main)]</label> + </control> + <control type="label"> + <posx>579</posx> + <posy>{{ vscale(55) }}</posy> + <width>1190</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFDDDDDD</textcolor> + <label>$INFO[Window.Property(title.sub)]</label> + </control> + <control type="textbox"> + <posx>579</posx> + <posy>{{ vscale(157) }}</posy> + <pagecontrol>152</pagecontrol> + <width>1190</width> + <height>{{ vscale(718) }}</height> + <font>font13</font> + <align>left</align> + <textcolor>FFDDDDDD</textcolor> + <label>$INFO[Window.Property(info)]</label> + </control> + <control type="scrollbar" id="152"> + <hitrect x="1754" y="157" w="126" h="718" /> + <left>1794</left> + <top>157</top> + <width>6</width> + <height>{{ vscale(718) }}</height> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>204</onleft> + </control> + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-16x9.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-16x9.xml.tpl new file mode 100644 index 0000000000..623dd62354 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-16x9.xml.tpl @@ -0,0 +1,404 @@ +{% extends "library.xml.tpl" %} +{% block header_bg %}{% endblock %} +{% block header_animation %}{% endblock %} +{% block filteropts_grouplist_attrs %} id="600"{% endblock %} +{% block no_content %}{% endblock %} + +{% block content %} +<control type="group"> + <posx>60</posx> + <posy>{{ vscale(248) }}</posy> + <control type="image"> + <visible>!String.IsEqual(Window.Property(media),show) + !String.IsEqual(Window.Property(media),movie)</visible> + <posx>0</posx> + <posy>0</posy> + <width>630</width> + <height>{{ vscale(355) }}</height> + <fadetime>500</fadetime> + <texture background="true" fallback="script.plex/thumb_fallbacks/movie.png">$INFO[Container(101).ListItem.Property(art)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <visible>String.IsEqual(Window.Property(media),show) | String.IsEqual(Window.Property(media),movie)</visible> + <posx>0</posx> + <posy>0</posy> + <width>630</width> + <height>{{ vscale(355) }}</height> + <fadetime>500</fadetime> + <texture background="true" fallback="script.plex/thumb_fallbacks/show.png">$INFO[Container(101).ListItem.Property(art)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(355) }}</posy> + <width>440</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>630</posx> + <posy>{{ vscale(355) }}</posy> + <width>180</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Container(101).ListItem.Label2][/B]</label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(435) }}</posy> + <width>630</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(463) }}</posy> + <width>630</width> + <height>{{ vscale(307) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFDDDDDD</textcolor> + <label>$INFO[Container(101).ListItem.Property(summary)]</label> + </control> +</control> + +<control type="group" id="50"> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <defaultcontrol>301</defaultcontrol> + <posx>30</posx> + <posy>{{ vscale(-25) }}</posy> + <width>1000</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>101</ondown> + <onright>101</onright> + <itemgap>-20</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + <visible>!String.IsEmpty(Window.Property(initialized))</visible> + + {% with attr = {"width": 126, "height": 100} & template = "includes/themed_button.xml.tpl" & hitrect = {"x": 20, "y": 20, "w": 86, "h": 60} %} + {% include template with name="play" & id=301 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="shuffle" & id=302 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="more" & id=303 & visible="String.IsEmpty(Window.Property(no.options)) | Player.HasAudio" %} + {% include template with name="chapters" & id=304 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>750</posx> + <posy>0</posy> + <width>1170</width> + <height>1080</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>1080</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20000000</colordiffuse> + </control> + <control type="list" id="101"> + <hitrect x="60" y="0" w="1010" h="945" /> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>945</height> + <onup>600</onup> + <onright>151</onright> + <onleft>304</onleft> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>4</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(76) }}"> + <control type="group"> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="group"> + {% include "includes/watched_indicator.xml.tpl" with xoff=915 & yoff=8 & uw_size=35 & uw_posy=-3 & with_count=True & force_nowbg=True & scale="large" & wbg="script.plex/white-square-rounded.png" %} + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(year))</visible> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(year)][/B]</label> + </control> + </control> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(72) }}</posy> + <width>915</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="{{ vscale(76) }}"> + <control type="group"> + <control type="group"> + <visible>!Control.HasFocus(101)</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="group"> + {% include "includes/watched_indicator.xml.tpl" with xoff=915 & yoff=8 & uw_size=35 & uw_posy=-3 & with_count=True & force_nowbg=True & scale="large" & wbg="script.plex/white-square-rounded.png" %} + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(year))</visible> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(year)][/B]</label> + </control> + </control> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(72) }}</posy> + <width>915</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <posx>63</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>1085</width> + <height>{{ vscale(156) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1005</width> + <height>{{ vscale(76) }}</height> + <texture border="12">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + + <control type="group"> + {% include "includes/watched_indicator.xml.tpl" with xoff=973 & yoff=12 & uw_size=35 & with_count=True & force_nowbg=True & scale="large" & wbg="script.plex/white-square-rounded.png" %} + + <control type="group"> + <posx>60</posx> + <posy>4</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>510</width> + <height>{{ vscale(72) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(year))</visible> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>510</width> + <height>{{ vscale(72) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Property(year)][/B]</label> + </control> + </control> + </control> + </control> + </control> + </focusedlayout> + </control> + + <control type="scrollbar" id="152"> + <hitrect x="1108" y="33" w="90" h="879" /> + <left>1128</left> + <top>33</top> + <width>12</width> + <height>910</height> + <onleft>101</onleft> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + </control> +</control> + +<control type="group" id="150"> + <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>151</defaultcontrol> + <posx>1830</posx> + <posy>{{ vscale(135) + 33 }}</posy> + <width>20</width> + <height>920</height> + <control type="list" id="151"> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>1050</height> + <onleft>100</onleft> + <onright>152</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(34) }}</height> + <colordiffuse>FFE5A00D</colordiffuse> + <texture border="12">script.plex/white-outline-rounded.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-square.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-square.xml.tpl new file mode 100644 index 0000000000..bb0417036a --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-listview-square.xml.tpl @@ -0,0 +1,441 @@ +{% extends "library.xml.tpl" %} +{% block header_bg %}{% endblock %} +{% block header_animation %}{% endblock %} +{% block filteropts_grouplist_attrs %} id="600"{% endblock %} +{% block no_content %}{% endblock %} + +{% block content %} + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(248) }}</posy> + <control type="group"> + <visible>String.IsEqual(Window.Property(media),photo) | String.IsEqual(Window.Property(media),photodirectory)</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>630</width> + <height>{{ vscale(355) }}</height> + <texture colordiffuse="A0000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>630</width> + <height>{{ vscale(355) }}</height> + <fadetime>500</fadetime> + <texture background="true" fallback="script.plex/thumb_fallbacks/photo.png">$INFO[Container(101).ListItem.Thumb]</texture> + <aspectratio>keep</aspectratio> + </control> + </control> + <control type="image"> + <visible>String.IsEqual(Window.Property(media),artist)</visible> + <posx>0</posx> + <posy>0</posy> + <width>355</width> + <height>{{ vscale(355) }}</height> + <fadetime>500</fadetime> + <texture background="true" fallback="script.plex/thumb_fallbacks/music.png">$INFO[Container(101).ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(Container(101).ListItem.Label2)</visible> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(355) }}</posy> + <width>310</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>630</posx> + <posy>{{ vscale(355) }}</posy> + <width>310</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Container(101).ListItem.Label2][/B]</label> + </control> + </control> + <control type="group"> + <visible>String.IsEmpty(Container(101).ListItem.Label2)</visible> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(355) }}</posy> + <width>630</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Container(101).ListItem.Label][/B]</label> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(435) }}</posy> + <width>630</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(463) }}</posy> + <width>630</width> + <height>{{ vscale(307) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFDDDDDD</textcolor> + <label>$INFO[Container(101).ListItem.Property(camera.model),,[CR]]$INFO[Container(101).ListItem.Property(camera.lens),,[CR]]$INFO[Container(101).ListItem.Property(photo.dims),,[CR]]$INFO[Container(101).ListItem.Property(camera.settings),,[CR]]$INFO[Container(101).ListItem.Property(photo.summary),[CR],[CR]]$INFO[Container(101).ListItem.Property(summary)]</label> + </control> + </control> + + <control type="group" id="50"> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <defaultcontrol>301</defaultcontrol> + <posx>30</posx> + <posy>{{ vscale(-25) }}</posy> + <width>1000</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>101</ondown> + <onright>101</onright> + <itemgap>-20</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + <visible>!String.IsEmpty(Window.Property(initialized))</visible> + + {% with attr = {"width": 126, "height": 100} & template = "includes/themed_button.xml.tpl" & hitrect = {"x": 20, "y": 20, "w": 86, "h": 60} %} + {% include template with name="play" & id=301 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="shuffle" & id=302 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="more" & id=303 & visible="String.IsEmpty(Window.Property(no.options)) | Player.HasAudio" %} + {% include template with name="chapters" & id=304 & visible="String.IsEmpty(Window.Property(hide.filteroptions))" %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>750</posx> + <posy>0</posy> + <width>1170</width> + <height>1080</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>1080</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20000000</colordiffuse> + </control> + <control type="list" id="101"> + <hitrect x="60" y="0" w="1010" h="945" /> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>945</height> + <onup>600</onup> + <onright>151</onright> + <onleft>304</onleft> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>4</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(76) }}"> + <control type="group"> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="group"> + {% include "includes/watched_indicator.xml.tpl" with xoff=915 & yoff=8 & uw_size=35 & uw_posy=-3 & with_count=True & force_nowbg=True & scale="large" & wbg="script.plex/white-square-rounded.png" %} + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][COLOR FFE5A00D]/[/COLOR][/B]</label> + </control> + </control> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(72) }}</posy> + <width>915</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="{{ vscale(76) }}"> + <control type="group"> + <control type="group"> + <visible>!Control.HasFocus(101)</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="group"> + {% include "includes/watched_indicator.xml.tpl" with xoff=915 & yoff=8 & uw_size=35 & uw_posy=-3 & with_count=True & force_nowbg=True & scale="large" & wbg="script.plex/white-square-rounded.png" %} + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>915</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][COLOR FFE5A00D]/[/COLOR][/B]</label> + </control> + </control> + </control> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(72) }}</posy> + <width>915</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <posx>63</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>1085</width> + <height>{{ vscale(156) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1005</width> + <height>{{ vscale(76) }}</height> + <texture border="12">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + + <control type="group"> + {% include "includes/watched_indicator.xml.tpl" with xoff=973 & yoff=12 & uw_size=35 & with_count=True & force_nowbg=True & scale="large" & wbg="script.plex/white-square-rounded.png" %} + <control type="group"> + <posx>60</posx> + <posy>0</posy> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>885</width> + <height>{{ vscale(72) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>885</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>[B]$INFO[ListItem.Label]/[/B]</label> + </control> + </control> + </control> + </control> + </control> + </focusedlayout> + </control> + + <control type="scrollbar" id="152"> + <hitrect x="1108" y="33" w="90" h="879" /> + <left>1128</left> + <top>33</top> + <width>12</width> + <height>879</height> + <onleft>101</onleft> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + </control> + </control> + + <control type="group" id="150"> + <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>151</defaultcontrol> + <posx>1830</posx> + <posy>{{ vscale(135) + 33 }}</posy> + <width>20</width> + <height>920</height> + <control type="list" id="151"> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>1050</height> + <onleft>100</onleft> + <onright>152</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(34) }}</height> + <colordiffuse>FFE5A00D</colordiffuse> + <texture border="12">script.plex/white-outline-rounded.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_current_playlist.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_current_playlist.xml.tpl new file mode 100644 index 0000000000..d23828a9fd --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_current_playlist.xml.tpl @@ -0,0 +1,517 @@ +{% extends "base.xml.tpl" %} +{% block controls %} +{% include "includes/default_background.xml.tpl" with background_source="$INFO[Player.Art(landscape)]" %} + +<control type="group" id="50"> + <posx>0</posx> + <posy>0</posy> + <defaultcontrol>101</defaultcontrol> + + <control type="group"> + <posx>90</posx> + <posy>0</posy> + <control type="image"> + <posx>-15</posx> + <posy>{{ vscale(75) }}</posy> + <width>669</width> + <height>{{ vscale(669) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20FFFFFF</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(90) }}</posy> + <width>639</width> + <height>{{ vscale(639) }}</height> + <texture>$INFO[Player.Art(thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(764) }}</posy> + <width>639</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[MusicPlayer.Artist]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(799) }}</posy> + <width>639</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[MusicPlayer.Album]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(834) }}</posy> + <width>639</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[MusicPlayer.Title][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(869) }}</posy> + <width>639</width> + <height>{{ vscale(35) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Player.Time]$INFO[MusicPlayer.Duration, / ]</label> + </control> + </control> + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>819</posx> + <posy>0</posy> + <width>1101</width> + <height>1080</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1101</width> + <height>1080</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20000000</colordiffuse> + </control> + <control type="list" id="101"> + <posx>0</posx> + <posy>0</posy> + <width>1101</width> + <height>1080</height> + <onright>152</onright> + <onleft>411</onleft> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>4</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(100) }}"> + <control type="group"> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>2</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>168</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>723</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>723</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="label"> + <posx>661</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(97) }}</posy> + <width>861</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="{{ vscale(100) }}"> + <control type="group"> + <control type="group"> + <visible>!Control.HasFocus(101)</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>0</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>168</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>723</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>723</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="label"> + <posx>669</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(97) }}</posy> + <width>861</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <posx>63</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>1055</width> + <height>{{ vscale(180) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>975</width> + <height>{{ vscale(100) }}</height> + <texture border="12">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="label"> + <visible>!String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>24</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>36</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="image"> + <posx>103</posx> + <posy>0</posy> + <width>100</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>235</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>669</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(51) }}</posy> + <width>669</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>98000000</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="label"> + <posx>735</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + </control> + </control> + + </focusedlayout> + </control> + + <control type="scrollbar" id="152"> + <hitrect x="1039" y="33" w="90" h="1014" /> + <left>1059</left> + <top>33</top> + <width>12</width> + <height>1014</height> + <onleft>101</onleft> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + </control> +</control> + +<control type="grouplist" id="400"> + <defaultcontrol>406</defaultcontrol> + <hitrect x="460" y="998" w="1000" h="55" /> + <posx>0</posx> + <posy>{{ vscale(116) }}r</posy> + <width>819</width> + + <height>{{ vscale(124) }}</height> + <align>center</align> + <onup>500</onup> + <onright>100</onright> + <itemgap>-40</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>false</usecontrolcoords> + + {% include "includes/music_player_buttons.xml.tpl" %} + +</control> + +<control type="group"> + <posx>0</posx> + <posy>{{ vscale(140) }}r</posy> + <control type="button" id="500"> + <enable>Player.HasAudio</enable> + <hitrect x="0" y="-19" w="819" h="48" /> + <posx>0</posx> + <posy>0</posy> + <width>819</width> + <height>{{ vscale(10) }}</height> + <onup>100</onup> + <ondown>400</ondown> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image" id="510"> + <visible>Control.HasFocus(500)</visible> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>0</posx> + <posy>1</posy> + <width>1</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="progress"> + <visible>!Control.HasFocus(500)</visible> + <description>Progressbar</description> + <posx>0</posx> + <posy>2</posy> + <width>819</width> + <height>{{ vscale(6) }}</height> + <texturebg>script.plex/transparent-6px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFCC7B19">script.plex/white-square-6px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> + <control type="progress"> + <visible>Control.HasFocus(500)</visible> + <description>Progressbar</description> + <posx>0</posx> + <posy>2</posy> + <width>819</width> + <height>{{ vscale(6) }}</height> + <texturebg>script.plex/transparent-6px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFAC5B00">script.plex/white-square-6px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> +</control> + +<!-- <control type="slider"> + <posx>0</posx> + <posy>{{ vscale(942) }}</posy> + <width>819</width> + <height>{{ vscale(6) }}</height> + <visible>true</visible> + <texturesliderbar>-</texturesliderbar> + <textureslidernib colordiffuse="FFE5A00D">script.plex/white-square-6px.png</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <action>seek</action> +</control> --> + +<!-- <control type="image" id="201"> + <visible>!Control.HasFocus(100) + !Control.HasFocus(500)</visible> + <animation effect="fade" time="100" delay="100" end="0">Hidden</animation> + <posx>0</posx> + <posy>{{ vscale(942) }}</posy> + <width>1</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFCC7B19</colordiffuse> +</control> --> + +<control type="group" id="202"> + <visible>Control.HasFocus(500)</visible> + <posx>0</posx> + <posy>{{ vscale(184) }}r</posy> + <control type="group" id="203"> + <posx>-50</posx> + <posy>0</posy> + <control type="image"> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>0</posx> + <posy>0</posy> + <width>101</width> + <height>{{ vscale(39) }}</height> + <texture>script.plex/indicators/player-selection-time_box.png</texture> + <colordiffuse>D0000000</colordiffuse> + </control> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>101</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(time.selection)]</label> + </control> + </control> + <control type="image"> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>-6</posx> + <posy>{{ vscale(39) }}</posy> + <width>15</width> + <height>{{ vscale(7) }}</height> + <texture>script.plex/indicators/player-selection-time_arrow.png</texture> + <colordiffuse>D0000000</colordiffuse> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_player.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_player.xml.tpl new file mode 100644 index 0000000000..a5ba4bf20a --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-music_player.xml.tpl @@ -0,0 +1,293 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>406</defaultcontrol>{% endblock %} +{% block controls %} +{% include "includes/default_background.xml.tpl" with background_source="$INFO[Player.Art(landscape)]" %} + +<control type="image"> + <posx>75</posx> + <posy>{{ vscale(75) }}</posy> + <width>786</width> + <height>{{ vscale(786) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20FFFFFF</colordiffuse> +</control> +<control type="image"> + <posx>90</posx> + <posy>{{ vscale(90) }}</posy> + <width>756</width> + <height>{{ vscale(756) }}</height> + <texture>$INFO[Player.Art(thumb)]</texture> +</control> + +<control type="group"> + <posx>939</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(305) }}</posy> + <width>1000</width> + <height>{{ vscale(54) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[MusicPlayer.Artist]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(359) }}</posy> + <width>1000</width> + <height>{{ vscale(54) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[MusicPlayer.Album]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(470) }}</posy> + <width>1000</width> + <height>{{ vscale(54) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[MusicPlayer.Title][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(580) }}</posy> + <width>1000</width> + <height>{{ vscale(54) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Player.Time]$INFO[MusicPlayer.Duration, / ]</label> + </control> +</control> + +<control type="group"> + <posx>1845</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(738) }}</posy> + <width>1000</width> + <height>{{ vscale(54) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>80FFFFFF</textcolor> + <label>$INFO[MusicPlayer.offset(1).Artist]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(794) }}</posy> + <width>1000</width> + <height>{{ vscale(54) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>80FFFFFF</textcolor> + <label>$INFO[MusicPlayer.offset(1).Title]</label> + </control> +</control> + +<!-- <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(140) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> +</control> + +<control type="group"> + <posx>0</posx> + <posy>{{ vscale(940) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(140) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> +</control> + +<control type="group"> + <posx>0</posx> + <posy>{{ vscale(965) }}</posy> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(time.current)]</label> + </control> + <control type="label"> + <posx>1860</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(time.duration)]</label> + </control> + <control type="label"> + <posx>1860</posx> + <posy>{{ vscale(40) }}</posy> + <width>800</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>A0FFFFFF</textcolor> + <label>$INFO[Window.Property(time.end)]</label> + </control> +</control> --> + +<control type="grouplist" id="400"> + <defaultcontrol>406</defaultcontrol> + <hitrect x="460" y="998" w="1000" h="55" /> + <posx>360</posx> + <posy>{{ vscale(116) }}r</posy> + <width>1200</width> + + <height>{{ vscale(124) }}</height> + <align>center</align> + <onup>100</onup> + <itemgap>-40</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% include "includes/music_player_buttons.xml.tpl" %} + +</control> + +<control type="group"> + <posx>0</posx> + <posy>{{ vscale(140) }}r</posy> + <control type="button" id="100"> + <enable>Player.HasAudio</enable> + <hitrect x="0" y="-19" w="1920" h="48" /> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(10) }}</height> + <ondown>400</ondown> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image" id="200"> + <visible>Control.HasFocus(100)</visible> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>0</posx> + <posy>1</posy> + <width>1</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="progress"> + <visible>!Control.HasFocus(100)</visible> + <description>Progressbar</description> + <posx>0</posx> + <posy>2</posy> + <width>1920</width> + <height>{{ vscale(6) }}</height> + <texturebg>script.plex/transparent-6px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFCC7B19">script.plex/white-square-6px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> + <control type="progress"> + <visible>Control.HasFocus(100)</visible> + <description>Progressbar</description> + <posx>0</posx> + <posy>2</posy> + <width>1920</width> + <height>{{ vscale(6) }}</height> + <texturebg>script.plex/transparent-6px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFAC5B00">script.plex/white-square-6px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> +</control> + +<!-- <control type="slider"> + <posx>0</posx> + <posy>{{ vscale(942) }}</posy> + <width>1920</width> + <height>{{ vscale(6) }}</height> + <visible>true</visible> + <texturesliderbar>-</texturesliderbar> + <textureslidernib colordiffuse="FFE5A00D">script.plex/white-square-6px.png</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <action>seek</action> +</control> --> + +<!-- <control type="image" id="201"> + <visible>!Control.HasFocus(100) + !Control.HasFocus(500)</visible> + <animation effect="fade" time="100" delay="100" end="0">Hidden</animation> + <posx>0</posx> + <posy>{{ vscale(942) }}</posy> + <width>1</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFCC7B19</colordiffuse> +</control> --> + +<control type="group" id="202"> + <visible>Control.HasFocus(100)</visible> + <posx>0</posx> + <posy>{{ vscale(184) }}r</posy> + <control type="group" id="203"> + <posx>-50</posx> + <posy>0</posy> + <control type="image"> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>0</posx> + <posy>0</posy> + <width>101</width> + <height>{{ vscale(39) }}</height> + <texture>script.plex/indicators/player-selection-time_box.png</texture> + <colordiffuse>D0000000</colordiffuse> + </control> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>101</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(time.selection)]</label> + </control> + </control> + <control type="image"> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>-6</posx> + <posy>{{ vscale(39) }}</posy> + <width>15</width> + <height>{{ vscale(7) }}</height> + <texture>script.plex/indicators/player-selection-time_arrow.png</texture> + <colordiffuse>D0000000</colordiffuse> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-options_dialog.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-options_dialog.xml.tpl new file mode 100644 index 0000000000..09abb3090c --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-options_dialog.xml.tpl @@ -0,0 +1,133 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>1001</defaultcontrol>{% endblock %} +{% block backgroundcolor %}{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture colordiffuse="99606060" border="10">script.plex/white-square.png</texture> +</control> +<control type="group"> + <visible>!String.IsEmpty(Window.Property(initialized))</visible> + <posx>585</posx> + <posy>{{ vperc(vscale(440)) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>830</width> + <height>{{ vscale(440) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>750</width> + <height>{{ vscale(360) }}</height> + <texture colordiffuse="EE323232" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>750</width> + <height>{{ vscale(80) }}</height> + <texture colordiffuse="99000000" border="10">script.plex/white-square-top-rounded.png</texture> + </control> + + <control type="image"> + <posx>48</posx> + <posy>{{ vscale(31) }}</posy> + <width>19</width> + <height>{{ vscale(19) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/indicators/circle-19.png</texture> + </control> + + <control type="label"> + <posx>115</posx> + <posy>0</posy> + <width>575</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[Window.Property(header)]</label> + </control> + + <control type="textbox"> + <posx>115</posx> + <posy>{{ vscale(105) }}</posy> + <width>575</width> + <height>{{ vscale(125) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <scrolltime>200</scrolltime> + <autoscroll delay="3000" time="3000" repeat="3000"></autoscroll> + <label>$INFO[Window.Property(info)]</label> + </control> + + <control type="grouplist" id="100"> + <defaultcontrol always="true">1001</defaultcontrol> + <posx>-10</posx> + <posy>{{ vscale(220) }}</posy> + <width>770</width> + <height>{{ vscale(155) }}</height> + <align>center</align> + <itemgap>-50</itemgap> + <orientation>horizontal</orientation> + <scrolltime>0</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + <control type="button" id="1001"> + <visible allowhiddenfocus="true">!String.IsEmpty(Window.Property(button.0))</visible> + <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> + <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <width min="120">auto</width> + <height>{{ vscale(143, 1.1) }}</height> + <font>font10</font> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> + <textoffsetx>70</textoffsetx> + <textcolor>FF000000</textcolor> + <focusedcolor>FF000000</focusedcolor> + <label>$INFO[Window.Property(button.0)]</label> + </control> + <control type="button" id="1002"> + <visible>!String.IsEmpty(Window.Property(button.1))</visible> + <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> + <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <width min="120">auto</width> + <height>{{ vscale(143, 1.1) }}</height> + <font>font10</font> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> + <textoffsetx>70</textoffsetx> + <textcolor>FF000000</textcolor> + <focusedcolor>FF000000</focusedcolor> + <label>$INFO[Window.Property(button.1)]</label> + </control> + <control type="button" id="1003"> + <visible>!String.IsEmpty(Window.Property(button.2))</visible> + <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> + <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <width min="120">auto</width> + <height>{{ vscale(143, 1.1) }}</height> + <font>font10</font> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> + <textoffsetx>70</textoffsetx> + <textcolor>FF000000</textcolor> + <focusedcolor>FF000000</focusedcolor> + <label>$INFO[Window.Property(button.2)]</label> + </control> + </control> + +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-photo.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-photo.xml.tpl new file mode 100644 index 0000000000..181120c0d9 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-photo.xml.tpl @@ -0,0 +1,670 @@ +{% extends "base.xml.tpl" %} +{% block headers %} + <defaultcontrol>250</defaultcontrol> + <zorder>100</zorder> +{% endblock %} + +{% block controls %} +<control type="group"> + {% include "includes/default_background.xml.tpl" %} + <control type="image" id="600"> + <!-- Doesn't work for all aspects --> + <!-- <animation effect="zoom" start="56" end="100" time="200" center="960,540" reversible="false" condition="String.IsEqual(Window.Property(rotate),90) | String.IsEqual(Window.Property(rotate),270)">Conditional</animation> + <animation effect="zoom" start="178" end="100" time="200" center="960,540" reversible="false" condition="String.IsEqual(Window.Property(rotate),0) | String.IsEqual(Window.Property(rotate),180)">Conditional</animation> --> + <animation effect="rotate" time="200" start="0" end="90" center="960,540" reversible="false" condition="Integer.IsGreater(Window.Property(rotate),89)">Conditional</animation> + <animation effect="rotate" time="200" start="0" end="90" center="960,540" reversible="false" condition="Integer.IsGreater(Window.Property(rotate),179)">Conditional</animation> + <animation effect="rotate" time="200" start="0" end="90" center="960,540" reversible="false" condition="Integer.IsGreater(Window.Property(rotate),269)">Conditional</animation> + <animation effect="rotate" time="200" start="270" end="360" center="960,540" reversible="false" condition="!Integer.IsGreater(Window.Property(rotate),89)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <fadetime>1000</fadetime> + <texture background="true">$INFO[Window.Property(photo)]</texture> + <aspectratio>keep</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(is.updating))</visible> + <animation effect="fade" time="500" delay="500">VisibleChange</animation> + <control type="image"> + <posx>840</posx> + <posy>465</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/busy-back.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + <control type="image"> + <posx>915</posx> + <posy>521</posy> + <width>90</width> + <height>{{ vscale(38) }}</height> + <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> + </control> + </control> +</control> +<control type="togglebutton" id="250"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <usealttexture>!String.IsEmpty(Window.Property(OSD))</usealttexture> + <alttexturefocus>-</alttexturefocus> + <alttexturenofocus>-</alttexturenofocus> + <label> </label> + <onclick>SetProperty(OSD,1)</onclick> + <onclick>SetFocus(406)</onclick> + <altclick>SetProperty(OSD,)</altclick> + <ondown>SetProperty(OSD,1)</ondown> + <ondown>SetFocus(400)</ondown> + <ondown>SetFocus(406)</ondown> + <onfocus condition="!String.IsEmpty(Window.Property(show.pqueue))">SetFocus(501)</onfocus> + <onfocus condition="!String.IsEmpty(Window.Property(OSD))">SetFocus(400)</onfocus> +</control> +<control type="group" id="200"> + <animation effect="slide" start="0,0" end="0,{{ vscale(-135) }}" time="100" condition="!String.IsEmpty(Window.Property(show.pqueue))">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <visible allowhiddenfocus="true">!String.IsEmpty(Window.Property(OSD))</visible> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(140) }}r</posy> + <width>1920</width> + <height>{{ vscale(140) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="grouplist" id="400"> + <defaultcontrol>406</defaultcontrol> + <hitrect x="460" y="998" w="1000" h="55" /> + <posx>360</posx> + <posy>{{ vscale(116) }}r</posy> + <width>1200</width> + + <height>{{ vscale(124) }}</height> + <align>center</align> + <onup>250</onup> + <onup>SetProperty(OSD,)</onup> + <ondown>250</ondown> + <onup>SetProperty(OSD,)</onup> + <itemgap>-40</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + <control type="togglebutton" id="401"> + <visible>String.IsEmpty(Window.Property(no.playlist))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}repeat.png</texturenofocus> + <usealttexture>!String.IsEmpty(Window.Property(pq.repeat))</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}repeat.png</alttexturenofocus> + <label> </label> + </control> + <control type="button" id="421"> + <enable>false</enable> + <visible>!String.IsEmpty(Window.Property(no.playlist))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}shuffle.png</texturenofocus> + <label> </label> + </control> + + <control type="togglebutton" id="402"> + <visible>String.IsEmpty(Window.Property(no.playlist))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle.png</texturenofocus> + <usealttexture>!String.IsEmpty(Window.Property(pq.shuffled))</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}shuffle.png</alttexturenofocus> + <label> </label> + </control> + <control type="button" id="422"> + <enable>false</enable> + <visible>!String.IsEmpty(Window.Property(no.playlist))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}shuffle.png</texturenofocus> + <label> </label> + </control> + + <control type="button" id="403"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}rotate{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}rotate.png</texturenofocus> + <label> </label> + </control> + + + <control type="button" id="404"> + <visible>String.IsEmpty(Window.Property(hide.prev))</visible> + <hitrect x="58" y="28" w="69" h="45" /> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true"{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus flipx="true"{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="424"> + <enable>false</enable> + <visible>!String.IsEmpty(Window.Property(hide.prev))</visible> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true" colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus flipx="true" colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="togglebutton" id="406"> + {% if theme.buttons.zoomPlayButton %} + <animation effect="zoom" start="100" end="124" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="Control.HasFocus(406)">Conditional</animation> + <animation effect="zoom" start="124" end="100" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="!Control.HasFocus(406)">Conditional</animation> + {% endif %} + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}play{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}play.png</texturenofocus> + <usealttexture>!String.IsEmpty(Window.Property(playing))</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}pause{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}pause.png</alttexturenofocus> + <label> </label> + </control> + <control type="button" id="407"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}stop{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}stop.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="409"> + <visible>String.IsEmpty(Window.Property(hide.next))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="419"> + <enable>false</enable> + <visible>!String.IsEmpty(Window.Property(hide.next))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texturefocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + + + <control type="togglebutton" id="412"> + <hitrect x="58" y="28" w="69" h="45" /> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}square2x2{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}square2x2.png</texturenofocus> + <usealttexture>!String.IsEmpty(Window.Property(show.pqueue))</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}square2x2{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}square2x2{{ theme.assets.buttons.focusSuffix }}.png</alttexturenofocus> + <onclick>SetProperty(show.pqueue,1)</onclick> + <altclick>SetProperty(show.pqueue,)</altclick> + <label> </label> + </control> + <control type="togglebutton" id="413"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}info{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}info.png</texturenofocus> + <usealttexture>!String.IsEmpty(Window.Property(show.info))</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}info{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}info{{ theme.assets.buttons.focusSuffix }}.png</alttexturenofocus> + <onclick>SetProperty(show.info,1)</onclick> + <altclick>SetProperty(show.info,)</altclick> + <label> </label> + </control> + <control type="button" id="414"> + <visible>false</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}tags{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}tags.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="411"> + <visible>false</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}more{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}more.png</texturenofocus> + <label> </label> + </control> + </control> + </control> + + <control type="button" id="501"> + <posx>0</posx> + <posy>1080</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <onup>SetProperty(OSD,1)</onup> + <onup>400</onup> + <font>font12</font> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + <onclick>SetProperty(OSD,1)</onclick> + <onclick>SetFocus(400)</onclick> + </control> + + <control type="image"> + <posx>0</posx> + <posy>1080</posy> + <width>1920</width> + <height>135</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="fixedlist" id="500"> + <posx>0</posx> + <posy>1080</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <hitrect x="28" y="28" w="69" h="45" /> + + <scrolltime>0</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <focusposition>7</focusposition> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="128"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>2.5</posx> + <posy>6</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>123</width> + <height>{{ vscale(123) }}</height> + <texture>script.plex/thumb_fallbacks/photo.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>123</width> + <height>{{ vscale(123) }}</height> + <texture fallback="script.plex/thumb_fallbacks/broken-photo-thumb.png" background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="128"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>2.5</posx> + <posy>6</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>123</width> + <height>{{ vscale(123) }}</height> + <texture>script.plex/thumb_fallbacks/photo.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>123</width> + <height>{{ vscale(123) }}</height> + <texture fallback="script.plex/thumb_fallbacks/broken-photo-thumb.png" background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + </control> + </control> + </focusedlayout> + </control> + <control type="image"> + <posx>892.5</posx> + <posy>1080</posy> + <width>135</width> + <height>{{ vscale(135) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window.Property(show.info))</visible> + <posx>1470</posx> + <posy>0</posy> + <width>450</width> + <height>1080</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>450</width> + <height>1080</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>4C000000</colordiffuse> + </control> + <control type="grouplist"> + <posx>0</posx> + <posy>0</posy> + <width>450</width> + <height>1080</height> + <itemgap>0</itemgap> + <orientation>vertical</orientation> + + <control type="button"> + <!-- margin --> + <width>450</width> + <height>{{ vscale(21) }}</height> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <colordiffuse>00000000</colordiffuse> + <label> </label> + </control> + <control type="button" id="650"> + <width>450</width> + <height>{{ vscale(37) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>00000000</colordiffuse> + <align>left</align> + <align>center</align> + <textoffsetx>28</textoffsetx> + <font>font12</font> + <label>[B]$INFO[Window.Property(photo.title)][/B]</label> + </control> + <control type="button" id="659"> + <width>450</width> + <height>{{ vscale(37) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>00000000</colordiffuse> + <align>left</align> + <align>center</align> + <textoffsetx>28</textoffsetx> + <font>font12</font> + <label>$INFO[Window.Property(photo.date)]</label> + </control> + <control type="button"> + <!-- margin --> + <width>450</width> + <height>{{ vscale(21) }}</height> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <colordiffuse>00000000</colordiffuse> + <label> </label> + </control> + + <control type="button"> + <!-- margin --> + <width>450</width> + <height>{{ vscale(21) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <label> </label> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(camera.model))</visible> + <width>450</width> + <height>{{ vscale(37) }}</height> + <control type="button"> + <posx>0</posx> + <posy>0</posy> + <width>450</width> + <height>{{ vscale(37) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <align>left</align> + <align>center</align> + <textoffsetx>28</textoffsetx> + <font>font12</font> + <label>$INFO[Window.Property(camera.model)]</label> + </control> + <control type="image"> + <posx>393</posx> + <posy>6</posy> + <width>29</width> + <height>{{ vscale(24) }}</height> + <texture>script.plex/indicators/camera.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + </control> + <control type="button"> + <visible>!String.IsEmpty(Window.Property(camera.lens))</visible> + <width>450</width> + <height>{{ vscale(37) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <align>left</align> + <align>center</align> + <textoffsetx>28</textoffsetx> + <font>font12</font> + <label>$INFO[Window.Property(camera.lens)]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(photo.container))</visible> + <posx>0</posx> + <posy>0</posy> + <width>450</width> + <height>{{ vscale(37) }}</height> + <control type="button"> + <posx>0</posx> + <posy>0</posy> + <width>450</width> + <height>{{ vscale(37) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <align>left</align> + <align>center</align> + <textoffsetx>28</textoffsetx> + <font>font12</font> + <label>$INFO[Window.Property(photo.dims)]</label> + </control> + <control type="grouplist"> + <right>28</right> + <posy>5</posy> + <width>200</width> + <height>{{ vscale(26) }}</height> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <align>right</align> + <control type="button"> + <width>auto</width> + <height>{{ vscale(26) }}</height> + <font>font10</font> + <align>center</align> + <aligny>top</aligny> + <focusedcolor>FF000000</focusedcolor> + <textcolor>FF000000</textcolor> + <textoffsetx>5</textoffsetx> + <textoffsety>-3</textoffsety> + <texturefocus colordiffuse="A0FFFFFF" border="12">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus colordiffuse="A0FFFFFF" border="12">script.plex/white-square-rounded.png</texturenofocus> + <label>[UPPERCASE]$INFO[Window.Property(photo.container)][/UPPERCASE]</label> + </control> + </control> + </control> + <control type="button"> + <!-- margin --> + <width>450</width> + <height>{{ vscale(21) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <label> </label> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(camera.settings))</visible> + <width>450</width> + <height>{{ vscale(80) }}</height> + <!-- sep --> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>450</width> + <height>{{ vscale(1) }}</height> + <texture border="30,0,30,0">script.plex/indicators/info-sep.png</texture> + <colordiffuse>99000000</colordiffuse> + </control> + <control type="image"> + <posx>28</posx> + <posy>0</posy> + <width>394</width> + <height>{{ vscale(1) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>999B9B9B</colordiffuse> + </control> + <control type="button"> + <!-- margin --> + <posx>0</posx> + <posy>1</posy> + <width>450</width> + <height>{{ vscale(21) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <label> </label> + </control> + <control type="button"> + <posx>0</posx> + <posy>{{ vscale(22) }}</posy> + <width>450</width> + <height>{{ vscale(37) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <align>left</align> + <align>center</align> + <textoffsetx>28</textoffsetx> + <font>font12</font> + <label>$INFO[Window.Property(camera.settings)]</label> + </control> + <control type="button"> + <!-- margin --> + <posx>0</posx> + <posy>{{ vscale(59) }}</posy> + <width>450</width> + <height>{{ vscale(21) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>99000000</colordiffuse> + <label> </label> + </control> + </control> + + <control type="group"> + <visible>!String.IsEmpty(Window.Property(photo.summary))</visible> + <width>450</width> + <height>{{ vscale(152) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>450</width> + <height>{{ vscale(152) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>661F1F1F</colordiffuse> + </control> + <control type="textbox"> + <posx>28</posx> + <posy>{{ vscale(24) }}</posy> + <width>394</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <label>$INFO[Window.Property(photo.summary)]</label> + </control> + </control> + + <!-- <control type="button"> + <width>450</width> + <height>{{ vscale(147) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>66000000</colordiffuse> + <font>font12</font> + </control> + <control type="button"> + <width>450</width> + <height>{{ vscale(150) }}</height> + <texturefocus>script.plex/white-square.png</texturefocus> + <texturenofocus>script.plex/white-square.png</texturenofocus> + <colordiffuse>661F1F1F</colordiffuse> + <font>font12</font> + </control> --> + </control> +</control> +{% endblock %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pin_login.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pin_login.xml.tpl new file mode 100644 index 0000000000..9ad928c203 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pin_login.xml.tpl @@ -0,0 +1,79 @@ +{% extends "base.xml.tpl" %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> +</control> +<control type="image"> + <visible>!String.IsEmpty(Window.Property(pin.image.0))</visible> + <posx>0</posx> + <posy>{% if core.needs_scaling %}{{ vperc(vscale(1080)) }}{% else %}0{% endif %}</posy> + <width>1920</width> + <height>{{ vscale(1080) }}</height> + <texture>script.plex/sign_in/pin-display.jpg</texture> +</control> +<control type="image"> + <visible>String.IsEmpty(Window.Property(pin.image.0)) + String.IsEmpty(Window.Property(linking))</visible> + <posx>0</posx> + <posy>{% if core.needs_scaling %}{{ vperc(vscale(1080)) }}{% else %}0{% endif %}</posy> + <width>1920</width> + <height>{{ vscale(1080) }}</height> + <texture>script.plex/sign_in/generating-code.jpg</texture> +</control> +<control type="image"> + <visible>!String.IsEmpty(Window.Property(linking))</visible> + <posx>0</posx> + <posy>{% if core.needs_scaling %}{{ vperc(vscale(1080)) }}{% else %}0{% endif %}</posy> + <width>1920</width> + <height>{{ vscale(1080) }}</height> + <texture>script.plex/sign_in/linking-account.jpg</texture> +</control> + +<control type="label"> + <posx>270</posx> + <posy>{{ vscale(738) }}</posy> + <width>800</width> + <height>{{ vscale(153) }}</height> + <font>WeatherTemp</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(pin)]</label> +</control> + +<control type="grouplist" id="400"> + <defaultcontrol>406</defaultcontrol> + <posx>265</posx> + <posy>{{ vscale(708) }}</posy> + <width>1000</width> + + <height>{{ vscale(200) }}</height> + <align>left</align> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <control type="image"> + <width>200</width> + <height>{{ vscale(200) }}</height> + <texture>$INFO[Window.Property(pin.image.0)]</texture> + </control> + <control type="image"> + <width>200</width> + <height>{{ vscale(200) }}</height> + <texture>$INFO[Window.Property(pin.image.1)]</texture> + </control> + <control type="image"> + <width>200</width> + <height>{{ vscale(200) }}</height> + <texture>$INFO[Window.Property(pin.image.2)]</texture> + </control> + <control type="image"> + <width>200</width> + <height>{{ vscale(200) }}</height> + <texture>$INFO[Window.Property(pin.image.3)]</texture> + </control> + +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlist.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlist.xml.tpl new file mode 100644 index 0000000000..716e16dcb1 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlist.xml.tpl @@ -0,0 +1,581 @@ +{% extends "default.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block content %} +<control type="group" id="50"> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>101</defaultcontrol> + + <control type="group"> + <posx>60</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>5</posy> + <width>420</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(playlist.title)]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(60) }}</posy> + <width>420</width> + <height>{{ vscale(40) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(playlist.duration)]</label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(142) }}</posy> + <width>630</width> + <height>{{ vscale(630) }}</height> + <texture>$INFO[Window.Property(playlist.thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + </control> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <defaultcontrol always="true">303</defaultcontrol> + <posx>50</posx> + <posy>{{ vscale(784) }}</posy> + <width>650</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <onright>101</onright> + <itemgap>-50</itemgap> + <orientation>horizontal</orientation> + <align>center</align> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = {"width": 174, "height": 139} & template = "includes/themed_button.xml.tpl" & hitrect = {"w": 94, "h": 59} %} + {% include template with name="play" & id=301 %} + {% include template with name="shuffle" & id=302 %} + {% include template with name="more" & id=303 & visible="!String.IsEmpty(Window.Property(show.options)) | Player.HasAudio" %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>750</posx> + <posy>0</posy> + <width>1170</width> + <height>1080</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>1080</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>20000000</colordiffuse> + </control> + <control type="list" id="101"> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>{{ vscale(945) }}</height> + <onup>200</onup> + <onright>152</onright> + <onleft>300</onleft> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>4</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(100) }}"> + <control type="group"> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(track.ID)) | !String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(track.ID)) + String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>2</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>168</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>132</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=132+63 & yoff=11 & uw_posy=11 & uw_size=24 & with_count=True & scale="tiny" %} + + <control type="group"> + <posx>226</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="label"> + <posx>730</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="group"> + <!-- Don't show the progress bar in the playlist because we don't start from the resume point so why show it --> + <visible>False <!-- !String.IsEmpty(ListItem.Property(progress)) --></visible> + <posx>63</posx> + <posy>{{ vscale(85) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>870</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>870</width> + <height>{{ vscale(6) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(97) }}</posy> + <width>930</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="{{ vscale(100) }}"> + <control type="group"> + <control type="group"> + <visible>!Control.HasFocus(101)</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(track.ID)) | !String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(track.ID)) + String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>0</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>168</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>132</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=132+63 & yoff=11 & uw_posy=11 & uw_size=24 & with_count=True & scale="tiny" %} + <control type="group"> + <posx>226</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="label"> + <posx>730</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>63</posx> + <posy>{{ vscale(88) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>870</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>870</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(97) }}</posy> + <width>930</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <posx>63</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>1124</width> + <height>{{ vscale(180) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1044</width> + <height>{{ vscale(100) }}</height> + <texture border="12">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <!-- comment the previous and uncomment the following for re-enabling options button --> + <!--<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>999</width> + <height>{{ vscale(100) }}</height> + <texture border="12">script.plex/white-square-left-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="image"> + <posx>999</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(100) }}</height> + <texture>script.plex/buttons/more-vertical.png</texture> + <colordiffuse>99FFFFFF</colordiffuse> + </control>--> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(track.ID)) | !String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>24</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(track.ID)) + String.IsEqual(ListItem.Property(track.ID),Window(10000).Property(script.plex.track.ID))</visible> + <posx>36</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <posx>103</posx> + <posy>0</posy> + <width>100</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>235</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>638</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(51) }}</posy> + <width>638</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>98000000</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>103</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=178+103 & with_count=True %} + + <control type="group"> + <posx>313</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>510</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(51) }}</posy> + <width>510</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>98000000</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="label"> + <posx>802</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>103</posx> + <posy>{{ vscale(91) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>899</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>899</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + </control> + </control> + + </focusedlayout> + </control> + + <control type="scrollbar" id="152"> + <hitrect x="1108" y="33" w="90" h="879" /> + <left>1128</left> + <top>33</top> + <width>10</width> + <height>{{ vscale(879) }}</height> + <onleft>101</onleft> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlists.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlists.xml.tpl new file mode 100644 index 0000000000..fbb8bf4978 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-playlists.xml.tpl @@ -0,0 +1,363 @@ +{% extends "default.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block header_bgfade %}{% endblock %} +{% block topleft_add %} +<control type="label"> + <width max="500">auto</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32333][/UPPERCASE]</label> +</control> +{% endblock %} +{% block content %} +<control type="group"> + <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true" fallback="script.plex/home/background-fallback_black.png">$INFO[Window.Property(background_static)]</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <fadetime>1000</fadetime> + <texture background="true">$INFO[Window.Property(background)]</texture> + </control> +</control> + +<control type="group" id="50"> + <posx>0</posx> + <posy>{{ vscale(115) }}</posy> + <defaultcontrol always="true">101</defaultcontrol> + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(360) }}</height> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32048][/UPPERCASE]</label> + </control> + <control type="list" id="101"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>{{ vscale(390) }}</height> + <onup>200</onup> + <ondown>301</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>2</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="298"> + <control type="group"> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <control type="group"> + <posx>21</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(238) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(238) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(248) }}</posy> + <width>298</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(278) }}</posy> + <width>298</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="298"> + <control type="group"> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="116" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="116" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>-19</posx> + <posy>{{ vscale(-19) }}</posy> + <width>318</width> + <height>{{ vscale(318) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>21</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(238) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>238</width> + <height>{{ vscale(238) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(248) }}</posy> + <width>298</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(278) }}</posy> + <width>298</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>16</posx> + <posy>{{ vscale(16) }}</posy> + <width>248</width> + <height>{{ vscale(248) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="300"> + <visible>Integer.IsGreater(Container(301).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <animation effect="slide" end="0,{{ vscale(-420) }}" condition="!Control.IsVisible(100)">Conditional</animation> + <defaultcontrol>301</defaultcontrol> + <posx>0</posx> + <posy>{{ vscale(445) }}</posy> + <width>1920</width> + <height>{{ vscale(360) }}</height> + <control type="image"> + <visible>Control.IsVisible(100)</visible> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>661F1F1F</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32053][/UPPERCASE]</label> + </control> + <control type="list" id="301"> + <posx>-21.5</posx> + <posy>{{ vscale(30) }}</posy> + <width>1941.5</width> + <height>{{ vscale(700) }}</height> + <onup>101</onup> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>2</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="602"> + <control type="group"> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <control type="group"> + <posx>41.5</posx> + <posy>{{ vscale(25.5) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>537</width> + <height>{{ vscale(303) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>537</width> + <height>{{ vscale(303) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(313) }}</posy> + <width>597</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(343) }}</posy> + <width>597</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="602"> + <control type="group"> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="310,{{ vscale(177) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="310,{{ vscale(177) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(301)</visible> + <posx>1.5</posx> + <posy>{{ vscale(-15.5) }}</posy> + <width>617</width> + <height>{{ vscale(383) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>41.5</posx> + <posy>{{ vscale(25.5) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>537</width> + <height>{{ vscale(303) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>537</width> + <height>{{ vscale(303) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(313) }}</posy> + <width>597</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>-30</posx> + <posy>{{ vscale(343) }}</posy> + <width>597</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(301)</visible> + <posx>36.5</posx> + <posy>{{ vscale(20.5) }}</posy> + <width>547</width> + <height>{{ vscale(313) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-plex_pass.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-plex_pass.xml.tpl new file mode 100644 index 0000000000..77da59379d --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-plex_pass.xml.tpl @@ -0,0 +1,29 @@ +{% extends "base.xml.tpl" %}{# this template is unused at the moment #} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/sign_in/plexpass.jpg</texture> +</control> + +<control type="button" id="100"> + <posx>1436</posx> + <posy>{{ vscale(802) }}</posy> + <width>275</width> + <height>{{ vscale(100) }}</height> + <onup>200</onup> + <font>font13</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters-small.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters-small.xml.tpl new file mode 100644 index 0000000000..fcab6d7c88 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters-small.xml.tpl @@ -0,0 +1,385 @@ +{% extends "library_posters.xml.tpl" %} +{% block header_animation %}<animation effect="slide" end="0,{{ vscale(-135, negpos=True) }}" time="200" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),9) + !ControlGroup(200).HasFocus(0)">Conditional</animation>{% endblock %} +{% block header_bg %} +<control type="image"> + <animation effect="fade" start="0" end="100" time="200" tween="quadratic" easing="out" reversible="true">VisibleChange</animation> + <visible>ControlGroup(200).HasFocus(0) + Integer.IsGreater(Container(101).ListItem.Property(index),9)</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> +</control> +{% endblock %} +{% block content %} +<control type="group" id="50"> + <animation effect="slide" time="200" end="0,-218" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),9)">Conditional</animation> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <visible>!Integer.IsGreater(Container(101).ListItem.Property(index),9) + String.IsEmpty(Window.Property(no.content)) + String.IsEmpty(Window.Property(no.content.filtered)) + !String.IsEmpty(Window.Property(initialized))</visible> + <defaultcontrol>301</defaultcontrol> + <posx>30</posx> + <posy>{{ vscale(-25) }}</posy> + <width>1000</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>101</ondown> + <itemgap>-20</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = {"width": 126, "height": 100} & template = "includes/themed_button.xml.tpl" & hitrect = {"x": 20, "y": 20, "w": 86, "h": 60} %} + {% include template with name="play" & id=301 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="shuffle" & id=302 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="more" & id=303 & visible="String.IsEmpty(Window.Property(no.options)) | Player.HasAudio" %} + {% include template with name="chapters" & id=304 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>0</posx> + <posy>{{ vscale(-35) }}</posy> + <width>1920</width> + <height>1080</height> + <control type="panel" id="101"> + <hitrect x="0" y="95" w="1780" h="1185" /> + <posx>0</posx> + <posy>0</posy> + <width>1800</width> + <height>1190</height> + <onup>300</onup> + <onright>151</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>2</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="176" height="{{ vscale(270) }}"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(137) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>144</width> + <height>{{ vscale(213) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>144</width> + <height>{{ vscale(213) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(203) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>144</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>144</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=144 & uw_size=29 & with_count=True & scale="small" %} + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(subtitle)) + !String.IsEmpty(ListItem.Property(year))</visible> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(218) }}</posy> + <width>144</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label] ($INFO[ListItem.Property(year)])</label> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(subtitle)) + String.IsEmpty(ListItem.Property(year))</visible> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(218) }}</posy> + <width>144</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(subtitle))</visible> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(218) }}</posy> + <width>144</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(subtitle)]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="176" height="{{ vscale(270) }}"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(137) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(185) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(185) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>234</width> + <height>{{ vscale(316) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>144</width> + <height>{{ vscale(213) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>144</width> + <height>{{ vscale(213) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(203) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>144</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>144</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=144 & uw_size=29 & with_count=True & scale="small" %} + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(subtitle)) + !String.IsEmpty(ListItem.Property(year))</visible> + <scroll>true</scroll> + <posx>0</posx> + <posy>{{ vscale(218) }}</posy> + <width>144</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label] ($INFO[ListItem.Property(year)])</label> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(subtitle)) + String.IsEmpty(ListItem.Property(year))</visible> + <scroll>true</scroll> + <posx>0</posx> + <posy>{{ vscale(218) }}</posy> + <width>144</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(subtitle))</visible> + <scroll>true</scroll> + <posx>0</posx> + <posy>{{ vscale(218) }}</posy> + <width>144</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(subtitle)] - $INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>0</posx> + <posy>0</posy> + <width>154</width> + <height>{{ vscale(225) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + +</control> + +<control type="group" id="150"> + <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>151</defaultcontrol> + <posx>1810</posx> + <posy>{{ vscale(150) }}</posy> + <width>20</width> + <height>920</height> + <control type="list" id="151"> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>1050</height> + <onleft>100</onleft> + <onright>152</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(34) }}</height> + <colordiffuse>FFE5A00D</colordiffuse> + <texture border="12">script.plex/white-outline-rounded.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> +</control> + +<control type="scrollbar" id="152"> + <hitrect x="1820" y="150" w="100" h="910" /> + <left>1860</left> + <top>{{ vscale(150) }}</top> + <width>12</width> + <height>910</height> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters.xml.tpl new file mode 100644 index 0000000000..224643af14 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-posters.xml.tpl @@ -0,0 +1,346 @@ +{% extends "library_posters.xml.tpl" %} +{% block content %} +<control type="group" id="50"> + <animation effect="slide" time="200" end="0,{{ vscale(-115, negpos=True) }}" tween="quadratic" easing="out" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5)">Conditional</animation> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <visible>!Integer.IsGreater(Container(101).ListItem.Property(index),5) + String.IsEmpty(Window.Property(no.content)) + String.IsEmpty(Window.Property(no.content.filtered)) + !String.IsEmpty(Window.Property(initialized))</visible> + <defaultcontrol>301</defaultcontrol> + <posx>30</posx> + <posy>{{ vscale(-25) }}</posy> + <width>1000</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>101</ondown> + <itemgap>-20</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = {"width": 126, "height": 100} & template = "includes/themed_button.xml.tpl" & hitrect = {"x": 20, "y": 20, "w": 86, "h": 60} %} + {% include template with name="play" & id=301 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="shuffle" & id=302 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="more" & id=303 & visible="String.IsEmpty(Window.Property(no.options)) | Player.HasAudio" %} + {% include template with name="chapters" & id=304 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>0</posx> + <posy>{{ vscale(-35) }}</posy> + <width>1920</width> + <height>1080</height> + <control type="panel" id="101"> + <hitrect x="0" y="95" w="1780" h="1185" /> + <posx>0</posx> + <posy>0</posy> + <width>1800</width> + <height>1190</height> + <onup>300</onup> + <onright>151</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>2</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287" height="{{ vscale(460) }}"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(137) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=45 & with_count=True & scale="medium" %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(year))</visible> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(396) }}</posy> + <width>244</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(year)]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287" height="{{ vscale(460) }}"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(137) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(185) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(185) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(451) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=45 & with_count=True & scale="medium" %} + <control type="label"> + <scroll>true</scroll> + <posx>0</posx> + <posy>{{ vscale(371) }}</posy> + <width>244</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Property(year))</visible> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(396) }}</posy> + <width>244</width> + <height>{{ vscale(72) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Property(year)]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + +</control> + +<control type="group" id="150"> + <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>151</defaultcontrol> + <posx>1780</posx> + <posy>{{ vscale(150) }}</posy> + <width>20</width> + <height>920</height> + <control type="list" id="151"> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>1050</height> + <onleft>100</onleft> + <onright>152</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(34) }}</height> + <colordiffuse>FFE5A00D</colordiffuse> + <texture border="12">script.plex/white-outline-rounded.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> +</control> + +<control type="scrollbar" id="152"> + <hitrect x="1820" y="150" w="100" h="910" /> + <left>1860</left> + <top>{{ vscale(150) }}</top> + <width>12</width> + <height>910</height> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_play.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_play.xml.tpl new file mode 100644 index 0000000000..504e85b3d9 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_play.xml.tpl @@ -0,0 +1,1076 @@ +{% extends "default.xml.tpl" %} +{% block content %} +<control type="group" id="50"> + <animation effect="slide" end="0,{{ vscale(-300) }}" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <posx>0</posx> + <posy>{{ vscale(155) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <visible>!String.IsEmpty(Window.Property(initialized))</visible> + <defaultcontrol>302</defaultcontrol> + <posx>428</posx> + <posy>{{ vscale(410) }}</posy> + <width>1000</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>400</ondown> + <itemgap>{{ theme.pre_play.buttongroup.itemgap }}</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = theme.pre_play.buttons & template = "includes/themed_button.xml.tpl" %} + {% include template with name="info" & id=304 %} + {% include template with name="play" & id=302 & visible="String.IsEmpty(Window.Property(unavailable))" %} + {% include template with name="trailer" & id=303 & visible="!String.IsEmpty(Window.Property(trailer.button))" %} + {% include template with name="media" & id=307 & visible="!String.IsEmpty(Window.Property(media.multiple))" %} + {% include template with name="settings" & id=305 %} + {% include template with name="more" & id=306 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(600) }}</height> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(preview.no))</visible> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>347</width> + <height>{{ vscale(518) }}</height> + <texture background="true">script.plex/thumb_fallbacks/movie.png</texture> + <animation effect="fade" start="0" end="100" time="0" delay="500">WindowOpen</animation> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>347</width> + <height>{{ vscale(518) }}</height> + <texture background="true">$INFO[Window.Property(thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with itemref="Window" & xoff=347+60 & uw_size=48 & scale="medium" %} + + </control> + + <control type="group"> + <visible>!String.IsEmpty(Window.Property(preview.yes))</visible> + <posx>60</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>347</width> + <height>{{ vscale(315) }}</height> + <texture background="true">script.plex/thumb_fallbacks/show.png</texture> + <animation effect="fade" start="0" end="100" time="0" delay="500">WindowOpen</animation> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(323) }}</posy> + <width>347</width> + <height>{{ vscale(195) }}</height> + <texture colordiffuse="FF111111">script.plex/white-square.png</texture> + <aspectratio>scale</aspectratio> + </control> + + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>347</width> + <height>{{ vscale(315) }}</height> + <texture background="true">$INFO[Window.Property(thumb)]</texture> + <aspectratio aligny="top">scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(323) }}</posy> + <width>347</width> + <height>{{ vscale(195) }}</height> + <texture background="true">$INFO[Window.Property(preview)]</texture> + <aspectratio>scale</aspectratio> + </control> + </control> + <control type="grouplist"> + <posx>466</posx> + <posy>0</posy> + <width>1226</width> + <height>{{ vscale(60) }}</height> + <align>left</align> + <itemgap>0</itemgap> + <scroll>true</scroll> + <scrollspeed>5</scrollspeed> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="label"> + <width>auto</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(title)]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Window.Property(remainingTime))</visible> + <posx>10</posx> + <posy>6</posy> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFE5A00D</focusedcolor> + <textcolor>FFE5A00D</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>$INFO[Window.Property(remainingTime)]</label> + </control> + </control> + <control type="grouplist"> + <posx>466</posx> + <posy>{{ vscale(68) }}</posy> + <width>1360</width> + <height>{{ vscale(34) }}</height> + <align>left</align> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="label"> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(duration)]$INFO[Window.Property(info), • ]$INFO[Window.Property(date), • ]$INFO[Window.Property(content.rating), • ]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Window.Property(video.res))</visible> + <posx>10</posx> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>$INFO[Window.Property(video.res)]$INFO[Window.Property(video.rendering), • ]$INFO[Window.Property(video.codec), • ]$INFO[Window.Property(audio.codec), • ]$INFO[Window.Property(audio.channels), • ]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Window.Property(unavailable))</visible> + <posx>10</posx> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="FFAC3223" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="FFAC3223" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>$ADDON[script.plexmod 32312]</label> + </control> + </control> + + <control type="grouplist"> + <visible>!String.IsEmpty(Window.Property(rating)) | !String.IsEmpty(Window.Property(rating2))</visible> + <posx>1426</posx> + <posy>4</posy> + <width>434</width> + <height>{{ vscale(32) }}</height> + <align>right</align> + <itemgap>15</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(rating))</visible> + <posy>2</posy> + <width>63</width> + <height>{{ vscale(30) }}</height> + <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating.image)]</texture> + <aspectratio align="right">keep</aspectratio> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(rating))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(rating)]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(rating2))</visible> + <posy>2</posy> + <width>40</width> + <height>{{ vscale(30) }}</height> + <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating2.image)]</texture> + <aspectratio align="right">keep</aspectratio> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(rating2))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(rating2)]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(rating.stars))</visible> + <posy>6</posy> + <width>134</width> + <height>{{ vscale(22) }}</height> + <texture>script.plex/stars/$INFO[Window.Property(rating.stars)].png</texture> + </control> + </control> + + <control type="label"> + <visible>!String.IsEmpty(Window.Property(directors)) | !String.IsEmpty(Window.Property(writers))</visible> + <posx>466</posx> + <posy>{{ vscale(130) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[Window.Property(directors)]$INFO[Window.Property(writers)]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(cast))</visible> + <posx>466</posx> + <posy>{{ vscale(165) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[Window.Property(cast)]</label> + </control> + <control type="grouplist"> + <posx>466</posx> + <posy>{{ vscale(223) }}</posy> + <width>1360</width> + <height>{{ vscale(34) }}</height> + <align>left</align> + <itemgap>15</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="button"> + <visible>!String.IsEmpty(Window.Property(audio))</visible> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>[UPPERCASE]$ADDON[script.plexmod 32048][/UPPERCASE]</label> + </control> + <control type="label"> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(audio)]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Window.Property(subtitles))</visible> + <left>30</left> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="8">script.plex/white-square-rounded-top-padded.png</texturenofocus> + <label>[UPPERCASE]$ADDON[script.plexmod 32396][/UPPERCASE]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(subtitles))</visible> + <width>auto</width> + <height>{{ vscale(34) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(subtitles)]</label> + </control> + </control> + <control type="textbox"> + <posx>466</posx> + <posy>{{ vscale(290) }}</posy> + <width>1360</width> + <height>{{ vscale(102) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <scrolltime>200</scrolltime> + <autoscroll delay="2000" time="2000" repeat="10000">!Control.HasFocus(13)</autoscroll> + <label>$INFO[Window.Property(summary)]</label> + </control> + <control type="image" id="250"> + <animation effect="zoom" start="0,100" end="100,100" time="1000" center="-1,561" reversible="false" tween="circle" easing="out">WindowOpen</animation> + <posx>-1</posx> + <posy>{{ vscale(557) }}</posy> + <width>1</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + <control type="image"> + <visible>!Control.IsVisible(500)</visible> + <posx>0</posx> + <posy>{{ vscale(565) }}</posy> + <width>1920</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + </control> + + <control type="grouplist" id="60"> + <posx>0</posx> + <posy>{{ vscale(540) }}</posy> + <width>1920</width> + <height>{{ vscale(1800) }}</height> + + <onup>300</onup> + <itemgap>0</itemgap> + + <!-- ROLES --> + <control type="group" id="500"> + <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>400</defaultcontrol> + <width>1920</width> + <height>{{ vscale(446) }}</height> + <control type="list" id="400"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(410) }}</height> + <onup>300</onup> + <ondown>401</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <control type="label"> + <scroll>Control.HasFocus(400)</scroll> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(400)</scroll> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- /ROLES --> + + <!-- REVIEWS --> + <control type="group" id="501"> + <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>401</defaultcontrol> + <width>1920</width> + <height>{{ vscale(446) }}</height> + <control type="label"> + <posx>60</posx> + <posy>{{ vscale(20) }}</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32953][/UPPERCASE]</label> + </control> + <control type="list" id="401"> + <posx>0</posx> + <posy>{{ vscale(36) }}</posy> + <width>1920</width> + <height>{{ vscale(410) }}</height> + <onup>400</onup> + <ondown>402</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="540"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>520</width> + <height>{{ vscale(310) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>60000000</colordiffuse> + </control> + <control type="group"> + <posx>20</posx> + <posy>{{ vscale(20) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>10</posx> + <posy>{{ vscale(-5) }}</posy> + <width>70</width> + <height>{{ vscale(70) }}</height> + <texture>script.plex/reviews/$INFO[ListItem.Thumb].png</texture> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>100</posx> + <posy>0</posy> + <width>400</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>DDFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>100</posx> + <posy>{{ vscale(30) }}</posy> + <width>400</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>66FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>480</width> + <height>{{ vscale(190) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Property(text)]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="540"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>520</width> + <height>{{ vscale(310) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>80000000</colordiffuse> + </control> + <control type="group"> + <posx>20</posx> + <posy>{{ vscale(20) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>10</posx> + <posy>{{ vscale(-5) }}</posy> + <width>70</width> + <height>{{ vscale(70) }}</height> + <texture>script.plex/reviews/$INFO[ListItem.Thumb].png</texture> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>100</posx> + <posy>0</posy> + <width>400</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>DDFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>100</posx> + <posy>{{ vscale(30) }}</posy> + <width>400</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>66FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>480</width> + <height>{{ vscale(190) }}</height> + <font>font10</font> + <align>left</align> + <textcolor>DDFFFFFF</textcolor> + <label>$INFO[ListItem.Property(text)]</label> + <autoscroll delay="6000" time="3000" repeat="12000">Control.HasFocus(401)</autoscroll> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>-5</posx> + <posy>{{ vscale(-5) }}</posy> + <width>530</width> + <height>{{ vscale(320) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- /REVIEWS --> + + <!-- EXTRAS --> + <control type="group" id="502"> + <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <height>{{ vscale(360) }}</height> + <width>1920</width> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(360) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32305][/UPPERCASE]</label> + </control> + <control type="list" id="402"> + <posx>0</posx> + <posy>{{ vscale(18) }}</posy> + <width>1920</width> + <height>{{ vscale(430) }}</height> + <onup>401</onup> + <ondown>403</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(180) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>389</width> + <height>{{ vscale(258) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(180) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>0</posx> + <posy>0</posy> + <width>309</width> + <height>{{ vscale(178) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- /EXTRAS --> + + <!-- RELATED --> + <control type="group" id="503"> + <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>403</defaultcontrol> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(divider.403))</visible> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> + </control> + <control type="list" id="403"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <onup>402</onup> + <onleft>false</onleft> + <onright>false</onright> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(441) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + + <control type="label"> + <scroll>Control.HasFocus(403)</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- /RELATED --> + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_signin.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_signin.xml.tpl new file mode 100644 index 0000000000..c597a23600 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-pre_signin.xml.tpl @@ -0,0 +1,36 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> +</control> +<control type="image"> + <posx>0</posx> + <posy>{% if core.needs_scaling %}{{ vperc(vscale(1080)) }}{% else %}0{% endif %}</posy> + <width>1920</width> + <height>{{ vscale(1080) }}</height> + <texture>script.plex/sign_in/pre-signin.jpg</texture> +</control> + +<control type="button" id="100"> + <posx>1437</posx> + <posy>{{ vscale(801) }}</posy> + <width>275</width> + <height>{{ vscale(104) }}</height> + <onup>200</onup> + <font>font13</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-refresh_code.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-refresh_code.xml.tpl new file mode 100644 index 0000000000..beddc0753b --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-refresh_code.xml.tpl @@ -0,0 +1,29 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/sign_in/refresh-code.jpg</texture> +</control> + +<control type="button" id="100"> + <posx>1383</posx> + <posy>{{ vscale(802) }}</posy> + <width>335</width> + <height>{{ vscale(102) }}</height> + <onup>200</onup> + <font>font13</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-search.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-search.xml.tpl new file mode 100644 index 0000000000..59b9c171a9 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-search.xml.tpl @@ -0,0 +1,8824 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<onload>SetProperty(dropdown,1)</onload>{% endblock %} +{% block backgroundcolor %}{% endblock %} +{% block controls %} +<!-- BACKGROUNDS --> +<control type="group"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>564</width> + <height>1080</height> + <texture colordiffuse="4C000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <width>564</width> + <height>{{ vscale(810) }}</height> + <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> + <texture colordiffuse="FF2D2D2D">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <width>564</width> + <height>{{ vscale(248) }}</height> + <visible>!String.IsEmpty(Window.Property(hide.kbd))</visible> + <texture colordiffuse="FF2D2D2D">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(945) }}</posy> + <width>564</width> + <height>{{ vscale(135) }}</height> + <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> + <texture colordiffuse="66000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(383) }}</posy> + <width>564</width> + <height>{{ vscale(697) }}</height> + <visible>!String.IsEmpty(Window.Property(hide.kbd))</visible> + <texture colordiffuse="66000000">script.plex/white-square.png</texture> + </control> +</control> + +<control type="button" id="999"> + <animation effect="zoom" start="100" end="144" time="100" center="80,{{ vscale(67.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="144" end="100" time="100" center="80,{{ vscale(67.5) }}" reversible="false">UnFocus</animation> + <posx>60</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>40</width> + <height>{{ vscale(40) }}</height> + <ondown>900</ondown> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/search-focus.png</texturefocus> + <texturenofocus colordiffuse="FFCC7B19">script.plex/buttons/search.png</texturenofocus> + <onclick>Close</onclick> + <label> </label> +</control> +<control type="label"> + <scroll>false</scroll> + <posx>160</posx> + <posy>{{ vscale(35) }}</posy> + <width>500</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32431][/UPPERCASE]</label> +</control> + +<control type="group" id="899"> + <!-- SECTIONS --> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(186) }}</posy> + <width>459</width> + <height>{{ vscale(60) }}</height> + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>151</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="group"> + <visible>String.IsEqual(Window.Property(search.section),all)</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>151</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>0</posy> + <width>151</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>All</label> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <visible>!String.IsEqual(Window.Property(search.section),all)</visible> + <posx>0</posx> + <posy>0</posy> + <width>151</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$ADDON[script.plexmod 32345]</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEqual(Window.Property(search.section),movie)</visible> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEqual(Window.Property(search.section),show)</visible> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEqual(Window.Property(search.section),artist)</visible> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> + </control> + </control> + <control type="group"> + <posx>384</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEqual(Window.Property(search.section),photo)</visible> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FFCC7B19">script.plex/white-square.png</texture> + </control> + </control> + + <control type="group" id="900"> + <defaultcontrol>901</defaultcontrol> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="901"> + <hitrect x="0" y="0" w="151" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>231</width> + <height>{{ vscale(140) }}</height> + <onright>902</onright> + <onup>999</onup> + <ondown>650</ondown> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="902"> + <hitrect x="0" y="0" w="74" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(140) }}</height> + <onleft>901</onleft> + <onright>903</onright> + <onup>999</onup> + <ondown>650</ondown> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="button" id="903"> + <hitrect x="0" y="0" w="74" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(140) }}</height> + <onleft>902</onleft> + <onright>904</onright> + <onup>999</onup> + <ondown>650</ondown> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="904"> + <hitrect x="0" y="0" w="74" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(140) }}</height> + <onleft>903</onleft> + <onright>905</onright> + <onup>999</onup> + <ondown>650</ondown> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="button" id="905"> + <hitrect x="0" y="0" w="74" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(140) }}</height> + <onleft>904</onleft> + <onright>3000</onright> + <onup>999</onup> + <ondown>650</ondown> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + </control> + </control> + + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="group"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(30) }}" reversible="true" condition="Control.HasFocus(902)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <control type="image"> + <posx>26</posx> + <posy>{{ vscale(20) }}</posy> + <width>22</width> + <height>{{ vscale(20) }}</height> + <texture colordiffuse="FFFFFFFF">script.plex/home/type/movie.png</texture> + </control> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="group"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(30) }}" reversible="true" condition="Control.HasFocus(903)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <control type="image"> + <posx>26</posx> + <posy>{{ vscale(20) }}</posy> + <width>24</width> + <height>{{ vscale(20) }}</height> + <texture colordiffuse="FFFFFFFF">script.plex/home/type/show.png</texture> + </control> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="group"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(30) }}" reversible="true" condition="Control.HasFocus(904)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <control type="image"> + <posx>26</posx> + <posy>{{ vscale(20) }}</posy> + <width>18</width> + <height>{{ vscale(20) }}</height> + <texture colordiffuse="FFFFFFFF">script.plex/home/type/artist.png</texture> + </control> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="group"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(30) }}" reversible="true" condition="Control.HasFocus(905)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(60) }}</height> + <control type="image"> + <posx>26</posx> + <posy>{{ vscale(20) }}</posy> + <width>22</width> + <height>{{ vscale(20) }}</height> + <texture colordiffuse="FFFFFFFF">script.plex/home/type/photo.png</texture> + </control> + </control> + </control> + </control> + + <!-- ENTRY --> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(276) }}</posy> + <width>459</width> + <height>{{ vscale(60) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>459</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="edit" id="650"> + <posx>0</posx> + <posy>0</posy> + <width>459</width> + <height>{{ vscale(60) }}</height> + <align>left</align> + <aligny>center</aligny> + <onup>900</onup> + <ondown>1001</ondown> + <onright>3000</onright> + <textcolor>00000000</textcolor> + <label> </label> + <hinttext> </hinttext> + <font>font13</font> + <textoffsetx>30</textoffsetx> + <texturefocus border="10">script.plex/home/selected.png</texturefocus> + <texturenofocus>-</texturenofocus> + <pulseonselect>no</pulseonselect> + </control> + <control type="label" id="651"> + <scroll>false</scroll> + <posx>30</posx> + <posy>0</posy> + <width>399</width> + <height>{{ vscale(60) }}</height> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <font>font13</font> + <label> </label> + </control> + </control> + + <!-- KEYBOARD --> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(360) }}</posy> + <width>459</width> + <height>{{ vscale(439) }}</height> + <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> + + <!-- IMAGES ROW 1 --> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>77</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>154</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>231</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>308</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>385</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + </control> + <!-- IMAGES ROW 2 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(77) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>77</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>154</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>231</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>308</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>385</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + </control> + <!-- IMAGES ROW 3 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(154) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>77</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>154</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>231</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>308</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>385</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + </control> + <!-- IMAGES ROW 4 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(231) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>77</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>154</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>231</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>308</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>385</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + </control> + <!-- IMAGES ROW 5 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(308) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>77</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF1F1F1F">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>154</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>231</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>308</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>385</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + </control> + <!-- IMAGES ROW 6 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(385) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>77</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>154</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>231</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>308</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>385</posx> + <posy>0</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + </control> + + <!-- BUTTONS ROW 1 --> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="1001"> + <visible allowhiddenfocus="true">true</visible> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>650</onup> + <ondown>1007</ondown> + <onright>1002</onright> + <onleft>1006</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>A</label> + </control> + </control> + <control type="group"> + <posx>77</posx> + <posy>0</posy> + <control type="button" id="1002"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>650</onup> + <ondown>1008</ondown> + <onright>1003</onright> + <onleft>1001</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>B</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="1003"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>650</onup> + <ondown>1009</ondown> + <onright>1004</onright> + <onleft>1002</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>C</label> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="button" id="1004"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>650</onup> + <ondown>1010</ondown> + <onright>1005</onright> + <onleft>1003</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>D</label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="1005"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>650</onup> + <ondown>1011</ondown> + <onright>1006</onright> + <onleft>1004</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>E</label> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="button" id="1006"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>650</onup> + <ondown>1012</ondown> + <onright>3000</onright> + <onleft>1005</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>F</label> + </control> + </control> + </control> + <!-- BUTTONS ROW 2 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(77) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="1007"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1001</onup> + <ondown>1013</ondown> + <onright>1008</onright> + <onleft>1012</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>G</label> + </control> + </control> + <control type="group"> + <posx>77</posx> + <posy>0</posy> + <control type="button" id="1008"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1002</onup> + <ondown>1014</ondown> + <onright>1009</onright> + <onleft>1007</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>H</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="1009"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1003</onup> + <ondown>1015</ondown> + <onright>1010</onright> + <onleft>1008</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>I</label> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="button" id="1010"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1004</onup> + <ondown>1016</ondown> + <onright>1011</onright> + <onleft>1009</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>J</label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="1011"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1005</onup> + <ondown>1017</ondown> + <onright>1012</onright> + <onleft>1010</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>K</label> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="button" id="1012"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1006</onup> + <ondown>1018</ondown> + <onright>3000</onright> + <onleft>1011</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>L</label> + </control> + </control> + </control> + <!-- BUTTONS ROW 3 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(154) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="1013"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1007</onup> + <ondown>1019</ondown> + <onright>1014</onright> + <onleft>1018</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>M</label> + </control> + </control> + <control type="group"> + <posx>77</posx> + <posy>0</posy> + <control type="button" id="1014"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1008</onup> + <ondown>1020</ondown> + <onright>1015</onright> + <onleft>1013</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>N</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="1015"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1009</onup> + <ondown>1021</ondown> + <onright>1016</onright> + <onleft>1014</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>O</label> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="button" id="1016"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1010</onup> + <ondown>1022</ondown> + <onright>1017</onright> + <onleft>1015</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>P</label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="1017"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1011</onup> + <ondown>1023</ondown> + <onright>1018</onright> + <onleft>1016</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>Q</label> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="button" id="1018"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1012</onup> + <ondown>1024</ondown> + <onright>3000</onright> + <onleft>1017</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>R</label> + </control> + </control> + </control> + <!-- BUTTONS ROW 4 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(231) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="1019"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1013</onup> + <ondown>1025</ondown> + <onright>1020</onright> + <onleft>1024</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>S</label> + </control> + </control> + <control type="group"> + <posx>77</posx> + <posy>0</posy> + <control type="button" id="1020"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1014</onup> + <ondown>1026</ondown> + <onright>1021</onright> + <onleft>1019</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>T</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="1021"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1015</onup> + <ondown>1027</ondown> + <onright>1022</onright> + <onleft>1020</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>U</label> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="button" id="1022"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1016</onup> + <ondown>1028</ondown> + <onright>1023</onright> + <onleft>1021</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>V</label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="1023"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1017</onup> + <ondown>1029</ondown> + <onright>1024</onright> + <onleft>1022</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>W</label> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="button" id="1024"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1018</onup> + <ondown>1030</ondown> + <onright>3000</onright> + <onleft>1023</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>X</label> + </control> + </control> + </control> + <!-- BUTTONS ROW 5 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(308) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="1025"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1019</onup> + <ondown>1031</ondown> + <onright>1026</onright> + <onleft>1030</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>Y</label> + </control> + </control> + <control type="group"> + <posx>77</posx> + <posy>0</posy> + <control type="button" id="1026"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1020</onup> + <ondown>1032</ondown> + <onright>1027</onright> + <onleft>1025</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>Z</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="1027"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1021</onup> + <ondown>1033</ondown> + <onright>1028</onright> + <onleft>1026</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>0[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="button" id="1028"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1022</onup> + <ondown>1034</ondown> + <onright>1029</onright> + <onleft>1027</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>1[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="1029"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1023</onup> + <ondown>1035</ondown> + <onright>1030</onright> + <onleft>1028</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>2[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="button" id="1030"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1024</onup> + <ondown>1036</ondown> + <onright>3000</onright> + <onleft>1029</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>3[B][/B]</label> + </control> + </control> + </control> + <!-- BUTTONS ROW 6 --> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(385) }}</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="1031"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1025</onup> + <ondown>951</ondown> + <onright>1032</onright> + <onleft>1036</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>4[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>77</posx> + <posy>0</posy> + <control type="button" id="1032"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1026</onup> + <ondown>951</ondown> + <onright>1033</onright> + <onleft>1031</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>5[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="1033"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1027</onup> + <ondown>952</ondown> + <onright>1034</onright> + <onleft>1032</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>6[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>231</posx> + <posy>0</posy> + <control type="button" id="1034"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1028</onup> + <ondown>952</ondown> + <onright>1035</onright> + <onleft>1033</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>7[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="1035"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1029</onup> + <ondown>953</ondown> + <onright>1036</onright> + <onleft>1034</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>8[B][/B]</label> + </control> + </control> + <control type="group"> + <posx>385</posx> + <posy>0</posy> + <control type="button" id="1036"> + <animation effect="zoom" start="100" end="120" time="100" center="37,{{ vscale(37) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="37,{{ vscale(37) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="75" h="75" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>154</width> + <height>{{ vscale(154) }}</height> + <onup>1030</onup> + <ondown>953</ondown> + <onright>3000</onright> + <onleft>1035</onleft> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>9[B][/B]</label> + </control> + </control> + </control> + </control> + + <!-- DELETE-ETC --> + <control type="group" id="950"> + <posx>60</posx> + <posy>{{ vscale(840) }}</posy> + <width>459</width> + <height>{{ vscale(60) }}</height> + <visible>String.IsEmpty(Window.Property(hide.kbd))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>151</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>154</posx> + <posy>0</posy> + <width>151</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + <control type="image"> + <posx>308</posx> + <posy>0</posy> + <width>151</width> + <height>{{ vscale(60) }}</height> + <texture colordiffuse="FF000000">script.plex/white-square.png</texture> + </control> + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="button" id="951"> + <animation effect="zoom" start="100" end="120" time="100" center="75.5,{{ vscale(30) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="75.5,{{ vscale(30) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="151" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>231</width> + <height>{{ vscale(140) }}</height> + <onleft>953</onleft> + <onright>952</onright> + <onup>1031</onup> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>$ADDON[script.plexmod 32322]</label> + </control> + </control> + <control type="group"> + <posx>154</posx> + <posy>0</posy> + <control type="button" id="952"> + <animation effect="zoom" start="100" end="120" time="100" center="75.5,{{ vscale(30) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="75.5,{{ vscale(30) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="151" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>231</width> + <height>{{ vscale(140) }}</height> + <onleft>951</onleft> + <onright>953</onright> + <onup>1033</onup> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>$ADDON[script.plexmod 32432]</label> + </control> + </control> + <control type="group"> + <posx>308</posx> + <posy>0</posy> + <control type="button" id="953"> + <animation effect="zoom" start="100" end="120" time="100" center="75.5,{{ vscale(30) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="120" end="100" time="100" center="75.5,{{ vscale(30) }}" reversible="false">UnFocus</animation> + <hitrect x="0" y="0" w="151" h="60" /> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>231</width> + <height>{{ vscale(140) }}</height> + <onleft>952</onleft> + <onright>3000</onright> + <onup>1036</onup> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/white-square-rounded-with-shadow.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label>$ADDON[script.plexmod 32433]</label> + </control> + </control> + </control> + + <control type="group"> + <animation effect="fade" start="0" end="100" time="100" condition="!String.IsEmpty(Window.Property(searching))">Visible</animation> + <visible>!String.IsEmpty(Window.Property(searching))</visible> + <posx>0</posx> + <posy>{{ vscale(993) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>420</posx> + <posy>0</posy> + <width>434</width> + <height>{{ vscale(39) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32434][/UPPERCASE]</label> + </control> + <control type="group"> + <posx>480</posx> + <posy>0</posy> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(searching))</visible> + <animation effect="rotate" start="0" end="-36000" time="100000" center="19.5,{{ vscale(19.5) }}" reversible="false">Visible</animation> + <posx>0</posx> + <posy>0</posy> + <width>39</width> + <height>{{ vscale(39) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/indicators/spinner.png</texture> + </control> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(no.results)) + String.IsEmpty(Window.Property(searching))</visible> + <posx>0</posx> + <posy>{{ vscale(993) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>0</posy> + <width>564</width> + <height>{{ vscale(39) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32435][/UPPERCASE]</label> + </control> + </control> +</control> + +<control type="grouplist" id="3000"> + <!-- 2108 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),8) + Control.IsVisible(2008)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2109 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),9) + Control.IsVisible(2009)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2110 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),10) + Control.IsVisible(2010)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2111 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),11) + Control.IsVisible(2011)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2112 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),12) + Control.IsVisible(2012)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2113 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),13) + Control.IsVisible(2013)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2114 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),14) + Control.IsVisible(2014)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2115 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),15) + Control.IsVisible(2015)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2116 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),16) + Control.IsVisible(2016)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2117 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),17) + Control.IsVisible(2017)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2118 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),18) + Control.IsVisible(2018)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2119 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),19) + Control.IsVisible(2019)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2120 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),20) + Control.IsVisible(2020)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2121 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),21) + Control.IsVisible(2021)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2122 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),22) + Control.IsVisible(2022)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2123 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),23) + Control.IsVisible(2023)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2124 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),24) + Control.IsVisible(2024)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2125 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),25) + Control.IsVisible(2025)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2126 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),26) + Control.IsVisible(2026)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2127 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),27) + Control.IsVisible(2027)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2128 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),28) + Control.IsVisible(2028)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2129 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),29) + Control.IsVisible(2029)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2130 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),30) + Control.IsVisible(2030)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2131 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),31) + Control.IsVisible(2031)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2132 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),32) + Control.IsVisible(2032)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2133 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),33) + Control.IsVisible(2033)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2134 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),34) + Control.IsVisible(2034)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2135 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),35) + Control.IsVisible(2035)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2136 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),36) + Control.IsVisible(2036)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2137 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),37) + Control.IsVisible(2037)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2138 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),38) + Control.IsVisible(2038)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2139 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),39) + Control.IsVisible(2039)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2140 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),40) + Control.IsVisible(2040)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2141 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),41) + Control.IsVisible(2041)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2142 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),42) + Control.IsVisible(2042)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2143 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),43) + Control.IsVisible(2043)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2144 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),44) + Control.IsVisible(2044)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2145 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),45) + Control.IsVisible(2045)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2146 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),46) + Control.IsVisible(2046)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <!-- 2147 Focus animation --> + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),47) + Control.IsVisible(2047)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-420) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + + <defaultcontrol always="true">2000</defaultcontrol> + <posx>564</posx> + <posy>{{ vscale(20) }}</posy> + <width>2130</width> + <height>{{ vscale(5540) }}</height> + <itemgap>20</itemgap> + <orientation>vertical</orientation> + <usecontrolcoords>true</usecontrolcoords> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + + <control type="group" id="2000"> + <defaultcontrol>2100</defaultcontrol> + <visible>Integer.IsGreater(Container(2100).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2100)][/UPPERCASE]</label> + </control> + <control type="list" id="2100"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <ondown>2101</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2100)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2100)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2001"> + <visible>Integer.IsGreater(Container(2101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2101)][/UPPERCASE]</label> + </control> + <control type="list" id="2101"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2100</onup> + <ondown>2102</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2101)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2101)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2002"> + <visible>Integer.IsGreater(Container(2102).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2102)][/UPPERCASE]</label> + </control> + <control type="list" id="2102"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2101</onup> + <ondown>2103</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2102)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2102)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2003"> + <visible>Integer.IsGreater(Container(2103).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2103)][/UPPERCASE]</label> + </control> + <control type="list" id="2103"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2102</onup> + <ondown>2104</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2103)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2103)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2004"> + <visible>Integer.IsGreater(Container(2104).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2104)][/UPPERCASE]</label> + </control> + <control type="list" id="2104"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2103</onup> + <ondown>2105</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2104)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2104)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2005"> + <visible>Integer.IsGreater(Container(2105).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2105)][/UPPERCASE]</label> + </control> + <control type="list" id="2105"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2104</onup> + <ondown>2106</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2105)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2105)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2006"> + <visible>Integer.IsGreater(Container(2106).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2106)][/UPPERCASE]</label> + </control> + <control type="list" id="2106"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2105</onup> + <ondown>2107</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2106)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2106)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2007"> + <visible>Integer.IsGreater(Container(2107).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2107)][/UPPERCASE]</label> + </control> + <control type="list" id="2107"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2106</onup> + <ondown>2108</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2107)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2107)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2008"> + <visible>Integer.IsGreater(Container(2108).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2108)][/UPPERCASE]</label> + </control> + <control type="list" id="2108"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2107</onup> + <ondown>2109</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2108)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2108)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2009"> + <visible>Integer.IsGreater(Container(2109).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2109)][/UPPERCASE]</label> + </control> + <control type="list" id="2109"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2108</onup> + <ondown>2110</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2109)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2109)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2010"> + <visible>Integer.IsGreater(Container(2110).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2110)][/UPPERCASE]</label> + </control> + <control type="list" id="2110"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2109</onup> + <ondown>2111</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2110)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2110)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2011"> + <visible>Integer.IsGreater(Container(2111).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2111)][/UPPERCASE]</label> + </control> + <control type="list" id="2111"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2110</onup> + <ondown>2112</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2111)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2111)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2012"> + <visible>Integer.IsGreater(Container(2112).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2112)][/UPPERCASE]</label> + </control> + <control type="list" id="2112"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2111</onup> + <ondown>2113</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2112)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2112)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2013"> + <visible>Integer.IsGreater(Container(2113).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2113)][/UPPERCASE]</label> + </control> + <control type="list" id="2113"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2112</onup> + <ondown>2114</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2113)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2113)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2014"> + <visible>Integer.IsGreater(Container(2114).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2114)][/UPPERCASE]</label> + </control> + <control type="list" id="2114"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2113</onup> + <ondown>2115</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2114)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2114)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2015"> + <visible>Integer.IsGreater(Container(2115).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2115)][/UPPERCASE]</label> + </control> + <control type="list" id="2115"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2114</onup> + <ondown>2116</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2115)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2115)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2016"> + <visible>Integer.IsGreater(Container(2116).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2116)][/UPPERCASE]</label> + </control> + <control type="list" id="2116"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2115</onup> + <ondown>2117</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2116)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2116)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2017"> + <visible>Integer.IsGreater(Container(2117).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2117)][/UPPERCASE]</label> + </control> + <control type="list" id="2117"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2116</onup> + <ondown>2118</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2117)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2117)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2018"> + <visible>Integer.IsGreater(Container(2118).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2118)][/UPPERCASE]</label> + </control> + <control type="list" id="2118"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2117</onup> + <ondown>2119</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2118)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2118)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2019"> + <visible>Integer.IsGreater(Container(2119).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2119)][/UPPERCASE]</label> + </control> + <control type="list" id="2119"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2118</onup> + <ondown>2120</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2119)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2119)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2020"> + <visible>Integer.IsGreater(Container(2120).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2120)][/UPPERCASE]</label> + </control> + <control type="list" id="2120"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2119</onup> + <ondown>2121</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2120)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2120)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2021"> + <visible>Integer.IsGreater(Container(2121).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2121)][/UPPERCASE]</label> + </control> + <control type="list" id="2121"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2120</onup> + <ondown>2122</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2121)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2121)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2022"> + <visible>Integer.IsGreater(Container(2122).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2122)][/UPPERCASE]</label> + </control> + <control type="list" id="2122"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2121</onup> + <ondown>2123</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2122)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2122)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2023"> + <visible>Integer.IsGreater(Container(2123).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2123)][/UPPERCASE]</label> + </control> + <control type="list" id="2123"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2122</onup> + <ondown>2124</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2123)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2123)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2024"> + <visible>Integer.IsGreater(Container(2124).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2124)][/UPPERCASE]</label> + </control> + <control type="list" id="2124"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2123</onup> + <ondown>2125</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2124)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2124)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2025"> + <visible>Integer.IsGreater(Container(2125).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2125)][/UPPERCASE]</label> + </control> + <control type="list" id="2125"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2124</onup> + <ondown>2126</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2125)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2125)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2026"> + <visible>Integer.IsGreater(Container(2126).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2126)][/UPPERCASE]</label> + </control> + <control type="list" id="2126"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2125</onup> + <ondown>2127</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2126)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2126)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2027"> + <visible>Integer.IsGreater(Container(2127).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2127)][/UPPERCASE]</label> + </control> + <control type="list" id="2127"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2126</onup> + <ondown>2128</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2127)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2127)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2028"> + <visible>Integer.IsGreater(Container(2128).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2128)][/UPPERCASE]</label> + </control> + <control type="list" id="2128"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2127</onup> + <ondown>2129</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2128)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2128)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2029"> + <visible>Integer.IsGreater(Container(2129).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2129)][/UPPERCASE]</label> + </control> + <control type="list" id="2129"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2128</onup> + <ondown>2130</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2129)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2129)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2030"> + <visible>Integer.IsGreater(Container(2130).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2130)][/UPPERCASE]</label> + </control> + <control type="list" id="2130"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2129</onup> + <ondown>2131</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2130)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2130)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2031"> + <visible>Integer.IsGreater(Container(2131).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2131)][/UPPERCASE]</label> + </control> + <control type="list" id="2131"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2130</onup> + <ondown>2132</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2131)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2131)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2032"> + <visible>Integer.IsGreater(Container(2132).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2132)][/UPPERCASE]</label> + </control> + <control type="list" id="2132"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2131</onup> + <ondown>2133</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2132)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2132)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2033"> + <visible>Integer.IsGreater(Container(2133).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2133)][/UPPERCASE]</label> + </control> + <control type="list" id="2133"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2132</onup> + <ondown>2134</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2133)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2133)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2034"> + <visible>Integer.IsGreater(Container(2134).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2134)][/UPPERCASE]</label> + </control> + <control type="list" id="2134"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2133</onup> + <ondown>2135</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2134)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2134)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2035"> + <visible>Integer.IsGreater(Container(2135).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2135)][/UPPERCASE]</label> + </control> + <control type="list" id="2135"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2134</onup> + <ondown>2136</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2135)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2135)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2036"> + <visible>Integer.IsGreater(Container(2136).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2136)][/UPPERCASE]</label> + </control> + <control type="list" id="2136"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2135</onup> + <ondown>2137</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2136)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2136)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2037"> + <visible>Integer.IsGreater(Container(2137).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2137)][/UPPERCASE]</label> + </control> + <control type="list" id="2137"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2136</onup> + <ondown>2138</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2137)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2137)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2038"> + <visible>Integer.IsGreater(Container(2138).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2138)][/UPPERCASE]</label> + </control> + <control type="list" id="2138"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2137</onup> + <ondown>2139</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2138)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2138)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2039"> + <visible>Integer.IsGreater(Container(2139).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2139)][/UPPERCASE]</label> + </control> + <control type="list" id="2139"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2138</onup> + <ondown>2140</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2139)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2139)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2040"> + <visible>Integer.IsGreater(Container(2140).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2140)][/UPPERCASE]</label> + </control> + <control type="list" id="2140"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2139</onup> + <ondown>2141</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2140)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2140)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2041"> + <visible>Integer.IsGreater(Container(2141).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2141)][/UPPERCASE]</label> + </control> + <control type="list" id="2141"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2140</onup> + <ondown>2142</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2141)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2141)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2042"> + <visible>Integer.IsGreater(Container(2142).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2142)][/UPPERCASE]</label> + </control> + <control type="list" id="2142"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2141</onup> + <ondown>2143</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2142)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2142)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2043"> + <visible>Integer.IsGreater(Container(2143).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2143)][/UPPERCASE]</label> + </control> + <control type="list" id="2143"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2142</onup> + <ondown>2144</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2143)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2143)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2044"> + <visible>Integer.IsGreater(Container(2144).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2144)][/UPPERCASE]</label> + </control> + <control type="list" id="2144"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2143</onup> + <ondown>2145</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="240"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="95,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="95,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2144)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>270</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>180</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>180</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2144)</visible> + <posx>0</posx> + <posy>0</posy> + <width>190</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2045"> + <visible>Integer.IsGreater(Container(2145).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2145)][/UPPERCASE]</label> + </control> + <control type="list" id="2145"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2144</onup> + <ondown>2146</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="140,{{ vscale(140) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="140,{{ vscale(140) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2145)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>360</width> + <height>{{ vscale(360) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>270</width> + <height>{{ vscale(270) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(280) }}</posy> + <width>270</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2145)</visible> + <posx>0</posx> + <posy>0</posy> + <width>280</width> + <height>{{ vscale(280) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2046"> + <visible>Integer.IsGreater(Container(2146).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(320) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2146)][/UPPERCASE]</label> + </control> + <control type="list" id="2146"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2145</onup> + <ondown>2147</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="360"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(64) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="155,{{ vscale(89.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="155,{{ vscale(89.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2146)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>390</width> + <height>{{ vscale(259) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(169) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(179) }}</posy> + <width>300</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2146)</visible> + <posx>0</posx> + <posy>0</posy> + <width>310</width> + <height>{{ vscale(179) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="2047"> + <visible>Integer.IsGreater(Container(2147).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <width>1356</width> + <height>{{ vscale(420) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1236</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF282828</colordiffuse> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(87) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(hub.2147)][/UPPERCASE]</label> + </control> + <control type="list" id="2147"> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>1356</width> + <height>{{ vscale(440) }}</height> + <onleft>899</onleft> + <onup>2146</onup> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(2147)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(254) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(282) }}</posy> + <width>244</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(2147)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-seasons.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-seasons.xml.tpl new file mode 100644 index 0000000000..e15c1f18c8 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-seasons.xml.tpl @@ -0,0 +1,1016 @@ +{% extends "default.xml.tpl" %} +{% block content %} +<control type="group" id="50"> + <animation effect="slide" end="0,{{ vscale(-300) }}" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-360) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),2) + Control.IsVisible(502)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <posx>0</posx> + <posy>{{ vscale(155) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <visible>!String.IsEmpty(Window.Property(initialized))</visible> + <defaultcontrol>302</defaultcontrol> + <posx>440</posx> + <posy>{{ vscale(445) }}</posy> + <width>1000</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>400</ondown> + <itemgap>{{ theme.seasons.buttongroup.itemgap }}</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = theme.seasons.buttons & template = "includes/themed_button.xml.tpl" & hitrect = None %} {# fixme: should hitrect be None? #} + {% include template with name="info" & id=301 %} + {% include template with name="play" & id=302 %} + {% include template with name="shuffle" & id=303 %} + {% include template with name="more" & id=304 %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(600) }}</height> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>347</width> + <height>{{ vscale(518) }}</height> + <texture background="true">script.plex/thumb_fallbacks/movie.png</texture> + <animation effect="fade" start="0" end="100" time="0" delay="500">WindowOpen</animation> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>347</width> + <height>{{ vscale(518) }}</height> + <texture background="true">$INFO[Window.Property(thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with itemref="Window" & xoff=347+60 & uw_size=48 & with_count=True & scale="large" %} + + <control type="label"> + <posx>466</posx> + <posy>0</posy> + <width>1360</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(title)]</label> + </control> + <control type="grouplist"> + <posx>466</posx> + <posy>{{ vscale(70) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <align>left</align> + <itemgap>0</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="label"> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(duration)]$INFO[Window.Property(info), • ]$INFO[Window.Property(date), • ]$INFO[Window.Property(content.rating), • ]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(rating.stars))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label> • </label> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(rating.stars))</visible> + <posy>4</posy> + <width>134</width> + <height>{{ vscale(22) }}</height> + <texture>script.plex/stars/$INFO[Window.Property(rating.stars)].png</texture> + </control> + </control> + + <control type="grouplist"> + <visible>!String.IsEmpty(Window.Property(rating)) | !String.IsEmpty(Window.Property(rating2))</visible> + <posx>1660</posx> + <posy>{{ vscale(70) }}</posy> + <width>200</width> + <height>{{ vscale(32) }}</height> + <align>right</align> + <itemgap>15</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(rating))</visible> + <posy>2</posy> + <width>63</width> + <height>{{ vscale(30) }}</height> + <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating.image)]</texture> + <aspectratio align="right">keep</aspectratio> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(rating))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(rating)]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(rating2))</visible> + <posy>2</posy> + <width>63</width> + <height>{{ vscale(30) }}</height> + <texture fallback="script.plex/ratings/other/image.rating.png">$INFO[Window.Property(rating2.image)]</texture> + <aspectratio align="right">keep</aspectratio> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(rating2))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(rating2)]</label> + </control> + </control> + + + <control type="label"> + <visible>!String.IsEmpty(Window.Property(directors))</visible> + <posx>466</posx> + <posy>{{ vscale(130) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[Window.Property(directors)]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(writers))</visible> + <posx>466</posx> + <posy>{{ vscale(165) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[Window.Property(writers)]</label> + </control> + <!-- <control type="grouplist"> + <posx>466</posx> + <posy>{{ vscale(225) }}</posy> + <width>1360</width> + <height>{{ vscale(30) }}</height> + <align>left</align> + <itemgap>15</itemgap> + <orientation>horizontal</orientation> + <usecontrolcoords>true</usecontrolcoords> + <control type="button"> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturenofocus> + <label>AUDIO</label> + </control> + <control type="label"> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(audio)]</label> + </control> + <control type="button"> + <visible>!String.IsEmpty(Window.Property(subtitles))</visible> + <left>30</left> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <focusedcolor>FFFFFFFF</focusedcolor> + <textcolor>FFFFFFFF</textcolor> + <textoffsetx>15</textoffsetx> + <texturefocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus colordiffuse="40000000" border="12">script.plex/white-square-rounded.png</texturenofocus> + <label>SUBTITLES</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(subtitles))</visible> + <width>auto</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(subtitles)]</label> + </control> + </control> + <control type="textbox"> + <posx>466</posx> + <posy>{{ vscale(300) }}</posy> + <width>1360</width> + <height>{{ vscale(113) }}</height> + <font>font13</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(summary)]</label> + </control> --> + <control type="textbox"> + <posx>466</posx> + <posy>{{ vscale(234) }}</posy> + <width>1360</width> + <height>{{ vscale(179) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(summary)]</label> + </control> + <control type="image" id="250"> + <animation effect="zoom" start="0,100" end="100,100" time="1000" center="-1,561" reversible="false" tween="circle" easing="out">WindowOpen</animation> + <posx>-1</posx> + <posy>{{ vscale(557) }}</posy> + <width>1</width> + <height>{{ vscale(8) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + <control type="image"> + <visible>!Control.IsVisible(500)</visible> + <posx>0</posx> + <posy>{{ vscale(565) }}</posy> + <width>1920</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + </control> + + <control type="grouplist" id="60"> + <posx>0</posx> + <posy>{{ vscale(565) }}</posy> + <width>1920</width> + <height>{{ vscale(1600) }}</height> + + <onup>300</onup> + <itemgap>0</itemgap> + + <!-- Seasons --> + <control type="group" id="500"> + <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <height>{{ vscale(380) }}</height> + <width>1920</width> + <control type="list" id="400"> + <posx>0</posx> + <posy>{{ vscale(36) }}</posy> + <width>1920</width> + <height>{{ vscale(380) }}</height> + <onup>300</onup> + <ondown>401</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="218"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(29) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=158 & with_count=True & scale="small" %} + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(230) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>158</width> + <height>{{ vscale(4) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(240) }}</posy> + <width>158</width> + <height>{{ vscale(54) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="218"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(29) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="84,{{ vscale(123) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="84,{{ vscale(123) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>248</width> + <height>{{ vscale(326) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(236) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=158 & with_count=True & scale="small" %} + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(230) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>158</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>158</width> + <height>{{ vscale(4) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + <control type="label"> + <scroll>Control.HasFocus(400)</scroll> + <posx>0</posx> + <posy>{{ vscale(240) }}</posy> + <width>158</width> + <height>{{ vscale(54) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>0</posx> + <posy>0</posy> + <width>168</width> + <height>{{ vscale(246) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- Seasons --> + + <!-- ROLES --> + <control type="group" id="501"> + <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>401</defaultcontrol> + <width>1920</width> + <height>{{ vscale(400) }}</height> + <control type="label"> + <posx>60</posx> + <posy>{{ vscale(-20) }}</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32419][/UPPERCASE]</label> + </control> + <control type="list" id="401"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(400) }}</height> + <onup>400</onup> + <ondown>402</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <control type="label"> + <scroll>Control.HasFocus(401)</scroll> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(401)</scroll> + <posx>0</posx> + <posy>{{ vscale(30) }}</posy> + <width>244</width> + <height>{{ vscale(60) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>AAFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- ROLES --> + + <!-- EXTRAS --> + <control type="group" id="502"> + <visible>Integer.IsGreater(Container(402).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <height>{{ vscale(360) }}</height> + <width>1920</width> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(extras.header)][/UPPERCASE]</label> + </control> + <control type="list" id="402"> + <posx>0</posx> + <posy>{{ vscale(18) }}</posy> + <width>1920</width> + <height>{{ vscale(430) }}</height> + <onup>401</onup> + <ondown>403</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(175) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(210) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>389</width> + <height>{{ vscale(258) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <control type="label"> + <scroll>Control.HasFocus(402)</scroll> + <posx>0</posx> + <posy>{{ vscale(175) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>Control.HasFocus(402)</scroll> + <posx>0</posx> + <posy>{{ vscale(210) }}</posy> + <width>299</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(402)</visible> + <posx>0</posx> + <posy>0</posy> + <width>309</width> + <height>{{ vscale(178) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- EXTRAS --> + + <!-- RELATED --> + <control type="group" id="503"> + <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>403</defaultcontrol> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(divider.403))</visible> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> + </control> + <control type="list" id="403"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <onup>402</onup> + <ondown>403</ondown> + <onleft>false</onleft> + <onright>false</onright> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(441) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + <control type="label"> + <scroll>Control.HasFocus(403)</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + <!-- RELATED --> + + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-seek_dialog.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-seek_dialog.xml.tpl new file mode 100644 index 0000000000..af9ad17bd9 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-seek_dialog.xml.tpl @@ -0,0 +1,1098 @@ +{% extends "base.xml.tpl" %} +{% block headers %} + <defaultcontrol>800</defaultcontrol> + <zorder>100</zorder> +{% endblock %} +{% block backgroundcolor %}{% endblock %} + +{% block controls %} +<control type="group" id="802"> + <visible>[!String.IsEmpty(Window.Property(show.OSD)) | Window.IsVisible(seekbar) | !String.IsEmpty(Window.Property(button.seek))] + !Window.IsVisible(osdvideosettings) + !Window.IsVisible(osdaudiosettings) + !Window.IsVisible(osdsubtitlesettings) + !Window.IsVisible(subtitlesearch) + !Window.IsActive(playerprocessinfo) + !Window.IsActive(selectdialog) + !Window.IsVisible(osdcmssettings)</visible> + <animation effect="fade" time="200" delay="200" end="0">Hidden</animation> + <control type="group"> + <visible>String.IsEmpty(Window.Property(is_plextuary)) + String.IsEmpty(Window.Property(settings.visible)) + [Window.IsVisible(seekbar) | Window.IsVisible(videoosd) | Player.ShowInfo]</visible> + <animation effect="fade" start="100" end="0">Hidden</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/player-fade.png</texture> + <colordiffuse>FF080808</colordiffuse> + </control> + </control> + + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(140) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image"> + <visible>String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))</visible> + <posx>0</posx> + <posy>{{ vscale(140) }}r</posy> + <width>1920</width> + <height>{{ vscale(140) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + </control> + + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(40) }}</posy> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(is.show)) + String.IsEmpty(Window.Property(hide.title))</visible> + <posx>60</posx> + <posy>0</posy> + <width>1720</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>15</scrollspeed> + <label>[B]$INFO[VideoPlayer.TVShowTitle][/B]$INFO[VideoPlayer.Title, • ]$INFO[VideoPlayer.Season, • Season ]$INFO[VideoPlayer.Episode, Episode ]$INFO[Window.Property(ep.year), • ]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(is.show)) + !String.IsEmpty(Window.Property(hide.title))</visible> + <posx>60</posx> + <posy>0</posy> + <width>1720</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>15</scrollspeed> + <label>[B]$INFO[VideoPlayer.TVShowTitle][/B]$INFO[VideoPlayer.Season, • Season ]$INFO[VideoPlayer.Episode, Episode ]$INFO[Window.Property(ep.year), • ]</label> + </control> + <control type="label"> + <visible>String.IsEmpty(Window.Property(is.show))</visible> + <posx>60</posx> + <posy>0</posy> + <width>1720</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <scrollspeed>15</scrollspeed> + <label>[B]$INFO[VideoPlayer.Title][/B]$INFO[VideoPlayer.Year, • ]</label> + </control> + <control type="label"> + <posx>1860</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(60) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[System.Time]</label> + </control> + </control> + + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(115) }}r</posy> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(direct.play)) + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Player.Time($INFO[Window.Property(time.fmt)])]</label> + </control> + <control type="label"> + <visible>String.IsEmpty(Window.Property(direct.play)) + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(time.current)]</label> + </control> + <control type="label"> + <visible>Player.IsTempo</visible> + <posx>60</posx> + <posy>{{ vscale(40) }}</posy> + <width>1000</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>A0FFFFFF</textcolor> + <label>$INFO[Player.PlaySpeed]x</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(direct.play)) + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>1860</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Player.TimeRemaining($INFO[Window.Property(time.fmt)])]$INFO[Window.Property(time.add)]</label> + </control> + <control type="label"> + <visible>String.IsEmpty(Window.Property(direct.play)) + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>1860</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(time.left)]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(media.show_ends)) + !String.IsEmpty(Window.Property(direct.play)) + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>1860</posx> + <posy>{{ vscale(40) }}</posy> + <width>800</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>A0FFFFFF</textcolor> + <label>$INFO[Window.Property(time.ends_label)] $INFO[Player.FinishTime($INFO[Window.Property(time.fmt.ends)])]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Window.Property(media.show_ends)) + String.IsEmpty(Window.Property(direct.play)) + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>1860</posx> + <posy>{{ vscale(40) }}</posy> + <width>800</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>A0FFFFFF</textcolor> + <label>$INFO[Window.Property(time.ends_label)] $INFO[Window.Property(time.end)]</label> + </control> + <!--<control type="label"> + <visible>Player.Paused + String.IsEmpty(Window.Property(show.OSD))</visible> + <animation effect="fade" time="200" delay="200" end="100">Visible</animation> + <posx>0</posx> + <posy>{{ vscale(20) }}</posy> + <width>1920</width> + <height>{{ vscale(60) }}</height> + <font>font13</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFCC7B19</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32436][/UPPERCASE]</label> + </control>--> + </control> + + <control type="group"> + <posx>0</posx> + <posy>{{ vscale(140) }}r</posy> + <control type="image"> + <visible>String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image" id="206"> + <visible>!String.IsEmpty(Window.Property(show.buffer)) + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>0</posx> + <posy>2</posy> + <width>1</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>EE4E4842</colordiffuse> + </control> + <control type="image" id="201"> + <visible>String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))</visible> + <posx>0</posx> + <posy>2</posy> + <width>1</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFAC5B00</colordiffuse> + </control> + <control type="image" id="200"> + <visible>[Control.HasFocus(100) | !String.IsEmpty(Window.Property(button.seek))] + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>0</posx> + <posy>2</posy> + <width>1</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + </control> +</control> +<control type="button" id="800"> + <visible allowhiddenfocus="true">String.IsEmpty(Window.Property(show.OSD))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + <onclick condition="String.IsEmpty(Window.Property(button.seek)) + String.IsEmpty(Window.Property(marker.countdown))">SetProperty(show.OSD,1)</onclick> +</control> + +<!-- PPI --> +<control type="group" id="803"> + <bottom>0</bottom> + <height>{{ vscale(350) }}</height> + <visible>!String.IsEmpty(Window.Property(show.PPI)) + String.IsEmpty(Window.Property(settings.visible)) + String.IsEmpty(Window.Property(playlist.visible))</visible> + <animation effect="fade" start="0" end="100" time="300">Visible</animation> + <animation effect="fade" start="100" end="0" time="200">Hidden</animation> + <control type="image"> + <left>10</left> + <top>{{ vscale(-220) }}</top> + <right>10</right> + <height>{{ vscale(420) }}</height> + <texture border="40">buttons/dialogbutton-nofo.png</texture> + </control> + <control type="grouplist"> + <left>52</left> + <top>{{ vscale(-184) }}</top> + <width>1786</width> + <height>{{ vscale(350) }}</height> + <orientation>horizontal</orientation> + <itemgap>10</itemgap> + <control type="grouplist"> + <left>0</left> + <top>0</top> + <width>793</width> + <control type="label"> + <width>793</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[Player.Process(videodecoder),[COLOR FFE5A00D]$LOCALIZE[31139]:[/COLOR] ]$VAR[VideoHWDecoder, (,)]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo</visible> + </control> + <control type="label"> + <width>793</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[Player.Process(pixformat),[COLOR FFE5A00D]$LOCALIZE[31140]:[/COLOR] ]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo</visible> + </control> + <control type="label"> + <width>793</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[Player.Process(deintmethod),[COLOR FFE5A00D]$LOCALIZE[16038]:[/COLOR] ]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo</visible> + </control> + <control type="label"> + <width>793</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[Player.Process(videowidth),[COLOR FFE5A00D]$LOCALIZE[38031]:[/COLOR] ,x]$INFO[Player.Process(videoheight),, px]$INFO[Player.Process(videodar),$COMMA , AR]$INFO[Player.Process(videofps),$COMMA , FPS]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo</visible> + </control> + <control type="textbox"> + <width>793</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <autoscroll delay="1000" time="1000" repeat="2000"></autoscroll> + <label>[COLOR FFE5A00D]$LOCALIZE[460]:[/COLOR] $INFO[Player.Process(audiochannels),,$COMMA ]$INFO[Player.Process(audiodecoder)]$INFO[Player.Process(audiobitspersample),$COMMA , bits]$INFO[Player.Process(audiosamplerate),$COMMA , Hz]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <width>793</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[System.Memory(used.percent),[COLOR FFE5A00D]$LOCALIZE[31030]:[/COLOR] ,]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + </control> + </control> + <control type="grouplist"> + <left>0</left> + <top>0</top> + <height>{{ vscale(350) }}</height> + <width>993</width> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[Window.Property(ppi.Status)]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Status))</visible> + </control> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>[COLOR FFE5A00D]Mode:[/COLOR] $INFO[Window.Property(ppi.Mode)]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Mode))</visible> + </control> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>[COLOR FFE5A00D]Container:[/COLOR] $INFO[Window.Property(ppi.Container)]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Container))</visible> + </control> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>[COLOR FFE5A00D]Video:[/COLOR] $INFO[Window.Property(ppi.Video)]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Video))</visible> + </control> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[Window.Property(ppi.Audio),[COLOR FFE5A00D]Audio:[/COLOR] ]$INFO[Window.Property(ppi.Subtitles), [COLOR FFE5A00D]Subtitle:[/COLOR] ]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + [!String.IsEmpty(Window.Property(ppi.Audio)) | !String.IsEmpty(Window.Property(ppi.Subtitles))]</visible> + </control> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>[COLOR FFE5A00D]Server:[/COLOR] $INFO[Window.Property(ppi.User)]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.User))</visible> + </control> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>[COLOR FFE5A00D]Buffer:[/COLOR] $INFO[Player.CacheLevel]%</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + String.IsEmpty(Window.Property(ppi.Buffered))</visible> + </control> + <control type="label"> + <width>893</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>[COLOR FFE5A00D]Buffer:[/COLOR] $INFO[Window.Property(ppi.Buffered)]% (% of Video cached)</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + <visible>Player.HasVideo + !String.IsEmpty(Window.Property(ppi.Buffered))</visible> + </control> + </control> + </control> + <control type="label"> + <left>52</left> + <top>{{ vscale(120) }}</top> + <width>1786</width> + <height>{{ vscale(50) }}</height> + <aligny>bottom</aligny> + <label>$INFO[System.CpuUsage,[COLOR FFE5A00D]$LOCALIZE[13271][/COLOR] ]</label> + <font>font14</font> + <shadowcolor>black</shadowcolor> + </control> +</control> +<control type="group" id="801"> + <visible>!String.IsEmpty(Window.Property(show.OSD)) + !Window.IsVisible(osdvideosettings) + !Window.IsVisible(osdaudiosettings) + !Window.IsVisible(osdsubtitlesettings) + !Window.IsVisible(subtitlesearch) + !Window.IsActive(playerprocessinfo) + !Window.IsActive(selectdialog) + !Window.IsVisible(osdcmssettings)</visible> + <animation effect="fade" time="200" delay="200" end="0">Hidden</animation> + <control type="group" id="300"> + <visible>!String.IsEmpty(Window.Property(has.bif)) + [Control.HasFocus(100) | Control.HasFocus(501) | !String.IsEmpty(Window.Property(button.seek))]</visible> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>0</posx> + <posy>752</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>324</width> + <height>{{ vscale(184) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="image"> + <posx>2</posx> + <posy>2</posy> + <width>320</width> + <height>{{ vscale(180) }}</height> + <fadetime>10</fadetime> + <texture>$INFO[Window.Property(bif.image)]</texture> + </control> + </control> + + <control type="grouplist" id="400"> + <defaultcontrol>406</defaultcontrol> + <hitrect x="460" y="998" w="1000" h="55" /> + <posx>360</posx> + <posy>{{ vscale(116) }}r</posy> + <width>1200</width> + <height>{{ vscale(124) }}</height> + <align>center</align> + <onup>100</onup> + <itemgap>-40</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + <control type="group" id="421"> + <visible>!String.IsEmpty(Window.Property(nav.repeat))</visible> + <width>125</width> + <height>{{ vscale(101) }}</height> + <control type="button" id="401"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <onup>100</onup> + <onright>402</onright> + <onleft>412</onleft> + <ondown>501</ondown> + <font>font12</font> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + <control type="group"> + <visible>!Control.HasFocus(401)</visible> + <control type="image"> + <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}repeat.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}repeat.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeatOne | !String.IsEmpty(Window.Property(pq.repeat.one))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}repeat-one.png</texture> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(401)</visible> + <control type="image"> + <visible>!Playlist.IsRepeatOne + !Playlist.IsRepeat + String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeat | !String.IsEmpty(Window.Property(pq.repeat))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + <control type="image"> + <visible>Playlist.IsRepeatOne | !String.IsEmpty(Window.Property(pq.repeat.one))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}repeat-one{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + </control> + </control> + + <control type="togglebutton" id="402"> + <visible>!String.IsEmpty(Window.Property(has.playlist)) + !String.IsEmpty(Window.Property(nav.shuffle))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle.png</texturenofocus> + <usealttexture>!String.IsEmpty(Window.Property(pq.shuffled))</usealttexture> + <alttexturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</alttexturefocus> + <alttexturenofocus colordiffuse="FFCC7B19">{{ theme.assets.buttons.base }}shuffle.png</alttexturenofocus> + <label> </label> + </control> + <control type="button" id="422"> + <enable>false</enable> + <visible>String.IsEmpty(Window.Property(has.playlist)) + !String.IsEmpty(Window.Property(nav.shuffle))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}shuffle{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}shuffle.png</texturenofocus> + <label> </label> + </control> + + <control type="button" id="403"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}settings{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}settings.png</texturenofocus> + <label> </label> + </control> + + + <control type="button" id="404"> + <visible>!String.IsEmpty(Window.Property(pq.hasprev)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> + <hitrect x="58" y="28" w="69" h="45" /> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true"{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus flipx="true"{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="424"> + <enable>false</enable> + <visible>String.IsEmpty(Window.Property(pq.hasprev)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true" colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus flipx="true" colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="405"> + <visible>!String.IsEmpty(Window.Property(nav.ffwdrwd))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true" colordiffuse="FFE5A00D">{{ theme.assets.buttons.base }}skip-forward{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus flipx="true"{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}skip-forward.png</texturenofocus> + <label> </label> + </control> + + <control type="group" id="426"> + {% if theme.buttons.zoomPlayButton %} + <animation effect="zoom" start="100" end="124" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="Control.HasFocus(406)">Conditional</animation> + <animation effect="zoom" start="124" end="100" time="100" center="63,{{ vscale(50) }}" reversible="false" condition="!Control.HasFocus(406)">Conditional</animation> + {% endif %} + <width>125</width> + <height>{{ vscale(101) }}</height> + <control type="button" id="406"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <onup>100</onup> + <onright>407</onright> + <onleft>405</onleft> + <ondown>501</ondown> + <font>font12</font> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + <onclick>PlayerControl(Play)</onclick> + </control> + <control type="group"> + <visible>!Control.HasFocus(406)</visible> + <control type="image"> + <visible>!Player.Paused + !Player.Forwarding + !Player.Rewinding</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}pause.png</texture> + </control> + <control type="image"> + <visible>Player.Paused | Player.Forwarding | Player.Rewinding</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}play.png</texture> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(406)</visible> + <control type="image"> + <visible>!Player.Paused + !Player.Forwarding + !Player.Rewinding</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}pause{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + <control type="image"> + <visible>Player.Paused | Player.Forwarding | Player.Rewinding</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texture{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}play{{ theme.assets.buttons.focusSuffix }}.png</texture> + </control> + </control> + </control> + + <control type="button" id="407"> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}stop{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}stop.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="408"> + <visible>!String.IsEmpty(Window.Property(nav.ffwdrwd))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}skip-forward{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}skip-forward.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="409"> + <visible>!String.IsEmpty(Window.Property(pq.hasnext)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="419"> + <enable>false</enable> + <visible>String.IsEmpty(Window.Property(pq.hasnext)) + !String.IsEmpty(Window.Property(nav.prevnext))</visible> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <texturefocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}next.png</texturenofocus> + <label> </label> + </control> + + + <control type="button" id="410"> + <visible>[!String.IsEmpty(Window.Property(pq.hasnext)) | !String.IsEmpty(Window.Property(pq.hasprev))] + !String.IsEmpty(Window.Property(nav.playlist))</visible> + <hitrect x="58" y="28" w="69" h="45" /> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}pqueue{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}pqueue.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="430"> + <enable>false</enable> + <visible>String.IsEmpty(Window.Property(pq.hasnext)) + String.IsEmpty(Window.Property(pq.hasprev)) + !String.IsEmpty(Window.Property(nav.playlist))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}pqueue{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus colordiffuse="40FFFFFF">{{ theme.assets.buttons.base }}pqueue.png</texturenofocus> + <label> </label> + </control> + <control type="button" id="412"> + <visible>!String.IsEmpty(Window.Property(nav.quick_subtitles))</visible> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus{% if theme.buttons.useFocusColor %} colordiffuse="{{ theme.buttons.focusColor|default("FFE5A00D") }}"{% endif %}>{{ theme.assets.buttons.base }}subtitle{{ theme.assets.buttons.focusSuffix }}.png</texturefocus> + <texturenofocus{% if theme.buttons.useNoFocusColor %} colordiffuse="{{ theme.buttons.noFocusColor|default('99FFFFFF') }}"{% endif %}>{{ theme.assets.buttons.base }}subtitle.png</texturenofocus> + <label> </label> + </control> + </control> + + <control type="group"> + <posx>0</posx> + <posy>940</posy> + <control type="button" id="100"> + <hitrect x="0" y="-19" w="1920" h="48" /> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(10) }}</height> + <onup>501</onup> + <ondown>400</ondown> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + </control> + </control> + + <control type="group" id="500"> + <animation effect="slide" time="100" start="0,0" end="0,{{ vscale(20) }}" reversible="true" condition="Control.HasFocus(501) + String.IsEmpty(Window.Property(has.chapters))">Conditional</animation> + + <!-- CHAPTERS --> + <animation effect="slide" time="100" start="0,0" end="0,{{ vscale(-60) }}" reversible="true" condition="Control.HasFocus(501) + !String.IsEmpty(Window.Property(has.chapters)) + !String.IsEmpty(Window.Property(show.chapters))">Conditional</animation> + <!-- /CHAPTERS --> + + <visible>String.IsEmpty(Window.Property(mouse.mode)) + String.IsEmpty(Window.Property(hide.bigseek)) + [Control.HasFocus(501) | Control.HasFocus(100)] + [!String.IsEmpty(Window.Property(show.chapters)) | String.IsEmpty(Window.Property(has.chapters))]</visible> + <posx>-8</posx> + <posy>917</posy> + <control type="image"> + <posx>-200</posx> + <posy>5</posy> + <width>2320</width> + <height>{{ vscale(6) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + <visible>String.IsEmpty(Window.Property(has.chapters))</visible> + </control> + <!-- CHAPTERS --> + <control type="image"> + <posx>0</posx> + <posy>-175</posy> + <width>1928</width> + <height>200</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + <visible>!String.IsEmpty(Window.Property(has.chapters))</visible> + </control> + <control type="label"> + <posx>40</posx> + <posy>-162</posy> + <width>auto</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>CC606060</textcolor> + <label>$INFO[Window.Property(chapters.label)]</label> + <visible>!String.IsEmpty(Window.Property(has.chapters)) + !Control.HasFocus(501)</visible> + </control> + <control type="label"> + <posx>40</posx> + <posy>-162</posy> + <width>auto</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(chapters.label)]</label> + <visible>!String.IsEmpty(Window.Property(has.chapters)) + Control.HasFocus(501)</visible> + </control> + <!-- /CHAPTERS --> + <control type="list" id="501"> + <hitrect x="-20" y="-20" w="10" h="10" /> + <posx>0</posx> + <posy>0</posy> + <width>1928</width> + <height>{{ vscale(16) }}</height> + <ondown>100</ondown> + <onfocus>SetProperty(hide.bigseek,)</onfocus> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="160" condition="String.IsEmpty(Window.Property(has.chapters))"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>16</width> + <height>{{ vscale(16) }}</height> + <texture>script.plex/indicators/seek-selection-marker.png</texture> + <colordiffuse>FF606060</colordiffuse> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="160" condition="String.IsEmpty(Window.Property(has.chapters))"> + <control type="image"> + <visible>!Control.HasFocus(501)</visible> + <posx>0</posx> + <posy>0</posy> + <width>16</width> + <height>{{ vscale(16) }}</height> + <texture>script.plex/indicators/seek-selection-marker.png</texture> + <colordiffuse>FF606060</colordiffuse> + </control> + <control type="image"> + <visible>Control.HasFocus(501)</visible> + <posx>0</posx> + <posy>0</posy> + <width>16</width> + <height>{{ vscale(16) }}</height> + <texture>script.plex/indicators/seek-selection-marker.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + </focusedlayout> + + <!-- ITEM LAYOUT CHAPTERS ########################################## --> + <itemlayout width="218" condition="!String.IsEmpty(Window.Property(has.chapters))"> + <control type="group"> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>CC606060</colordiffuse> + <visible>!Control.HasFocus(501)</visible> + </control> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>DDAAAAAA</colordiffuse> + <visible>!Control.HasFocus(501)</visible> + </control> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>FFAAAAAA</colordiffuse> + <visible>Control.HasFocus(501)</visible> + </control> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>FFAAAAAA</colordiffuse> + <visible>Control.HasFocus(501)</visible> + </control> + <control type="label"> + <posx>40</posx> + <posy>{{ vscale(120) }}</posy> + <width>auto</width> + <height>{{ vscale(10) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>CC606060</textcolor> + <label>$INFO[ListItem.Label]</label> + <visible>!Control.HasFocus(501)</visible> + </control> + <control type="label"> + <posx>40</posx> + <posy>{{ vscale(120) }}</posy> + <width>auto</width> + <height>{{ vscale(10) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFAAAAAA</textcolor> + <label>$INFO[ListItem.Label]</label> + <visible>Control.HasFocus(501)</visible> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT CHAPTERS ####################################### --> + <focusedlayout width="218" condition="!String.IsEmpty(Window.Property(has.chapters))"> + <control type="group"> + <animation effect="slide" time="100" start="0,0" end="0,{{ vscale(-10) }}" reversible="true">Focus</animation> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>CC909090</colordiffuse> + <visible>!Control.HasFocus(501)</visible> + </control> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + <colordiffuse>FF666666</colordiffuse> + <visible>!Control.HasFocus(501)</visible> + </control> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>script.plex/thumb_fallbacks/movie16x9.png</texture> + <aspectratio>scale</aspectratio> +<!-- <colordiffuse>FF606060</colordiffuse>--> + <visible>Control.HasFocus(501)</visible> + </control> + <control type="image"> + <posx>40</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> +<!-- <colordiffuse>FFFFFFFF</colordiffuse>--> + <visible>Control.HasFocus(501)</visible> + </control> + <control type="label"> + <posx>40</posx> + <posy>{{ vscale(120) }}</posy> + <width>auto</width> + <height>{{ vscale(10) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFDDDDDD</textcolor> + <label>$INFO[ListItem.Label]</label> + <visible>!Control.HasFocus(501)</visible> + </control> + <control type="label"> + <posx>40</posx> + <posy>{{ vscale(120) }}</posy> + <width>auto</width> + <height>{{ vscale(10) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> +<!-- <textcolor>FFFFFFFF</textcolor>--> + <label>[B]$INFO[ListItem.Label][/B]</label> + <visible>Control.HasFocus(501)</visible> + </control> + </control> + </focusedlayout> + </control> + </control> +</control> +<control type="group" id="202"> + <visible>[Control.HasFocus(100) | Control.HasFocus(501) | !String.IsEmpty(Window.Property(button.seek))] + [String.IsEmpty(Window.Property(no.osd.hide_info)) | !String.IsEmpty(Window.Property(show.OSD))]</visible> + <posx>0</posx> + <posy>896</posy> + <control type="group" id="203"> + <posx>-50</posx> + <posy>0</posy> + <control type="image" id="204"> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>0</posx> + <posy>0</posy> + <width>101</width> + <height>{{ vscale(39) }}</height> + <texture>script.plex/indicators/player-selection-time_box.png</texture> + <colordiffuse>D0000000</colordiffuse> + </control> + <control type="label" id="205"> + <posx>0</posx> + <posy>0</posy> + <width>101</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(time.selection)]</label> + </control> + </control> + <control type="image"> + <animation effect="fade" time="100" delay="100" end="100">Visible</animation> + <posx>-6</posx> + <posy>{{ vscale(39) }}</posy> + <width>15</width> + <height>{{ vscale(7) }}</height> + <texture>script.plex/indicators/player-selection-time_arrow.png</texture> + <colordiffuse>D0000000</colordiffuse> + </control> +</control> + +<!-- SKIP MARKER BUTTON --> +<control type="grouplist" id="790"> + <right>30</right> + <top>797</top> + <width>1670</width> + <height>143</height> + <align>right</align> + <orientation>horizontal</orientation> + <control type="button" id="791"> + <visible>[!String.IsEmpty(Window.Property(show.markerSkip)) + String.IsEmpty(Window.Property(show.markerSkip_OSDOnly))] | [!String.IsEmpty(Window.Property(show.markerSkip_OSDOnly)) + !String.IsEmpty(Window.Property(show.OSD))]</visible> + <animation effect="zoom" start="100" end="110,120" time="100" center="auto" reversible="false">Focus</animation> + <animation effect="zoom" start="110,120" end="100" time="100" center="auto" reversible="false">UnFocus</animation> + <animation type="Conditional" condition="String.IsEmpty(Window.Property(show.OSD)) + !Window.IsVisible(seekbar)" reversible="false"> + <effect type="slide" end="0,100" time="100" delay="100"></effect> + </animation> + <width min="200">auto</width> + <height>{{ vscale(143, up=1.1) }}</height> + <align>center</align> + <right>0</right> + <top>0</top> + <texturefocus colordiffuse="FFE5A00D" border="50">script.plex/buttons/blank-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF" border="50">script.plex/buttons/blank.png</texturenofocus> + <textoffsetx>70</textoffsetx> + <textcolor>FF000000</textcolor> + <focusedcolor>FF000000</focusedcolor> + <label>$INFO[Window.Property(skipMarkerName)]</label> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings.xml.tpl new file mode 100644 index 0000000000..6f4d60def0 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings.xml.tpl @@ -0,0 +1,683 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>300</defaultcontrol>{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/home/background-fallback.png</texture> +</control> + +<control type="group"> + <animation effect="slide" end="-582,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <control type="group"> + <animation effect="slide" end="-297,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> + <control type="image"> + <posx>843</posx> + <posy>135</posy> + <width>1077</width> + <height>945</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>32111111</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>865</posy> + <width>1920</width> + <height>215</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>32000000</colordiffuse> + </control> + </control> + <control type="image"> + <animation effect="slide" end="-297,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> + <posx>843</posx> + <posy>865</posy> + <width>1077</width> + <height>215</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>32111111</colordiffuse> + </control> + <control type="image"> + <animation effect="slide" end="-297,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> + <posx>1920</posx> + <posy>135</posy> + <width>879</width> + <height>945</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>66111111</colordiffuse> + </control> + </control> + + <control type="textbox"> + <animation effect="slide" end="-277,0" time="200" tween="quadratic" easing="out" condition="Control.HasFocus(125)">Conditional</animation> + <visible>Control.HasFocus(100) | Control.HasFocus(125)</visible> + <posx>872</posx> + <posy>886.5</posy> + <width>1024</width> + <height>172</height> + <font>font10</font> + <textcolor>FFFFFFFF</textcolor> + <align>left</align> + <scrolltime>200</scrolltime> + <autoscroll delay="5000" time="4000" repeat="15000"></autoscroll> + <label>$INFO[Container(100).ListItem.Property(description)]</label> + </control> + + <control type="group" id="50"> + <posx>248</posx> + <posy>131.5</posy> + <defaultcontrol always="true">75</defaultcontrol> + <control type="list" id="75"> + <posx>0</posx> + <posy>0</posy> + <width>590</width> + <height>741</height> + <onleft>201</onleft> + <onright>100</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(75) }}"> + <control type="group"> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>414</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.last))</visible> + <posx>0</posx> + <posy>{{ vscale(75) }}</posy> + <width>414</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>661F1F1F</colordiffuse> + </control> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(75) }}"> + <control type="group"> + <visible>ControlGroup(50).HasFocus(0)</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>590</width> + <height>{{ vscale(155) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <visible>Control.HasFocus(75)</visible> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <width>510</width> + <height>{{ vscale(75) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="image"> + <visible>!Control.HasFocus(75)</visible> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <width>510</width> + <height>{{ vscale(75) }}</height> + <texture colordiffuse="FFCC7B19" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="image"> + <visible>!Control.HasFocus(75)</visible> + <posx>512</posx> + <posy>{{ vscale(66) }}</posy> + <width>16</width> + <height>{{ vscale(23) }}</height> + <texture>script.plex/settings/expanded.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="label"> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <width>414</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="label"> + <visible>!ControlGroup(50).HasFocus(0)</visible> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <width>414</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </focusedlayout> + </control> + + <control type="list" id="100"> + <visible>Integer.IsGreater(Container(100).NumItems,0)</visible> + <enable>String.IsEmpty(Window.Property(section.about))</enable> + <posx>604</posx> + <posy>0</posy> + <width>776</width> + <height>715</height> + <onleft>75</onleft> + <onright>150</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <pagecontrol>101</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(75) }}"> + <control type="group"> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>200</posx> + <posy>0</posy> + <width>400</width> + <scroll>true</scroll> + <scrollspeed>25</scrollspeed> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(75) }}</posy> + <width>600</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>661F1F1F</colordiffuse> + </control> + </control> + <control type="group"> + <posx>643</posx> + <posy>{{ vscale(55) }}</posy> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(checkbox))</visible> + <posx>0</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(45) }}</height> + <texture colordiffuse="EE000000" border="10">script.plex/settings/checkbox.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> + <posx>0</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(45) }}</height> + <texture>script.plex/settings/checkmark.png</texture> + </control> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(75) }}"> + <control type="group"> + <visible>Control.HasFocus(100) | Control.HasFocus(125)</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>776</width> + <height>{{ vscale(155) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <visible>!Control.HasFocus(125)</visible> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <width>696</width> + <height>{{ vscale(75) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="image"> + <visible>Control.HasFocus(125)</visible> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <width>696</width> + <height>{{ vscale(75) }}</height> + <texture colordiffuse="FFCC7B19" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="image"> + <visible>Control.HasFocus(125)</visible> + <posx>698</posx> + <posy>{{ vscale(66) }}</posy> + <width>16</width> + <height>{{ vscale(23) }}</height> + <texture>script.plex/settings/expanded.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="group"> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>500</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <scroll>true</scroll> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>200</posx> + <posy>0</posy> + <width>400</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <scroll>true</scroll> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="group"> + <visible>!Control.HasFocus(100) + !Control.HasFocus(125)</visible> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>400</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>200</posx> + <posy>0</posy> + <width>400</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <scroll>true</scroll> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(75) }}</posy> + <width>600</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>661F1F1F</colordiffuse> + </control> + </control> + <control type="group"> + <posx>643</posx> + <posy>{{ vscale(55) }}</posy> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(checkbox))</visible> + <posx>0</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(45) }}</height> + <texture colordiffuse="EE000000" border="10">script.plex/settings/checkbox.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> + <posx>0</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(45) }}</height> + <texture>script.plex/settings/checkmark.png</texture> + </control> + </control> + </focusedlayout> + </control> + + <control type="scrollbar" id="101"> + <visible>Control.IsVisible(100) + !Control.IsVisible(125)</visible> + <left>1388</left> + <top>40</top> + <width>9</width> + <height>675</height> + <visible>true</visible> + <texturesliderbackground colordiffuse="66000000" border="4">script.plex/white-square-rounded-4r.png</texturesliderbackground> + <texturesliderbar colordiffuse="66FFFFFF" border="4">script.plex/white-square-rounded-4r.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="4">script.plex/white-square-rounded-4r.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + + <control type="button" id="150"> + <visible>Integer.IsGreater(Container(100).NumItems,0) + String.IsEmpty(Window.Property(section.about))</visible> + <width>10</width> + <height>{{ vscale(10) }}</height> + <onright>125</onright> + <onleft>100</onleft> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + <onfocus>SetFocus(100)</onfocus> + </control> + + <control type="list" id="125"> + <visible allowhiddenfocus="true">Control.HasFocus(125) + Integer.IsGreater(Container(100).NumItems,0)</visible> + <enable>Integer.IsGreater(Container(100).NumItems,0) + String.IsEmpty(Window.Property(section.about))</enable> + + <posx>1383</posx> + <posy>0</posy> + <width>845</width> + <height>715</height> + <onleft>100</onleft> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <pagecontrol>126</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(75) }}"> + <control type="group"> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>594</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(75) }}</posy> + <width>594</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>661F1F1F</colordiffuse> + </control> + </control> + <control type="group"> + <posx>637</posx> + <posy>{{ vscale(55) }}</posy> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> + <posx>0</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(45) }}</height> + <texture>script.plex/settings/checkmark.png</texture> + </control> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(75) }}"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>610</width> + <height>{{ vscale(155) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <posx>40</posx> + <posy>{{ vscale(40) }}</posy> + <width>690</width> + <height>{{ vscale(75) }}</height> + <texture colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="group"> + <posx>88</posx> + <posy>{{ vscale(40) }}</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>594</width> + <height>{{ vscale(75) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="group"> + <posx>637</posx> + <posy>{{ vscale(55) }}</posy> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(checkbox.checked))</visible> + <posx>0</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(45) }}</height> + <texture>script.plex/settings/checkmark.png</texture> + </control> + </control> + </focusedlayout> + </control> + + <control type="scrollbar" id="126"> + <visible>Control.IsVisible(125)</visible> + <left>2161</left> + <top>40</top> + <width>9</width> + <height>675</height> + <visible>true</visible> + <texturesliderbackground colordiffuse="66000000" border="4">script.plex/white-square-rounded-4r.png</texturesliderbackground> + <texturesliderbar colordiffuse="66FFFFFF" border="4">script.plex/white-square-rounded-4r.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="4">script.plex/white-square-rounded-4r.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + + </control> +</control> + + +<control type="group" id="200"> + <defaultcontrol always="true">201</defaultcontrol> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>135</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>135</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="grouplist"> + <posx>60</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>1000</width> + <height>{{ vscale(40) }}</height> + <align>left</align> + <itemgap>60</itemgap> + <orientation>horizontal</orientation> + <ondown>50</ondown> + <control type="group"> + <width>40</width> + <height>{{ vscale(40) }}</height> + <control type="button" id="201"> + <animation effect="zoom" start="100" end="144" time="100" center="20,{{ vscale(20) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="144" end="100" time="100" center="20,{{ vscale(20) }}" reversible="false">UnFocus</animation> + <width>40</width> + <height>{{ vscale(40) }}</height> + <onright>204</onright> + <ondown>50</ondown> + <font>font12</font> + <focusedcolor>FF000000</focusedcolor> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/home-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/home.png</texturenofocus> + <label> </label> + </control> + </control> + <control type="label"> + <width max="500">auto</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(heading)][/UPPERCASE]</label> + </control> + </control> + <control type="group"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>438</posx> + <posy>0</posy> + <control type="button" id="204"> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>-10</posx> + <posy>{{ vscale(38) }}</posy> + <width>260</width> + <height>{{ vscale(75) }}</height> + <onleft>201</onleft> + <ondown>50</ondown> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>right</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>100</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(48) }}</posy> + <width>42</width> + <height>{{ vscale(42) }}</height> + <texture>$INFO[Player.Art(thumb)]</texture> + </control> + + <control type="group"> + <visible>!Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(204)</visible> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(48) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>53</posx> + <posy>{{ vscale(72) }}</posy> + <width>187</width> + <height>{{ vscale(20) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <info>MusicPlayer.Title</info> + </control> + </control> + + <control type="progress"> + <description>Progressbar</description> + <posx>0</posx> + <posy>{{ vscale(102) }}</posy> + <width>240</width> + <height>{{ vscale(1) }}</height> + <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> + </control> + <control type="label"> + <right>213</right> + <posy>{{ vscale(35) }}</posy> + <width>200</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[System.Time]</label> + </control> + <control type="image"> + <posx>153r</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>93</width> + <height>{{ vscale(43) }}</height> + <texture>script.plex/home/plex.png</texture> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings_select_dialog.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings_select_dialog.xml.tpl new file mode 100644 index 0000000000..7a3fa27406 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-settings_select_dialog.xml.tpl @@ -0,0 +1,134 @@ +{% extends "base.xml.tpl" %} +{% block backgroundcolor %}{% endblock %} +{% block controls %} +<control type="group"> + <posx>660</posx> + <posy>{{ vscale(145) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>680</width> + <height>{{ vscale(870) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(80) }}</height> + <texture border="10">script.plex/white-square-top-rounded.png</texture> + <colordiffuse>F21F1F1F</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>600</width> + <height>{{ vscale(710) }}</height> + <texture flipy="true" border="10">script.plex/white-square-top-rounded.png</texture> + <colordiffuse>F2606060</colordiffuse> + </control> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B][UPPERCASE]$INFO[Window.Property(heading)][/UPPERCASE][/B]</label> + </control> + <control type="list" id="100"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>600</width> + <height>{{ vscale(700) }}</height> + <onup>noop</onup> + <ondown>noop</ondown> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(100) }}"> + <control type="label"> + <visible>String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>0</posy> + <width>560</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>{{ vscale(15) }}</posy> + <width>560</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>{{ vscale(40) }}</posy> + <width>560</width> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFBBBBBB</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(100) }}"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>600</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>0</posy> + <width>560</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>{{ vscale(15) }}</posy> + <width>560</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(ListItem.Label2)</visible> + <posx>20</posx> + <posy>{{ vscale(40) }}</posy> + <width>560</width> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF222222</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </focusedlayout> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_background.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_background.xml.tpl new file mode 100644 index 0000000000..fb6ea78fad --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_background.xml.tpl @@ -0,0 +1,18 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> +</control> +<control type="image"> + <posx>0</posx> + <posy>{% if core.needs_scaling %}{{ vperc(vscale(1080)) }}{% else %}0{% endif %}</posy> + <width>1920</width> + <height>{{ vscale(1080) }}</height> + <texture>script.plex/sign_in/back.jpg</texture> +</control> +{% endblock %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_blank.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_blank.xml.tpl new file mode 100644 index 0000000000..067f1bd94d --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-signin_blank.xml.tpl @@ -0,0 +1,46 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">script.plex/home/background-fallback_black.png</texture> +</control> +<control type="image"> + <posx>0</posx> + <posy>{% if core.needs_scaling %}{{ vperc(vscale(1080)) }}{% else %}0{% endif %}</posy> + <width>1920</width> + <height>{{ vscale(1080) }}</height> + <texture>script.plex/sign_in/back.jpg</texture> +</control> + +<control type="textbox"> + <posx>210</posx> + <posy>{{ vscale(375) }}</posy> + <width>1502</width> + <height>{{ vscale(530) }}</height> + <font>font13</font> + <textcolor>FFFFFFFF</textcolor> + <align>left</align> + <label>[B]$INFO[Window.Property(message)][/B]</label> +</control> + +<control type="button" id="100"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <font>font20</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> +</control> +{% endblock %} diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-slideshow.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-slideshow.xml.tpl new file mode 100644 index 0000000000..5cf4f05870 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-slideshow.xml.tpl @@ -0,0 +1,64 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<zorder>6</zorder>{% endblock %} +{% block backgroundcolor %}{% endblock %} +{% block coordinates %}{% endblock %} +{% block controls %} +<control type="group"> + <control type="image" id="1"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true"></texture> + <aspectratio>keep</aspectratio> + <fadetime>1000</fadetime> + <texture>$INFO[Window.Property(thumb)]</texture> + </control> + <control type="group" id="100"> + <posx>20</posx> + <posy>{{ vscale(20) }}</posy> + <height>{{ vscale(100) }}</height> + <width>1880</width> + <control type="label" id="101"> + <visible>String.IsEqual(Window.Property(align),0)</visible> + <posy>0</posy> + <height>{{ vscale(50) }}</height> + <font>font45</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <shadowcolor>FF000000</shadowcolor> + <label>$INFO[Window.Property(clock)]</label> + </control> + <control type="label" id="105"> + <visible>String.IsEqual(Window.Property(align),0)</visible> + <posy>{{ vscale(50) }}</posy> + <height>{{ vscale(20) }}</height> + <font>font13</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <shadowcolor>FF000000</shadowcolor> + <label>$INFO[Window.Property(title)]</label> + </control> + <control type="label" id="111"> + <visible>String.IsEqual(Window.Property(align),1)</visible> + <posy>0</posy> + <height>{{ vscale(50) }}</height> + <font>font45</font> + <align>right</align> + <textcolor>FFFFFFFF</textcolor> + <shadowcolor>FF000000</shadowcolor> + <label>$INFO[Window.Property(clock)]</label> + </control> + <control type="label" id="115"> + <visible>String.IsEqual(Window.Property(align),1)</visible> + <posy>{{ vscale(50) }}</posy> + <height>{{ vscale(20) }}</height> + <font>font13</font> + <align>right</align> + <textcolor>FFFFFFFF</textcolor> + <shadowcolor>FF000000</shadowcolor> + <label>$INFO[Window.Property(title)]</label> + </control> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-squares.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-squares.xml.tpl new file mode 100644 index 0000000000..d3478f17d3 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-squares.xml.tpl @@ -0,0 +1,412 @@ +{% extends "library_posters.xml.tpl" %} +{% block filteropts_grouplist %} +<control type="grouplist"> +<visible>String.IsEmpty(Window.Property(hide.filteroptions))</visible> +<right>340</right> +<posy>35</posy> +<width>1000</width> +<height>65</height> +<align>right</align> +<itemgap>30</itemgap> +<orientation>horizontal</orientation> +<onleft>204</onleft> +<onright>210</onright> +<ondown>50</ondown> +<control type="button" id="311"> + <enable>false</enable> + <width max="300">auto</width> + <height>65</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(filter2.display)][/UPPERCASE]</label> +</control> +<control type="button" id="211"> + <width max="500">auto</width> + <height>65</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(filter1.display)][/UPPERCASE]</label> +</control> +<control type="button" id="310"> + <visible>!String.IsEqual(Window.Property(media),artist)</visible> + <enable>false</enable> + <width max="300">auto</width> + <height>65</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturenofocus>-</texturenofocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> +</control> +<control type="button" id="312"> + <visible>String.IsEqual(Window.Property(media),artist)</visible> + <width max="300">auto</width> + <height>65</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <disabledcolor>FFFFFFFF</disabledcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(media.type)][/UPPERCASE]</label> +</control> +<control type="button" id="210"> + <width max="300">auto</width> + <height>65</height> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>20</textoffsetx> + <textoffsety>0</textoffsety> + <label>[UPPERCASE]$INFO[Window.Property(sort.display)][/UPPERCASE]</label> +</control> +</control> +{% endblock filteropts_grouplist %} +{% block content %} +<control type="group" id="50"> + <animation effect="slide" time="200" end="0,{{ vscale(-135) }}" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5)">Conditional</animation> + <animation effect="slide" time="200" end="0,{{ vscale(-200) }}" condition="Integer.IsGreater(Container(101).ListItem.Property(index),5) + Integer.IsGreater(Container(101).Position,5)">Conditional</animation> + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>101</defaultcontrol> + + {% block buttons %} + <control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <visible>!Integer.IsGreater(Container(101).ListItem.Property(index),5) + String.IsEmpty(Window.Property(no.content)) + String.IsEmpty(Window.Property(no.content.filtered)) + !String.IsEmpty(Window.Property(initialized))</visible> + <defaultcontrol>301</defaultcontrol> + <posx>30</posx> + <posy>{{ vscale(-25) }}</posy> + <width>1000</width> + <height>{{ vscale(145) }}</height> + <onup>200</onup> + <ondown>101</ondown> + <itemgap>-20</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + {% with attr = {"width": 126, "height": 100} & template = "includes/themed_button.xml.tpl" & hitrect = {"x": 20, "y": 20, "w": 86, "h": 60} %} + {% include template with name="play" & id=301 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="shuffle" & id=302 & visible="!String.IsEqual(Window(10000).Property(script.plex.item.type),collection) | String.IsEqual(Window.Property(media),collection)" %} + {% include template with name="more" & id=303 & visible="String.IsEmpty(Window.Property(no.options)) | Player.HasAudio" %} + {% include template with name="chapters" & id=304 & visible="String.IsEmpty(Window.Property(hide.filteroptions))" %} + {% endwith %} + + </control> + {% endblock %} + + <control type="group" id="100"> + <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>101</defaultcontrol> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <control type="panel" id="101"> + <hitrect x="0" y="95" w="1780" h="1185" /> + <posx>0</posx> + <posy>0</posy> + <width>1800</width> + <height>1280</height> + <onup>300</onup> + <onright>151</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>2</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="287" height="{{ vscale(343) }}"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(97) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>{{ vscale(244) }}</posy> + <width>244</width> + <height>{{ vscale(40) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>80000000</colordiffuse> + </control> + <control type="label"> + <scroll>true</scroll> + <posx>0</posx> + <posy>{{ vscale(244) }}</posy> + <width>244</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="287" height="{{ vscale(343) }}"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(97) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(374) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>{{ vscale(244) }}</posy> + <width>244</width> + <height>{{ vscale(40) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>80000000</colordiffuse> + </control> + <control type="label"> + <scroll>Control.HasFocus(101)</scroll> + <posx>0</posx> + <posy>{{ vscale(244) }}</posy> + <width>244</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.folder))</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(294) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> +</control> + +<control type="group" id="150"> + <visible>String.IsEqual(Window(10000).Property(script.plex.sort),titleSort) + Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>151</defaultcontrol> + <posx>1780</posx> + <posy>{{ vscale(150) }}</posy> + <width>20</width> + <height>920</height> + <control type="list" id="151"> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>1050</height> + <onleft>100</onleft> + <onright>152</onright> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="34"> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="label"> + <visible>!String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(letter))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>99FFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <visible>String.IsEqual(Window(10000).Property(script.plex.key), ListItem.Property(key))</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(32) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFE5A00D</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(151)</visible> + <posx>0</posx> + <posy>0</posy> + <width>34</width> + <height>{{ vscale(34) }}</height> + <colordiffuse>FFE5A00D</colordiffuse> + <texture border="12">script.plex/white-outline-rounded.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> +</control> + +<control type="scrollbar" id="152"> + <hitrect x="1820" y="150" w="100" h="910" /> + <left>1860</left> + <top>{{ vscale(150) }}</top> + <width>12</width> + <height>910</height> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-track_context.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-track_context.xml.tpl new file mode 100644 index 0000000000..bf6c3288f7 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-track_context.xml.tpl @@ -0,0 +1,58 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block controls %} +<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true" fallback="script.plex/home/background-fallback.png">$INFO[Window.Property(background)]</texture> +</control> + +<control type="image"> + <posx>236</posx> + <posy>{{ vscale(131) }}</posy> + <width>638</width> + <height>{{ vscale(638) }}</height> + <texture>$INFO[Window.Property(track.thumb)]</texture> +</control> + +<control type="textbox"> + <posx>236</posx> + <posy>{{ vscale(131) }}</posy> + <width>1502</width> + <height>{{ vscale(530) }}</height> + <font>font13</font> + <textcolor>FFFFFFFF</textcolor> + <align>left</align> + <label>[B]$INFO[Window.Property(message)][/B]</label> +</control> + +<control type="grouplist" id="300"> + <animation effect="fade" start="0" end="100" time="200" reversible="true">VisibleChange</animation> + <defaultcontrol>301</defaultcontrol> + <posx>965</posx> + <posy>{{ vscale(131) }}</posy> + <width>750</width> + <height>{{ vscale(638) }}</height> + <itemgap>30</itemgap> + <orientation>vertical</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <control type="button" id="100"> + <posx>30</posx> + <posy>{{ vscale(30) }}</posy> + <width>1920</width> + <height>1080</height> + <font>font20</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-user_select.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-user_select.xml.tpl new file mode 100644 index 0000000000..f897129b5a --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-user_select.xml.tpl @@ -0,0 +1,934 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block backgroundcolor %}<backgroundcolor>$INFO[Window.Property(background_colour_opaque)]</backgroundcolor>{% endblock %} +{% block controls %} +<control type="group"> + <visible>String.IsEmpty(Window.Property(use_solid_background))</visible> + <control type="image"> + <visible>String.IsEmpty(Window.Property(use_solid_background)) + String.IsEmpty(Window.Property(use_bg_fallback)) + String.IsEmpty(Window.Property(background_static))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/home/background-fallback_black.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(use_bg_fallback))</visible> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/home/background-fallback.png</texture> + </control> +</control> + +<control type="group"> + <animation effect="fade" time="100" start="100" end="20" condition="ControlGroup(400).HasFocus(0)">Conditional</animation> + <visible>Player.HasAudio + String.IsEmpty(Window(10000).Property(script.plex.theme_playing))</visible> + <posx>441</posx> + <posy>{{ vscale(780) }}</posy> + + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>225</width> + <height>{{ vscale(225) }}</height> + <texture>$INFO[Player.Art(thumb)]</texture> + </control> + + <control type="group"> + <posx>255</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>783</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Artist</info> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(40) }}</posy> + <width>783</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Album</info> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>783</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[MusicPlayer.Title][/B]</label> + </control> + </control> + + <control type="grouplist" id="600"> + <defaultcontrol>406</defaultcontrol> + <hitrect x="460" y="998" w="1000" h="55" /> + <posx>255</posx> + <posy>{{ vscale(134) }}</posy> + <width>783</width> + <height>{{ vscale(124) }}</height> + <align>center</align> + <onup>101</onup> + <itemgap>-40</itemgap> + <orientation>horizontal</orientation> + <scrolltime tween="quadratic" easing="out">200</scrolltime> + <usecontrolcoords>true</usecontrolcoords> + + <control type="button" id="404"> + <enable>MusicPlayer.HasPrevious</enable> + <animation effect="zoom" start="100" end="124" time="100" center="93,{{ vscale(50) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="124" end="100" time="100" center="93,{{ vscale(50) }}" reversible="false">UnFocus</animation> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>30</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus flipx="true" colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> + <texturenofocus flipx="true" colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> + <onclick>PlayerControl(Previous)</onclick> + <label> </label> + </control> + <control type="togglebutton" id="406"> + <animation effect="zoom" start="100" end="124" time="100" center="63,{{ vscale(50) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="124" end="100" time="100" center="63,{{ vscale(50) }}" reversible="false">UnFocus</animation> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/pause-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/pause.png</texturenofocus> + <usealttexture>Player.Paused | Player.Forwarding | Player.Rewinding</usealttexture> + <alttexturefocus colordiffuse="FFE5A00D">script.plex/buttons/play-focus.png</alttexturefocus> + <alttexturenofocus colordiffuse="99FFFFFF">script.plex/buttons/play.png</alttexturenofocus> + <onclick>PlayerControl(Play)</onclick> + <label> </label> + </control> + <control type="button" id="409"> + <enable>MusicPlayer.HasNext</enable> + <animation effect="zoom" start="100" end="124" time="100" center="63,{{ vscale(50) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="124" end="100" time="100" center="63,{{ vscale(50) }}" reversible="false">UnFocus</animation> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/next-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/next.png</texturenofocus> + <onclick>PlayerControl(Next)</onclick> + <label> </label> + </control> + <control type="button" id="407"> + <animation effect="zoom" start="100" end="124" time="100" center="63,{{ vscale(50) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="124" end="100" time="100" center="63,{{ vscale(50) }}" reversible="false">UnFocus</animation> + <hitrect x="28" y="28" w="69" h="45" /> + <posx>0</posx> + <posy>0</posy> + <width>125</width> + <height>{{ vscale(101) }}</height> + <font>font12</font> + <texturefocus colordiffuse="FFE5A00D">script.plex/buttons/stop-focus.png</texturefocus> + <texturenofocus colordiffuse="99FFFFFF">script.plex/buttons/stop.png</texturenofocus> + <onclick>PlayerControl(Stop)</onclick> + <label> </label> + </control> + </control> + + <control type="label"> + <posx>255</posx> + <posy>{{ vscale(177) }}</posy> + <width>783</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.Time</info> + </control> + <control type="label"> + <posx>1038</posx> + <posy>{{ vscale(177) }}</posy> + <width>783</width> + <height>{{ vscale(40) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <info>MusicPlayer.TimeRemaining</info> + </control> + + + <control type="progress"> + <description>Progressbar</description> + <posx>255</posx> + <posy>{{ vscale(222) }}</posy> + <width>783</width> + <height>{{ vscale(3) }}</height> + <texturebg colordiffuse="9AFFFFFF">script.plex/white-square-1px.png</texturebg> + <lefttexture>-</lefttexture> + <midtexture colordiffuse="FFCC7B19">script.plex/white-square-1px.png</midtexture> + <righttexture>-</righttexture> + <overlaytexture>-</overlaytexture> + <info>Player.Progress</info> + </control> +</control> + +<control type="image" id="110"> + <visible>ControlGroup(400).HasFocus(0) + String.IsEmpty(Window.Property(busy))</visible> + <posx>770</posx> + <posy>{{ vscale(275) }}</posy> + <width>380</width> + <height>{{ vscale(695) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> +</control> + +<control type="group" id="100"> + <posx>0</posx> + <posy>{{ vscale(315) }}</posy> + <defaultcontrol always="true">101</defaultcontrol> + + <control type="fixedlist" id="101"> + <posx>-180</posx> + <posy>{{ vscale(-40) }}</posy> + <width>2100</width> + <height>{{ vscale(455) }}</height> + <scrolltime>200</scrolltime> + <onup>500</onup> + <ondown condition="Player.HasAudio">600</ondown> + <ondown condition="!String.IsEmpty(Container(101).ListItem.Property(protected))">400</ondown> + <orientation>horizontal</orientation> + <focusposition>3</focusposition> + + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="330"> + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(empty))</visible> + <posx>0</posx> + <posy>{{ vscale(40) }}</posy> + <control type="image"> + <visible>Control.HasFocus(101) | ControlGroup(400).HasFocus(0)</visible> + <posx>75</posx> + <posy>{{ vscale(75) }}</posy> + <width>150</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/user_select/refresh.png</texture> + <colordiffuse>FFA0A0A0</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(empty))</visible> + <posx>0</posx> + <posy>{{ vscale(40) }}</posy> + <width>300</width> + <height>{{ vscale(300) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <texture diffuse="script.plex/user_select/item-background.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> + <colordiffuse>FFA0A0A0</colordiffuse> + </control> + + <control type="image"> + <posx>45</posx> + <posy>{{ vscale(45) }}</posy> + <width>210</width> + <height>{{ vscale(210) }}</height> + <texture>script.plex/user_select/avatar-background.png</texture> + <colordiffuse>E0C0C0C0</colordiffuse> + </control> + <control type="image"> + <posx>54</posx> + <posy>{{ vscale(54) }}</posy> + <width>192</width> + <height>{{ vscale(192) }}</height> + <texture diffuse="script.plex/user_select/avatar-diffuse.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Thumb]</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Thumb)</visible> + <posx>54</posx> + <posy>{{ vscale(54) }}</posy> + <width>192</width> + <height>{{ vscale(192) }}</height> + <font>WeatherTemp</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(protected))</visible> + <posx>15</posx> + <posy>{{ vscale(231) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/protected-back.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/protected-icon.png</texture> + </control> + </control> + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(admin))</visible> + <posx>231</posx> + <posy>{{ vscale(231) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/admin-back.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/admin-icon.png</texture> + </control> + </control> + </control> + + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="330"> + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(empty))</visible> + <posx>0</posx> + <posy>{{ vscale(40) }}</posy> + <control type="image"> + <visible>Control.HasFocus(101) | ControlGroup(400).HasFocus(0)</visible> + <posx>75</posx> + <posy>{{ vscale(75) }}</posy> + <width>150</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/user_select/refresh.png</texture> + <colordiffuse>FFFFFFFF</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(empty))</visible> + <posx>0</posx> + <posy>{{ vscale(40) }}</posy> + <control type="image" id="110"> + <visible>Control.HasFocus(101)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>380</width> + <height>{{ vscale(455) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <visible>Control.HasFocus(101) | ControlGroup(400).HasFocus(0)</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(300) }}</height> + <texture diffuse="script.plex/user_select/item-background-top.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> + <colordiffuse>FFA0A0A0</colordiffuse> + </control> + <control type="image"> + <visible>!Control.HasFocus(101) + !ControlGroup(400).HasFocus(0)</visible> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(300) }}</height> + <texture diffuse="script.plex/user_select/item-background.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> + <colordiffuse>FFA0A0A0</colordiffuse> + </control> + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(300) }}</posy> + <width>300</width> + <height>{{ vscale(75) }}</height> + <texture>script.plex/user_select/item-background-bottom.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(300) }}</posy> + <width>300</width> + <height>{{ vscale(75) }}</height> + <texture diffuse="script.plex/user_select/item-background-bottom.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Property(back.image)]</texture> + <aspectratio scalediffuse="false">stretch</aspectratio> + <colordiffuse>40FFFFFF</colordiffuse> + </control> + </control> + + <control type="image"> + <visible>!Control.HasFocus(101) + !ControlGroup(400).HasFocus(0)</visible> + <posx>45</posx> + <posy>{{ vscale(45) }}</posy> + <width>210</width> + <height>{{ vscale(210) }}</height> + <texture>script.plex/user_select/avatar-background.png</texture> + <colordiffuse>E0C0C0C0</colordiffuse> + </control> + <control type="image"> + <visible>ControlGroup(400).HasFocus(0)</visible> + <posx>45</posx> + <posy>{{ vscale(45) }}</posy> + <width>210</width> + <height>{{ vscale(210) }}</height> + <texture>script.plex/user_select/avatar-background.png</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>45</posx> + <posy>{{ vscale(45) }}</posy> + <width>210</width> + <height>{{ vscale(210) }}</height> + <texture>script.plex/user_select/avatar-background.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + + <control type="image"> + <posx>54</posx> + <posy>{{ vscale(54) }}</posy> + <width>192</width> + <height>{{ vscale(192) }}</height> + <texture diffuse="script.plex/user_select/avatar-diffuse.png" fallback="script.plex/gray-square.png">$INFO[ListItem.Thumb]</texture> + </control> + <control type="label"> + <visible>String.IsEmpty(ListItem.Thumb)</visible> + <posx>54</posx> + <posy>{{ vscale(54) }}</posy> + <width>192</width> + <height>{{ vscale(192) }}</height> + <font>WeatherTemp</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(protected))</visible> + <posx>15</posx> + <posy>{{ vscale(231) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/protected-back.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/protected-icon.png</texture> + </control> + </control> + + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(admin))</visible> + <posx>231</posx> + <posy>{{ vscale(231) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/admin-back.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>54</width> + <height>{{ vscale(54) }}</height> + <texture>script.plex/user_select/admin-icon.png</texture> + </control> + </control> + + <control type="label"> + <visible>Control.HasFocus(101)</visible> + <posx>10</posx> + <posy>{{ vscale(300) }}</posy> + <width>280</width> + <height>{{ vscale(75) }}</height> + <font>font13</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFCC7B19</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + + </focusedlayout> + </control> + + <control type="group" id="400"> + <defaultcontrol always="true">205</defaultcontrol> + <visible allowhiddenfocus="true">!String.IsEmpty(Container(101).ListItem.Property(protected)) + ControlGroup(400).HasFocus(0) + !String.IsEmpty(Window.Property(initialized))</visible> + <posx>810</posx> + <posy>{{ vscale(375) }}</posy> + <control type="button"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(239) }}</height> + <onleft>400</onleft> + <onright>400</onright> + <onup>400</onup> + <ondown>400</ondown> + <texturefocus>-</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(-75) }}</posy> + <width>300</width> + <height>{{ vscale(75) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(-75) }}</posy> + <width>300</width> + <height>{{ vscale(75) }}</height> + <texture fallback="script.plex/gray-square.png">$INFO[Container(101).ListItem.Property(back.image)]</texture> + <colordiffuse>40FFFFFF</colordiffuse> + </control> + <control type="label"> + <visible>String.IsEmpty(Container(101).ListItem.Property(editing.pin))</visible> + <posx>0</posx> + <posy>{{ vscale(-75) }}</posy> + <width>300</width> + <height>{{ vscale(75) }}</height> + <font>font13</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFCC7B19</textcolor> + <label>$INFO[Container(101).ListItem.Label]</label> + </control> + <control type="label"> + <visible>!String.IsEmpty(Container(101).ListItem.Property(editing.pin))</visible> + <posx>0</posx> + <posy>{{ vscale(-75) }}</posy> + <width>300</width> + <height>{{ vscale(75) }}</height> + <font>font13</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFCC7B19</textcolor> + <label>[B]$INFO[Container(101).ListItem.Property(pin)][/B]</label> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(239) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="group" id="300"> + <defaultcontrol>205</defaultcontrol> + <control type="group" id="200"> + <defaultcontrol>205</defaultcontrol> + <control type="button" id="201"> + <posx>0</posx> + <posy>0</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>202</onright> + <onup>101</onup> + <ondown>204</ondown> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]1[/B]</label> + </control> + <control type="button" id="202"> + <posx>75</posx> + <posy>0</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>203</onright> + <onleft>201</onleft> + <onup>101</onup> + <ondown>205</ondown> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]2[/B]</label> + </control> + <control type="button" id="203"> + <posx>150</posx> + <posy>0</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>211</onright> + <onleft>202</onleft> + <onup>101</onup> + <ondown>206</ondown> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]3[/B]</label> + </control> + <control type="button" id="204"> + <posx>0</posx> + <posy>{{ vscale(60) }}</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>205</onright> + <ondown>207</ondown> + <onup>201</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]4[/B]</label> + </control> + <control type="button" id="205"> + <posx>75</posx> + <posy>{{ vscale(60) }}</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>206</onright> + <onleft>204</onleft> + <ondown>208</ondown> + <onup>202</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]5[/B]</label> + </control> + <control type="button" id="206"> + <posx>150</posx> + <posy>{{ vscale(60) }}</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>211</onright> + <onleft>205</onleft> + <ondown>209</ondown> + <onup>203</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]6[/B]</label> + </control> + <control type="button" id="207"> + <posx>0</posx> + <posy>{{ vscale(120) }}</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>208</onright> + <ondown>210</ondown> + <onup>204</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]7[/B]</label> + </control> + <control type="button" id="208"> + <posx>75</posx> + <posy>{{ vscale(120) }}</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>209</onright> + <onleft>207</onleft> + <ondown>210</ondown> + <onup>205</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]8[/B]</label> + </control> + <control type="button" id="209"> + <posx>150</posx> + <posy>{{ vscale(120) }}</posy> + <width>73</width> + <height>{{ vscale(58) }}</height> + <onright>211</onright> + <onleft>208</onleft> + <ondown>210</ondown> + <onup>206</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]9[/B]</label> + </control> + </control> + <control type="button" id="210"> + <posx>0</posx> + <posy>{{ vscale(180) }}</posy> + <width>223</width> + <height>{{ vscale(59) }}</height> + <onright>211</onright> + <onup>200</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFCC7B19">script.plex/white-square.png</texturefocus> + <texturenofocus colordiffuse="FF333333">script.plex/white-square.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label>[B]0[/B]</label> + </control> + </control> + <control type="button" id="211"> + <posx>225</posx> + <posy>0</posy> + <width>75</width> + <height>{{ vscale(239) }}</height> + <onleft>300</onleft> + <onup>101</onup> + <font>font12</font> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FF000000</focusedcolor> + <align>center</align> + <aligny>center</aligny> + <texturefocus>script.plex/user_select/backspace.png</texturefocus> + <texturenofocus>script.plex/user_select/backspace_nf.png</texturenofocus> + <textoffsetx>0</textoffsetx> + <textoffsety>0</textoffsety> + <label> </label> + </control> + </control> + +</control> + +<control type="group"> + <defaultcontrol always="true">201</defaultcontrol> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(135) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>19000000</colordiffuse> + </control> + + <control type="grouplist"> + <posx>60</posx> + <posy>{{ vscale(34.5) }}</posy> + <width>1000</width> + <height>{{ vscale(66) }}</height> + <align>left</align> + <itemgap>60</itemgap> + <orientation>horizontal</orientation> + <ondown>101</ondown> + <usecontrolcoords>true</usecontrolcoords> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <width>124</width> + <height>{{ vscale(66) }}</height> + <control type="button" id="500"> + <posx>0</posx> + <posy>0</posy> + <width>124</width> + <height>{{ vscale(66) }}</height> + <ondown>101</ondown> + <onright>101</onright> + <align>right</align> + <aligny>center</aligny> + <texturefocus colordiffuse="FFE5A00D" border="10">script.plex/white-square-rounded.png</texturefocus> + <texturenofocus>-</texturenofocus> + <label> </label> + </control> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(dropdown))</visible> + <posx>0</posx> + <posy>0</posy> + <width>124</width> + <height>{{ vscale(66) }}</height> + <texture colordiffuse="FFCC7B19" border="10">script.plex/white-square-rounded.png</texture> + </control> + <control type="group"> + <posx>27</posx> + <posy>{{ vscale(13) }}</posy> + <control type="group"> + <visible>!Control.HasFocus(500) + String.IsEmpty(Window.Property(dropdown))</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>40</width> + <height>{{ vscale(40) }}</height> + <texture colordiffuse="99FFFFFF">script.plex/buttons/power.png</texture> + </control> + <control type="image"> + <posx>55</posx> + <posy>{{ vscale(13.5) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture colordiffuse="99FFFFFF">script.plex/indicators/dropdown-triangle.png</texture> + </control> + </control> + <control type="group"> + <visible>Control.HasFocus(500) | !String.IsEmpty(Window.Property(dropdown))</visible> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>40</width> + <height>{{ vscale(40) }}</height> + <texture colordiffuse="FF000000">script.plex/buttons/power.png</texture> + </control> + <control type="image"> + <posx>55</posx> + <posy>{{ vscale(13.5) }}</posy> + <width>15</width> + <height>{{ vscale(13) }}</height> + <texture colordiffuse="FF000000">script.plex/indicators/dropdown-triangle.png</texture> + </control> + </control> + </control> + </control> + <control type="label"> + <posx>-27</posx> + <posy>0</posy> + <width max="500">auto</width> + <height>{{ vscale(66) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32437][/UPPERCASE]</label> + </control> + </control> + + <control type="label"> + <right>213</right> + <posy>{{ vscale(35) }}</posy> + <width>200</width> + <height>{{ vscale(65) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[System.Time]</label> + </control> + <control type="image"> + <posx>153r</posx> + <posy>{{ vscale(47.5) }}</posy> + <width>93</width> + <height>{{ vscale(43) }}</height> + <texture>script.plex/home/plex.png</texture> + </control> +</control> + +<control type="group"> + <visible>!String.IsEmpty(Window.Property(busy))</visible> + <animation effect="fade" start="0" end="100">Visible</animation> + <control type="image"> + <posx>840</posx> + <posy>{{ vperc(vscale(150)) }}</posy> + <width>240</width> + <height>{{ vscale(150) }}</height> + <texture>script.plex/busy-back.png</texture> + <colordiffuse>A0FFFFFF</colordiffuse> + </control> + <control type="image"> + <posx>915</posx> + <posy>{{ vperc(vscale(38)) }}</posy> + <width>90</width> + <height>{{ vscale(38) }}</height> + <texture diffuse="script.plex/busy-diffuse.png">script.plex/busy.gif</texture> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_current_playlist.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_current_playlist.xml.tpl new file mode 100644 index 0000000000..1d1eeb7031 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_current_playlist.xml.tpl @@ -0,0 +1,451 @@ +{% extends "base.xml.tpl" %} +{% block headers %}<defaultcontrol>100</defaultcontrol>{% endblock %} +{% block controls %} +<control type="group"> + <control type="group" id="100"> + <!-- <visible>Integer.IsGreater(Container(101).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> --> + <defaultcontrol>101</defaultcontrol> + <posx>750</posx> + <posy>{{ vscale(140) }}</posy> + <width>1170</width> + <height>{{ vscale(800) }}</height> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>{{ vscale(800) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>B3111111</colordiffuse> + </control> + <control type="list" id="101"> + <posx>0</posx> + <posy>0</posy> + <width>1170</width> + <height>{{ vscale(800) }}</height> + <onup>200</onup> + <onright>152</onright> + <onleft>300</onleft> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <preloaditems>4</preloaditems> + <pagecontrol>152</pagecontrol> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(101) }}"> + <control type="group"> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(playing))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(playing))</visible> + <posx>2</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>168</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>132</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=132+63 & yoff=11 & uw_posy=11 & uw_size=24 & scale="tiny" %} + <control type="group"> + <posx>226</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="label"> + <posx>730</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(98) }}</posy> + <width>930</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout height="{{ vscale(100) }}"> + <control type="group"> + <control type="group"> + <visible>!Control.HasFocus(101)</visible> + <posx>120</posx> + <posy>{{ vscale(24) }}</posy> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(playing))</visible> + <posx>-10</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(playing))</visible> + <posx>0</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>74</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>168</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>692</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>63</posx> + <posy>{{ vscale(11) }}</posy> + <width>132</width> + <height>{{ vscale(74) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=132+63 & yoff=11 & uw_posy=11 & uw_size=24 & scale="tiny" %} + <control type="group"> + <posx>226</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(15) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(50) }}</posy> + <width>584</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>B8FFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="label"> + <posx>756</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font10</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>D8FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.footer))</visible> + <posx>0</posx> + <posy>{{ vscale(97) }}</posy> + <width>930</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + </control> + + <control type="group"> + <visible>Control.HasFocus(101)</visible> + <posx>63</posx> + <posy>{{ vscale(21) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>1124</width> + <height>{{ vscale(180) }}</height> + <texture border="40">script.plex/square-rounded-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1044</width> + <height>{{ vscale(100) }}</height> + <texture border="12">script.plex/white-square-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <!-- comment the previous and uncomment the following for re-enabling options button --> + <!--<control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>999</width> + <height>{{ vscale(100) }}</height> + <texture border="12">script.plex/white-square-left-rounded.png</texture> + <colordiffuse>FFE5A00D</colordiffuse> + </control> + <control type="image"> + <posx>999</posx> + <posy>0</posy> + <width>45</width> + <height>{{ vscale(100) }}</height> + <texture>script.plex/buttons/more-vertical.png</texture> + <colordiffuse>99FFFFFF</colordiffuse> + </control>--> + <control type="label"> + <visible>String.IsEmpty(ListItem.Property(playing))</visible> + <posx>24</posx> + <posy>0</posy> + <width>60</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.number)][/B]</label> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(playing))</visible> + <posx>36</posx> + <posy>{{ vscale(32.5) }}</posy> + <width>35</width> + <height>{{ vscale(35) }}</height> + <texture>script.plex/indicators/playing-circle.png</texture> + <colordiffuse>FF000000</colordiffuse> + </control> + <control type="group"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(video))</visible> + <posx>103</posx> + <posy>0</posy> + <width>100</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>235</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>638</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(51) }}</posy> + <width>638</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>98000000</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(video))</visible> + <control type="image"> + <posx>103</posx> + <posy>0</posy> + <width>178</width> + <height>{{ vscale(100) }}</height> + <texture>$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=178+103 %} + <control type="group"> + <posx>313</posx> + <posy>0</posy> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>510</width> + <height>{{ vscale(30) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>DF000000</textcolor> + <label>[B]$INFO[ListItem.Label][/B]</label> + </control> + <control type="label"> + <posx>0</posx> + <posy>{{ vscale(51) }}</posy> + <width>510</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>98000000</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + <control type="label"> + <posx>802</posx> + <posy>0</posy> + <width>200</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>B8000000</textcolor> + <label>[B]$INFO[ListItem.Property(track.duration)][/B]</label> + </control> + </control> + </control> + + </focusedlayout> + </control> + + <control type="scrollbar" id="152"> + <hitrect x="1108" y="33" w="90" h="734" /> + <left>1128</left> + <top>33</top> + <width>10</width> + <height>{{ vscale(734) }}</height> + <onleft>101</onleft> + <visible>true</visible> + <texturesliderbackground colordiffuse="40000000" border="5">script.plex/white-square-rounded.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square-rounded.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square-rounded.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>151</onleft> + </control> + </control> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_player.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_player.xml.tpl new file mode 100644 index 0000000000..a9224f9adc --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_player.xml.tpl @@ -0,0 +1,1014 @@ +{% extends "default.xml.tpl" %} +{% block header %} +<control type="group"> + <visible>!String.IsEmpty(Window.Property(post.play))</visible> + {{ super() }} +</control> +{% endblock header %} + +{% block content %} +<control type="group"> + <visible>!String.IsEmpty(Window.Property(post.play))</visible> + <control type="group"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture background="true">$INFO[Window.Property(post.play.background)]</texture> + {% include "includes/scale_background.xml.tpl" %} + </control> + </control> + + <control type="group" id="50"> + <animation effect="slide" end="0,{{ vscale(-300) }}" time="200" tween="quadratic" easing="out" condition="!String.IsEmpty(Window.Property(on.extras))">Conditional</animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <animation type="Conditional" condition="Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)" reversible="true"> + <effect type="slide" end="0,{{ vscale(-500) }}" time="200" tween="quadratic" easing="out"/> + </animation> + + <posx>0</posx> + <posy>{{ vscale(135) }}</posy> + <defaultcontrol>102</defaultcontrol> + + <control type="image"> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + + <control type="label"> + <scroll>false</scroll> + <posx>60</posx> + <posy>{{ vscale(57) }}</posy> + <width>462</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>A0FFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32438][/UPPERCASE]</label> + </control> + + <control type="group" id="100"> + <defaultcontrol>102</defaultcontrol> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(580) }}</height> + <control type="group"> + <posx>60</posx> + <posy>{{ vscale(131) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="231,{{ vscale(129.5) }}" reversible="true" condition="Control.HasFocus(101)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(101)</visible> + <posx>-45</posx> + <posy>{{ vscale(-45) }}</posy> + <width>552</width> + <height>{{ vscale(349) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>462</width> + <height>{{ vscale(259) }}</height> + <texture>$INFO[Window.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>462</width> + <height>{{ vscale(259) }}</height> + <texture background="true">$INFO[Window.Property(prev.thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <posx>193</posx> + <posy>{{ vscale(91.5) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>76</width> + <height>{{ vscale(76) }}</height> + <texture colordiffuse="99000000">script.plex/indicators/circle-152.png</texture> + </control> + <control type="image"> + <posx>15</posx> + <posy>{{ vscale(15) }}</posy> + <width>46</width> + <height>{{ vscale(46) }}</height> + <texture>script.plex/indicators/replay.png</texture> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(269) }}</posy> + <width>462</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(prev.title)]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(301) }}</posy> + <width>462</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(prev.subtitle)]</label> + </control> + </control> + <control type="button" id="101"> + <posx>-5</posx> + <posy>{{ vscale(-5) }}</posy> + <width>472</width> + <height>{{ vscale(269) }}</height> + <onup>200</onup> + <ondown>400</ondown> + <onright>102</onright> + <texturefocus border="10">script.plex/home/selected.png</texturefocus> + <texturenofocus>-</texturenofocus> + </control> + </control> + </control> + + <control type="group"> + <visible>!String.IsEmpty(Window.Property(has.next))</visible> + <control type="label"> + <scroll>false</scroll> + <posx>572</posx> + <posy>{{ vscale(57) }}</posy> + <width>462</width> + <height>{{ vscale(40) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32439][/UPPERCASE]</label> + </control> + <control type="group"> + <posx>582</posx> + <posy>{{ vscale(131) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="268.5,{{ vscale(151.5) }}" reversible="true" condition="Control.HasFocus(102)">Conditional</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(102)</visible> + <posx>-45</posx> + <posy>{{ vscale(-45) }}</posy> + <width>627</width> + <height>{{ vscale(393) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>537</width> + <height>{{ vscale(303) }}</height> + <texture>$INFO[Window.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>537</width> + <height>{{ vscale(303) }}</height> + <texture background="true">$INFO[Window.Property(next.thumb)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(Window.Property(countdown)) + Integer.IsGreaterOrEqual(Window.Property(countdown), 0)</visible> + <posx>192.5</posx> + <posy>{{ vscale(75.5) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>152</width> + <height>{{ vscale(152) }}</height> + <texture colordiffuse="99000000">script.plex/indicators/circle-152.png</texture> + </control> + <control type="image"> + <posx>8</posx> + <posy>8</posy> + <width>136</width> + <height>{{ vscale(136) }}</height> + <texture colordiffuse="FFCC7B19">script.plex/circle-progress/$INFO[Window.Property(countdown)].png</texture> + </control> + <control type="image"> + <posx>59.5</posx> + <posy>{{ vscale(57) }}</posy> + <width>33</width> + <height>{{ vscale(38) }}</height> + <texture>script.plex/indicators/pause.png</texture> + </control> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(313) }}</posy> + <width>537</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(next.title)]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(345) }}</posy> + <width>537</width> + <height>{{ vscale(30) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(next.subtitle)]</label> + </control> + </control> + <control type="button" id="102"> + <posx>-5</posx> + <posy>{{ vscale(-5) }}</posy> + <width>547</width> + <height>{{ vscale(313) }}</height> + <onup>200</onup> + <ondown>400</ondown> + <onleft>101</onleft> + <texturefocus border="10">script.plex/home/selected.png</texturefocus> + <texturenofocus>-</texturenofocus> + </control> + </control> + </control> + </control> + </control> + + <control type="group"> + <visible>!String.IsEmpty(Window.Property(has.next))</visible> + <control type="label"> + <scroll>false</scroll> + <posx>1177</posx> + <posy>{{ vscale(131) }}</posy> + <width>683</width> + <height>{{ vscale(43) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Window.Property(info.title)][/B]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>1177</posx> + <posy>{{ vscale(189) }}</posy> + <width>683</width> + <height>{{ vscale(32) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>A0FFFFFF</textcolor> + <label>$INFO[Window.Property(info.date)]$INFO[Window.Property(info.duration), • ]</label> + </control> + <control type="textbox"> + <scroll>false</scroll> + <posx>1177</posx> + <posy>{{ vscale(300) }}</posy> + <width>683</width> + <height>{{ vscale(215) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(info.summary)]</label> + </control> + </control> + + <control type="group"> + <visible>String.IsEmpty(Window.Property(has.next))</visible> + <control type="label"> + <scroll>false</scroll> + <posx>580</posx> + <posy>{{ vscale(131) }}</posy> + <width>1280</width> + <height>{{ vscale(43) }}</height> + <font>font13</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[Window.Property(prev.info.title)][/B]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>580</posx> + <posy>{{ vscale(189) }}</posy> + <width>1280</width> + <height>{{ vscale(32) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>A0FFFFFF</textcolor> + <label>$INFO[Window.Property(prev.info.date)]$INFO[Window.Property(prev.info.duration), • ]</label> + </control> + <control type="textbox"> + <scroll>false</scroll> + <posx>580</posx> + <posy>{{ vscale(300) }}</posy> + <width>1280</width> + <height>{{ vscale(225) }}</height> + <font>font12</font> + <align>left</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[Window.Property(prev.info.summary)]</label> + </control> + </control> + </control> + + <control type="grouplist" id="60"> + <posx>0</posx> + <posy>{{ vscale(530) }}</posy> + <width>1920</width> + <height>{{ vscale(1610) }}</height> + + <onup>300</onup> + <itemgap>0</itemgap> + + <control type="group" id="500"> + <visible>Integer.IsGreater(Container(400).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <height>{{ vscale(360) }}</height> + <width>1920</width> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>{{ vscale(360) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>40000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>800</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32440][/UPPERCASE]</label> + </control> + <control type="list" id="400"> + <posx>0</posx> + <posy>{{ vscale(18) }}</posy> + <width>1920</width> + <height>{{ vscale(430) }}</height> + <onup>100</onup> + <ondown>401</ondown> + <onleft>false</onleft> + <onright>false</onright> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(158) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>299</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=299 & uw_size=35 & wbg_w=40 & wbg_h=32 %} + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(180) }}</posy> + <width>299</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(212) }}</posy> + <width>299</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>85.5</posx> + <posy>{{ vscale(20) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="359"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="154.5,{{ vscale(87.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>389</width> + <height>{{ vscale(258) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(158) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>299</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=299 & uw_size=35 & wbg_w=40 & wbg_h=32 %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(180) }}</posy> + <width>299</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(212) }}</posy> + <width>299</width> + <height>{{ vscale(35) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>299</width> + <height>{{ vscale(168) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>119</posx> + <posy>{{ vscale(34) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>85.5</posx> + <posy>{{ vscale(20) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(400)</visible> + <posx>0</posx> + <posy>0</posy> + <width>309</width> + <height>{{ vscale(178) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="501"> + <visible>Integer.IsGreater(Container(401).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>401</defaultcontrol> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(divider.401))</visible> + <posx>60</posx> + <posy>0</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$INFO[Window.Property(related.header)][/UPPERCASE]</label> + </control> + <control type="list" id="401"> + <posx>0</posx> + <posy>{{ vscale(16) }}</posy> + <width>1920</width> + <height>{{ vscale(520) }}</height> + <onup>400</onup> + <ondown>403</ondown> + <onleft>false</onleft> + <onright>false</onright> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(72) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(180.5) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(180.5) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>324</width> + <height>{{ vscale(441) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(is.boundary))</visible> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture colordiffuse="FF404040">script.plex/white-square.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(right.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white.png</texture> + </control> + <control type="image"> + <visible>String.IsEmpty(ListItem.Property(is.updating)) + !String.IsEmpty(ListItem.Property(left.boundary))</visible> + <posx>91.5</posx> + <posy>{{ vscale(130.5) }}</posy> + <width>61</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="40000000">script.plex/indicators/chevron-white-l.png</texture> + </control> + <control type="image"> + <visible>!String.IsEmpty(ListItem.Property(is.updating))</visible> + <posx>58</posx> + <posy>{{ vscale(116.5) }}</posy> + <width>128</width> + <height>{{ vscale(128) }}</height> + <texture>script.plex/home/busy.gif</texture> + </control> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture>$INFO[ListItem.Property(thumb.fallback)]</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(361) }}</height> + <texture background="true">$INFO[ListItem.Thumb]</texture> + <aspectratio>scale</aspectratio> + </control> + <control type="group"> + <visible>!String.IsEmpty(ListItem.Property(progress))</visible> + <posx>0</posx> + <posy>{{ vscale(351) }}</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(10) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>C0000000</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>1</posy> + <width>244</width> + <height>{{ vscale(8) }}</height> + <texture>$INFO[ListItem.Property(progress)]</texture> + <colordiffuse>FFCC7B19</colordiffuse> + </control> + </control> + {% include "includes/watched_indicator.xml.tpl" with xoff=244 & uw_size=48 & with_count=True & scale="medium" %} + <control type="label"> + <scroll>false</scroll> + <posx>0</posx> + <posy>{{ vscale(369) }}</posy> + <width>244</width> + <height>{{ vscale(38) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(401)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(371) }}</height> + <texture border="10">script.plex/home/selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + + <control type="group" id="503"> + <visible>Integer.IsGreater(Container(403).NumItems,0) + String.IsEmpty(Window.Property(drawing))</visible> + <defaultcontrol>403</defaultcontrol> + <width>1920</width> + <height>{{ vscale(410) }}</height> + <control type="image"> + <visible>!String.IsEmpty(Window.Property(divider.403))</visible> + <posx>60</posx> + <posy>{{ vscale(20) }}</posy> + <width>1800</width> + <height>{{ vscale(2) }}</height> + <texture>script.plex/white-square.png</texture> + <colordiffuse>A0000000</colordiffuse> + </control> + <control type="label"> + <posx>60</posx> + <posy>{{ vscale(20) }}</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[UPPERCASE]$ADDON[script.plexmod 32419][/UPPERCASE]</label> + </control> + <control type="list" id="403"> + <posx>0</posx> + <posy>{{ vscale(36) }}</posy> + <width>1920</width> + <height>{{ vscale(410) }}</height> + <onup>401</onup> + <ondown>404</ondown> + <scrolltime>200</scrolltime> + <orientation>horizontal</orientation> + <preloaditems>4</preloaditems> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <width>244</width> + <height>{{ vscale(90) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label][CR]$INFO[ListItem.Label2]</label> + </control> + </control> + </control> + </itemlayout> + + <!-- FOCUSED LAYOUT ####################################### --> + <focusedlayout width="304"> + <control type="group"> + <posx>55</posx> + <posy>{{ vscale(61) }}</posy> + <control type="group"> + <animation effect="zoom" start="100" end="110" time="100" center="127,{{ vscale(127) }}" reversible="false">Focus</animation> + <animation effect="zoom" start="110" end="100" time="100" center="127,{{ vscale(127) }}" reversible="false">UnFocus</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>334</width> + <height>{{ vscale(334) }}</height> + <texture border="42">script.plex/buttons/role-shadow.png</texture> + </control> + <control type="group"> + <posx>5</posx> + <posy>5</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture diffuse="script.plex/masks/role.png">script.plex/thumb_fallbacks/role.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>244</width> + <height>{{ vscale(244) }}</height> + <texture background="true" diffuse="script.plex/masks/role.png">$INFO[ListItem.Thumb]</texture> + <aspectratio scalediffuse="false" aligny="top">scale</aspectratio> + </control> + <control type="textbox"> + <posx>0</posx> + <posy>{{ vscale(253) }}</posy> + <width>244</width> + <height>{{ vscale(90) }}</height> + <font>font10</font> + <align>center</align> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label][CR]$INFO[ListItem.Label2]</label> + </control> + </control> + <control type="image"> + <visible>Control.HasFocus(403)</visible> + <posx>0</posx> + <posy>0</posy> + <width>254</width> + <height>{{ vscale(254) }}</height> + <texture>script.plex/buttons/role-selected.png</texture> + </control> + </control> + </control> + </focusedlayout> + </control> + </control> + </control> + </control> +</control> +{% endblock content %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_settings_dialog.xml.tpl b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_settings_dialog.xml.tpl new file mode 100644 index 0000000000..cd387171b0 --- /dev/null +++ b/script.plexmod/resources/skins/Main/1080i/templates/script-plex-video_settings_dialog.xml.tpl @@ -0,0 +1,151 @@ +{% extends "base.xml.tpl" %} +{% block backgroundcolor %}{% endblock %} +{% block controls %} +<control type="group"> + <visible>String.IsEmpty(Window.Property(is_plextuary)) + !String.IsEmpty(Window.Property(via.OSD)) + !Window.IsVisible(sliderdialog)</visible> + <animation effect="fade" start="100" end="0">Hidden</animation> + <posx>0</posx> + <posy>0</posy> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1920</width> + <height>1080</height> + <texture>script.plex/player-fade.png</texture> + <colordiffuse>FF080808</colordiffuse> + </control> +</control> +<control type="group"> + <visible>!Window.IsVisible(sliderdialog) + !Window.IsVisible(osdvideosettings) + !Window.IsVisible(osdaudiosettings) + !Window.IsVisible(osdsubtitlesettings) + !Window.IsVisible(subtitlesearch) + !Window.IsActive(selectdialog) + !Window.IsVisible(osdcmssettings)</visible> + <posx>460</posx> + <posy>{{ vperc(vscale(600)) }}</posy> + <control type="image"> + <posx>-40</posx> + <posy>{{ vscale(-40) }}</posy> + <width>1080</width> + <height>{{ vscale(770) }}</height> + <texture border="42">script.plex/drop-shadow.png</texture> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <texture border="10">script.plex/white-square-top-rounded.png</texture> + <colordiffuse>F21F1F1F</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>1000</width> + <height>{{ vscale(610) }}</height> + <texture flipy="true" border="10">script.plex/white-square-top-rounded.png</texture> + <colordiffuse>F2606060</colordiffuse> + </control> + <control type="image"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>400</width> + <height>{{ vscale(610) }}</height> + <texture flipy="true" border="10">script.plex/white-square-tl-rounded.png</texture> + <colordiffuse>30000000</colordiffuse> + </control> + <control type="label"> + <posx>0</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(80) }}</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B][UPPERCASE]$INFO[Window.Property(heading)][/UPPERCASE][/B]</label> + </control> + <control type="list" id="100"> + <posx>0</posx> + <posy>{{ vscale(80) }}</posy> + <width>990</width> + <height>{{ vscale(600) }}</height> + <onup>noop</onup> + <ondown>noop</ondown> + <scrolltime>200</scrolltime> + <orientation>vertical</orientation> + <pagecontrol>101</pagecontrol> + <onright>101</onright> + <!-- ITEM LAYOUT ########################################## --> + <itemlayout height="{{ vscale(100) }}"> + <control type="label"> + <posx>20</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>320</posx> + <posy>0</posy> + <width>650</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </itemlayout> + <focusedlayout height="{{ vscale(100) }}"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>1000</width> + <height>{{ vscale(100) }}</height> + <texture colordiffuse="FFE5A00D">script.plex/white-square.png</texture> + </control> + <control type="label"> + <posx>20</posx> + <posy>0</posy> + <width>300</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label]</label> + </control> + <control type="label"> + <posx>320</posx> + <posy>0</posy> + <width>650</width> + <height>{{ vscale(100) }}</height> + <font>font12</font> + <align>right</align> + <aligny>center</aligny> + <textcolor>FF000000</textcolor> + <label>$INFO[ListItem.Label2]</label> + </control> + </focusedlayout> + </control> +</control> +<control type="scrollbar" id="101"> + <hitrect x="1108" y="33" w="90" h="734" /> + <left>1450</left> + <top>{{ vperc(vscale(600)) + vscale(80) }}</top> + <width>10</width> + <height>{{ vscale(600) }}</height> + <onleft>100</onleft> + <visible>!Window.IsVisible(sliderdialog) + Control.IsVisible(100) + !Window.IsVisible(osdvideosettings) + !Window.IsVisible(osdaudiosettings) + !Window.IsVisible(osdsubtitlesettings) + !Window.IsVisible(subtitlesearch) + !Window.IsVisible(osdcmssettings)</visible> + <texturesliderbackground colordiffuse="30000000" border="5">script.plex/white-square.png</texturesliderbackground> + <texturesliderbar colordiffuse="77FFFFFF" border="5">script.plex/white-square.png</texturesliderbar> + <texturesliderbarfocus colordiffuse="FFE5A00D" border="5">script.plex/white-square.png</texturesliderbarfocus> + <textureslidernib>-</textureslidernib> + <textureslidernibfocus>-</textureslidernibfocus> + <pulseonselect>false</pulseonselect> + <orientation>vertical</orientation> + <showonepage>false</showonepage> + <onleft>100</onleft> +</control> +{% endblock controls %} \ No newline at end of file diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/chapters-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/chapters-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..52cef8e6420f0958fc1770f0dd58dde12505a06b GIT binary patch literal 451 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|Dgt~$T!HlefdI!=JXr&@TfHR6FPI_r@Pf)yGv7R~`S{x6Lc)iJ7qxTt zm%J;Ae7kMe=T9g5=k^qrg`e2{VxnX@P|G$?7srr_TW_zO&TC2#X${ofrm-Sq^|pI& zeeeC}&E@+iJekk;z#7xvhf<D9SnQPp>VSfR>|j3UpK?E^n$N6v`*$Yo?B(LsZt|~I zS3b!;75v2H>5|aJ^DnJ&e4_ExJH`I#=8JC9weI`>@3Fmi>(93vVwD=xCf?tz_Wk&Y z{;RtxcYSbWp0ms^czgRrH*4Ry%Rp9?oUvHFsqng6dTDHWtaR+(-gSR2{ksgdoc{^a W<}ACkMHBvpgZQ4VelF{r5}E)g$pgax literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/chapters.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/chapters.png new file mode 100644 index 0000000000000000000000000000000000000000..62a5941fbf5bf31df380ed75cc7c7c6ac62828e7 GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|@&kNAT!Hj|Is*O6Oc#Mxs+0uz1vAvdzCK(z^Ud>9A73O~sBM@NzUy7d z=l#1+7Qda_U(~bhQ`w2gc{g`11gf9q>EaktaqI21oqSCJBCdfVqO8v==l%aL?W?!% z*pW*uN4D;gofT}GH;oaf7z*a=RoXvUej+w7y|8aiXz1V4%PTJ4etz4cXwoMEOCQUu zD=++JUG2?T`o?uzFkg?^trzmU>ML!R`PSJ!OBFno`Xo2>`B#ab5pQ0v&#pH)kon4_ nv|1u}%jGMXpb&?E1MwA%b6U-}Tbl|RgG4-C{an^LB{Ts5COhN8 literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/info-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/info-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..5d076f7ed5445d7e760bd6fb92ee797dee70d86d GIT binary patch literal 1777 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-HD>U~&ua32_Aq{vQRSAwXFO+>H7B449G*mIV0)GrY3kWMmVtU*P+J>Fd+` zTVGr|UE%%f@4la`n$8>9Z%e;Z5fAzFHgM1DH|~!+jCnra3;!K?_@P_Izdx5)I85gU zNI5RCPI$IDA~*E}^P}&!UnH}1Eq5OID7<;@x7`kFtCF5ye94=<CO!7%CgnLMp3AzA z%?Q#7HZ;GLBdB#lraVe^QN3bWqeRJcyE}S6yk=^PTn@Xi!{4g&`c$K<MaOG*`7JGw zpT%_`v%hb{exFHqi?ic3wm<3RR#!?}zoL@AUG=<6|IC@E7#NsqJY5_^DsH`<6&@|@ zDAFcADWS!|Dc{LqNqK<dgmsG=6hf;4yY_y+SN$GDoVG7Mr#9nk)0%rfWNP+(|1^7N z#Z1Yx=Vx3d0mB6g_}}v4-!xIlz@28Z&t6`BC}MY}h=zaMGvlMn6jrQyze_wjS^xX9 zu-gJ@$G3-nDwV50_eADl*yQ3P{Pr7*O8w@(D427-Y|Cfo%4ciV{+8Y&J2BqW|M`-X z_WOC?e>UH|t!gg)cBN|D;$nw2I@=SXHfEhod47`D_vxQG$5kdpUOQ#!JiE`HW8t=0 zOYh7ncbzmn{oIGO%z0O4)$~mNe5EyIs>Ju(cccHc*L-Q6TEdr`|5AOf<Gyx<kd2Qr zzdrf3`B%~JOAd8mDy;jOgj_$&sq$Hstn$|1Ep4un=E5Z&f-md?KZTw@R(V?Wp>Xwq zRAa@X8};VTduejzV$PEAiHR${zcep0)w{^rwQGlk^fXTC;F;cHX*xP4>q>hUxol^X z6@Iz*?xD0rul9&18n~?JTe94BJLmhIGFBP)=4XE2?f!R@<XhRD>05uV<r9$&p5bv{ zOpkMwar-^*_2J?=(zPzfC4H8hJ*1kyFDv9YCs&N|-PntTtimtl9ty3wC3-0H@4BG3 zM&>TtW_FsK-Br2j)e@^GkCi+ZcDqhH=<=(jp!53Q#u80YPM;<5oYUu-<YvZhIH5Je z<MNvG((85Kehf*G^;u&5@>s&$Z6y++v8Q)V*`i_*9KCD$CPuYOVXGLLw=P|&VqBZ7 zBzw_aePM|1OV>~L%i2%hG?~m3y=BS$fGg*hmF#r=&Yt&G+55V$Q0I4Rv#H&6>Y8OC zeId$TtyAti4_5X{WWOqXV%LeUuaysr9^9g{>%#66FZmu82~6GAFWRo0UAQr{P%d+N ze)hKwyViJSE33ahxj$R~^n!2N#gU%g`cJFlw&xz+KCe=DyO_rriy-CwAxkQFjCsQ^ zuhgCJkhe5#@?S4ozpZRGOmFyEmPHCVC+U2%{{Lgn*0zH>{{z<Foaa{Rsk8FmyNZOB zS#kRkeJd(ra!)zSyO-3hJTm32_U1a<jHT)-J_Y+uy^T=WsA|8`Fy)1H(t`Mjj*omY zwpH$0z3J(#ZjMe{?{8-<uIlnvEKq&FxPC7SBoF-XzSBF;?fXTwToKoX!Y!WFm->$z hT#C4ioI^gye-y5MaeBUXqv2VQxTmY1%Q~loCIBCIYx@8I literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/info.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/info.png new file mode 100644 index 0000000000000000000000000000000000000000..1da667871b9dbe172cfbfee50e666ca30f5b53d6 GIT binary patch literal 1755 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-HD>U~&ua32_Aq{vQRSAwXFO+>H7B449G*mIV0)GjK9JWfOR1@5}gg>x=u> zPVcMu<^A_3tL8>$_S@3${@i;Ta>-cS?M;V!;3uBXuYYHRs~q0*IP%{^77o+-3j(AZ zmslsvh{&~E{p>`lEwg0S$1l3yH^+WkyVK;u?qhRqK6g;=et9u@&0OB9O^+;uJ(r~) zNea>lHZ;E_c)m<#`XX7y`bv?d65Ds_-ML(zIn&FkFYLk&{~zktry8xOEuN)xAif}{ zX#ErU{zgA-pGkLbWFOavDrxUk?M&OxZ+Dez1GkpTPyTxc7#Nt-JY5_^DsH`<86GX{ zDAHywa6v^ub_wUD>i52mOS}b_YPkjqE?JfEe((2t)$jK{pKqBioU*y$wdnbemHWPb zvM&CZR%UFS?luV+E?B^2r%wl7U0ZN~XY<WFZ(`<!|NU$q!1um<UUJxjo10%vl+8}w zeec)OXPi2Ix$7Ujmiczj!tStl?_=Y-cbN>~&o79qe%v)J`L2BTWUaoO>@C~f^rqU( zU3_UxU3As;o>co;dAw0U%XiAmwQWk>`P7wlRk@n2i{2HH&&Bfu9n(0u#e8+%TE2AM zddn{Fob}(6t1SyZy%KU?waoU}(>Z&mtx;OEJZA4x`zOoKuUR6TS=nuEDwkr(u}3uD zX0NSe-kN=PHfJc6YfqXJ*;Lu}fVKC;nq-x?Zf<IGm1eqo?o%>|S@vXYWAEo{>kp~_ z=sug|)McD&XPatr^<>VH_LBwse7|%r;x)VI+SRth;`Q&=-i;U3KA${&_U!EpY1Xd9 zUMsarzi+kpc4h5<zWn;{mD`r2AK5VDb&Q$pmpkjT`mMblUy@uaE2+Na_}X%DX62b4 z@xpo^SJ}27JeLq)t}}bi(E~whm((5#ZE`bRy_wZ=+st=u5;sn{R4pwi3|-5$@5?{F z)nPODDpj9znKf^hX7twJxgQEAs=QBC;!aYkjo7i|)j!87J5x@dCEvNHPu+Oyl2!P` zsm2qRE#If)6MgI9%o9>GJjyS39_-k*g}*d*ZcJ2^P|OP5yRJ8d)GjezVceDF9qgS} zbKd1vzUbQ)r>#q@pWOe}d-|S9Cr@~`=l;bR4Zg37=AYx2@&2b5J6%)g_vaid@xyvS zIV*le_iH>2`qbdxuklkRNMAwu-{Qsp_H`}LXyp5%S7_zD<FV)3x57uCX)IWv;IL6X zbGm=F+$O6vow<tYzdx*e)#?~hzq4=ZmM>m*&r54;E5E+6-8oCy@Nvc3nqa|~1}Bqu z2)Ub<x2a$8G@YjWHRG!Fg9nK_6%4{WcxJv%vHa}sduN6G=}mlPGj%c_OgJ*>)Y)s? z)8_p;cU!uqcJXTE{npWoxod@j%XB<`6fYDNmzOuL)84+<ImtWh%7W`hs$I&b*X%ta z`MxB0=Gsk{8)w%ERnNLNWnSK7^*eVppR9}SWWkaJ7#L=V)iFzJ9`1__6BGw2@O1Ta JS?83{1OS+bTt)x@ literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/media-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/media-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..048c00e0a61d7a46fce05e346f0638206584a69b GIT binary patch literal 998 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%z-2;3=T!DiBM*+nlV3k=N1q{lZk|4iehN7<mj1TwSd#QAaN$ljc>&i10 zI4pkfclC!qo)%m8{C3$U^0=_p%$c86kY&ra<HC*~zc0)CVJfcgdg2R5<CSJnEn6YJ zy-U2-G~M2@u0Am5*9(bDsh{U7@@AjOoPPMmyXcJ5<yH187s)cK%Bk6Dsks58@~Eea zV@SoVw>Lb4r5q(19`-c|vKlT{SfSIk;1SoP9q(^0?o8`fyLiO(<oEyQB{kMeay`}D z{_jhzp7B-N_U+56mQ@{-06HHI96AH`J+<mIZ=UAH?<u@qcWs?U=l6r(q7KR{*{i!8 zW7qA?d;O{G$|t|>IkL}O*=(k{)#n-1C>3S(b>)4XGWX&?w!?Ro_8zP0?O1YcitFqx z(YE_m>fBl){Eka9SS+`0dYFep<QB`a``7iaxQJ^l-)wwoncA=FP3u)=_IOA5ep%`f z=v}fYi+_<y)!yfk{;i+Ay}yM1eso#<Z^Mh|?tL?Eafeh3Nvw@|u+{We{`>6-Tfem) zfBJGRzh(5||36>ZZ+&+6<l49Wtl87u!&j`cyq0_B*pd^Ct6o^1|I|}mvqZBh$s*Kl zRac*@OZ*qrMV)y9vKJ-xTF8X|_;x~Pt=m;sf9c7!S;b%G7yK2TQL649r)C!^U27-s zYK>Ub$tla{@0Z<by6f@j8Ox7(ocs3IWPY@Zu&>EQ(M;~e<$v!zOVjPCGndTIRr_~p z*ZyU8I~x^GFFGu>n2~{@K>v$%;PUwBEsx*Lm(9Jn)c$4QJCkfFXrRBF@L%i^m-oq8 QB_BW{p00i_>zopr0GShSpa1{> literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/media.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/media.png new file mode 100644 index 0000000000000000000000000000000000000000..f97810280f9e78cfaf17d1b77505215fd504c61f GIT binary patch literal 961 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zT>^YUT!DiBM*(FaP{UDj3mA^sB|(0{3`JiB7$5Gt_fqK;li0~?*Og~D zEPn8J^&iizdw#oY6M0-%Yv#-^$jY+i+i_vXkKdQ&{m>Ub;cCiprSVI%sMZHtA-=s! zyw)_`UbiE#KIfOji_fW-6zB71pUIqlIQmA$yVK=WD;F)Wmt|I!Q#<KfkO+*%C7v#h zAr-gY-f;J4a+GLz7<hmyiIICj!u!47?^VCw`}^<z-P#9Tx{frr|D5!F=b5xL{`ZMx zn|2=qx)=exepDCL3&*YAY+|Jqxh6VluKq*j_&}}uQ&0Hr_K2Rl^djrhcaK8e=}kO- zT5h7$^raWuC6~>2l{-_qKlpBDdP!p2%c6;1$$m{rTZ2z6@;$RMZ+5U)Zc<`;yNPzU zS$Vwmk<~i4?pQznx@p#ndq+~^w~MUk+}9CO-|6Bc6d?Rp_r`ivt4Uw@7O7P2O4_LO z@MW0y7ytA}7scl~f7$Q4zwBMbWZtT1A@d!%y>;ttzN%_VNp<SyzuA6E>hD9(|5v2S z#GadfuUdOoZt1@*&sG&Br&+t43w7n+acuY8jXuF8)wQ`bA)>LOBDELqcc@u8mjon# zajErq`0}EGmE~f+U8iRpW1YSDKGRG8gvFb0Y!R~CWcF+6vG_@6?5_#L$KA@>Xu9ji zj+;{#t-Si}d#2s?4z*bsi-eQJ+}?}r+WdO6LDg>MDbsy3uI}2uOzvm%iqwmYy%!N7 d%fN78y&Yo%6O(?X$3uRQxTmY1%Q~loCICi8TMz&M literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/more-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/more-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..f517bd5264457ebca3791ee0dd4519d197b113fe GIT binary patch literal 439 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|Dgt~$T!HlefdI!=JXr&@TfHR6FPNdSCic|fnQxviu=w!tbwk317qxSW zOWqYl?%H<pbJ?f<xo>;+ho9JOC%^L#P|GS$7srr_TW_zP%sb>D;_8@|%)`QzC^w1W z<NyDPFD&<_bfzrGD!(#Y`}C_k6QFt+XfWR<`Soyyq~-ZlXX=#CU(PK36~6l7?N9g9 zpIAICf8u`1bFEwX<uz$3+Nt`R=59*fa?#EH!qana4Of4DyHPGJ@rUTn`=ON<ZtKMC zuf9Cl%?37iec}Z1pAT-jJx`5%cHV5)j$XZ*%>Q6p4{+~fdZVYH&v@$E5s*?(S3j3^ HP6<r_dRh8E literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/more.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/more.png new file mode 100644 index 0000000000000000000000000000000000000000..04f9b45677409cb0c020063188d8b08e2144bcbd GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|@&kNAT!Hj|Is*O6Oc#Mxs+0uz1vAvdzCK(z^Ud>9A73O~sBM@NzUy7d z=l#1+7Qda_U(~bhQ`w2gc{g`11gh`zba4!+xb^m`CEp<j0awRn#^$s8-v9o4zT--o zlaq?~x>NJieg^taV+5*&0o}6G?TY(d<hrc7v!5(l_3C=;Vz>AA<1e3xJQe)J;^~sW z#nqW%_M0Xb3EcFxG`f|s`2UNakE_niuCbk#DtM~&NpkS>zcN3gWM5xjE6)ov6iDBC Y!+h(%^qmafE3qI^Pgg&ebxsLQ0BD%s%>V!Z literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/next-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/next-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..476b8258bf2755bd02cba3746fe122f7f0233f70 GIT binary patch literal 713 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|J_PuLxB}__BMCgcdgvk0&;BJre!&dC|AsHH`0#Oi!ohd_9ZWM`rhR`d zG~19-B5|_#@wxg>c1sKL?3-7bo}6OyKqS)9z?kJ3f7Z`))+f%qHjne>-FaX8Xy%VR z;Xv+S=DlBc?WxvUxB(c%GM+AuAr-gY-f%5CVj$ugcr(}f!kxr4AgK9$-?xhKV~qaJ z^k3@RL$o4`IDk$;0)LYCW?mA`ymdA8=9B1GE>d^>USC($);+rGQthR)a}&4ZZRc5h zb*1hPSMTo2Z5MB?kZ^mwqV9pX?$`GcZrS^jB-So5dm(=JuF~$di&7HOAG@a=d(OMq z)H+9E?aZy^`!iJY>n=V&y}s<?^4E3MRT+ogeOV!A_U7En&AI#aA6=Sr_wM3do6^fq zTib2i?Z5nN;O^<(*;n89T2v-}m-1g`_V!=(7P-3FM`UZ~vu}Q}ZPxjNy1$;T%=x5R z>n3$qV{VN{KO@*H%9UX$JEKd~G>g0Sc3ouEK0A*M;>8C0C+w?aJG@>mNdE^C@pScb JS?83{1OUwgxoiLc literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/next.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/next.png new file mode 100644 index 0000000000000000000000000000000000000000..893989e5c109b02a887efa1bd39cac738f67341a GIT binary patch literal 693 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|UIqAsxB}__BLj3-?_~%2*0&_cFPI_x;Je>{`#)|^=wNy|BklY1+4CNV zSnJPCej+ZN9=Y$Qkb$B3WC@lNiO-Dr8B=U_ALl7`6g-!8<~6Uk_Whl4fj=_yEQF78 z2Q%;ex@!-^9{I<>pcU|RaSW-r_4dZ~FeXC@*M|zm9a}bbv+iD$^q%#|x)sm=#=FZO z*m?fo-@E_Jt5Z``Cvh?Yor3@k^=sy+EuOgS?!D)}`<Cildf^te^JHYE=C!GEldH<x zF235vvv}%MzdwtXK8-w_;Va6scx%whAFkfY*=-kZ=}Ne1Yp(s}`af@??ct2x_iui? zde45|cF`)zyyx1VgYEHKCYA4h@%pm)?ib${-k&!wVuQ79*Ywcc#lK#idEafZGo$>w zhF<RNyPx#Z-n_e<S$q23)1d5Mdj<Q=-^4vWd1uSr`u<yw<0tP}96!G~vc&o8^ao;h t>rc(D@ti-=ExcHr`K2PlBOsQ+mpX<!zZ(1fScFqSd{0+Dmvv4FO#pKMuJ-@{ literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pause-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pause-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..77946d6d91f3ac6dad9572a1d5985e7b66520f16 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X3p0?M(bV4pq*&4&eH|GXHuiJ>Nn{1`8H<D5 zofy`glX(f`s08?gxB}__guoWgUXXh3k|4iehNf!^x-9PIf4F|DH0Sz%pm2?+i(^Q} zy|>pF@-{n2v?YoxQ+{yn>Q!T=Wt`jw?5jLg`&2hfxbpY(!M6uYC)o7=x-$Fp%H6A& zfI1o0E%AG~^NHa(P2T0p<OM&TUTl4=s;cVr;)&DXVBd$!dmpqjGvuxLzt4N=?TV>h l{vUTfT*-aUl!4*TS-v{0tKRo|uIPeH^K|udS?83{1OUwugk%5! literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pause.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..6ebe03071a105228f8f459b6b327a745c527a831 GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X3p0?M(bV4pq*&4&eH|GXHuiJ>Nn{1`8H<D5 zofy`glX(f`NC)_YxB}__IKXRPyF)-}j*=k1V1}k^cW>oi@46zzxC|&3@9E+gl5y|t z^@Y3*4g#(Ry$z-`#5FGCv|7Nl%Ax7eskXNdJ@gXYYQKKT(*!DKaPV*Is64yzt)Tbi zFA>>$i)G$h%wE1;X7Uy|C^^3TcRN2jNb#Q|%*Afg-8q-_Yk|0)u6{1-oD!M<@-}3j literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/play-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/play-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..42d8ca0fad1d814ab5a032111875f993e4eeaf29 GIT binary patch literal 823 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zl>>Z2T!DiBM*-dtaNS#70Su;uk|4iehKTR)EQG)8U+`h;r-L{7T4Xet zj6?o3{9~My_})63JMGx1yhUf1-QJk2dvWPE_w$q4JXHHj4y?aZuOMgOqa-e(K2b31 zNzP0EO&TBHnC)CVoz-QD{<&30T(wvJ+<fSU({cBUYo7q4#?8~kF{I+w+Z#uNm;*&z zFHUE9sn#OE!BP$a*FXP{cbpO6BXM})w_i=MvD<gwuT=y(5DC<I{*7*q|MENg-uhpz zrRTSrrd@nG>Csu<{TZ5<L!XN4mOkTMJax`z$+zn>R<0?$svq@gw&vIFX;wmQ7o}E4 zeCyWh`}So~{1%h@QLn^x&#Lh(p86*LWB0U6kFVBUymao{uJ|n>`|2NxuYGc`Gk!}+ zP2CIewR>ZCzgWC^&g}{jKmE6HM|_e_zny%2&fm@I6Xq|ve7L!6|Hm%T-OQH*f@j~> z)DPYNY#Ymwy}@O#!=A3Vn`C`0uh90Jt<}`Ed<V66t+5tw3NML$n!=HG(Uw{GppMnn z4I)k9UoKxQ{ZJIVV>f?Zp1eF0$hQ%iosU)=(Y4Zg_iSQx$)C#nQ<Kw{F+#%Of&5Pf X(ZxS@Oeyw!3KH>j^>bP0l+XkKk&O+& literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/play.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/play.png new file mode 100644 index 0000000000000000000000000000000000000000..c4872bedac695d19a855bdb42ade970604f1bff6 GIT binary patch literal 789 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zWdnRdT!DiBM*)ryn8-Ih1{gqbB|(0{44?Q~BEG-d|3&!V)|)b#9~%Ds zVG1#3tnZ(6Hj#V%##4FUZnG^@P0qgP@!m&ivTn&S_eBTN<jyPHF<5FXE}}kBFzbmw zYtE*R8jH=|Om}&?bIB2Heb=AoR<7E7=(y7jo*lcN0HZ|5)5S5Q;?~<6u3;>J0xlQt zZ`ple$L`(PkKe7^_&@bP$Ke*kBM<M2?r{tYO#{U*68NFIbi3RB7uUb9ivQZJb)NTY z+C@*#qqmmDZ<+FX-RJIUyH>Sb>?;4!^DTVKlq|{b-P5X;U#h!!spO17l<iH?{V&d6 z%!~WfJ#AV$NHhj0`th9U{tQi{i9n@g+sywgTKeSOy!b7T*wumZFK<qa-=g>J?IQku z?!3o=`)syX3lwkE-5!1~<IDLx1$$TbF!i@~k8c|8Zq3}W_HOQJ?<v>r_BAB^Z@9a2 z>dcMSIpWWC>-uZ^{aijPR=6%t;|7x9M#_paT(|RmW8M71<+2k;+{N$V+Yg?0{`pI9 kM`hI>P9(oFFnr*zVc?thK0jgKtkob1Pgg&ebxsLQ0J)L;RsaA1 literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pqueue-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pqueue-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..d2aa311ddd1e746dd9e24c905e0b54be1bb40a4b GIT binary patch literal 717 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|J_PuLxB}__BMCgcdgvk0&;BJre!&cNVhb*Bc+a$F^DT=H8z0QQ!{5aF zP1pOrEnift;_lpC4eLd?7H`uLoL1AtBYsm-p)u#>xz%#%H`wnnSGH{OEIKtk^m|Y3 zj_Y^lFkYJaqO)plpcycT6+B%WLn>~)y>>k4P=H9o!wi=|p{52_>8`H5-@ABs&-q?2 z-Mo1AjFWdaShWA#fA{9!;^$`PL2-rzUbLS4%~^d>|I-b*?P9S)6R)!;UrfGK`e(cQ zwQcN^&uw+{-Wv1LZ*%+M|8sn^d&MlRI{lX}*?C!7_hZwxpvC%E+@_~JN-S5`{S}p2 z@^$4mV^cmc_DOkD<&HdGwpM%nkKM*TKmWX%Q7y2yy!vEXuZ4!sy1lhLsoc-6xVk?w zS+7@hN;Wn`y!L5d-xb&RdG~tKZbv-Z#B@R5zQ1*;!F0tlQ@3AneZO0Ny6C)*aS`S2 z>sNKJ%enUX<|11^JFq7_G=4P3ZxDOi-I1?r)v=g4Y?duA)OWQ{q!;#-?XQ1zO9~|7 M>FVdQ&MBb@0L<06V*mgE literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pqueue.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/pqueue.png new file mode 100644 index 0000000000000000000000000000000000000000..12c201e107261c0e7a19ee8f7e38d4599e07774c GIT binary patch literal 688 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|o(K4ZxB}__BLGCL?$`wMs!vIfUob<R*saSO-ZSmlym9V>JN&#&_jSK{ z+eY!VDvIyk)wN!-<|UWHHXXs-#%VVj7W3qYoGVISeS?|(UQbJ?r`)OOm78k6@3?-q zlkw8jIWLy8-Tey;R(?+x$B>F!Z?ByUI^-bG@K8fxLW6=rw|0llqjfv<8#=Q0|NktZ zu`@xd_~gRlzxGGp|L1kq=XfE|MaW=LK$YGN@xNO7i$iZO+N@->bGwd}TJZGG#+U9z z#FeZyjq3V&r(~5`*uNL+vwOuXtH0zgWvRR*t^1GNmcM6Tp!8hb--q+`HGcVJmVDf1 zG~3UgZ@QSR#@>#{(_;POo_$Y=c>4MG*<GzK_S~MHvvx`2p(m%VyW7l(4i<mgd2!jU z7pBD}Zn0ku$h=+Iy>FMqvcp%uSFB<9Gu^)bT;FVthiadWzgo2W+0&vUQvHV-Evw>V oOY*9<MbBjyeP%@V1cQT09Rmwv-hyxM6IehJp00i_>zopr033>>cmMzZ literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..8dacf1be9e7efc194ca1eca9fc77b1cc515265c6 GIT binary patch literal 611 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|)&=;4xB}__LkH+~ebEBC*s>(ZFPLG$2Mf-#MsLIJe%jyg?T)tG1jDCK zva?#%C#JuCTyD_c#^pQ1QvXFr%>CrK%=0GYOfJ>cvI&0lrtH+58;Zc7;PZ5G45_&F z_Qpv+CPxv6i+KT#0*nVM=RL1n^Z&o0G^;XKTdP{=vpIKPhj-8RTPi*`6=*XA9C`3j z@!*T;&wqbeG~KBj$h@%ATer%vrC^t6b!u(ZiC{rltH08l%qpV#b#@85-N@MYb{c!J z@}?K3R=n77@73F9Y{{yfFaF;Bvgr2v-E&tgHeb#Bd~e~_{n_8<<s6sV`^j*g=;f;y z8uvylPPeOHe)}-{s*mpR?Xz`uzPNo_XYY$^u1y#3cZ%soZOOQ}$hBKf=3l`Bi)$~M zSAO(M>V0>vuYAgx`hI<v|4p}4E^a-s=()D=jPpQ;H|!5S=Ur*J^@UB#gymwfT8q5z hZL#JB`RGIc9;W>Kv_l8Zv>pQSJzf1=);T3K0RYh+ZJz)D literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-one-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-one-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..a1b2217df36e7cbb52cd13c7aecf8db31193babf GIT binary patch literal 687 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|&II^`xB}__!v$DPddLCvk8??oUogXh4;Gwfjo#i3oB2umTf?3GPYs`B zO~{rj4{c4K@!EG{oBHE^11`&$7y2RhC(YH;Een41#wIyu_Zj9@la)%11?RcEo2VUf z6&Pejo-U3d6}R5rxaoH&K%n8_<)&>S0s=Sh9IZWC8-JnlfB7a+uQiN^Th)wz)t6r` z*869o?i>9a=nf<xH78c8$8N91M)AE0Un`q02EC5#&g(kyaN4(1uY8VG%II!=$QkLi zK5VM%^wgfbm&v(?b5EaI)LeLR(<QHK&n_7n2=3jJtG~-IB0605uHKTq$%VN)!o1ey zWcA*Y=nel^GUeumRi;(nJ{RwrcsJmJe6243xtK4(_iuLR-IeTlcc)z_s(atW=<198 z`sd<GdNLMus{PvUvfpju9@mSTSHAf6Ab4r=+lq+F#9RN<4mVzVG51f(?x@ADAEs2N z{j08V{KBu{Cmb6h7R$LTpb+e<2j8FA+&>-J{mtdbX0f-&FWQyQGUkQ)xBi6nylr(E T)Bfwe0f~6J`njxgN@xNATqc{V literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-one.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat-one.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab80235f67e8ac0abca4962bcec6bb3708d8ac0 GIT binary patch literal 654 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|4hQ&zxB}__LmV7z(VY+UhC@k^UogYWJD)hu8oj+6_D#ECzv0s-SrfA5 z%0pWpPfYiHt=`YoHp3vqQvXHF{Yi7ng5T&q(y~d;IWtd**?3i{;O@yT?=rT(aR3IB ztfz}(NX4zUH%<l}au8^E$f>}o@LMTQqkBj9Z@n+S?WcAMoC-)N{BR-m&;7OO&pya6 z3-X);3U>s^C@4)g`1R@6wYZW{E!F0WLHjm}#fnedJn!47M`4FFdZvAP)Ar`*YS+|@ zm63~Lf84y?`Fzi&jQYqeGA4`mzODG;>r&qT#`XHL>f@^x&)#{%)#Tl|Z(J9>+_S$t ztl7iA{PU5<+O-#N-ar2`>XU<C{g>t%%i@dg{m;dfJU*IG@>+Mofv7LbZEkhf{VVvk z$k|2M*W}`CA=_^@Gb`?`UisqLm*AzTZ>u6I6Rmzec8JgZqOkea%4;vYHr%>!roNxm s<$v=RtBaYb7d7j7HQ5n<0<pIIWQ%-W#wOzz>;>X_y85}Sb4q9e05pq=-T(jq literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/repeat.png new file mode 100644 index 0000000000000000000000000000000000000000..eddcba762f5476b2d4d590bbe177d51610f8e741 GIT binary patch literal 576 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|mInBQxB}__gC6Yo`#2QnP_vRCzhH*_pT2RPHF_I%SG(bk+yuj?PqMRG zXOycO^uM0yo6hyPEkyrCjAiNENt5sA%wta04KCAq^v34yvcL&I6TW-8IEGZ*dVAw! z&>;sAhl>nZ0*nVMk5$fV|M%bDI50_)wY#<Z-KyfU_3`@el&*HCNCGuMfMG?Ax52NM zUoH2(xM~pNXJEx67t|fcsTh-gH16h%^_7~74k!F+eG|UC_r#*;#HPUK$=k!uu065n zv**Rc<>Bw9tupjis`{(2_r<^G?+jkO=q-D?NT&SwZokS+ve{prU9X7unZA{~dZU|u zP5tuUU%B7@Se$<-bXv@ppSjcGO5W=od~x5UTTC}<OUA`TuHt?FcNB<Zf4O<5Wcfxn ze(~kjp3n9l=U?>Sv3S~xw3Lf?YuN7cz#Pudan}0Px_HfrHy_>xiFvyExvX<aXaWFv CnN)oM literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/rotate-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/rotate-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..5ca7eee7d57a33ed5b3ef1d3d9ad014d80576a17 GIT binary patch literal 818 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|ZU^{;xB}__!xY?GE3^#gJ&%$gzhH)k+zXUA@4glK_Wi>r!GG^8?lAtn zb(Z7a{Rc8%GruTn39uQxm$K)NaZ_6yU&^GOvF!NIiprha^-l?lrtAFrC?co*l!f=r zWBJx+C*J^raiOP+V@SoVx3`Xm9dZz9c<9)|xv-^A!Ig32_j|iP{quivL_wk>C&uFX z=X&iKIdw(PeDq|dFaaHd0DoGW`a(`<P1T)#zR%jsExm1`QD0DB{n@*>w&+K>yJy?~ z(yQ2+n_RL^{GL>tX2&_bsZIVHk`uSwE_IU1cP#n%YER{l$h~>-C9f3sY>DDuRJ;3Z zs_@*r+v0mA;-Wfy7frqOVKsk?>*`wJ+AZojyDAb_`2%^`!nInuzmB<FU+Q}Q`W8L! zZoPFDeqm8trfzmm`O<wLW4&zMmhKyJmibxxrU}>@$9wl&6I$f$ebTUgjhNuuufoZ- z{vKQ8eD3jYnerl^U%WkI(Nb6QL*D00885!Om2~3q<c1duXLFtQ?D+RE-LQIb^u>#7 zy=O1hK3EgD+w^fpj!}L{SWe$Mw$H7>#>+j@f!uC0_x?3%zF(@pm}V~)K6&$V)t?QO zTP>=7?fG}<ZKRBCaa{in%jm_)hj$v8xrJ+2t!n}Y;~zh}d4129x*k9K{l<<hFSh*u iZt%{eS_&Gx|0eQJGpdQb5owhT67h8Pb6Mw<&;$U>Mce}b literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/rotate.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..a6082d9248b1c0c424b18b91b5dd60ecfa4e3e22 GIT binary patch literal 784 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|t_JvoxB}__!wwuWxw8`JF}IQ+zhH)k+~1Wr@4glK_DS&HyE}}3Z=L11 zcmILR*UT@<S^{iRM(^$UKa{F1c8iZ;$~dmRtg_<g&h4l4h0{ep>iiOs(|*dr`{uE{ z9m~~;z~F25ba4!+xb^nN^`a&Rk%ot+E4r1E%*%RT?)@HD^WU9|McJ`)`@5Mx_iIPw z)uqk2YpekZbp(iLUE~*1GNtI$)6<*Rbzc1GxoFSYDY7=3%eI~EzIO7WRmVPl{qH_K zdOeTkw?%U;o?E3^)2z$9c<n;j%YS$l@7?|S+C~4b`zkN)eEuV7zn~jCU)1ZmFKNg3 zyeO&3)D?Br-YOk3pQAghz3$7;jT<uFpIUDxDz-N7?+fnCi~MyZ&QV{2eP3_dlCeJh zcHfo^<@Ej|FUlJ)=Bd|h>HcBE_3loMu3}Z<zG)I`Rb8gPx;ZmpjhNtDJ|ko1aE~o= z?%$JjRezm-m?Z4GWy_1SnwM)86>i<~IKF2OSI4}FojaOZUewoh&y>FF*OzyHhD<Ey z^X^-V?faH3s$6`@*m9TDIq|Zy_g!~g+!OfKr*Gb?^uI6GKS@94mcFU`_t!TYei~R* z)$RXhDkCYgcSF2?Bx~^E;K@rrskwz~SFK#cga|<(Yt13^*38l>>jo9Du&1k^%Q~lo FCIE6#%$NWG literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/settings-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/settings-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..671a0c488036f2aa664a0da6460a2d362e1a4103 GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|J_PuLxB}__BMCgcdgvk0&;BJre!&cHG#AWm^?56D=!1poccx=2v%~hf zcPOj*Mrg%snN%Y@^Y$G^A*D;-{=GXeeZSoG_xBvd>s=R3xwd0|-C}N0{`7@z7w0$| zclJ%@oyPTgs(@Is@GoEx`*^xIhE&{odowb)DM6wwv73uoQ*86zGbWpB?|(lU_Vxe& z*%giZn2*owoAt2t-Rq9$Z{*k<HwFM5g#;3A=-%EqHAm;9#`5E<vyIY<C3C+f8Q+{S z&2YM$xU3}i&K|kRTR!IaoSJcBk$XyyknfgPFJvY4XDuo}T%f;mYRl77(~I4E<F{&> zUi_?9)tsT%|L?_Nja$<{irBvXsc>vtip{42#b4)N^yf>8`d&PGEZh5-=i@N{FVUB8 zPkCs%x@wX2vt@r5sQ<d_69206pUK7LRf}$yY42Pn``gF=OZeWD(*>{1Eqm@w+p?PR z`^&sf1)5I{EIB5H%ZeZTJ9nP?qMtjKE)R*^60SJw^y2yN<vnigtgl`2a&>0trM{nn zAO45zn;-VmAL8BSozs$c-dgmuwP~qt)V)%RIhpG+p#dSGWbe3P(IcyS2ctnEp00i_ I>zopr05a~>VE_OC literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/settings.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..c4c4f2ccf40a08b710eab5514e0a7a41a6cea126 GIT binary patch literal 744 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|J_PuLxB}__BMCgcdgvk0&;BJre!&cHG{4Vn^?56DNR{bW_R76s?jJgo zCuwc*Ra+1dQzLwPCgYt;N<!cMy_^32z&*MB*B!;{T^CKcwqw3U-C|LG?(~Hh=eRi= z_r0FXE5Ow`by`}QtsF3jtvy{FLn>~)y?H$7P=ZKXqDdBmFXO?u32I#5;slQ{t+@05 z?u^Mt>JM5xc1tgs^F8wE?Y)PWICv}tx(W&Wc;8i)U@O;cRCMv<v1L6^UEJ39Fn#_w zWAa83+2x;&#DpYmRWmPtJaJ-1=VJ8~A0gi@uU^zj+WKCs-d8Vh&+E^fX|rBzy*T~T znprPGg<}<GT~4<7b>VYaYRR5;^SBK!O!;`?aO(^C#lQ89xMnT7e06zS&*WEY=e>Bo zYpd?zRnxz??4LdRTl2gZ;li~m)qfp!ng6P@ZnN}5%emXne{tc@j*LDQ`qr-TqV=S* zzh`T!1ngoqar%_a`4D=%_42;UpIuC*M}L{9)xC|&rMRl6`0lhNb9bA&&)PR@n#$W5 q@{INVPk(1l{m+8rT_E$rY&*vP@8_o;w)uDwB;)Do=d#Wzp$P!+;mkGw literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/shuffle-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/shuffle-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..d75616ff1223d9991dbe264758d6c69959ddc67f GIT binary patch literal 1370 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zp9T1YxB><LkAmSI0+Pz={J@xASQ6wH%y5*8(c**m0w#{&AFm#q-SJgO z`V#Zfzd>ogec9|qdT!KkZ#{YY*&Yd}!q@NjyYTva>v-pA%Mxg~*551k<wwP7afx@* z{n&X--YmM7T=Bj0z&$CWq7(e0I-YA})FiXs%2h6FeRTikjPsKPFX-m3NZ9b{r|jZw zzswHlYfevjalL-h#_h_7w}gf`aJm+FM9=wh%%FB<W79&bgO?-seJ*}_D*wzSp=5ss z2BuU`7srr_TW@b%Ethf>IsWmW;)MVePL@aaDx}KS?*;<%((>=${w=>dcW$2f*5!70 zGVABFC+O?nKRk1@akl`_yXc_)_}@a_#qu_@*2b4G@@~l%kM%Gqm>xfEf4Se;{QW(5 zl^6YTE4wJTXj@lO{Z0RPmfQN~U!F@}ESYk5*F48d>qK2IAA7ftYtz}7)5fzh+)wSy z5PC8p{(w%^=kMFz?U*(7ZK>MjjdFRX9~Zm~_!<)$eo58+we*#*zpuYPb9Cb2Psg?u zHlAKJXX~9Ew}O&l_xv=_sOmgqGuwCWRHH3f%^h#I|2nSr<eAVn<9lvNpHs5mJ+b;J zCp+cx_Lp)8ZzV<U4%+vu^-AB3<F)7S<=)pnWt;URvHpUGUf|j3VVNa1QJYV6<%w8n zPCI-4i&dvwzTvFP{$ING%{5yTTV={FKYO+ERGyb2bB$)(x4E^MWZB(LbE_Adzan7v zv(&|DpEK0FpS%v*Z1H(&QNli(_vv@zd$#|J%C@*8`{a&|(8TXAo-1YBChER1SZ+Dx zc)9v|+oZRx{Jqg9xL-g1dag&{v5UU(pCa3Zvo4pul5FrharDBfbwd8}y))JK@s(Xv z*M9x>@ZB=g+amwWCd%`v?sSdcGI_e$ZRh-VThwpo`uhBL>e#Zb?BCmsrOP+(>WeIy zDp{K4pZTZ#=f383V!vlD=!pC>)8*?=?&o!t=KIWSRHu7RxyvW~>+!pbIVSgaEWW<+ z{Ee6wUX#<#J`!_PFUb}&U%v}f)&aqv?RyyG53G(ZY3N|u<@&oPL%uF^O(sMRNH)}; Y2!FSYds$MD!Zwhgr>mdKI;Vst0KgA|Q2+n{ literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/shuffle.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/shuffle.png new file mode 100644 index 0000000000000000000000000000000000000000..9c79a53970cb18c7e1a5fd3acb5ef68a03ea49e3 GIT binary patch literal 1349 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%z9|!n^xB><LkAh(x0vq|Hz5%0oK}nEbFhlT<S4X)RnK-;3>^Lj*Rr(V1 z(!W7zzkS*4Z=B>7*;>;haeL1*r^46o_xreXeB*uRXluBZCD1F@|K&%;X>p0^?05VY zEz6qxJ)!9QTMJJ?Q4`(!a-BLCk`HWnBhxDR=|tsCqufVoGgk1dskkS_e@%1S;ureA z%&s4rp7K++e*2b<4xE!hltT}HiJs%(T5!y&aiKwN)5;H*KOZcP+?W6K%qfXueL@Tj zOd*~wjv*Dd-rfi;zU?5=_OLf_-Q!z+Nyqt2=CoZlNS+A-ikim7)pc20SFc?)CC%z` z_h#e!#fjd>&EFsGD@#=bdKex2>t}z==5~L#_31q?m|o=@>+PDb;=khlH6Gu)y6pc+ zRJ*v8_P$y4*JbU|rxPc|*Kur*UHSg>_QjdfyGw0*r_AN{Uf$Ded-TbyeN)m+F3y`$ zeo^Iw^8SX%FOTGNWeaV!XFm5`=DqjMwBt>i4zBXuwQfahui5q2zqh})J9Tv8;ZFy* zmDV0uIcMkTebKQ`?(C_wSJ>5AV>5f{Ixo?vz2Qf$S^iaCoK^hMRU%(`<IPp3-w!x` zm6Z*+%>Od(;4P`p-LbXLBCFirJlvQ5zIeX4u~U^uQvC&wybEWa_equ5L|NbO%o9=5 z3_rX6j8$h`-nQA7&!6quH*woy<}}lG`O{Y?dPS+ZE>HQKo?UTa!L!S2jebr3;njM~ zL|$_8+2olz7hjjzb{ofQYWJ`FTxa&<=)YI13)`G!6VIJJT=%u7PHWRS>1zx9EYB{q z*=JpO)-7FsPrkiVoYnO5T}Dnl!nUVBoaT)bP0#*n%`i8ld!grj)i@i;iR%0O$}XyF zy}on!u9)rY*T3xo#eYw}v&etv$#&^G4=3Hx%->cVHRE6FgZ!v>e{Uxr*UB%|-TWd; zvNSC)^3U?0o9;HIeV@BvO5~THE>~N-kJtY;nJ2Sr=`_zNclnb4mVVFJFnj%7lh-%W z^Yu#h9^H^;=y);k@~oq8S35GI$2<eW2mgJHm&};<2i)oL2g!Q6`njxgN@xNAR<d<G literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/skip-forward-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/skip-forward-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..ec007435c782db60dd44b076cff891f758098956 GIT binary patch literal 1046 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zGXi`<T!DiBM*;0aU}ut9EikOhOM?7@89rEic|B*rTiMS)1-|i|`E_gB zGPdNW=9ASqouh2`sU8r`xww#9`W%Pc{X;V^obs4>+US-2axSKu$L8r)ESer)F0*sC z=W)i{SKK6$3QGjDe}7Fh_E(5pna}FPKIM;Q$P1emp*KtaS{1Cw;9cFXf2Zovr_1*w ze~8yb+?@f8_LH72jv*Dd-rfig4-OP@eJJ8%GF8vCr6tSR^=O|6t1ByanSge}(Ov)c z8Pt^8razu>|8?C=<;TzN6_+V70=<9){{8y-_qc~MbJd@W#TjhLsY|7$=B_K>eK9Qa z?fvHF_9?j;C1K2>##Rf=UmGr-y=3}cy{PwbqRnpJ?dNA@yi8He+VX67%oZy-m)>hH z%fxlh_ObO&>)W<7L-u8t)Y^Z)^`d-N2QCiX@qE$JX$u!zyyUXI``XX;z{RD1rgVq7 zS6|6c&EJ{v(kuGHi@W^37hSU-BwfjneO+?VE5281ZOQuXY4iA5d+*gAv@N`-^_NfT zu1)z}*XjHFj`hsjnJM4@Y`Nk5mxt~af9t;y)%(+3=KaR^FYi2F@cyOo^*6^;6Ahn< z8<yXmXIr8u|Jk@M`O>^k)AU(wpKj&5y*P8F{<F$mHW~SPRVC`rR1;pc>{VW;!@5^F z?bElU=+`}!(&v3|?`_w6p1e-L?cQ$Q$&;EL&3*FYZ*PrwTYMrm?%~m8(pSH3oW&t| z_kOzj{B36w-b~+TYVvEQd~HGV!?|y!vw*{R<5HuOK3V%+)4zq){MNPFxn1<}^k*~K dAmQKe|Af4HcVL%F@g+r&h^MQc%Q~loCIAE5n=k+X literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/skip-forward.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/skip-forward.png new file mode 100644 index 0000000000000000000000000000000000000000..a95d14955d32942dd59b3f533a8a295b26a5481c GIT binary patch literal 1017 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zQv-ZLT!DiBM*)pPfcIZg5-_04N`m}?83cZQdp+mNTiMS%XMVA%Pn(>) z?CC9YTjzb8s!<1WK8Rji$Sr-2LvDJZ|80qt7bebQJgx95ad|nD?y<;2vllIh7nJd2 z%|32_-=o59X343YH^2VAVw7Z@&*fBL6Y__BiqM-Enk!nC{<T`&&#Rwtr|QwCdy+pc zi~AjRy9$i*4W2HJAr-gY-f$0}oG9Y@P{c!pQ)A(GIgzQ0IK*bfuDW3@>*#QxtZx6B zr&o;6#jg45^FD=t-}~H77NGNyz>nw8-^>3^<<0oCxZl!PLv)H}cFD5kM|-z@j{Ywn zvm$8Qnv0QJx6cY(YG!w|XWay|+c8`Ay?fH+<~{x1%#6%6rdeC$uJ6dW8rvzgcJ@}i zs991RQo6cfyEE>t28uj0*NYM@U+kuB`)<+F?!AtSmp&8|Uu$i?$SwQl)b6m@+$$NS z`^qj}N+`YXVso$B^F>$dth2VPGvASsng-N$`PrhSTkkEnn9hC2S$yrE`3o+7<#&rM zd03&4_T^OQ@5(Ft`+xc_m-oFTzww6XXZM<0Dc4_KxxL`^m$kpkiYs>t6ubNA-rU^o zHpy`N$A#+OrhHGbd!f1hMtc9UpT}lAf9ce|cjt>+F=xCFd`|z?x1-APg>0c(rvA3O zyoULYS91P-xA0}k8TFQbw%-peIoG#9-)HyhZ;@+$8$5}Q`}LXK{ME&}aHW)z;>EJH z)<(^j^yf}9{nafmyTkFm=eKGmq#$NsX!!g>|JGm6BinacfP>%D)z4*}Q$iB}F>a9w literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/square2x2-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/square2x2-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..53690a6f9492591aec08a47739199d078c8a1020 GIT binary patch literal 645 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|wg>oxxB}__Ll6jbt@H#s-KHeSFPP!Q-|PCeT34MPF1Yf@;->cf2OsWk zd9LH=dg;!w!{0Sc-zpot`E26m^v~$kA3Fzr`zPF79G1V;b)OkO{qj5KqBk&DR6JcA zLn>~)y?HX|kb{WZ!_~ZPX9PTWy0}(6usQ$i@BGtilJur=uZk&o{Bzp>S0b*dFFJs> zBY_PM-I^DEl<KscbolSy4U%UH3^wUot=ckgj@%2?P5Qg`3+>f@u3q)>ws>yI!<$n} z^uDCL>E<ham>O=ibDq=hMYgd!V%_s!o>ZQdv8YpR){Czy+UMoA8`)p;POAU1mHXny zMQ^t1<UiRLt+&6uNbvKekLqczv)-9p`r;@T-}Nov%$x3cKA%tIyOjHXlB(O%R%5kM z|JMJH&p!QIDSm(7i;a3U>(*b+uaYV*Rs>t{OMZ@lW#zQzPgbs+{QR<C9Vgf)55x;6 wu%4@J=3cdmE2jJ0s~0`-v;LbvJ()8>|APJ%#uMAPwt_@FUHx3vIVCg!00U@$H~;_u literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/square2x2.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/square2x2.png new file mode 100644 index 0000000000000000000000000000000000000000..97a763da4c39d486e1066026708eb5fb77f2e707 GIT binary patch literal 615 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|HU{{FxB}__Lkeu4Q8WkWXsePSzhH*HFRts`YF%}Hc;(Se?Jaj7+<&g) z=z8hSvBR3*P2XB58@w_3?B?{(=#||c2Y&k}+*}-%zn|%<8-IDa=CspgU~uqxx;TbZ z+<JTSWY{4G0k?;j*qqhcjx11UR<by6bn>_Tj5SGI;qwkJl6t@WPk8y%CDuwntC4`r zj<nrRn}Qy(U9z|DK6P;GE#K;kAKkJ~JaN+Bxc9|5zb`BA#Jygctbgm}q1n|d@4h^F zv%9b4p>u53%y~-H7aR3#Zn??7)>N34v8YpR){Fg~W&3RBJ^kdR-}(22yZj>e%ZmaH zt0!HrGW;#s^|HhHcwEnC6I;!tFK6%3|NLq~|6AAZZILq59!=+ubcvs;DE;k?Yx{mb zz13UeoT@Lz#{Sq@>v#U^m8VagOfI?z`+l+Ck@)G8-uctf!TRr)@BJf;<PRY8KwK@e WGSA6J%ThXBKr)`LelF{r5}E+lTWcTy literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/stop-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/stop-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..9959be9c53dbaa2a257ff93a0b0136cfad56496d GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X3p0?M(bV4pq*&4&eH|GXHuiJ>Nn{1`8H<D5 zofy`glX(f`NCfzVxB}__*no1~+<2fIdr6RAFvF$=7B#y+EZE7s6eyJL>EalYaqsPQ zL#_q`9*2u@jsh`vV~$E!aD^8ZmQ9GezqeRfcTahP|A{F}Sb*vowj|4QC2##Qkvo6u zmyl)hnQ-uu&Hwv>c4mfM+hVgrs!kS%{5qH39?bquih-f-GvliRVpAGKyn)VVVDNPH Kb6Mw<&;$U=BVT?1 literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/stop.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..b07b3692d191dc7b2c31e3dd99eee19e6e782a74 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X3p0?M(bV4pq*&4&eH|GXHuiJ>Nn{1`8H<D5 zofy`glX(f`@CW#WxB}__NTA>8UIs{CNswPK!={?us|p09fP5cM7srr{dvC8F<Yf>L zadFfY;C<o9?DXGs=YQkQBR-7p_skXoDr5N2H?6ry=We(`|I%z9{!BP{$-eye(Zh@& aCHHUi7R;M!y_5M6i0A3*=d#Wzp$Pyemq-Ty literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/subtitle-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/subtitle-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..0cedaf3cbef9ba560796262d432e0f12957eea21 GIT binary patch literal 560 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|W(N3#xB}__gA!boWeEW~&Zs2FFPLH10wGt=?Qd_`zxiVE;fmbllULt4 zSj%5iefaAWC!2?Y???7Ke{Sv-SNt5bW6!qT`+Y(K)+{ms>i+KO;uunK>+Ow`euoW2 z90Df?c}-e&K{6_1=5xdU{|ielZgN<;DIuWe+|8=u)SLdBoPm0vpdtR+{q<M#V@l$# zost&6yR!dXhnVg!{YB~i=c_~I-b>5OotqPBn^W{9v*qIF@2<NKJ$ie?RV4OYT)EcX zC(GJj2A-2I)86XKe{qp(zVVuVxvJj(Egv;}FK_;Q{*a^f-z1Z~XZ>egw`IQ5UHmgG zD|cP;dj%J9+m02L!gpu4yjZl{@a<=-U!OEw#A{_Ei!)LK&-RvnxmqF=UA$xOPHqN< z1KUd{E4@4>Hh0au9iBNCk817OaQPg_%M1tXKQZz%x7oTJ`Rf4Ud%F6$taD0e0syKs BMri;5 literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/subtitle.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/subtitle.png new file mode 100644 index 0000000000000000000000000000000000000000..6d4ea2e9bded61f0a31d286a0296fb46948a78a4 GIT binary patch literal 524 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|CIt9|xB}__g9%Jyko*92lYU8%UogWip*OCc+uz=>|8hm{^3{{?9IWN9 zsXqMmiIdGkf&HWJotxr&|0sSA+OcQb?)^TYPYc#-0JYxtba4!+xb^mir{7@*0f&of z$5?JpkQCzhZ1ely_GIDB4t;wP3q0TFR)4-4H2um{A)pp0__OI_-SWcsi%#zfzPbBF zV)>VVEg2W<1^3p}-OT>{<-+3^Z&FUbOq{>ipV@7_-L=Z@ufI38YwU{K_jXH_t}p-P z#c{Upww?0jzqrUX-}q(UydS;)TW)UA=sMlK{!n0Cjq%*C#mU9<OwV48oMC!-L1o`n zM=o(&t}Az3!as}XRSCYFXMQo<T{GrO>4s+}C!Egq`hK~aB)8V`?wxz;Fc&_UU&AEb XSbgtijvp{u85lfW{an^LB{Ts5H`Ov( literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/tags-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/tags-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..458469a34abd99e63b54e710c3276dca4ddd256c GIT binary patch literal 1644 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-HD>VB!k!32_Aq{vQRSA@Kh{57UzEz|^p|B*-tAfsyA;^q&a}{t3Q*duq}< z-l*Sge@|NI|6<$!{aeiL4|>OSh1j`1a+ENYzE^n_=d66kK%jr#{1co{mN2&;&3azU zaxiS4QKajhc(V)K!i)G9KIju;mA3UiT===8M)YSyF5l%<_hP@MDY)D||6}ht#TQDd zceQ67GVDFzuwJWr&fHJeuAHsa+*)s`^KetrmkPP1t$8iiyNfO^+gKUwIrEu^jqEgY znfqNgO)r_a89VWvXpdoFV0QO(aSW-r^>$`>cyORVtA7<^i;4h;ZvfMx4u#mN&?S)@ zF0rtR1Tt2?-~0Vu_00b-=CtTIPWtZn{d-a56T6!1^_JD|e5Wu0g8&=&r+j9<$792_ z-aLN_SJzx9-@ZI?V#@QU+!{P```@q1dCok4_1)+#uR338i|%U=Jb2{zI?hnD8FO8h z?NEL7*jTB$-C6S0B)9m!FMHPet7+ZR2(~iqIw86IN|#CBwQF*}%D27RTJ_?j?99yv zEuU}v+~RL-?euZ~N{JQOYZtO|D$TWgzK88x<(#?Q&gWKD%jZ`A&YSRNHmlY8hsHC~ z)1JG{{XD<x_63ji_D8M>^QxSDonB^Us%^S6%6k2rkDcYeyLYWw?(({Nspb2m^yTLw zt>>4W`PGws_<`E4LeE<{GfJ*&Zta=-_GsTu^N{ZsfBJ6vWm&5Eeo9^0vvr&2b8g>c zuD^6vT48#?`Ohof?Gkd|5p8sS;{Qb}<|c8yoANhPaPHN<(<vK0U-71Y;PK0NzK)~6 zSbE!prOp$K-%rsvS6TGu{kqwXVLnE4?`ox+{ouJaqd9#-*WvSRUA+(8_byCznlia; z<L1ut?{)W@%c9d&()k0Ad1_kT*Li+-?y8WR+I5%oGy5OpY~8#${7gXz>-hz@o~Vb1 zx7^Iw{ON&<_$kZQ>nBV7<KJ%%EB_JQWA*%pk7McfzL@P_OSJ=Qe>^fc_Tr|6M&|k$ zg<CfdUH_BfRXIg=-RqKblhT@3KAm)L^K9{Z0)g>QW3nFyiU+O?pR)PY8Bay66XB~e z<tHvJ`Z%X@TfsTsM{x&=f4ctWPQSZrTKBJmIoZjA-`#2!3LT#`CvnlrX$!WdR)1S# zeBzwsOfQAD11%d$g`=zQq#A!)@GgDgxjCipzQp{OdCXbZ9v8ovY4gKSr^v5!p6_}v zJ?Q>^K~=x`$IP_9yZv!eownrG-a9pOzJ|xW?##>0jme+*_Dtk!&Y8a!hRCemRk1F) z^m=G#*)`cik?+^YYF>?>5XJX3{DYj1=({zW<@oAE_pYt^W&QGnvX@QU@xZ97^{;+x zZ1|kG9-g9~sd8>Bi9S>_dE3i)$LF(4th|>iXPz-ZPVIl3|FET(imsWw{D>Y%+|$+1 JWt~$(695;N9OD20 literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/tags.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/tags.png new file mode 100644 index 0000000000000000000000000000000000000000..f468cc28dc67e9794dd4b36bc3c7e63d6f8ba50f GIT binary patch literal 1614 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-HD>U}6vO32_Aq{vQP+J_OQo-qr$>!kUsGzhDNQHw*quVEiW-{rc^xN$+^0 zez*NSssD>@|Mzb(yY-Ii3bAv2<S1b(eXsH=&RO}6fxx`}`6oD^EMaaxn)ST+AWPUj zqe$01@n#peg%|NJe9$MxYAfx3xbSmFjp)yaT)xYz?!~5kRdBg|{>R>PiZ7H@@6PHq zJfwZVL2Lb->balJUb&{ZwN}Tn{^6#Iq%W;Y<t*}Au6JK7TDGy$GkE4S8*|xb9y0g4 zZkoE8TrzfA*%q>hfq_}q)5S5Q;?~<6SA(Mi1=v1J7Er1XY7&o<@mg3>n5*emsCzGH zfx}%8_}2eM&S_b|r0;Vd{@xqYcBehR?Ax1r)l->(-bVvB9CG44iluHVP5Zwi*hH!{ ze?iseCugFaPjIIPT`|2mlfO>4_{)nG%TKKncemv$39os!>cWY%XoiV~I-#|7jwzYj zw2DKYd|7?6ar@MZE|t|OZGF5dTpYn!(K6Gotv~tseTwOe_e++4PyNPr-Ey+AzRSxq zVg5huMf*ccrv#s1o;Y*oxtUjEo=2XW^ZMkPUC&m$zuO+Tsf7E?p6>Gr%X*Ekzp(l* zT_|h%<zsDz>P3$wdw!mo*<0$R`|irj?dyLXz50Kb)<?_0-wU>!5uRh|a6K~JE;shG zbU*Lr<`>UYGxsK5+3dHH=UmRot?TwL%<0f8IW_D2#+Q47+boUGTb+)~*WPVC_tfhn za~<!Vzg%_gY4qN^lL{tITGw$))9t(8%>K_aBj4`zQM30fRz6V6CSLL^OuoNZ);1+e zY|6}XFNN!sh2Q>1Zud$mFq!*$>SgH~w$r)qj6HVVt9EW>`@HyGMB9WD6NTs8Jh8ia z-uDGZ*B=c}QxE*(sad)&_Q-DQu$70*|16n*|B3SE{jJ8kkC?cx{LQoKoXV!{zh3mZ z)#uGwAY-}w1KZ8_uU<R%U48mjta)8=Mbm=9>u%qof8Fv9d0AT^(Nvl*GkHt+IpN;x zpG~!ACCyW*o?W`@+@z}J&<_*t?e7=ACvh?0<gY7jhszc*O<!?lm8xo+hPC&~Tb4?} zC#RME&3R;Xy{nqh|FQVn{Fv8mcWqY4ul3D6@pz};yv0X6eP=2~ttww`_EmkoW%C?M zJ4eoxxOW16v8Pwg?K>1&9dJG!7=70=wQK)Yw^<)~SXt{E^Nx4AP}Xtpcdy^rd;R_6 zDzdRiO8ReQUQ2#Zl53dEgOkU%{yUd#duU;>^ex{_#>Hz(+jag1X!R_<wR64m*EQOr zb0g0StovGVG^O#MLzb0E%$e#94i#y!uQk6ff3a`T)ci}1?o%qBr8in-U79I;e7doG hsU}*2267vCpXe92abKAGP@DxM>*?y}vd$@?2>|VC4afih literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/trailer-focus.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/trailer-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef63a614474e793c11e4dd77fc7e31bdff098a5 GIT binary patch literal 1311 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%z4+Z#yxB><LkAk5b0#~1gS_5NoYDth^Fauw<(aN@`Z|{aREIRyc!M}IE zl|IySTKxP|{_K70Od<PgiTAcjKiMa><$mqliiw(UeyCPGJbHqaIkNI|&1B0@+w?bn zWolI9Vq2FQ&A~X~`sUlydA=__`!a3z-^)u5W@fn0I=$!2Def1^+ZU@z_-o5dQfDu# zt4=Z#(A&AgcZJ5Uq6fD`vg8aO+iCIUD%?3z@Y*<FVb7sc&otT?7?`3wT^vIyZoR$r z-2b+N#PN^IGd+8v)em+maw>98U`U<5*Zt<|lJ|SR-|K$2_xA7l-*Z;2;?TUZXQkZq z`_Fs*_f>!NE!lS>r~~L#ba3a!WW$)-w-i)%d9HQXJmJNqsV?j-F6>iQnVg**BXaAe ztnP*RigVVOzAkyZvEqu&igdm!?!KFSLP{(HSIxa$wzT7tt=G|0KkC;0OXBYIlYM@$ zGi%>w&nT1F)ts7J{~HDVck8n`RUTEQu{D2IM#_YAt#jVp&)z0(i_v^|<4nevUy*wa z)y_)q-DPK%e(%j?<6|o}ynT3*{o>?{^M95<K0Hk+HZ;+ucF}s<wuzjt9S<4Qoqyuu zT3<A0=FPmhW~O!%cbyOa@13qP_rbwGn`hpPv)yd)?n`&qyho>Z&j@n0Th!;NcZOGR zZ{}0Sr!0Xx=XHLb<Q8}_@OIzp`4jfNxv@A=&Slr8Z?D5`GWP#IRJSf&YE$yIzYZZ^ zl22dSZ6<Or=jCPJsV(()1DKiX({xr#E<e7iXPtJ5s-D)bp50T!U0r|QSsSBm`0MSg znj>!aD`$LuJ~3mripj5QMaz#_F1+~i>7v(5-@WWU*;K<<+EFWDTUn*>>%NQi{ra4U zlz-jgi<VE9k&xdj@VC_S%L4I5*0uMq=^K5ID>B(%EMK<0$iolFP`|s@W>Lt>2`{vk z`rR+v{K08<(C${3@{i8xccZ_DAFhkr;p<V7-upZJ$h9oRi(6{*gAdGI<;Db#<%ZDZ z780Cd)w)(E*57kn@9O@gUhso&vOlPdgMdHobxe;vH%$uqpIZtN@pScbS?83{1ONyL BRpkHx literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/trailer.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern-dotted/trailer.png new file mode 100644 index 0000000000000000000000000000000000000000..4b1a3868a73240232a85d0475d276b0491c5f230 GIT binary patch literal 1277 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%z_XPNaxB><LkAk5Y0;_JkoC1u$$t6L4!3=!aMl0K%zP%gPu;}o&fA4-P z)pP#*Q~vCI>r5g0YxfejN<Wd>x8;6q#oUQ+G=Hd8Jv@4XIg+*VbB*QXPuujrZe(iY zQe<0~8qGN2I>+YQ(|KMlJ^Ouj+TY7dPP@;_*mE%R4EL!Q+mqSLwEbn&7Ee-_sIE&g z6VTgPwBy%@TN=JA9>|Gg**(@W<W<OhU0{6VPQam_h0G7u++|>3a`1F<45_&F_WE=G z+YS=PKQ7Po?1@&tp~k7mIe{T{`rd_aLSNjge!utoz3Mymcb<oYx_T@;KKs?iU%&T! zJXx;4uk&2`Ob(zo(ZGQt@7AQ|6fd6eLTxLPuG6B^VM4NkLb8FYPHpoq2rQ}Y4_{L6 ztP`4U{^HnQ&hvJQ(!X7;-WIE;wQG{b-GjN-mt1DXEq(N~X20M6jYnOM^M8I2VS4|j zg6^zySKOxFs%~6SZ|g4i#Comu)LX{RCRRs`Ma7r8e*U&0T7P;`PT3jjYOnkr&EHk? z*Y%&jd7bS`kEvQtHOnVQo|G@_b@??nLl&*pTGQ_Tb?fy_n+$C|qOQH4xo5?T{(biL zw-;Ytc3l1P_a9PqkNeXm*+f*>+23BC{;u!$-$jd-|NLaPF2u8AMRgbV=ff`RZ&w7E zdWNh_7uvHVGGxp1U7UZpBv1I-NIg8*yl&3#Pon%*dG^KeFJ>OQ)AHI*OtkiX;g@y2 z$IPsLl>{%{7;k>%!Grmd$1@MU{21?ME+XyO(Pfvr?Nir^7ZYxtx+=8z{yHs}oG)wD ze-<#F{8sF=IA5ncD@I6aZlvC>xL5P+=4)v^$=H5_-EhKk_C^1FxBUNmdzY)29jjth z+R4U`mK+!3r@Qd8D(*7=lKfVw_`QnzXY=oho2MQwTJ&?ab?UZH4MC|+i?XL!RbEbc zc(rWlHqOp>kJ``e-2804+o3%L-4kA%i~8(;WLuWv#Vw`b!AE?2jTzD67|50Q$$59j U(l{>Z2^T?<p00i_>zopr09qnF=>Px# literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/chapters.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/chapters.png new file mode 100644 index 0000000000000000000000000000000000000000..62a5941fbf5bf31df380ed75cc7c7c6ac62828e7 GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|@&kNAT!Hj|Is*O6Oc#Mxs+0uz1vAvdzCK(z^Ud>9A73O~sBM@NzUy7d z=l#1+7Qda_U(~bhQ`w2gc{g`11gf9q>EaktaqI21oqSCJBCdfVqO8v==l%aL?W?!% z*pW*uN4D;gofT}GH;oaf7z*a=RoXvUej+w7y|8aiXz1V4%PTJ4etz4cXwoMEOCQUu zD=++JUG2?T`o?uzFkg?^trzmU>ML!R`PSJ!OBFno`Xo2>`B#ab5pQ0v&#pH)kon4_ nv|1u}%jGMXpb&?E1MwA%b6U-}Tbl|RgG4-C{an^LB{Ts5COhN8 literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/info.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/info.png new file mode 100644 index 0000000000000000000000000000000000000000..1da667871b9dbe172cfbfee50e666ca30f5b53d6 GIT binary patch literal 1755 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-HD>U~&ua32_Aq{vQRSAwXFO+>H7B449G*mIV0)GjK9JWfOR1@5}gg>x=u> zPVcMu<^A_3tL8>$_S@3${@i;Ta>-cS?M;V!;3uBXuYYHRs~q0*IP%{^77o+-3j(AZ zmslsvh{&~E{p>`lEwg0S$1l3yH^+WkyVK;u?qhRqK6g;=et9u@&0OB9O^+;uJ(r~) zNea>lHZ;E_c)m<#`XX7y`bv?d65Ds_-ML(zIn&FkFYLk&{~zktry8xOEuN)xAif}{ zX#ErU{zgA-pGkLbWFOavDrxUk?M&OxZ+Dez1GkpTPyTxc7#Nt-JY5_^DsH`<86GX{ zDAHywa6v^ub_wUD>i52mOS}b_YPkjqE?JfEe((2t)$jK{pKqBioU*y$wdnbemHWPb zvM&CZR%UFS?luV+E?B^2r%wl7U0ZN~XY<WFZ(`<!|NU$q!1um<UUJxjo10%vl+8}w zeec)OXPi2Ix$7Ujmiczj!tStl?_=Y-cbN>~&o79qe%v)J`L2BTWUaoO>@C~f^rqU( zU3_UxU3As;o>co;dAw0U%XiAmwQWk>`P7wlRk@n2i{2HH&&Bfu9n(0u#e8+%TE2AM zddn{Fob}(6t1SyZy%KU?waoU}(>Z&mtx;OEJZA4x`zOoKuUR6TS=nuEDwkr(u}3uD zX0NSe-kN=PHfJc6YfqXJ*;Lu}fVKC;nq-x?Zf<IGm1eqo?o%>|S@vXYWAEo{>kp~_ z=sug|)McD&XPatr^<>VH_LBwse7|%r;x)VI+SRth;`Q&=-i;U3KA${&_U!EpY1Xd9 zUMsarzi+kpc4h5<zWn;{mD`r2AK5VDb&Q$pmpkjT`mMblUy@uaE2+Na_}X%DX62b4 z@xpo^SJ}27JeLq)t}}bi(E~whm((5#ZE`bRy_wZ=+st=u5;sn{R4pwi3|-5$@5?{F z)nPODDpj9znKf^hX7twJxgQEAs=QBC;!aYkjo7i|)j!87J5x@dCEvNHPu+Oyl2!P` zsm2qRE#If)6MgI9%o9>GJjyS39_-k*g}*d*ZcJ2^P|OP5yRJ8d)GjezVceDF9qgS} zbKd1vzUbQ)r>#q@pWOe}d-|S9Cr@~`=l;bR4Zg37=AYx2@&2b5J6%)g_vaid@xyvS zIV*le_iH>2`qbdxuklkRNMAwu-{Qsp_H`}LXyp5%S7_zD<FV)3x57uCX)IWv;IL6X zbGm=F+$O6vow<tYzdx*e)#?~hzq4=ZmM>m*&r54;E5E+6-8oCy@Nvc3nqa|~1}Bqu z2)Ub<x2a$8G@YjWHRG!Fg9nK_6%4{WcxJv%vHa}sduN6G=}mlPGj%c_OgJ*>)Y)s? z)8_p;cU!uqcJXTE{npWoxod@j%XB<`6fYDNmzOuL)84+<ImtWh%7W`hs$I&b*X%ta z`MxB0=Gsk{8)w%ERnNLNWnSK7^*eVppR9}SWWkaJ7#L=V)iFzJ9`1__6BGw2@O1Ta JS?83{1OS+bTt)x@ literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/media.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/media.png new file mode 100644 index 0000000000000000000000000000000000000000..f97810280f9e78cfaf17d1b77505215fd504c61f GIT binary patch literal 961 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zT>^YUT!DiBM*(FaP{UDj3mA^sB|(0{3`JiB7$5Gt_fqK;li0~?*Og~D zEPn8J^&iizdw#oY6M0-%Yv#-^$jY+i+i_vXkKdQ&{m>Ub;cCiprSVI%sMZHtA-=s! zyw)_`UbiE#KIfOji_fW-6zB71pUIqlIQmA$yVK=WD;F)Wmt|I!Q#<KfkO+*%C7v#h zAr-gY-f;J4a+GLz7<hmyiIICj!u!47?^VCw`}^<z-P#9Tx{frr|D5!F=b5xL{`ZMx zn|2=qx)=exepDCL3&*YAY+|Jqxh6VluKq*j_&}}uQ&0Hr_K2Rl^djrhcaK8e=}kO- zT5h7$^raWuC6~>2l{-_qKlpBDdP!p2%c6;1$$m{rTZ2z6@;$RMZ+5U)Zc<`;yNPzU zS$Vwmk<~i4?pQznx@p#ndq+~^w~MUk+}9CO-|6Bc6d?Rp_r`ivt4Uw@7O7P2O4_LO z@MW0y7ytA}7scl~f7$Q4zwBMbWZtT1A@d!%y>;ttzN%_VNp<SyzuA6E>hD9(|5v2S z#GadfuUdOoZt1@*&sG&Br&+t43w7n+acuY8jXuF8)wQ`bA)>LOBDELqcc@u8mjon# zajErq`0}EGmE~f+U8iRpW1YSDKGRG8gvFb0Y!R~CWcF+6vG_@6?5_#L$KA@>Xu9ji zj+;{#t-Si}d#2s?4z*bsi-eQJ+}?}r+WdO6LDg>MDbsy3uI}2uOzvm%iqwmYy%!N7 d%fN78y&Yo%6O(?X$3uRQxTmY1%Q~loCICi8TMz&M literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/more.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/more.png new file mode 100644 index 0000000000000000000000000000000000000000..04f9b45677409cb0c020063188d8b08e2144bcbd GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|@&kNAT!Hj|Is*O6Oc#Mxs+0uz1vAvdzCK(z^Ud>9A73O~sBM@NzUy7d z=l#1+7Qda_U(~bhQ`w2gc{g`11gh`zba4!+xb^m`CEp<j0awRn#^$s8-v9o4zT--o zlaq?~x>NJieg^taV+5*&0o}6G?TY(d<hrc7v!5(l_3C=;Vz>AA<1e3xJQe)J;^~sW z#nqW%_M0Xb3EcFxG`f|s`2UNakE_niuCbk#DtM~&NpkS>zcN3gWM5xjE6)ov6iDBC Y!+h(%^qmafE3qI^Pgg&ebxsLQ0BD%s%>V!Z literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/next.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/next.png new file mode 100644 index 0000000000000000000000000000000000000000..893989e5c109b02a887efa1bd39cac738f67341a GIT binary patch literal 693 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|UIqAsxB}__BLj3-?_~%2*0&_cFPI_x;Je>{`#)|^=wNy|BklY1+4CNV zSnJPCej+ZN9=Y$Qkb$B3WC@lNiO-Dr8B=U_ALl7`6g-!8<~6Uk_Whl4fj=_yEQF78 z2Q%;ex@!-^9{I<>pcU|RaSW-r_4dZ~FeXC@*M|zm9a}bbv+iD$^q%#|x)sm=#=FZO z*m?fo-@E_Jt5Z``Cvh?Yor3@k^=sy+EuOgS?!D)}`<Cildf^te^JHYE=C!GEldH<x zF235vvv}%MzdwtXK8-w_;Va6scx%whAFkfY*=-kZ=}Ne1Yp(s}`af@??ct2x_iui? zde45|cF`)zyyx1VgYEHKCYA4h@%pm)?ib${-k&!wVuQ79*Ywcc#lK#idEafZGo$>w zhF<RNyPx#Z-n_e<S$q23)1d5Mdj<Q=-^4vWd1uSr`u<yw<0tP}96!G~vc&o8^ao;h t>rc(D@ti-=ExcHr`K2PlBOsQ+mpX<!zZ(1fScFqSd{0+Dmvv4FO#pKMuJ-@{ literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/pause.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..6ebe03071a105228f8f459b6b327a745c527a831 GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X3p0?M(bV4pq*&4&eH|GXHuiJ>Nn{1`8H<D5 zofy`glX(f`NC)_YxB}__IKXRPyF)-}j*=k1V1}k^cW>oi@46zzxC|&3@9E+gl5y|t z^@Y3*4g#(Ry$z-`#5FGCv|7Nl%Ax7eskXNdJ@gXYYQKKT(*!DKaPV*Is64yzt)Tbi zFA>>$i)G$h%wE1;X7Uy|C^^3TcRN2jNb#Q|%*Afg-8q-_Yk|0)u6{1-oD!M<@-}3j literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/play.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/play.png new file mode 100644 index 0000000000000000000000000000000000000000..c4872bedac695d19a855bdb42ade970604f1bff6 GIT binary patch literal 789 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zWdnRdT!DiBM*)ryn8-Ih1{gqbB|(0{44?Q~BEG-d|3&!V)|)b#9~%Ds zVG1#3tnZ(6Hj#V%##4FUZnG^@P0qgP@!m&ivTn&S_eBTN<jyPHF<5FXE}}kBFzbmw zYtE*R8jH=|Om}&?bIB2Heb=AoR<7E7=(y7jo*lcN0HZ|5)5S5Q;?~<6u3;>J0xlQt zZ`ple$L`(PkKe7^_&@bP$Ke*kBM<M2?r{tYO#{U*68NFIbi3RB7uUb9ivQZJb)NTY z+C@*#qqmmDZ<+FX-RJIUyH>Sb>?;4!^DTVKlq|{b-P5X;U#h!!spO17l<iH?{V&d6 z%!~WfJ#AV$NHhj0`th9U{tQi{i9n@g+sywgTKeSOy!b7T*wumZFK<qa-=g>J?IQku z?!3o=`)syX3lwkE-5!1~<IDLx1$$TbF!i@~k8c|8Zq3}W_HOQJ?<v>r_BAB^Z@9a2 z>dcMSIpWWC>-uZ^{aijPR=6%t;|7x9M#_paT(|RmW8M71<+2k;+{N$V+Yg?0{`pI9 kM`hI>P9(oFFnr*zVc?thK0jgKtkob1Pgg&ebxsLQ0J)L;RsaA1 literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/pqueue.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/pqueue.png new file mode 100644 index 0000000000000000000000000000000000000000..12c201e107261c0e7a19ee8f7e38d4599e07774c GIT binary patch literal 688 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|o(K4ZxB}__BLGCL?$`wMs!vIfUob<R*saSO-ZSmlym9V>JN&#&_jSK{ z+eY!VDvIyk)wN!-<|UWHHXXs-#%VVj7W3qYoGVISeS?|(UQbJ?r`)OOm78k6@3?-q zlkw8jIWLy8-Tey;R(?+x$B>F!Z?ByUI^-bG@K8fxLW6=rw|0llqjfv<8#=Q0|NktZ zu`@xd_~gRlzxGGp|L1kq=XfE|MaW=LK$YGN@xNO7i$iZO+N@->bGwd}TJZGG#+U9z z#FeZyjq3V&r(~5`*uNL+vwOuXtH0zgWvRR*t^1GNmcM6Tp!8hb--q+`HGcVJmVDf1 zG~3UgZ@QSR#@>#{(_;POo_$Y=c>4MG*<GzK_S~MHvvx`2p(m%VyW7l(4i<mgd2!jU z7pBD}Zn0ku$h=+Iy>FMqvcp%uSFB<9Gu^)bT;FVthiadWzgo2W+0&vUQvHV-Evw>V oOY*9<MbBjyeP%@V1cQT09Rmwv-hyxM6IehJp00i_>zopr033>>cmMzZ literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/repeat-one.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/repeat-one.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab80235f67e8ac0abca4962bcec6bb3708d8ac0 GIT binary patch literal 654 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|4hQ&zxB}__LmV7z(VY+UhC@k^UogYWJD)hu8oj+6_D#ECzv0s-SrfA5 z%0pWpPfYiHt=`YoHp3vqQvXHF{Yi7ng5T&q(y~d;IWtd**?3i{;O@yT?=rT(aR3IB ztfz}(NX4zUH%<l}au8^E$f>}o@LMTQqkBj9Z@n+S?WcAMoC-)N{BR-m&;7OO&pya6 z3-X);3U>s^C@4)g`1R@6wYZW{E!F0WLHjm}#fnedJn!47M`4FFdZvAP)Ar`*YS+|@ zm63~Lf84y?`Fzi&jQYqeGA4`mzODG;>r&qT#`XHL>f@^x&)#{%)#Tl|Z(J9>+_S$t ztl7iA{PU5<+O-#N-ar2`>XU<C{g>t%%i@dg{m;dfJU*IG@>+Mofv7LbZEkhf{VVvk z$k|2M*W}`CA=_^@Gb`?`UisqLm*AzTZ>u6I6Rmzec8JgZqOkea%4;vYHr%>!roNxm s<$v=RtBaYb7d7j7HQ5n<0<pIIWQ%-W#wOzz>;>X_y85}Sb4q9e05pq=-T(jq literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/repeat.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/repeat.png new file mode 100644 index 0000000000000000000000000000000000000000..eddcba762f5476b2d4d590bbe177d51610f8e741 GIT binary patch literal 576 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|mInBQxB}__gC6Yo`#2QnP_vRCzhH*_pT2RPHF_I%SG(bk+yuj?PqMRG zXOycO^uM0yo6hyPEkyrCjAiNENt5sA%wta04KCAq^v34yvcL&I6TW-8IEGZ*dVAw! z&>;sAhl>nZ0*nVMk5$fV|M%bDI50_)wY#<Z-KyfU_3`@el&*HCNCGuMfMG?Ax52NM zUoH2(xM~pNXJEx67t|fcsTh-gH16h%^_7~74k!F+eG|UC_r#*;#HPUK$=k!uu065n zv**Rc<>Bw9tupjis`{(2_r<^G?+jkO=q-D?NT&SwZokS+ve{prU9X7unZA{~dZU|u zP5tuUU%B7@Se$<-bXv@ppSjcGO5W=od~x5UTTC}<OUA`TuHt?FcNB<Zf4O<5Wcfxn ze(~kjp3n9l=U?>Sv3S~xw3Lf?YuN7cz#Pudan}0Px_HfrHy_>xiFvyExvX<aXaWFv CnN)oM literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/rotate.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..a6082d9248b1c0c424b18b91b5dd60ecfa4e3e22 GIT binary patch literal 784 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|t_JvoxB}__!wwuWxw8`JF}IQ+zhH)k+~1Wr@4glK_DS&HyE}}3Z=L11 zcmILR*UT@<S^{iRM(^$UKa{F1c8iZ;$~dmRtg_<g&h4l4h0{ep>iiOs(|*dr`{uE{ z9m~~;z~F25ba4!+xb^nN^`a&Rk%ot+E4r1E%*%RT?)@HD^WU9|McJ`)`@5Mx_iIPw z)uqk2YpekZbp(iLUE~*1GNtI$)6<*Rbzc1GxoFSYDY7=3%eI~EzIO7WRmVPl{qH_K zdOeTkw?%U;o?E3^)2z$9c<n;j%YS$l@7?|S+C~4b`zkN)eEuV7zn~jCU)1ZmFKNg3 zyeO&3)D?Br-YOk3pQAghz3$7;jT<uFpIUDxDz-N7?+fnCi~MyZ&QV{2eP3_dlCeJh zcHfo^<@Ej|FUlJ)=Bd|h>HcBE_3loMu3}Z<zG)I`Rb8gPx;ZmpjhNtDJ|ko1aE~o= z?%$JjRezm-m?Z4GWy_1SnwM)86>i<~IKF2OSI4}FojaOZUewoh&y>FF*OzyHhD<Ey z^X^-V?faH3s$6`@*m9TDIq|Zy_g!~g+!OfKr*Gb?^uI6GKS@94mcFU`_t!TYei~R* z)$RXhDkCYgcSF2?Bx~^E;K@rrskwz~SFK#cga|<(Yt13^*38l>>jo9Du&1k^%Q~lo FCIE6#%$NWG literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/settings.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..c4c4f2ccf40a08b710eab5514e0a7a41a6cea126 GIT binary patch literal 744 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|J_PuLxB}__BMCgcdgvk0&;BJre!&cHG{4Vn^?56DNR{bW_R76s?jJgo zCuwc*Ra+1dQzLwPCgYt;N<!cMy_^32z&*MB*B!;{T^CKcwqw3U-C|LG?(~Hh=eRi= z_r0FXE5Ow`by`}QtsF3jtvy{FLn>~)y?H$7P=ZKXqDdBmFXO?u32I#5;slQ{t+@05 z?u^Mt>JM5xc1tgs^F8wE?Y)PWICv}tx(W&Wc;8i)U@O;cRCMv<v1L6^UEJ39Fn#_w zWAa83+2x;&#DpYmRWmPtJaJ-1=VJ8~A0gi@uU^zj+WKCs-d8Vh&+E^fX|rBzy*T~T znprPGg<}<GT~4<7b>VYaYRR5;^SBK!O!;`?aO(^C#lQ89xMnT7e06zS&*WEY=e>Bo zYpd?zRnxz??4LdRTl2gZ;li~m)qfp!ng6P@ZnN}5%emXne{tc@j*LDQ`qr-TqV=S* zzh`T!1ngoqar%_a`4D=%_42;UpIuC*M}L{9)xC|&rMRl6`0lhNb9bA&&)PR@n#$W5 q@{INVPk(1l{m+8rT_E$rY&*vP@8_o;w)uDwB;)Do=d#Wzp$P!+;mkGw literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/shuffle.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/shuffle.png new file mode 100644 index 0000000000000000000000000000000000000000..9c79a53970cb18c7e1a5fd3acb5ef68a03ea49e3 GIT binary patch literal 1349 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%z9|!n^xB><LkAh(x0vq|Hz5%0oK}nEbFhlT<S4X)RnK-;3>^Lj*Rr(V1 z(!W7zzkS*4Z=B>7*;>;haeL1*r^46o_xreXeB*uRXluBZCD1F@|K&%;X>p0^?05VY zEz6qxJ)!9QTMJJ?Q4`(!a-BLCk`HWnBhxDR=|tsCqufVoGgk1dskkS_e@%1S;ureA z%&s4rp7K++e*2b<4xE!hltT}HiJs%(T5!y&aiKwN)5;H*KOZcP+?W6K%qfXueL@Tj zOd*~wjv*Dd-rfi;zU?5=_OLf_-Q!z+Nyqt2=CoZlNS+A-ikim7)pc20SFc?)CC%z` z_h#e!#fjd>&EFsGD@#=bdKex2>t}z==5~L#_31q?m|o=@>+PDb;=khlH6Gu)y6pc+ zRJ*v8_P$y4*JbU|rxPc|*Kur*UHSg>_QjdfyGw0*r_AN{Uf$Ded-TbyeN)m+F3y`$ zeo^Iw^8SX%FOTGNWeaV!XFm5`=DqjMwBt>i4zBXuwQfahui5q2zqh})J9Tv8;ZFy* zmDV0uIcMkTebKQ`?(C_wSJ>5AV>5f{Ixo?vz2Qf$S^iaCoK^hMRU%(`<IPp3-w!x` zm6Z*+%>Od(;4P`p-LbXLBCFirJlvQ5zIeX4u~U^uQvC&wybEWa_equ5L|NbO%o9=5 z3_rX6j8$h`-nQA7&!6quH*woy<}}lG`O{Y?dPS+ZE>HQKo?UTa!L!S2jebr3;njM~ zL|$_8+2olz7hjjzb{ofQYWJ`FTxa&<=)YI13)`G!6VIJJT=%u7PHWRS>1zx9EYB{q z*=JpO)-7FsPrkiVoYnO5T}Dnl!nUVBoaT)bP0#*n%`i8ld!grj)i@i;iR%0O$}XyF zy}on!u9)rY*T3xo#eYw}v&etv$#&^G4=3Hx%->cVHRE6FgZ!v>e{Uxr*UB%|-TWd; zvNSC)^3U?0o9;HIeV@BvO5~THE>~N-kJtY;nJ2Sr=`_zNclnb4mVVFJFnj%7lh-%W z^Yu#h9^H^;=y);k@~oq8S35GI$2<eW2mgJHm&};<2i)oL2g!Q6`njxgN@xNAR<d<G literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/skip-forward.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/skip-forward.png new file mode 100644 index 0000000000000000000000000000000000000000..a95d14955d32942dd59b3f533a8a295b26a5481c GIT binary patch literal 1017 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%zQv-ZLT!DiBM*)pPfcIZg5-_04N`m}?83cZQdp+mNTiMS%XMVA%Pn(>) z?CC9YTjzb8s!<1WK8Rji$Sr-2LvDJZ|80qt7bebQJgx95ad|nD?y<;2vllIh7nJd2 z%|32_-=o59X343YH^2VAVw7Z@&*fBL6Y__BiqM-Enk!nC{<T`&&#Rwtr|QwCdy+pc zi~AjRy9$i*4W2HJAr-gY-f$0}oG9Y@P{c!pQ)A(GIgzQ0IK*bfuDW3@>*#QxtZx6B zr&o;6#jg45^FD=t-}~H77NGNyz>nw8-^>3^<<0oCxZl!PLv)H}cFD5kM|-z@j{Ywn zvm$8Qnv0QJx6cY(YG!w|XWay|+c8`Ay?fH+<~{x1%#6%6rdeC$uJ6dW8rvzgcJ@}i zs991RQo6cfyEE>t28uj0*NYM@U+kuB`)<+F?!AtSmp&8|Uu$i?$SwQl)b6m@+$$NS z`^qj}N+`YXVso$B^F>$dth2VPGvASsng-N$`PrhSTkkEnn9hC2S$yrE`3o+7<#&rM zd03&4_T^OQ@5(Ft`+xc_m-oFTzww6XXZM<0Dc4_KxxL`^m$kpkiYs>t6ubNA-rU^o zHpy`N$A#+OrhHGbd!f1hMtc9UpT}lAf9ce|cjt>+F=xCFd`|z?x1-APg>0c(rvA3O zyoULYS91P-xA0}k8TFQbw%-peIoG#9-)HyhZ;@+$8$5}Q`}LXK{ME&}aHW)z;>EJH z)<(^j^yf}9{nafmyTkFm=eKGmq#$NsX!!g>|JGm6BinacfP>%D)z4*}Q$iB}F>a9w literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/square2x2.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/square2x2.png new file mode 100644 index 0000000000000000000000000000000000000000..97a763da4c39d486e1066026708eb5fb77f2e707 GIT binary patch literal 615 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|HU{{FxB}__Lkeu4Q8WkWXsePSzhH*HFRts`YF%}Hc;(Se?Jaj7+<&g) z=z8hSvBR3*P2XB58@w_3?B?{(=#||c2Y&k}+*}-%zn|%<8-IDa=CspgU~uqxx;TbZ z+<JTSWY{4G0k?;j*qqhcjx11UR<by6bn>_Tj5SGI;qwkJl6t@WPk8y%CDuwntC4`r zj<nrRn}Qy(U9z|DK6P;GE#K;kAKkJ~JaN+Bxc9|5zb`BA#Jygctbgm}q1n|d@4h^F zv%9b4p>u53%y~-H7aR3#Zn??7)>N34v8YpR){Fg~W&3RBJ^kdR-}(22yZj>e%ZmaH zt0!HrGW;#s^|HhHcwEnC6I;!tFK6%3|NLq~|6AAZZILq59!=+ubcvs;DE;k?Yx{mb zz13UeoT@Lz#{Sq@>v#U^m8VagOfI?z`+l+Ck@)G8-uctf!TRr)@BJf;<PRY8KwK@e WGSA6J%ThXBKr)`LelF{r5}E+lTWcTy literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/stop.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..b07b3692d191dc7b2c31e3dd99eee19e6e782a74 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X3p0?M(bV4pq*&4&eH|GXHuiJ>Nn{1`8H<D5 zofy`glX(f`@CW#WxB}__NTA>8UIs{CNswPK!={?us|p09fP5cM7srr{dvC8F<Yf>L zadFfY;C<o9?DXGs=YQkQBR-7p_skXoDr5N2H?6ry=We(`|I%z9{!BP{$-eye(Zh@& aCHHUi7R;M!y_5M6i0A3*=d#Wzp$Pyemq-Ty literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/subtitle.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/subtitle.png new file mode 100644 index 0000000000000000000000000000000000000000..6d4ea2e9bded61f0a31d286a0296fb46948a78a4 GIT binary patch literal 524 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|CIt9|xB}__g9%Jyko*92lYU8%UogWip*OCc+uz=>|8hm{^3{{?9IWN9 zsXqMmiIdGkf&HWJotxr&|0sSA+OcQb?)^TYPYc#-0JYxtba4!+xb^mir{7@*0f&of z$5?JpkQCzhZ1ely_GIDB4t;wP3q0TFR)4-4H2um{A)pp0__OI_-SWcsi%#zfzPbBF zV)>VVEg2W<1^3p}-OT>{<-+3^Z&FUbOq{>ipV@7_-L=Z@ufI38YwU{K_jXH_t}p-P z#c{Upww?0jzqrUX-}q(UydS;)TW)UA=sMlK{!n0Cjq%*C#mU9<OwV48oMC!-L1o`n zM=o(&t}Az3!as}XRSCYFXMQo<T{GrO>4s+}C!Egq`hK~aB)8V`?wxz;Fc&_UU&AEb XSbgtijvp{u85lfW{an^LB{Ts5H`Ov( literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/tags.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/tags.png new file mode 100644 index 0000000000000000000000000000000000000000..f468cc28dc67e9794dd4b36bc3c7e63d6f8ba50f GIT binary patch literal 1614 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-HD>U}6vO32_Aq{vQP+J_OQo-qr$>!kUsGzhDNQHw*quVEiW-{rc^xN$+^0 zez*NSssD>@|Mzb(yY-Ii3bAv2<S1b(eXsH=&RO}6fxx`}`6oD^EMaaxn)ST+AWPUj zqe$01@n#peg%|NJe9$MxYAfx3xbSmFjp)yaT)xYz?!~5kRdBg|{>R>PiZ7H@@6PHq zJfwZVL2Lb->balJUb&{ZwN}Tn{^6#Iq%W;Y<t*}Au6JK7TDGy$GkE4S8*|xb9y0g4 zZkoE8TrzfA*%q>hfq_}q)5S5Q;?~<6SA(Mi1=v1J7Er1XY7&o<@mg3>n5*emsCzGH zfx}%8_}2eM&S_b|r0;Vd{@xqYcBehR?Ax1r)l->(-bVvB9CG44iluHVP5Zwi*hH!{ ze?iseCugFaPjIIPT`|2mlfO>4_{)nG%TKKncemv$39os!>cWY%XoiV~I-#|7jwzYj zw2DKYd|7?6ar@MZE|t|OZGF5dTpYn!(K6Gotv~tseTwOe_e++4PyNPr-Ey+AzRSxq zVg5huMf*ccrv#s1o;Y*oxtUjEo=2XW^ZMkPUC&m$zuO+Tsf7E?p6>Gr%X*Ekzp(l* zT_|h%<zsDz>P3$wdw!mo*<0$R`|irj?dyLXz50Kb)<?_0-wU>!5uRh|a6K~JE;shG zbU*Lr<`>UYGxsK5+3dHH=UmRot?TwL%<0f8IW_D2#+Q47+boUGTb+)~*WPVC_tfhn za~<!Vzg%_gY4qN^lL{tITGw$))9t(8%>K_aBj4`zQM30fRz6V6CSLL^OuoNZ);1+e zY|6}XFNN!sh2Q>1Zud$mFq!*$>SgH~w$r)qj6HVVt9EW>`@HyGMB9WD6NTs8Jh8ia z-uDGZ*B=c}QxE*(sad)&_Q-DQu$70*|16n*|B3SE{jJ8kkC?cx{LQoKoXV!{zh3mZ z)#uGwAY-}w1KZ8_uU<R%U48mjta)8=Mbm=9>u%qof8Fv9d0AT^(Nvl*GkHt+IpN;x zpG~!ACCyW*o?W`@+@z}J&<_*t?e7=ACvh?0<gY7jhszc*O<!?lm8xo+hPC&~Tb4?} zC#RME&3R;Xy{nqh|FQVn{Fv8mcWqY4ul3D6@pz};yv0X6eP=2~ttww`_EmkoW%C?M zJ4eoxxOW16v8Pwg?K>1&9dJG!7=70=wQK)Yw^<)~SXt{E^Nx4AP}Xtpcdy^rd;R_6 zDzdRiO8ReQUQ2#Zl53dEgOkU%{yUd#duU;>^ex{_#>Hz(+jag1X!R_<wR64m*EQOr zb0g0StovGVG^O#MLzb0E%$e#94i#y!uQk6ff3a`T)ci}1?o%qBr8in-U79I;e7doG hsU}*2267vCpXe92abKAGP@DxM>*?y}vd$@?2>|VC4afih literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/trailer.png b/script.plexmod/resources/skins/Main/media/script.plex/buttons/player/modern/trailer.png new file mode 100644 index 0000000000000000000000000000000000000000..4b1a3868a73240232a85d0475d276b0491c5f230 GIT binary patch literal 1277 zcmeAS@N?(olHy`uVBq!ia0vp^TYz{X2Q!e2ElO$yQY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D%z_XPNaxB><LkAk5Y0;_JkoC1u$$t6L4!3=!aMl0K%zP%gPu;}o&fA4-P z)pP#*Q~vCI>r5g0YxfejN<Wd>x8;6q#oUQ+G=Hd8Jv@4XIg+*VbB*QXPuujrZe(iY zQe<0~8qGN2I>+YQ(|KMlJ^Ouj+TY7dPP@;_*mE%R4EL!Q+mqSLwEbn&7Ee-_sIE&g z6VTgPwBy%@TN=JA9>|Gg**(@W<W<OhU0{6VPQam_h0G7u++|>3a`1F<45_&F_WE=G z+YS=PKQ7Po?1@&tp~k7mIe{T{`rd_aLSNjge!utoz3Mymcb<oYx_T@;KKs?iU%&T! zJXx;4uk&2`Ob(zo(ZGQt@7AQ|6fd6eLTxLPuG6B^VM4NkLb8FYPHpoq2rQ}Y4_{L6 ztP`4U{^HnQ&hvJQ(!X7;-WIE;wQG{b-GjN-mt1DXEq(N~X20M6jYnOM^M8I2VS4|j zg6^zySKOxFs%~6SZ|g4i#Comu)LX{RCRRs`Ma7r8e*U&0T7P;`PT3jjYOnkr&EHk? z*Y%&jd7bS`kEvQtHOnVQo|G@_b@??nLl&*pTGQ_Tb?fy_n+$C|qOQH4xo5?T{(biL zw-;Ytc3l1P_a9PqkNeXm*+f*>+23BC{;u!$-$jd-|NLaPF2u8AMRgbV=ff`RZ&w7E zdWNh_7uvHVGGxp1U7UZpBv1I-NIg8*yl&3#Pon%*dG^KeFJ>OQ)AHI*OtkiX;g@y2 z$IPsLl>{%{7;k>%!Grmd$1@MU{21?ME+XyO(Pfvr?Nir^7ZYxtx+=8z{yHs}oG)wD ze-<#F{8sF=IA5ncD@I6aZlvC>xL5P+=4)v^$=H5_-EhKk_C^1FxBUNmdzY)29jjth z+R4U`mK+!3r@Qd8D(*7=lKfVw_`QnzXY=oho2MQwTJ&?ab?UZH4MC|+i?XL!RbEbc zc(rWlHqOp>kJ``e-2804+o3%L-4kA%i~8(;WLuWv#Vw`b!AE?2jTzD67|50Q$$59j U(l{>Z2^T?<p00i_>zopr09qnF=>Px# literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/home/plex.png b/script.plexmod/resources/skins/Main/media/script.plex/home/plex.png index 9a94e24096b26273c8398858395fa77d23b08bd1..e4c95a6340014961dab8dfaebc7129a0df91031f 100644 GIT binary patch literal 2046 zcmb7E2~bm46#am-6tJiP6okks+LT2gsfdWtK!V637$cAxER?O02#Jb>Ri&YIi4ZlS zfMON`$Zn~kEVhb9ln4@QQ791?lAu9|0$E6Zz_vKfblN}f-*?}==bpRF`~Qc~VDx-L zOG5wv<_BO<Vc`BX_`(eIK<V5|aR#?}@yH+~0MyfsR6F&-vko~7y#c7{vJwM;?y=C# zTm3+zMmecbE4A`pmP#S5ok7mUsHQ$JsucgmFgI{E-T%eUWth>Wb^on+<>Y(hM+_eq z{6R-EcuD04jY}?ma0D5oHGr6>HNGqbr1gNf91wE>jasF3eKfRLB<K=zv`CFcBdMN= zJr9OVgLcrOmEf8)pV|6n+2(SBx^~rRB^WZ-^`2yg>L1uluDPziqomdENwi+Yghs6a zyLiv6Qfl=%xj?(50?<rri`C+1AEiP|QU_?~Py@E3*1|3V!)$Gvpgz(#bL9NhDHuLe zGw9MNC%~lsTNg6H8!4oO1&0I1-s*{5hf$pA0)3T^&%3^thLhV6ZBhkfynB%J$qMeU zfv*$#)tY*1*_Q2%1$2zXIr7v~8|Y{I#?17dO+OAWcXad08+dKSnXIyu5;_E(rzJ?; zn!o{*y+1yWzWx<+z48ny!6A;Fl!!R7_>kW6PmF@#XK%1J2{S`l)3JEUxoZpRtG|`Q zE-&dR2|S9XiT2>btseLt`01Wc?4!elyi>vr=V^R@j|k#{km94OQt}6~{gt>1yVYC& zs2z>vq?~uq{f0LM;S{|fZrcBhf7<MdJ#9I>sU7?*odZzFt(aS{m{SC-pJ}^bXlJ`r zM5UXIm99%$6qPq}HOIigCO>DBqQLrzS<rP(7=C>?nG|xV=gy`Fsjz)f_&`|o!b#E@ zYJ69V2ML*d#aBK>$vWdj?waWGnJD%k>-e7xVBZl__6Av)_}~5tb#l;d<8WCq^qsG| zEik)v#RIvqe0N~AqpBzeX*4u6w6v`Oc!s;oNWIwf<jTqvR(E+k+Ur0y{8$rr?VeTz ztuw~VYjj<tX~=h0>_sQG8|K~hH85WgbTLRr>{>2~b4aoi;+w}0@jp!<&-*RJzQyxY z{?n$(a##BX`Ii2pw#P_ui2d-4?j6Rq5}Wdyox6ftebbwnW){;0NhGp@A;7Y-@EHqN z_v1#O1O<}NC^`%5i%(Vb!h45<@RoYH;@Dghwa>154;vsf`zRem46!S;iku;ucbkGn zZ@ycfV0Y~_ioSa^kJ)F`J`T^~6%c@?okSOaXdS1(Ii%x^55Kw!x%|!di`CQ``ZGdW zS<yY2p0TP!j7ua!tNQphJ&ev(W$shZec$sb-b>H*y0@L6RTxLxCudn#pN)2mKwkJ+ z`quq6mf@g?L=Yig)E}%!?iQ^HUe;$Y`p{q%Gf?hXpVjDDvR)SRYxwa|E5^KpZ!41| z4RK%G5?BF`f=?Yp5nw&kA{XohQYhLH?wD@bTX$O!ma*=}BO<H+dHnI=?l9TP7~wY8 zZlxZ_g^%@)^yr8)YOi(gckUi4u53VFs5QaV{uo+pKJ-FkiaAoMti%W?qNU{K{cGB} zIr7E54X-;|NL=SgF2iihXXD9!%aRdYUK~q4vT8?R)8;q7)1owoJ2IOVXSQMfIR93c z-B$CKj?&yh32Z;tu+aP>)1u^3UKAoVwj`LKf4|E=Vp>dy#zXICEL)D<nF{~?Cwtkh z9aS}vIi{`60kuM#OEAoe@(9g@3#SZ!{W9f&UPs5{{73OGV%_{=Z4t2h;<&!oF=?HH zq{K5fsiVFC{Ss7V*`ADTvAUMdreeRAI_=%H27`m7gdypafpvjBkhP+5=HT)|vGq7K zxdk%l)aKI@)hjD4-y@F{ZDHR}6e_5$?dBsgf}y&l$I~#=q$(%9*p<T|5*iC=0IZfg znR1h5!j$Z37Jf;^ng>(}3KtE$@tW)ke+56%xn1aY74CV+Hd7qIhut|?RL}g5%kx6G zqPZ|9zHAATewwB)a4XD}Thw7DKC6JZ7nSTrl&)NusO!CLDsg*8!LKGPbm>MaCI3_w z*HL{XuZhiyuo!brE`2OfY}QP<<!xIQ)R2eDzQ#M!f3sDcTx?eYgEOA;PrCf}Bx8YC z^6*QjZ{8A7wfwGY+8zBKQ>PcyN?Tk4Tjq9Rx}r>uu@_5^<~A<f`#kO7uy-M2fS2!K bFzxCvHge;a<4GalpAiV~3r5v!h(7Qq4lvVz delta 1575 zcmV+?2H5%j533B27k?fI1^@s6PQ4NV00006VoOIv00000008+zyMF)x010qNS#tmY z4c7nw4c7reD4Tcy000McNliru-~<Q~054wGbxHsL1-MB>K~!ko?V5RPR8<tlf8U+y zP_d;b6$HTu4U54I7hIx$kcctSKTM2@Aua?XqDF~`ENZBtXn&1M-OwtD8X{3NF;OGN zjl?aAySPCRtfGh@0tHK_oqPOa-q7hd@6B}4+S)HU$;_R5&%5)@_s%)@ypfq1g^>gr zfStf^z?Z<sz;lvzge@|&vA}mBAD<@aT{-|Wy91a<=deLi6~L-$;^i$vR|6BAGhEzo zu^e-@v9Y=2$bX~fY}pgBuS#GYa6rU$UvounFaZn#Mgb=QmjjOho6YPIGpnEnV^TFO z$X@~^<v_|~j*(^iC2I<}swqHt6L6*L<bF$mD}Xg-c0^Am{`f^()*$XehGfX)wVCyG z2b>zB@`=Eu1upY|r0-o9?Rf<7rkRcE$;4Oe*#9<(Z+}pz+8xd>-S`BhIfM(S1)})e z3@oC+r1oMkaBoj0ee{Fto8*`-XI|loA6vqJ1vyKn0w))6zd%w0fFcs<?Z6Ac>wZ8b zFdmo&j1J2sz~PeCc2gqV44hM>o4u00%=f|9cUCS@jG3`~2{mmk7WXF%pStIBGaCS` z1rCn5)_;e<$&w5p9x<_A(kD4%FPd2`usr0;2{<d*M0X%5X?16vB=-7wsWNvqvJoMQ zkH?_SR&WY1zX0JLxGF<<hr)}bMqoP77&2udJshK}x9^g4g_M?2c17a?lVjo^WyjnK zTvx!|vRv_YD5gu=4!jo;+j~65&ffZp#ItF#TYuF~pmygBYy4rZ-?K3h;btc=H+Qfz ziF9kocsacUKG}S=WLrb48Jc2$etu<;%JO2dq%B=Z`k;{U-+K$`W3O-6CUJv;Y?V<w zS@Avf`zo3@Ezh@nT~J2;4e<_E4;2w5(l6b}Q^L%SD{}4^l3EH)8aZ>vll6~PTqxNY z>3`7L)|`XncXNmzG#T}46Io|VN_Gk9W)=e;jR+%ecO&UTgPu?^7#5V61(9;PJSM)9 zD9b3G?24vk8_Bh^>37t!%#xLoUJmo;+Cg@?nVk!)2Bw5eYX)AWmtoXpJL(Y&Gc|EW z@wA>)u`SP#`t7Amf90Aee^I2@n%VZic7FrAfaif@Bi7VO`juXYLpC<lDluRUt>t$5 z2goQsW;B0$HNJ7vQc3Hhd_{$q{(%*X4Ztn*W=P<bzgn@(Jz&j++;mm%<wsz$q;0*G z@1IAO&$6bSM_NwL0~6+j_fRsv4!7TktITZNKS{a)PXb3v+VCIXrariP3!0?OMSm-* zuA&NWi?UU1mj3o;;61n@Q;1cb2~Yw&*wv)BkbZJ>7cfTBw5X>?|9%8esu(N2fIuc5 z2ld}aG+=?k%?sj#NsPNMd)et`c6LW%`n|x)toMz;ZeU%|fB9eFhb03qaV0h>-7+`K zz<gS+8I_lgt3ip%e1*vClA78>`hT~Q-r#?X4Yh-Zn3DIjhLUtx$q?@aiNTX889p`N z@+#okAR_!DiL_TD<y!7H(}DZQ_Ut3w8=%sb{>MBN<>DqY8`ej9k@)8BLFbs~g0?De zjpOD8{f6J^`X9PC!c94_xR3NA@Y#I>2MR4Q)4mF&jd`$?y?@|GYZitzwSTg3v6-FN z>4sMqVS<^Jv}68yNk0{sQ)*_DiuBhg>4Usov&Q&hD`9AxIPTNupTLrMH$&BUTgdIe zMZh6p1r_kHnN5`ByPNa}+Btu2zND0cA;4ShI6+tC4t{a#(9=Ar8P0qw*)B)rQq95B z8omlj)ZJz_4_Fp)t>c0p=6|Wa@REa7)rXZDw$uzqCWhz4aWlT&x&N-)a+W>~yi>q^ zP3BKoeWYh+y;ReUW;TYLN+nC>-g~BxKc8gIfy{teq#r^@-GvMKNYBDYHxHYDG0(yj zp0-Cu&e-)~$VvFqpd}K8S!On-k91(gdBmJq9T3OoQF(gor{+De`5*;c%?F}dA_?H0 ZzW}^GpnTlSyl4Ob002ovPDHLkV1f%V_hbM7 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/indicators/watched.png b/script.plexmod/resources/skins/Main/media/script.plex/indicators/watched.png new file mode 100644 index 0000000000000000000000000000000000000000..e0ca3627968dcbcc5cdcd532c8006ef530396dc4 GIT binary patch literal 585 zcmV-P0=E5$P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80006INkl<ZScUD^ zKS)(k90%}El3NrcO$p`dC^Wc56c#8UflEU!4w|$YH5U~$1eJqJOG87UC{zSdlS9zx zoM4M#LevmJ#FgKB-0pk#&%3@i)fW!$!8zyq=lt&b-FN)+IM6tNiPbx0XK@S{a0aJv zJTw0pAMh40@ui4tb>jNo=fMgUIE)*(jKP9+M=*>l*uqoX#<wE!z7p{<tYe`>Jd45D zvmP9^49wzHq^gVI;F#^yz%@MHhj11N*VU>9&f-BA#T$5t(`5z@VW|h=4Lk{rTmv_8 zvWEsvghpEfM={eSp-%;KGojUDU>pNo5MRbf{0x7znI8zP76a$HAijnv?BX7_bJjJr z(gsHMDZYw}_=SGFz);TGrdHZOS*I(iYm)pDeh24sOctzfYL&HOQOAXFz1(I#n|vjC zw^iV+Y+yU;xf}IeOU<=QK3>38%fL|7vp-TMY2U}FoxGiat%7xvk*+V&j>V{(ys4Eo z@UdjmM5Ij8{)|yKc~dKG;7x^%<B_(3j%%LPO8+BD9;lrP-7rb}EcLxp?4%#$^a*_J z;7vFcqYjortHnTqTiC2gTm_q<(L~n3cTD%tz;tNj8c6UC^F0us5AMH^*N7fru8ZPx z!P$bMPPmBk*w}~gMsO_VEhuZnuQ7_dC7m*ht=Kaf9J#1+GfHkY$vx_RH?L;@u?PGC X8zpNZ6JhlE00000NkvXXu0mjf(a;d; literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/indicators/watched_2024.png b/script.plexmod/resources/skins/Main/media/script.plex/indicators/watched_2024.png new file mode 100644 index 0000000000000000000000000000000000000000..06196803ef04a4339bad57754cdf791459b6efee GIT binary patch literal 356 zcmV-q0h|7bP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80003iNkl<ZScUDA zJ8r^25QfKx;06g0ju2iF1yW9sn%p5JqDqsJl7@$oxCIqwNXb2LAb&JMPAq$8*7ka# z@h?qd?e6!jXO`;Jxp#t?55T9&h=?L0I>aA>;EKMLz@CUsMD&st_zMeosu2HK#EeWl z!MDg}2cUBcft3LsXX0C6DS$70d*3Zs3-B|5w(l9x;H~6Zo4_2vrXV~N;NJk6>Ghhx zdt&pa!?bfE0FS0UCV>Wkso@Ztgaqf`{vho$3A_mhaXtz@wV!m)^R{4AKtg+JPqwyc zGtgHgW)^s6+RF%V^%RLO;k$9#%L;IH6$vMJUV*$4;!~?afa_U-t52;e0j_}nw@!Oi z0$jsX&)a3;Wd*p#0FEv<cNO4zb%h%R>eRVQi0Bu|B{5((kk|JB0000<MNUMnLSTZj CPnhli literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/splash.png b/script.plexmod/resources/skins/Main/media/script.plex/splash.png index e7a2a53ac5f5bca42c13de3624a4c304311e9bee..baf74bd359ce6ac19096986e2ac33463a2bfd3a5 100644 GIT binary patch literal 15885 zcmd^mc{r3`*f5cO7qX0fkA#qskjK79giy&|B*SDhmJ~B~k$oK`d!?dbs3a=eV~xy6 z!eg%tYJ~6U_xs-WdcW`bmjAwgzU!Kc`#$GB=iKMaz0Wy#ds{P3HW4;DIyz1ZbKo2u z9Roy1M-Q?vz%2v0-UaYKMn5APBRaY#>Fj?lABJ)IuybZ-=^6*bmS7mLw{|jt8xMAW z{hvQ8O?2?*|4j4$tao>{|G%#Fe`V}ng8%#r1ON2{PxUYQpTK|Zh2j5Q`+pzx=Qj+@ z?$k@b=NO1OXX{AUVP17bXyYgU$~c2j)iy?Yw<nE*<y-Cki!a&Qagg|AgEQlF{@PRj zHsfE4?jt<M!jVY{Ap(7NRz>t)`a^14!Wxd>MGZ?|V{fhz_+|fe2TeM1_%zA{4b6$+ zUS@f|Rbjey(&BV1p%8oF5{-^dlFkA!a=JCOR=i^@syotSVqyJKQ~grZHOvNShpt?H zcKzIY^86dQi4yF=!HgFN<Hd0b80hQL)+cn9MSa_C7}6|2q-OJFJ_;*KbJ`lNl+MJu z9d;|W%1Q#ZYifQ^ArXZ1AT3K6brvBSCxn@Cc*yb*k^yNcqWS*_oJIX@0)*hs{{ZnY zl=-*qe*$pF;ikLL-%i|dJ{XezUjRHFa33pp5ANjg`2T6u0;m7+VE^-||2fvXqvOk{ zoo`=ee|`91Y1fk~*w|UDTfb2fGpr1>n1l^-rEznsxi}95>($JyKFpPGQ*-v=NDlPx zjQW1F<}yKUQ~G>A6JLG~-bH^-G^+S4HDeT`KG}LgW4uJ7xOUj0Mks%B+P6G+;i`SI zrFDCBd(f3r<whjR<mzOfksD6D5<kdYQd&P>{e7b{GU8g~?gcuvbIPQVUx7OTOQ&`i zDd_o?9N+D`5WRoMW4|k>=9_X&(O#)`Y||3W5yyKHjwPh&e7BU)`TUry3ivspy(7k3 zb2ZlVMRzs6N|YCjn?+bL-8+6P>EOBE(`Z@1Z-{!StKL0+ce!d|L|kfjZg}~N;lgFf zyvJYn+rW!+?L5Wj+>`ZPYJU1^ugdkN-1}rhxTF<%Uuh}YkuY=cEO`Db&i062{_2!! zke@N!a#HKbV+B*5D1>S~IX*cJnu*EyaJ?zP8+sy5yW(Oc*UO6AKOtA@g;QdDG#!9= zU>lZq{^pMP*YYkrK6=Mxvp0>03<&wH&G%bcP}@2ky)|tfy3l@frPtG>9?fpn#yL*% z9?mY<zHPkaEvMoqNn4w!`}pz|r@lO3*OV@xd+{RBxi|IM=T_S{a^ZpZ*e3e*N!rox zwKj6ShKw21o9~tt)^`gsA+)!DfE%u{spG{yTViq|gg!uGL$c?7(R7=t4vw1F>1ce8 zboLO1byAAk*q}u5E29F~8B^$Sgb>u&XZP>}F)<g?@zOMP{ORs#e9+lKe{wfEiHk2- zLJfKT22eT>y)kKsi{9P5Na8^>ZHcu~GwsS;1}IfAdNW=XWlRj*`v#uIF~YH%(cK(W zV}YaK$j7Q@;g+XQRbPX?*v~pqc9k%xZ85f^>|kiYOXV#bN1Uf_RPMgVLiD^mR&B)V zryGrVJI9OOv#eB6;0UPWw%)cyFH}X|C>wcXCBc0DYuAofnBG~`-TbBp+bJKd>se9E zV-L7V^Pfi#d?P5GCv^5uzo};RlxJ)>$c)p(*Ha^~h;48{RA{~Pyxe%$X4Yy654kJA z>lkb4sd>$Z5@ie@bdRkobUqwdZ8wPN|NN_YrZ8@iA=q7uj=-%gR2cby_X}ObLBVdw zgWU~V)>34_U1&_p)#b%Ww1;c}1Nn91Hwn-1z6rOzm8SNb{ru-!xpBFWhvnh3)Pbxh zO|-Di(IBQ#u`l=UGH_>E`MTpgO*SWge#b|BaukIg&8}o`^IxOkUmfsVUfe6|OD60e zrJRf7A+=TY4*ak!-alf$8knPYh&|>e^I4Qozv_ce`Htc$n)Jj9dg`u0jhsY{Z459T zDIs#ah4Tuwv%All`jJml!H~F^5vnYoy<zOHs|u)1L_F+$S1V0c7&2mjO!l%%!DvzU z5W;dhn*JDg*`kIHcjn}|Yl~bwk_diUDCr<#?`4}Jpq9GBW%!<0D>BSLhY2-!o%iBk zpSyW;pWTsLOsLI~qu{(U9YMn5<=iyg5*O3bmlrRtCSVxx6ikkaNu*X~GXtrzlr82V z#%=8;C5F~Je0ZsE2i?a=We}hPg`()E1tEF!o-~n`+x2f2r{Z|_qNrCJPPLQ|FHG|v zxe)6)Zl^<;Nb?xj9aO>IIMfboIMDO#-Kf2~Hg7M9SYsxB^Cm~z7PEsPDCfwL=}<GI z!H`wR#0;mf%_B1~(o2m!!#<{7soRcfr5O5-+N^|%;}UNP?o2O>)0H9?gs8oa+>-6S z6zloYUeVBFaF?ckb0F$+->D*?)cFsvp_J4p88!L2)`6kgSJ2t$_j@xt>W{0OX{`&Y zKM#>^Zk_*S-SGBvqy&RA!MO0N0wxhXaF@H%8*Ms1FnZ`h<TPNX(|Y*0{;C>FS#Fc8 z<PI=*eXo19J*J}Lx$Bh$YM@I}F@*TSijpwzSx=$fT%*^P&;*6tKZu2An;{s7j=AvV zb4C^I98`o;cB+&5i^QRtGu^gSUd5SW(>tgW04B3~wBx`ZAI;ir%s!(2nw~swq%RVZ zs=K(yA7D^)NDWjI&;xTnBnk0Ik<|gBqu6La%HSL!<m~Tl>A^HsE-3iJY%*<MSZWbl z-q%+X7hQWq2h6qH$<B~MaAbNebV{5tCG0$Rxps7WHSa`RbQWK-o&O&lje%X%Qkv~e zf?b1hFhNbo?tlw1jBu>f^Ev#{SzH2S*R>w2MV?>FyAkJk>qzv<tO9HhjK}#^=Y4I( zLYw?GZW5XdA3QaBXwJ-6DRfY`_=K1AL^_!TRG&SxH!hZQEtGN~w~Y7sB8Rb6@+ENR zNOqMQ6OH4kd`_s-#|b;J5}F)B5Sm-m|M}a<gRFPWwI{;d$`lrkXoBfh{33B&ONMu- zPhU@e&%<>rY3gcSEt`qH?v<Lkc_v$pyk=rcHR`sc)-*h1%tm@#HAnkrc%I2&7Uu-@ zdQk2lU)jv$>k~g8y+}8h+-Og4J++=~h!!2o1_m!abJ05HSjoUTe9UE)A^k2?yoQ;+ z(a<WvHq`m~wc|HVFr;r_*Xtct-F5YeCJ*+R#ScDGi^R#eG*g&)RBrj{?~1sN&bp7O zu`e3Reb+vlDP%?+iH1#9i}m8Pr;esV5#Z6xs)S$9=`z2Ix@1J_pIDWVq(yg{<~ju* zhPTY^5~r6kC!;wWqqCag^2!Re^UCqgs)=%h+$oef`c_8tu8-_CFtf39`61mb1L>q~ z>~mCG@lLplW_2N8rdKD7R2oL;m&s&ushA(^_aW33Xn~y)zE0LfQgmb`WAngawncJp zXpGynIS!ynLs%YKSWY_4tWl|V+Pt&WRPc%o^-gi&vnx2mCdISy&D8Y4wQx#L?Wy%j z=7#e!$R%YDZb-3`L38-B{5v3IS?5~!i8#;9-PmTTSA96eudL5oK^`OTK^}6=7#Q0a zHSdi2V|xuxAuhCGRp~JEt{yj1A}2~CIrk=-qATRy2m0Ec{9gCM_Rxil^~d3-)rU8- zZwtB*CVns8<1|FS?|dtk|63F`Mu~%zJUUMTx@I|H{f4A|Yl)6AZEr4d<cBO~{H~B7 z9l0vN^OF3$8vN~WcVOn8*5;3J?EcC4DT#c7)uoRhg<_`H=E9!HViE_pB29WO9HNS5 z^`0~tjf`2iGE)gOWuDHX<Emu-ypymListr8lLCdT8$M{4&FueFd9#P<Uu{1aG()c* zItB)<x7pG$3>RP0n-N>mnc;kw2E{+Df6NDQl}$Ib!0XRUkwcm0f9SXoHfjqJ)`w*D zA&QPEE%ls`x(tn8O6A%iqT?}$TE^X;u>Z3-8a;X<?9Q12m!ky!sa$^4PNDSPdRxx; z1zr*)nek=)3gaP^;TZi~1SMv4`tBKycAyFS>B1o>Q~dTpVaOHDeoRX`<Q_Crdd%0b z6MO&t_u`!vw>|LuNMHXhWT_+uzF+;w8cmlcwRic1#5)|MV2|qcDT<BWjpoCGHz^9_ z_Havr!KMZ(QDo_I3f+j!HMCmkZ9Y*#x=@4v++k{4_2gD?JX)<Glrlnk-ap-%d|aRa zl9DZRyDz?TW0F5qibm=Br5^11IW~IdbfLpdifC*uRQ=)eP>o-(!WDD1{GfMpMpWu| zW66O$p%?UfyPMY%*I^%=x|(imr>UUt-yaW29U_ZVcA2Q)DE93s8rNK{;?}cE4m{+3 z!rnT@FfFY**vE?%A6?VVS&UhaAf!_3PVr#dWO)`1RpPi#hzcxX`$j@_L?N7j-<{h( z6U=4EaXX*_#;bPpEoV#S1vb<)tC)csPozQ9LIXc9Hc-L`de+>+?@>9k|86v^m!CvB zRrNai==LE*xXxbj;en|5mVD9Fn|+ro?CoZFV6we87e?_N--q%R%v*#Zy8hylh95ex zSa!D=FJN5pX(EqVzyAJ=KR&!6(aC$A;B|W12zJi>hCKo+`)YrBqewgbS_j^zb*rg( z@xWk{Uh~eFTfU0JfLA=B@`hvOXHM!$Q)0Q^Mrr8prfUx9>Bf(Y83SKzQJJ1ps6>$; zJ4+wSXx;)F#2FIq?k1(c&%Ht>UBoh@FwhAmxpXS&IG9dnxgD7=MQ(0#>~9O7Oh}s- z4L^BxW!%)Uv6B@gcfzvMxCpn~3Co8`V_z$1TVL*|H^Xa!dGF0ku%fcwn8w?ZF^+2r z`kKkR0(13YF`-d4<@auJp=)Cnv9~{t7s4aC#0eD)maNM++~8$@+Cyo|Aah(XbU1~h z2r+Tyar^TSY`_(^*itAj<AVXL3TiBi*t~mC(-F#0KuCtkktLt>Yw3#MNdGHa>ULGJ z{PftWMB2BP_~<>K_q&$+U$m&D(Z&<I<*CHQkq<iH_1*>+@g*N_Kzz{;0p`MT^?1Cw zI^3wZM<$Yv`6xc^edHpn7p5n>h3Ry`bOFi`>)P0n_L@F7@~c<9=X!=0UcCaMtU@l) zze(zO4%~-?y0>lYsBaf4)03CQ`a&B)#OT7;&Npbvn1~kWP_<dhuYaU+kV|C{<&{mL zNdy*nPOrcB)SoxQba$bG-b@)$)i24?Zn&2YzKSc@z<e-AF^`kfX3@Tjdol!pM|g@s zB`jIH=crL9!pEMU@mjgR8{y347OVO4<Gh0^uPlx0J1_QDm80;Zkfp;C;N_#Chf7z( zD4Z4RZc=lMRqX4=`EmJ?PT2u|K3B4@?}xglikqfGK~+q)=2S|UjAp0$R$66d^Mzyx zxA$pvU{?naUA<p2`n2*HNAZh@yUsJIzTAr^8@K%B_1MHV(^ul%q|K<tU!*ZT{3d0| zyvGR@!=`z~I|sXtpCfhLD+XUEI}(@~sKg)GwI@#xqNODXdYCA86-i8x#jV0L=tO84 z?%4>JN)U=UtV|I7ZI55uARh-|S`7FM-DY^nA$Z<Sv-=XL6sEH%lAER=4~h2zuEfpZ zE^<x^S(_BgIj}1t0EX*al~wEt^w;-T*F36Xv$$u(gAkN4p}Lo4HGwM&0yPT?vC*k% zr*F@B`C6F)6tzdVGj%A=VwJ{(^{143@*}ev&F}0`4Qxkd`S<j1@L(-6>k{Lj39l0? zuk0dpH<%pIYtj!{SwxoJ&&wyx4(Bb(6X(Kz-8&Dc9YP{N{=_7s9$`tZin)w^1<m0D zlNk|pIoh3J9jaj_mjV{(lEZ3uTcfPkjDm1yxTru#zKhCKlZ;n|%#PrJX!N(esCnB8 zEn2}j0Ps7D@z9yQ6*>OOnhGG1z@V`!7#2pbLn$9Gh6ONmL<2SnOnP#Ky!vB{T|>oR zGAL~}r#-cO<FX);#TR#Ns78_sv}4_mG?%rA3>JO&Gd@QiAVN8-9|AjJCH9Bz7-PDW zf8Pr5_$rHBkTkHub-24(q{c!DN$2MbZBWyk)giNb8)izzgb5{q<6uz4dEX45SEJm` zydH~O?!7=Mqa7h=K&vpxbpt;EaitKpZ~YPL*o<a1b=awq@lglEcC8uYi|1vK;z3gU z`Yw?t@`b_4wLkBM1Mq2jR~P5(;M9istH|<n(i?(S#T$7{YP8!WF?IHfumm`Ik1`Rw z=!P1>o@}<a!xs3o>5}j4@P@g+zAzrXlv?8W!HuvJ{5UNywfZ8ExMt2ns$hf`0I$z% zZ-&O$GWf_wf){5aD7>jHoE;O;`}01k-~=tttPjQhod<!~VR--*S3CnYJkGy<6rTh2 zE|aDQ^yGh*Y+9jW(xOfPgAXUo`lgk*K?Iac2e!oJKxAb_PC6x!UWnyu1m)l?K*>6T zKU3!P3(z@!&4=fHo%&U49M>YRBrSk-!5W`d^VP7bT<{#BOL*PKAW<SRhP#8Xu2zuU z0EDn}aftz5&85(Yp(VAR&0fgS(1Ln-x^92_G;F*ZuLU7(J9H#&@RRNMxSxyq11Las z_A$PL<0!$~FW(wzZrrJwYz&~7Jq|wI>5Uq3lnA0SRjJ5fykot6W8)$7bXkB9GH-!D zQ*&pGg>OlbP_Y@2U%cbhiSc?<b_O&X`Cv<64qTKAkU;?<Eya+Yp*dAj!^d*0pxV7c zFT+q!>e=f^2|61>{A-UuPXcq$qB6<U4#nKkZ2%C`4VAv9;La3qO%1U#r`~S>e{k;P zOhz8iht@#>7T?J3GM26us0*x^zP|amBB)gobqkQdB*`FylU!Y1*Cl5_zuKR0!-AEF zaX?o<tP0@Z9SKb#3k<>TlMR(qQWoRE645w}lcroC=s^urO)%#Yyc0uo$RH}hM-EIC z<D99jR=^P62NFuN3!Z=?h=newIkBJ02=ugNP7mz5zdbUMtU$c{`^*`_;#pzMmhK&M zeA-PvV;KxhNea~ITGG6yxRWM_EFyS4n2e11J+R9s{{skd_#i^aEt;Md9xfBEkVgjo zN;IWf81f<1UsrA$FE^W<B~%Z!J@@MT_MFO%3;OhSJ8dD7Gmck3oOd|Sp_nuZNCZF6 zgFFn)sEv<l^*1<FKoJiGla&zmq8*Men4Xhgx&hQtj_Z9#){i;zA$0N+OsSV8-7D<Y z636|bP{72b)qxBw;38}7Be_`41Zeh&(fQ!$lXA!e-pjmLZV1;Qe5Ew9Waf?n@m)tc z8g_Vo7eyEe=!Xw%fX)N*{)x3e`zj0?1ny5()O$BIw>wR_mA>uMY4Z_Q<`3O4qjcW# zdgDwfgc$X@ZsDSNYRl`quMid!>*X+MX%K(;cD~tcFef31JmC{TDU~VOL4*)mj`_%d zUA@^#c7S9Gu|jZ3ikGArCy(@#){3JzHh>6!@YJb4#fLL@c-2H+-+Ou=+PnPu<&<3} zAL4QZOe@}tD-mXU{t?M<_{?;ojo-)U8&+`+)Iajzyf9&%-dVb~R$EezhHC)4m}<3< zDv8rR3Ri)Ny14HW@JWbj7&?%GrXIl4Hoa*H(;Bt5q`JD}&ls6eNf~Xcd1;Va_}DdE zJ9=!n)T#7oD%4_jso(VyRGWEXIeM=oZB>?b@qP*vbb05KbAsY>V_W~q#&?;GhR83+ zXW_*Au+Ke>Y+#4W>7FswTT%w&4(X2{1{~1j?zxy*Gm6lp&XM~~pmEyLbdV?ueqBEb zrfX*I96zxvzHCFi|4N!3)M6Lt*wwndNUCsSwrNn-!=I^8aVWVDx$5Cd<YZ{qej%K3 zbwl-Fco%T+X|}yBX}L0VSqnoE)N?t8azOWd<~l1yv-gaLo>%8^v16{qDlV@ZCNE^3 zi}@}>v%~f75~4aYu5Uk-Cu$kG6kD7nM6K_z+=K0gDHX$xSuIL|h*1hHl<#h|L0k|N zx{?EAJ<Wu;Uc^RA61}#0c*xBxHx&T`MrDG6o+|V>Sc4Fh+wnKJH@eu>XeBUj?4ty# zscKLI;F-lq2sSVm{=%LUdIHH;hoy<peA^qaqHflc&$gMyfB~81b;r&U(4Wky^pZ(L z<A|qcZriNi=k<sQ*j0khprJiWqxi!)nBeMSZDt0f%Z{f^ojdvUBgL|N2z^7R=}pce zA0qztMTfF;djWBq9q*2wDwm_RpHHA<GZJ<o%Im}vIEv2sYlnRd)qZ@Y&xEexAM6(6 zEwLgJ5Bm0fUQi7}lWiI`K4b&c?>nkHy^M`eP2c^F0y8xiE*}w%{9Qn1HjUqZ6s<aC zH|IU53QG_xdZyf8@3PyZB{lRT2R0!M@^pQ0nP(4MBalr`?*1b~hw8Z<Fsq~7x7HqG zeD8rc(#H&@<w<5I1{qkGqMAezmwB)?qii2y*Y}Ip44FmBc9q@y<2Ivz3>|y><G3Zk zPVqC!(u^vwi#tOXTqApa9WXfzrG?giU(mgsYEoFVbGz<o4z$srNj;2&PsWU@)$-ZK z_JN**EfCA~(6E!eE#&vn<JzY-*3b=x9;AC2P>tWXFijc(HjndSkI(rYKEGK1h>on@ z@jJ0j^2@`&E_pC`h9Qz9fh4#Kg}LY?esbU?k&y(iR#&4f-H&*dq1Q*C7Q1=1Y`8Mi zX>{?;uT*0~HVN>0Iye-PPLt|Q36u0jfaqxrO6^S9oxgMUFQ}hV#{G>B1TK7iv|?gT z<z(l?#-%{-<v-)jKpMtlOz4xbTt^HO!(tfT9a_X1bUUmkra^cGK@pm)FsLs-$%Bht z_dQZ(knfsD3(P4AdiHvM5f0(!qpMWpiTA8fRkZs~K%)0&9EHA7akQ}i8Y41~esB9d z)9tjpbc1{A?IHb2h4?d9D$46TGzbz?rc|bh?uLbHzDu5h&3oFW)4%V*PDVk@xJ-uD z`XJ%2c16LwIj9>)D!ejbfG#mn3#&K1Mp9s^tswIRTNA3uF-~lL3UvJiFA1(9*j~Ts z_Cj~epW*r}t0{J4em@nal$iqTwp|0D)T{9Eq(Do8H(nmp>y%Eip-wO%t$!QjoyZx` z69(NA>Q7QFGze%{Q|ikUE7Sai+rFwp2>vqBQo3LHlaVt?C%_u6?6UFONlB3FM;s+r zv9P>dwPkxRurQWO9?q1{#{X35)K4$nw1qdO$BFF}#^KKR3WI9rh=%AuzcSaus2(~< zz9#hbsSN`l53-67q1m$wfOe`fG^1{3EweDwW?|?O8>+d@u+&>9QbC4xr#QjW;l|+N zx>i${+Z_d(?Ywqyzi@wGncjY!t$pO_=)auLxCcV~PH?c10+H<<@=QW3n?<2760m$s zdY`=3@wWf(OvI{$k_u_e8rz%K{G<+*YlkoJ<5-3`k7r&{{VnDDcN%6@Eh@h<q0{`c z2{oUO;N4G%xULOv&DT(;;pH~Xr@aWRL9lZRgk+om2^*M5*uYS&j#tzUu4ptaT`&8m zP{Auli>pfLurQ%I6yno#lBc#tyy;QjGPkAlHq^Y#vLHcG%n>{#L7pf+gdhb--8VE7 z_`NwU2<x#_0WiZ$a6A|6nhYU*XK$61i?Np#iqgFLT0V7{WI->O=A?<H8%F#d{7{<F zJ69mq)|lGV`HmGr0S3<|hAPad;t0Y@{ylGydBo=&&tCckRdCLZ8rRD2Ap~uUW%fl# ziX8?Ie7T67smoZZl@%vedLNk3N;acM85_q4)tQUQfrBbq)H;7Y?8s&+C+#qiA6@3i zvuEI`7qjnX@&Jk$PjGT?24!i-2GK9(Vqz@&;%pzArWek^*;IWoY~#wMY3v_y9sZXD ze=yP3_&JWI6rlTfcO)JpsepECC#lIw%7h&zOR9QG`R<EkGdfhokxvr&GV2>oC_Lr< zi{T-mxFo1eS&<;**&jtIvNaJ~x;^2Ca!UR>Q$ce!$%S4x$9b3?A{Rm>3AUD0M;kA> zJLZ1v?RWl!IARekI6Wm$wPB?L_8r@X_>RxZTLaEfQo}F>v9S8P*H6g!j~MzxmfMSl zlT>~ULi%A#s-T^*-A-Zly(Imiz4V^EH9I*4V)2+%Qwn~cr290EPk-dw@A2^zYngYj zh;wz$mw0Jz`24o3@#oj~t0+eM_Tnf4ilEo6#MAOAZ2IqxLTO;f(qJfRS_xm$qP`kU z2df=dHYDEjL}-+b*A%((K%hi+c5`)BP4LvZu`@sU!!W<*lpKE@-`;6^g3R^~I`2Vn zn(mNa#Y(GMk(&*wkG?D}=x!R6`kD{hwMlv|EMit4x31&$?oO8I!b6^733<@V)gNj@ z0W&N)kS2y=`8H#K3ss7qXhop=jB0gbDN?Z2nGP&2Hn0MD_arY6qPRy*a4N%*P0I_e zx6jMHnDwW=F`9Y!yw(-JexcR8lwN~SO}isUM7wwyUd<e^qh75p{qZyG*P`5poiJIG z<qm}VP-PUvzjNjU5Ms-0h1$?sxR`*094jj9ydT!^8+6SJv5W1np1{j78B>paUcIeo zXGWc>S*HSKMLILK0JU#_IV-PbaFFB~B!=E7JUz>YUGCK|-e5u!7M(5uW?~dfg^B>U z#@={W+P7zq^DEzWR;;^nf+eb1rbhS~2MX9=%Y*vs@><N!q98#T?pL7)>`SdP;UDgj zfS%UExY~PnATDJ#TU!(mIIVqt6l-69u_nDQVqfp8$nj*e*BnpE`S}nflM63Lc(Erg z5oFf6!yS1^Hho1ip=QAJ?zwJ#+B5w4(0g1k8MpMNgPQ|vi<c+vXn!1&Eqpe;N=GL; z|MxBcFX)BOcb{!7&Ebk?ax<=$#ZYSVqBNyI(zf{!Ke_E`)a8m=i-Pxi8|z8MF;~-C z50X*SRtZM>HRU64Y}saOVZeBn(DJAZpO!Z$YK~ifH9B3PgM#<W|CKN8+`O^kh(!RD z4YUM0Vh}uh*jJy2@c52}J+46<E_m#ZSW<_&-g=C5<81BiqxZ#g42h<l`&H~gv|w?6 z_~*t>eM*9Df$*YX(+<kh4nXy3NR897CI{3NWJ`^I>q`%J_2Thqr*26ql7>$;^cF(# zFugS@Zzt`Y4ZX!^F|FkKH>%R@9xQGA>Bj`4XxzY%(gZZ|k))7AB|9W#L!1B5UobP7 zV<D`k4XR2$0XO;#4{)ssWOq$9i3bQ&f~^&*iR0<3XRO(<tVD?-wLsn-WiuRZz+p)e zNlTs__#3DRxAGMq56Zlix^5UamNcMuD3#$J3BN9U^{OQD>w1I?FW8V@(ls=p(;l&} zi7az^0&jEYaRbou?ZTK199?U?8LGjjwYKTom{4cUu0b*1r+(XYmW%D^={2d?P8-2B zq#%^lp$#l-843@?fTPGYEOq6crt~yu#}^(my6d+8<W=ZKTrJRZ4a1TMIZs<jMEUEm z5voh1IEo9Pytj{b<NZ1C!An0xjZUq1CTz4yOdEASfB-GU-U;Y!e$@UmmS=E&#bR77 zkF3Ad30^ON3lhH@%mN|pQ|o)&zMkqTO$LK1a>T>&59gy3Dy3+w?}pyv({S&$9C*oh zCVzv-^^f*hP+m&XiE+ruF(b}7HUnx+5}`VvQzSz9yQQRvJ>bo+t(&^*QQf|tx+(}K zZImLwoX7QiXWNlGn41&aIgtPhytP(2mn5DTpEVVelCW<8D`HNRXwz9#;+0*UE|Fq? zwx3O6Jp80i0dMFVkZ8QIgRwTDn&ofo$D8o(hyc}+3hZF9eeuqZVQpziBq8DiGpJtv zovN5o4;Kn-43K(@5z_`My6a<jTSHrMLSm%Xw(D|vsy|^pZ`nfy=n;D{VQ7N7rN)bP z)1OFcosdMDd`iYc8LX+?L2%8*S~y6Mpul@rim3+2wfD7kWSRY|NDiF|YO`058*DP@ zIlD~C{OYgE2{s-1FjTWqF{k~wD(fVG7Do(sc5uvuZXDMM+tETAO>qc;UBsU4j!$p! zxab5;6oydobL^=hUwF?oFgbVMJ7U@^%InSejnKCwK@c%=Nl6GSzEOKmP0%LA$pJkY zhdvGTyuHMPABWN#hWch;dyI&cCkA{<PKPcteoNysw4?4fJjSileYM3P=}!isVn@Nb zC!6TLwB7VmDi1#0v>_OGjGZCOL}RCfZY+j#F))A*yNr>zG&k)|X}5~RqZja{bNfFL zSCR&t3L?)F3I#bY$-+_*+uSf!e#>1=07N_80(xX0+TQ0SN1lG*OVNOpS*Gza|1;eB z(KWL#vdC9A%4UnF<MUx-<x-lChwRij^Q2^G74Hio_fEr#Io#hD#EU4<Q<Wn!tkH87 zJz?IImqk8(!^{slWZmK(0?3&?rf-cT@(?>sEIp)_(_hyuP+7%h?ErIY0sGJZf{P&W zhzFmh+!t<Sib|w$*ja6LAL`j-MB#%+_4)wxr3fwak`aDH<Z)pk(4l(LhHgv*;b^VE zl%^N<c8~k5)~HLtOC3-u^6D{=o)&*pw>aEB`+=DSRa-zB%<P^Xe?Jc0;}>#gP=7(? zAr1H5`|9VZcOWp^iryv`M)qqVZ|)kOf|o&MVn?ZKf}Pq*U@06+JKdaihEo|^$wbA8 zjqR49ItjEv?(W@h5<GC3qysjScb>zd|8*d9Wgz=pMh5h$D=BXr;%ejx6O{sA?_78j zq<>h9cy{c>ZmRCreS;$Ig><L`-NI;y+MYU>>R9#8!W@MXR}%$ikN#M$bG!>I+Ido# z-n>)B2%Qpr{5muwBDu8!m!^C|kPmFqdUdPS#jJZk7fGntIM&RI$mM>{iURza<~}nS ze!9S&C4IbUBY7;XO$fwF^a!$m><S;nG*b(b>xM5ITcJ=DKY2+)S&ubsEK#faCRzCW zIOtIp7wn#`-(tJSeW5_l?^{y5<jbF55cdf6SQdO^*fNL9D8fazF+;%IgjyKlx%zlA za{Qi$>>K($Ki?h%ue`aAi%!^}7Hz8(v`vP~{gEb}g$*I~SKGvN!5@hO-+2)_v27Ok zfko1Wmw?@yO2CXPF$=q&_|^pa6Vk-FpbdvhfZCs^{9l4=yWkaZunE*Es(k415H?$_ zXZ!dKEl`&%Gxd6fT)xVWu`X=I!1-?v_Hj<WH!e-rPtuwoB%QEwH{SQ>Ge#2*V1ng_ zcIs33V4B0Mtx$>c$3M?Hg{oynSC(8l{_0Q<_PDF+*ED%zX}mT6t2pXUg<Evj)0Crp ziRF1yr-6ysDSP$_5%TM**R{v45ExF{Z<sH~ef?wNraJkh_26D>g8B(LVw2+tJQk(n zwZA)7VqYX14xaCLcvTY9G$63{lNZtAc}7wmBPAM<KHOLMPMpH03!15C4V(Gu9l$5t z!%sH49&xr2RLWe>UOh51t*O1~6fp9g2Wzre(D)0Nmcp7wuL`oqcnnYe{(1v6msdar zj?wTF12c-*bL%`jh)6XiGn8dz?pegsEP2)@1xNb`zs!4(h3a5<N;<?9Y@uyuOI;a^ zW0%$oITmI0j2G>6a=!3zS`?Q*j>{1{l_1VIoZSCsp~q#;rsLhmX=?;swuDs=T;?x$ z#F+w^IkW4PE6}!L-O5jF`n??9l^F$kV(08&>usv0X~su-+(?i?st$kLj4II4LB;F4 zZ^`5nGT&QK?|QnOWmW*Q9=ZOoNGgKv#S|AP3>GPT#3bcG-mpz8<;lHq^8B%{jV35F zO#$t4?-o<@ChPh5*-XyU6N}nJn$<g5O;9VjNbLq6V&I9x^_v8tjt-6FQgLf1>Je2? zebK5}Z(SnvJ=ax$nPgeQ%EGgBT)+6ehj>&xDa`M5ZjDORTMMdZ|LLylwghAG`9GDK zVnFA9mdKBgWvqt@za~5AFgZ4zwyP7?<B<hrKqH#eFBzW0Aol^e)SdFF&e^?j=@M2~ zhhsh?)bctp8|v;FR~rr=F_9OB1^Z<x5hpB2m~qO(%n!yHxQU0aD4ioz*nWbw)DBaq zTLKj%Dk(@_sLb7>c7=RfdHOL|vxh8%9b{WB+$bs1^%80Qklnd9{34Vd1J?aABW?#g z7ODq&<d-~t@a!FruJw3$@bz6^GTDZU;Qg>HCO>Xp!RW0=F65@?%#Vo(N<vlFS04)~ zu%sx?ZU@=caO!<2SoZu$jLz(6(0d5~@YZ5#R(e&3+ZyQn-Q(X?me5eG^R(uvESn%9 z#Pn@w=i9uOT;TKCH}aD9mARBk)dPpI3AM;aA7jpcyPq#j?vZ-F26H1#iic}^>7xA| zW@Oimi>v-h$*(kc5zhm%CPNQ|`RmLhO{TZ-Tr~j%Eu{Kzu|{R?!J`i!UDQ9h8R`JU z^utTXE?ums$c&Csp<@R(4!o~lz1=ZRzCS>E;3E9!WSBU?d)s1fAZXD5`?j%`1t0A) zBxeJlmZ_~8o~IsY8eT7JLsE|$>KGGCIXnH@fyC%(pV4N%z5V5qk~C_cn1Q>hxSxCR zZq&-6$IF!6Q$AA2W&ivb*sFN)Og#R2ec=pjlIcK^;#>TMj;tvK=1qrD)$&6&86`i% zI98D>B8V8uZ3a!yYDzPI@_K2n;K>`|W5e!X!73at*zRnl9!}F6?hD7Kow+4RPcMy7 z&g9a{^yG)^`QfWhA)A*MmxVRKC+2nrV<j0MT^xKy{Fjg)!+xRyHlN;$wy+*sWym`D zleu|rU-bB$E@RX+iZ%Sx577~is@5J3Vj$PBq7KZ>$hi%pCstrPgUD%Qt6~mcoI97M z=W|-AIH&k&l!UEMXh`lMV>zduY8A}#Ti6G(D~H@qhPY%)L7rl+C3`&T5gx@|W^7Zo zYepQLI?DOYTulxcJoucb*J0P}PLB0Fz5Rjsx<>px>M(Ja@amUL{G*KBEf?6`r9heb zuYhSRA0k&ff2hU1(;OYR**2bjo1UyTZ1!jJcYl3<t0{VDX~#HnXze_@Om8gKQ<bw8 zIfPK`&mkBgA1ZIfz+p$wTi<%uXZb692#+R7`Zy`lwq2lpufz~mT7Rx3c9;wH!}m_- zZ^yDg_MDJb)a#mvrm8=CM_c&hZGMNqriAN~95PVG{m`AW#EMjuW7)1TaU)B9xS~CX zx)SnuQR0PBnIW3T5M36yP4K#GxV`1`E3M6q$&=vCwkj*BSQ&qOI5lpad8t=~yHSMh zOA65&JGT35`Bf|zOIiF!8m0b0!QvbAbZMt)cn_l{$XmX1SE6kz9%UxFv|u;^U}hb< zjQ2UQ_aalH_dN6>Hlv%u4VzH*9GM;7adZ2E6Np{bOK>3bK9Y^#D2YI2+R~wHDuu4z zEa*F_2O_A)6A&x0TmppxeFf~zhA};>tuaHr55LMGzb&$iLyYF=XPLJ2DE&&&(v8y} zZBhR364(YC7%)C-bo`YS=L}-LJ>SfQtKAjJSy0P>=P`P)Ka-1Su0T&bKHQYD`bQgj zb2OZ}*f`8<l8JhM`jl~{u~psSv|XV;L;lz4Jqb}hB!x$-IU-9Z4JV8-H)r~WxIe)L z3a`36N@U8RC&$%JCKD}f&EAK0B1HRu9h{89E89wbdJpy`%-DAA)z=!Zk6mVN@Ks^J zY_+LPao$C?Ef@re?X=xi_9RRU95atCHm^QJ<Qk5$UTgo-rr87{Qb!z#uQkf_=oaQ` zC7l|6w?qKbR>6@s`Sxgb6}ljUDN=YyE91=NYl}{yI|V>ujl!poaDEIue<~Dy#y&I& zJ*awfI%GNYB&>Wv=V#4_CROEzmtxaQF%L(kheFUYPa8qd><O7N*}@LV&at@$%`(7h zWE*v3G>m_bwn9(`8BCB;Lr=_03*;Yfo()GYJc^oS@3`rc?qOJc)WvfrQzd-5bFqDs z5AkrpW&(<nF6M*GE1MiY>2@r~vw~9i2+A1C1uoQD=$M9I{M>%&0l+R#n9=gxyr%>* zm?3$G9Ly)qG?f?R#A0EwsIomqKNDEC^1@}Im#GK7)6`+wqxqqE;v#<CaHDosMBl$M ziyjeA<&xG@8)foVAjaz_uO0ssq%*YjZcMSUXhsOmotY1;^n3{n)Fu%={Y!u8<EZu0 zjtt+MK>AW`$0u3+$g-g4E?2m>a$?{t;o!Ue>8B+FZAx%{vvJbBf;ky=wk%2-duL!E zq?ReP32Zu`wgkGumro{+y0CuJCJ#Cz*L94FJR=AU7di8J^&#ph<+3PAM8wG51luRa z;ObP`c*pOeF~gn~q49y3%kUEFN5%F20O&8MUjI~a*<p(~Ptm2e;_L{|Q~N4(gcY)U zuPY~NwbfE`hbK&Ly|d8I?k69jEVvg3(MuN}fwVG9CS9Hpj4`SN<0~`FBMpqmr=-Ub zjnNCwH+2%`yc?Xq6(>NpRaFYFEGzjLNKC_;LT@9Y!(uh`K&{&TBRwo@j6~!2VOy!N zJNbCy_Gzmh{D@10vAa;5RPj-0EYmh*QHRz34{Qep`HP>r6bdpRMm&XAu?g^nzSUNt zQI=P>sMw2juSN6~E3+6#BE!4Fs~7uI;cE)TBTquc6SfbLqb|<sC4CN^(U6ez{sT09 z;>)BH&9vpBDw}&1I*N%T(*2FkX>a0>mwzY$zsIfTzil7Ci_Pu4uny0k%@PaQ*1+ta zgV`qwEUlf62yVx7T2QU}>)h;K+U9A~k-aa@59ye$qNmvl;^=UmAE=Bk$=VEuhil^2 z@1S}))h8oo1x0s75D{Byb)5?$N<i5}uv%(SoLz+3v_#R4awgi6z%UxF!G~>6g*=g} zL&q|s3BN}9=|Jw=zf$<^v8hLthk`g&QaR0Lq`$Pzpx!3a;iC8aBGOW!@B0zN;e0YV z-J{|#=J0T?Ky^f1A+*0ei*i!ifQQxTOk|t-4)q))-<k6qVlt!y&}BXasgR$Ky9~m> z+>Z_;Jlx{Cc2R$BAm!ukMf6GMLS17f%=1jGw(2X3@Bs+0fK6K|$<XzgTuG6Us0Ri7 zm4<3Yn9Z~+<56EyiE1>`<9OFs9ljZcO*b7}i~n2=?%A`uS(;u94Rw4lp}zQelle@> zz#%H($uy<<(^k?0h)EP0aqSCY;zIS@h-@77f{S0NsM}(4@sgMrw@|*lbruowo6GHn zF|7m}fmk-bu*bZlZWXN{wp9k=N4fc}w8zn1L5rn0=H3MNZ^d~KUZ&&GZbP|Hpz>1R z2BpoSKQ4Mlxn@V1N8d_=caJvm`2M_S+dadkqwe0A0Ip6=hCP`rI^8)1jLr;}x{(ka zrEwT@2VJ9U#6|t=SE6rEAHdg2SkHYoG49wfZFb90Eh;B_p)e(9F1nNGEk~2`^PNT; zyTm)5$sAy!zHv-{R{IL|{+X$SWb2D!kBNM3>$2R_{RQjv<FI2K6l195x}Z6CTvu~W zoWn!a_Z9c>?^v#kd<UaI)>F6=JIBa0`?YT=_OYIQGHWW#u#Kor7n`eS?i|J~;V4~& zD-`D=7q0EZqhyEnjt+gQWpgeR14<Q$t=$nHW1|m%<{sk4yaYT<sN@GY@zIRRTR{#& z0xq@Bt<XKE#39=1Elka!iK7|(#Y0NEF>KoOd+V%@`coh48Wdq;;mT>zsD+tqkaH#o z<<uyV{N6Em?7k7DWwUj|_daY3iJw~n1cpLN0<YK|V1eP#P6ssKDV!&7&#WBg@`pe$ z##d|zQRuSBUH_h532c5lp)<*~O}FPpnma>z>jk2wLxk+*s$1-N^(SiK!tJ?YnKJzj z2g8Y}6be}BbSuZ!6h%54+8f0{5~L^1;Y;Ox;TldeSB9RIf*i)UyY4ano|`6X|BqBg zWQl|~v-0WdoOA-<<ri7AhYEA}a_IEi7FRg`ybf9%jG047lKV%4sFr%%vCzE-mz=9< zND=7Mu@Zf!+1lhJNcdqJ6V}6rJ-pOVr{ecgWoO+%9Bg#nlo;!BR08PFEWC^$`+Lnu zgThbdv6Qyq+BeRk89e%3LbgRSjEBk!C9(Y*ugAP%QlHL6uQ-nBUwEtw4ra6Ap^1W( zS2+c*84#Oy^Y7{U#QC0M1O^S}+TZ@pR622(7*nu8YvTTHuz=fLk!0#+L4f3n0eW5% zPqc)w@gY{!hO0shrDk==v$N@JPIt`Ox~7-+%uTghRT|&vNaQk(-Wm9oV2GA&vuUFB zgR_T?cu8fc#|H6d*&)xtvCjL><Nm>~48V{MYsM3P;hqC`Scmq&+izqOey+<k700jy z#;Oby@a}B~ku%Rp@$bEhCvV-3&>*zvyil%tc1RwOV1<+?dTxla*53LxWl7RFw!Ik# zS0<2;e`Hb^y$NdPvD=b(&!LE@{`Y6oA*~X5_on)huLU85F3Z@ulqwG2vx&8f!TuZ% zbF{l!yZ$=4>lqAJNi!+XZ;>B;m+;Y>!8ca{iS?KE&dVHsOvs4}45U8lC2jc0fa9dG zV|8-d>Pq6J9y1~X2Ye^=n39S=VMdnanltwNrWR7Rc_qN7j@a~vha~kY<H}4V;?^%u zQ=rq+O;s%4YoVvb;PG<M7lz6KHE{EJSbMwz#%OoZ#TqDWJ$=r31uK3MFYcVPPnlE_ z1<`uM2fgRx+rA`12=Nmv@lcDSOOFcOyvW{^K+%Plk2_`bKAVC-=cKdP73o)hK3q6t z7!N)AF+zEwxP9?h+VeUKRBX{=yD%3RGK!ggVroY1d$nx>AaBMfF<c<nt=_%;1iPZp zb{CN7ZxF*NMfnGPXZyf4RcC@aMgAT=FocWl+1kWYZYBiq?YX_LtD-$r-1@fsMuiP> zNpwzWi~sRNFn8^k8_+qPJW`b^qwYP8DCqZ8(>$R334b&_%Y)y?4%wBA`TXJ64<ojR z@{-c7c?`<a1=>DzoU}-8Y>A3$CQTZEo8cctu~#~g5$c*l998aP$M9VFyx%kwuM%bg zf}e(lsXB%!hrYafJIZA))bVQ6&&gf)kcS_{)9(eWG~SB2dHb8P*Rji!KK0gHr4iRR zP)YMN|BZZ?X1cNd+b1V*l!2pXK#6)%)Q!tm300H3BBt)PIxbw?1cO`7+__U8l#TDN zew93*D588mx^eV#zbr{xTz<378!;z3VtnNZ({k`C(d^O_zGj(tWTC{WB<4xMcADS2 zL8Rxr{8VCMVj;gBJ4PL|w|Cwn;%cN%Tl9uS5$5Sq>yyQ?x9i`(LnE`Z<Y|k~eV### z$MyEEg<_*F2WYyxOc<Ol>RhS<Hp11OPjD8Yo@t36_pI!;4j7%(51UlKF{M!y>G1gO z<aF-`;ySWdn$YGQ9rL_w@8K`B-$)>;iL~`T>#Q0+e&BT5`tA$H-M_C9dwujk6KUSm za(4Ki6p`oed&hsl|LMUa-1%?Ie>`{m=jG%7>b>LN7m)w)-0?p^2;|wb7CA4QWB~S5 zIhYWB@ncQ@MZ1Sg2xf*<On_6S;yy5wX)1vKYDbOyi*5sU+7=Z_z!L?Guhm~_eeiRY z%|C+;r=0%IrC0ecYVt3t^Dj!W`-|#<QffBJeBGrGA4&)>P7exITKqHiTmjsx50*y! zedqZ^fp+)VBl9CMgi@>IB;bbv@tUa+{)!#y(*ve|I1vx9|I1iu4vfOhN=PX_{X>Kh ztEhkY3Uixs{JYfrEt5=$m&b!mKN(1mg{+1Pq#aiAB}G}|NAO>5Q5IqUaIouMrEWs_ z#P4BiCHQxj^(U*$k3<pDEoE*0?q;G&&V<m)kI=4?`b$MJkzW62miCN@BY)R+Eld8( zpjfub-(5Y;HTgTJt&;PfDOWH4#kvRnZqegkq{_VL@5Zdc{W2BTfyBNi&q~aXpb2)T zGvD#!ufPdf)<b@nJL+?j0NqSQ3XlkHss^0;3)zJuESmAa4|&??Li@=A^CMbu<3CR~ zpH{Vz=QFWWAo=Gh+>F0@{Hgg7n|{vY{b%-~XX;fHn8Z7l`n9($yzzj8v*X_H_f!63 zBmA43>{)MaW-1CUPwQQDjXvL!BY`cr<HW{SkxwQjlzhanK1~MH9f={)KUzC}xNS_N kqZf9ORTcmNS~;N4Zj+WrW*5xCPmbv<Ol*P1vzPAtH|$%d*Z=?k literal 9464 zcmX9^1z3|`7pJ@V10p3QBBgW)Q#u3`q+4WkNR19b5kb0B>5y*5V1fupgA%fhDIMDo z29p?k!|&O%dY^mV6ZgdLocks|G18%@xk*DrL`1Krt7$?+M2sc;E~BC#e0Bu`z7xJE zo*U?B5?x)tK0vB730J87bgcpi6pPnyV)Z+PA%u&RfqI5olt?miW^po=;MiM4M7N0a zG#@<+`H3nH&Ejz>#sLOa43zaW<VpCwVwpN)1d?dp1w3>O#2%!S-IIBzc$13GhGn5y zQ#oGvmJq+V-cpbz^K|{xp7OWx(eN2&`c}7x3rsAnX-w)TfxQ?Eel1v}%hv*4*NY1V znQfgbRU5BH`4Ik22b@Rko_{wr&IhaD6XYE=W>*Vi7E(q+9fL-u^&Qy`j7Bio&~e}i z1Na8IpGi@k94tLDQFW`%d%7^Twl2}$r7&O4tnC%RaOGS(pfLs9XSGGT`lq{0Iwr$k z24l|NDZaUWP`h?}0Av6-y*d>-2+;;zDIDYX`RaLZm}7Cx8C#4gZWA5Q)fkT0T$Ly( z7@L+<{I)8^5Bk#nN^cZ^c+GjB#<Vp%E2vlL;Y_>)*WuEbVRR7spfm*>f=c4d4JGxn zFlW3QdlYbHu{-F8)I@qAZJ^V!X6SwxoG$>UhmQILF09k1dMfs{OWb4lko68$Nc(Ny zxpUH8!8hIG6$g?lD04I^HyX#@iq52s8ItbBfC`p9S;8KiP#95e64AyEqt!;>fZIK^ z{2rfQ%9yL7mijE!q(s)GGb9VA;!-%j>Gm7+1Ps;-zA>EeQ|2RoJiU!>B5I^en-N<h za%4I9?;r;}9gJfY2Jvgkd3kz6Xe@7v6x%#`UM;`Fo%G}W%mxw)^9dzr6)9tVJRb{} z>BY=Xc*VurbDfaiCLJKP2jRrvk@0m}ROwl%tG&RuwXNZU)2Tr2UZU8YBAR)nS-S&p z;pqik)zR9WBH*MzG#T&ig@$^Q1SN?~tPA>*2Lv!N6NuLx{G;&c;`JJU%6NyFboEt6 z_i%`JQ6TRE`9RxtK+~$yMG|L5&r`+h0xb^Zd&?7tEMe1gWD#s32sq!qB0w;nsl{!2 zON7`{G_xNp>}8PiyS#TJPKfU(%D(95B*xl*I?ai*c2_1Q)dlN(7%6jJ`kRCr;yOm` zK#B0f<)aaw?lP-u{+TUASZx4v6V6~PLMMtY+S@G}7qe)UZ#v#M+ubGu5biV7n-l-m zi=>f?C1pF5g2aMky61fB8IStgJ1K=N7yL!5@%l<Tj@>oV>STtR%8VgiekXe%`qLNR z>i_!FIDcpzeJm4hqmHrpN&?tZ98k0T!5>dG1l_wCA<!)9@jbNYvtPPP&VynOPzOl0 z3k_5%><V1yCp9gY8X*&gB{wU6a($$Z;p(Rm55zIn+>K{)il}kfC`1QG&Y@4x>B~dH z#j?dCm{)v@3++zU)~u4ROXkJ>d-A=rXXb~Upr+`{raBsa%^O@?InyL1df(wC*o@A+ zod<ed;Z8ikr-ig{xHDS=FF{a%D|YRGOXhsl$yk3oa@+@sgW(xK7B*D;y)XS~y|sNv znpI~e*%;CcvZluA;>C76FeYeiRUg`m`@1FrN6Iw0wJz!MANJ`#38e@6-S;c4kc_AL zoyX}5V4O(I0$DznGS!~2+7ORjPl{II?s|cm(G#uxMh%_i#NU8<0+WQWUI+BZr=TVa zGb(=l<<5_n%E*pxI4br~LXGL|-6R%;mtZ*0glk`i<LHu_(UwLmm-NpI3`zPLvk*4$ zrSd(4AGhM~Y<yWB@63Cd!Um+Gz2~aA7{(URuTvS2gnq@BrGP#@ET&PN41$g(%U=b` z*ob{}O-+JDw$?qOdipKF+We9|MDZyoTtdp7Ha!BzLBU>nxPaFf_^GpVp^F?$mOpoh z3I8pA=VNu|3LM{7N5QWt`u@8E#iw^!pt;X}PhBd>opy@+YvHaC`KHimwVKZ5hvvqv zM)GaJ)T-e1m;`tv!0a_sS>7Ls@r9d@>w;r!a}9ocv+XyRFBU2Cqc~!IPv5f)DVj1S zSIeH=yiCkjP1ocWC{C`pr`u>`#vgxYb9>Jm4@Ck5H+Y<5Y?btMs*Vl}$@wh*i;4^# z!-I=|8c6faq))Ytnj_~b^qy4Yvc}RrqgQ`x^79C_RoEgqQ^Q7=CI(u?TK-N2JWR2j zLR;gZyx?PXIm5Dh8^P@P-aud7ZG2Kb&k+MH{}+Z7cdIs7vuF9-%T)R_T9{?~1nq1- zzRP+qnb&A5oOBV`9-2$4ARL(<UlK(@qEL4;o~e@iN54PsrtxqNVauD^KRtupKk0Eh zO+rNZb+Lvwhxt_8<8o!s_W*JUV=u>Y;dnB$IHs~BZky4y)3*DaUvoghr0dV=3hF=5 zs%<H;i-#qD<<;Hdqv+3>1xC{R^%0iJnrRz4t|K8BpRcHM(<Q-1V8d>bNU4l+lAKpW zQ#f>Ml)tc`=~K%DeYaqF)VOK)<4FRm$!Zur<eF918A{N1(DIo%BK!7<zYFtk28{I` zYs7v5+p4!(*_$7K*pTI%-rq2J%QD&hmg>{&xwSL|wUT|UzFQ|468&TyR}pXFP<3*0 z*<hgf4f@PD+O<N8FoC4PAo+t3g6+?t-|HCmO|ZZ!62K>a9{Pte%_=kB|AZJLb&+pV zR)=IRqR+`ed@ew-W47BSQ+JUScI%K$Q~u+63swALq0Usf^SgP?!<20w#sb^hvc;?| zaHM@)YNKLJsDM|IgNvLk`F`f?^z0<Cvu=PYGHA{defPmDF4_x?k?ApL8l7AS>1(cT zn5e_sta%?`Q{Bz5+_NGFcurR|$w`thrkiyA)hF9W%Bgu)=p2_-p1*C8)3DZ0gP4<- zFS<C6*gWnLPf0Fr5GV_mAIO}Oyk1_KB8tlW*md9%=}pc5N^$?29GCx8Xv>D30KQJj zLCng%jM~)^SF}~9x83y+r89wJ$t|?1kGC&|brmi%PVTQkt7Ek|mr$v0DTJzXL&p|! z#sR#zrH^<tCvqpkX0Y`w@lSK0%9}`^VNl_~vq#ETlt@}m?^cKW<*VA^cd~bUs$tRe z-1Lu$<*P$2L<7OJ{F=9pgXlR(JnsnlCONIleCO#B_p0hXTx?wJSx@I5Vj1m=-Je?Q z=jpC67t5Rh>q90dHi`Hsb1FhCj7>eM`3DuTts9;(V&ZT5oP|$ni2YyAg+AlBm>Slm z|A1d0^TpZH#Fey-ssc|k;t_4nquCXCL)0q4A$?$l+DbwWP9E?-)^Hq16vI3`wa8q` z4E_w#L#a7!;3%V|wUt-n_KkWwZo1WO&<JDwYMZM37~#35-Qn+{2|x7J-?pwgqk>pt z4L`CN3iz^A{3Ws)*?A>posci%yW>ok9FimfZBCY-mX)y)`G_m|zWC&ZTl&|4T|P5f zYW{C8|C))dl2w5+{W{<%mlOsPDbpmuQ^^%FM_Y|^q`S-9Ddh(@&FIb$iteTbvFw@h z%1ai%moy-hP)7=rz&o?Tg$Xp1?q8g(a3cJbl!KsG&z&*Kir~0$3xM)=UK+fF^t(&5 z9(Udgpj>I1u6pW7Tm{DZIJL$qp6O{3Ox<S6pOvmNq3Tb~*o(Wm`z^riq+V05?<x<F zSMVSfSrFj;;1@@$^#tI8pj!IOT4i9hpL=YzTbFk4x!*qlG^8T8LX{;^?;@uUnL<bO z_nmeggqZzGrCkApO{&C+u#NRmcT1ETwj}ZvO&Y1EN*x1Cx{bXH6dy_m#=jkM<XU=u zVC{ZWN&ysJQ!~U8UeucAIomKHw~JhC3JZiTrMOCxGfcS2z<@vlVQk<%fXjKnhXPG1 z<^;T?Rj06TFay8p`<9IGJgjKum+{J@?OAlOR-Ati41%^{AZna)V-^4SxBr+Wtn`T0 zv7V)uNg#<^&1KS;p7&k$*Yb596Gvjwb@lns1Ihm&jpON`MQtvF7jdzVI2$f&ft_0F z#?-)0&JcBKJF0ZE-Oddu;vAi*)!~q`vM;>Cr_J9Pyh2^3s87A?+bmJW1<U2C5N2w~ zt2cVH{rmNsOzJ{T``>YhX--p?Qb3bzORie;htIxn;Z@Ylpn$$0iNewW0Z%go!(;S& zdcEy2tGu#Eck=)${tRiKxt}B4SJR`iyvS`!ILfX>$`tr<gjslSwI^b4j&G*-_m)*1 znsRbqiCVR|!u{^jBM%0CP2rG6bVPDc;#^229L4TDV+&JhB_=Q-^Ib`M?O{)8J8#34 zIg{Czq0aFxUNU}EJi)FVsN}PFTYt?Z=Y8Rlgpo2MAButEbkbnC)h&#@?({6>{FUyu z`<IEIv1X#n#h*Qx`86xKFA(4(?&!MTvb;awyg5r6b3L#1)Er}Aox?|NHs=Yl78n8K z6aw}k-k#H)`Rt(_p-BFYnNwFQZBi-B%U%0wwC^;RYRc~1uCj>?l?Q<M*KOvlA(@k( z4AqSR?mg^wI86@qXTwgJi+x^7rB<0oTlXnPtu(D*#QvwpNlRzDDEChbrTNQi5Xe(% zh;-*3RGn(pm*v}Tkb>#9KuY%Dka|$r7ay0Y0m{deHg}JvsyqArX;EDE`ldlX<++lk znKPbol`jDD^`h}iKcxF#FL3uz2QvIMRQwGw_?EKk!>GSS4Mu{+GgrUnxK5K!S63=; z6)f+ugazx4JGL8o5D=Jz;=v%OG&s*fk0v!cWUzuSXDU%KWt$01jM^)y3L3+^*L-Dz zCinmBjxX{4==;=^ir+)a#uWYoI_LkU(^}+2vF+PyczVNjPlJ@bLDb$#q}}Vq0;^KH zTT&lIzQEsOANSM|_Naz4!O*geKcSdQBx6ywW#kSm4+<fAc5>_$`D?KMQ$K)&5x2ph zyFIq7pha!BHS?ND&Sl~hgP;4OGj6SPtHnk*u{cABH*0E0p3m<Rf+}`sjT}xr6WV*) z{kXx{c->%oOi4iNyj6XYKfXrJyXQhnv0hZh>apAyysW~(n*9g419s3my7-lEbW>OT zemL+15DE8T3G+{RJlo$_OYrgU1sc=vW{U2z{h02%Q>7yM`|y&ZnGO1bg>0|zon6GI z#`n-{cQ*xURi#oR0?kJP4VH}Z^1L?z{@0Mh*F1em;;Zx{S}RMAh$o>Vm);I%OeoKi z?S{Gncc5?e$4Mb9S@$^_I+9IL4orrUXWmo$EB|DU*}V@Op}`WqEQC&%#ymJ!>f9D^ z!~CI*wI}s4FbE*TlVWDzWa(uuAzRGGiQ)~Dcb?cUWKXoaxRkuTdCS5GTiiPB8}@!- z(Pww(ZtvVgr{4Cm!4^ePW|>{s>IA}coQgjzgY-=wfOaikC?h4{vTyDSZ+J}6qrKl& z>x+ODQ?nyane(RwKkMxI7MF@BxQom1q1uK5CKE)UtC6TPgnZ$0CRktNCuh49L<;x* z!RhOV8p}0ybB4TPJvx;aX-cc(V-X{zh_9UkMdMJ`Xhw5Wcn7iR+=4kvSYIH5=&`}F z5B`yapveRkk^_&0K!}s!**60Q0ubR&V|WeVtWtrB4`2A0TX2$e<gB#0PmC@1DacD@ z;FnUTR8Quc`*Oz^5}EM(-lz&mT*zZewY=8IF#Sn^_-#3>PpjU_uOB(4n>2W&f5_td zZpar9!~Jltetyiiaarq;r^$^2A#C2xg%I+v9mRgoZmmN#>nV!QaIq231%TJiMOwa4 zvj%8B7cqLynAX!0kXE#z&=xrx8Vk19gBtAp6{d#tO{9`UX`dMxic7b3c<}RUHtFNJ zxJqT)5;7DY=soYc(bN({W*-K1T!`dBc}5$o9O~3HyyBqh7Az*<&-_&KD3bk>LAWUh z%v5IV1}_1VS=uY-O?sp)kvi~pJnkX(S1Ako<$As<IbyR~yNNQse+|rSq_4;hM35h{ z(7#i^6RLB+<9-hY;_G92mtmb+(prj;<;rT>z>v|McF6ciu2em?;c983L^ohXciT?O z2OY(HVBlz}4+`KpsIWGmnzh(h`Gp_pn~CErst^q@3}Z`F^@y?E)|Az1a(DQ12UQ=P zgO%_lmoy9q>u#&KL@^yG-s8BD_1g~LlHXA`9M2SaR-ErU@IlZ~NPorL{drSh42)qJ z6VZpS)C*a8BjgLp$(P8PnU^}$faC8Y&5&7i`-ekkgl-lqcW%7Y2lJ0I{M62KYfC6| zDk~^r>4p4oIox1j$0oNG-?8_*|3_C0SKG{OaK#K9@)-`;L#IBu(Ge1+z5Clx_LdP< zI*YaxLUG_Hrb0*%rokHCm7Sd&+|_v0=WKL77e3l_9$6$|=L{?))K<NScJNgjc$zea z6hPTeCkx#6o{($n>(`EFa)(-v&QC4>H+5eJCisJOY&ql8P_M{Iv(-kh5p7}h@i6Tz zhZDL@Q>dVoduo)zaXlEL<z)RePC4o;u}B)e_U0lnZcj{;D*g6Je)F%5t^xQ1R=1t> zIEo}rn1)oi7`x`ksy)+yukDwU;ngxHFJyk)gL`9ld#L;3rxf7$3mW?_t{K>$@UEzf z=z!dO@0rB}CV?P#XXMwy1aEIOo*NEaNjkJ@M$e^GEigRN3Z$5jos(gi+Lb+7|H*{h z#*G!=$(DGBMnQbk!;#eODQl$7b-Q<yGn%47Y#_5RP2@`DgJem2J#GJI)}L9Nx3)S3 zi$IgVR^04l)2kQ()SYYM*mJ0vl_#ZLXAV8Ea5;?7dk8cnD|_PSH({&_?u*IIlBXHO z{_sXKsk`G%;RPrIj9ApMA+S?lougw@7-@b@fVvUaMB)G=6>Ajl(SdtH-ga6ve(vh0 zKcKlMl5{NfvAT4uKv$b8{e4!y2kRzB#on#B?Lr6<qO-(1Ns_2ryneNZC9F5!7dT)p zN5$XzDzmXLH{`HVhU<e67TZdfSLeZ`{^Ioy#{HJU9{A#jIpUN>YTXxiqu%Gnw-~`K zQWy$NDirustdrP5whd>-rvCQR%tG_Aw&RtDrfu!MD*AR3$3b!AANn<*Bk9ST!6IP} zgY7c&$8v3e>t@jE7b*dCp2r1=y6j7WCXqqr4?5RG9-s6$@s&Fb1iVYC>N!WS^w#8n zC%jS!U3fa1eepQa_$fZI=r{ZPoUn0dvJhG&7nK2vd)_BEs~Gj@kKFc?yo!AaYP)Ac zSLBjUueJK};p3zQNy7095?oCj38Mjuhmx3oT7f%|yytTQSp$9*h94p@dA4~qKG9iE z7@=4>4aZIDAcGBGcp2r5s%l#^Mi_p1s3^7ju50s;EO&^O5@6~jXk6b$cY6mZilnvb z(JEz9CkmnMiJ0R3Kmlq<maCBvPtVQl$`v}EI=19_zlM2jyKD!D9kf#t4rETk5SM;` zZ$V(RhQb$4ldD-LLNv(jodhtgh%)Kwy&kO5?ukk&ENyMgYm*)1n=_;JABf1+{k9^% z=7MGLDl`)A1^gsym*2!H?2jX=%|&atE<^9jrX;Cudh;Q_iMQ)P)N&#R*^ykplbSkp ztm)5Kh4Y<oo3c&v-MuZYeO?hQ5NuyOgkoVTJPSnAHDR~(j)PwEPDa?)iGBqd8Z)$| z4o3=MPNYH6GZXC9y?WT%{U8KUzXx!@!t8C-#9bK`%O5kw^QUnd{bZ-pK?VbxD%@O~ zKMzC(EBEaK`LHZI91J&<JK-)pNTXN1PhFpMjksp?Z``KoYQ8inSkbaWLlQ`Fq&fzh z>Tf54jbSn`^435Uk)O%0o}z8;J9R}o=>mi7EOOBym@{X3LH7rre!HvnZ=<87J|?Xa zj}$B`-MqLRKPug$?L)2|WIvhhR`;VulNVbMBY6asCVAnYKE$u!{675I(TOWK+#|eG z7+c~Zd?1Guk_k5_jMzp4l?S3nMc@(Y8*>coFN<<Vc&RL~MI4n!y}wG!qDtEcmE#Xo zlR9$oIjx_FUqyc8$b>CnEIBG|;EGb2ISAD(CQkk1y#+T3d5cy3+uHddi&wrEPTa)x zcrE?N!;DP^78xIpxUyn+Orf2>JPbT(tRuh%zEK6=Jc{Ic#q{u2gM|kV4|#iRUv}Y* zS`>IAB;*fbtj&h~kjm5$KE6Jayg2+58Sv1=LcM-G6aKXV2b~hd+F?cFgN60`_gO+` zXf&!rkBirkME+ntgQ2{!j>e25IQ|Yb<f@q^kCxjNcwV^dC9_iFLCE|fgdv>x2+42T zP1~Xh))F^52>o5*!<6i8l`lT@bc!CtmUa#Gl?=LYyZb>rVbby>0CHaPs7g)*fpf9& z-Wwz73&nShn5y%gy}yek91cwg7m~b~V|E7%-sYCUx?uZU``(DPyrePINo+}7fhi1s z1UzA-R^{rWe1JH02Kv?zbO6)%O5Bi^Po1VR{Nb~I<A^I@Fb_KXP9%xCz^qXdq4I@C zASkByv$H$5LPK@^b};BF`~PD~cBC+JIHj~YraF6&0NDi4OBv)aTDskK&uXY3-0pUI zuHhN6%piFc_TF+^fFNl~0b>wpcy9qi**&JPs(8ftp#AKhHkuId+Lo3h^FdYq#<8z> zJX3SX<&2EPR&{)ErOs&2?ZgL0`cig?_iymiWj<d-!s_c9U*ZU39)IdckpLBwmvUYx zrY=&#!G%2O_~d>hK8XO@Wt%2F5%bB*PZbQPjZU;g)$XQqaAZ%A^X1L0=|)0J=oI@b zNCRa2SPy(z&WtYIfPn7<83ed0p|tBtESMp5*p0L0e{l<zlJLmIh4EIeKE(Y3WjS<! zXl!kRMV92N!n;tn<C)Y055B^OjL7>lgwjDRVbC>b=xVv-OIq-b{-|sd(Q&y^r4x21 z@~JlkAt6WZJ|lFO{A5H)Xx`=IQ@g|sZr-m$)gkl`sHoCGJ7tgN2NoDV?$q=|T1AeK zxax1KQ}Le_-S#Xc-Zzd1t=&HKufn};g(d=DRfVGRes}CNv-=x{<AT@_yJ)b%ztzc$ zXx=CRG)L|?Ig_cEtf9}k!t?r^A0JsOT#(%yDJp#90i(^k`;nGEew&qD^22A?7O7II zY;db4x^icQ)SUUpun}kN3K2z=8?U8DU~nxsHIsnF)v?MNHVJmW{GR2;a}Vup_*Agy z9O{{bDSQT9%m$9Se3#=ZsM_@+^SK7@>e#zYFxB6Fj@CtlyAIMfhl!7k=<N`iZ~d-f zPqm^djYeJPjwl2iAn{KQHrV~~^9aX>&F@7mxJyPMj|Ecm=LB`SY*HSLOeEMkTi1hf zzzVw8>V*|8ZZQBTw^*H88?6K|hkdX4IN~c`VkD1=ou@uV{Y{v+h3F7%>HS-qmFxO` zY2=s9qvs8J0*v8y@qHR1X`<FTjqVN<DFbS>KOVs0xU_!)-^e-YfudDxclbq>^%pdC z)!ekZyY2SLN{#s<CW<YG&{j2@PSC*X&C{H&I8xD$AXb#{@9a`cgt6ZCe>Ihu%dMNm z2}d+fyUQk@1?JS9+k&oQ2t6HBSyi7O;XI>z6>bKFyYMXIjl3xa$={Wr%U9s^p4{J% z<-XI_*^9&hLV^78OmdYkZQzqoMEb`E1d%f%-18F}Ta&tn<|5}mb6oN-wp*~*<6nTT z%KqK@_J#M!TT{Bi8wI0+XGqokRR4fB5xt!aoi2dd_FK_vQZ5;5{Hj0h_CLAJ#C<sD z<7HAaY?4Lv*Ei-sy5Eel=D@lGN#DCd?9NYtaXG{?GC#>ENpk-=Ufpw>qc@&08e!7u ztkubBk|!CO4$^G<$Kg@#EA>3laEd;{T(|ot9G81-!e?K~R&=698~iw$>sUiMopgd) z!jmOWVk)k-(!;%b8v-JMo%G$(<%ajEx}U0Zs8glih)(V;Iw$$iPYCb2m13sQ+-376 z*`|kFDEZGuRSkbTfG2{;MNaRGrtWh+!Zb(yt!5u~VU#v@ZJa*7{!V)M0e(8Of-nqx zJp$T4%{H8V-Pa*HV}|AY9HWG`54gHkV%9ixV-vzKh_7nRU`U*16FE%FDv1aL4<Pzi zs(jyA&+cnEKGH7Syn*!m$HB6Fv165<j)sTI0;rxpqiHlDEfwC!blKf(%+QlqZtN29 z#ioej)0o@QL?Dj;A4#ituS;r^Vnh`|4P+{`l}r=@+YU~+x^cYm-dGdWnGeyCn##6! zJ|Sz&xi(b%;jUr1_A7Y0V){s0L{}?~X&91O;}=c^<=tbz(gzQP5(cPsW9X>2*Ly6G z=G}9$62ttG`)1b)9Gs-!_nNH|TV{4s&1JR8J468;F4q=JL%QCoEBJbESNPh8>`wP4 zQ~~rwKP0Sl4DYbcqIf}mwwC&-^T!OA^G{uU&g|!KUO;0az?55N@h-YF{aUJh$EV|? zzy|}j?j?>Gt~+I<nr`0L<m=`kT|$-&G{5VL7HyU*H&hshbJf}DK`zNP^%Y_8X%o4F z?tBRhCB_*k`Mm@MJkh-wEChgB(=lv6UI%LZ?tJLL@eU5{GjPhy%@PY35|22^<EfXl z?`-G3H*Ls;?|AQPc7~YrY5`A|eI=a?+dF6Mj=AgG=7C0whHAK0ZInK@7=&|>jMUvW z8FHQ2AE<MiF8p|JxO!WzGvCV80rSPdXK78*zX#xGzbNW21MR!z<UE3rbWzDcJ$cmO zvfm!{>TosHzVDZiC%?l6Zuu5c*zt-kDrJE<A#ZtC-{ONLhyXYgX*p()IpIV#E9oU5 z%f<<+<Fdh}+$!>Ha&N($*v}v3N~cRL8YWas&Va~*Wcjrxj@oi!*NH=5O}1a<&;&^e zXZ1{fQNH;sl_?rF{)0rz;e;Cu?_FI~z*iEEC8!RbX%`-HgPOWWo)KLCE#1+ep&)~x zuf%X7Owi<I-un3anAGAq)eE2)yaL_V?t(w#^04AF-<~cd`yq0vc8e1BD^Z8-+M(0k zVfTHTN*U?y7_GxUab@?j+FRJmSAtZisDd)Lj-n9VNxle@S|TE{(CcRbmd*FV?zaI* zSEt<CqUaRuuDRQZ7EdpEk{p2K4Ax%)qXi%7OPQkoLe5Jef3A)lk8R2ON@uGe4bCy8 z*A9p;-txK8l4>(6?kxOVQl+*~=Pf{+^Qql_Whxk<=e^wd^^I6qYt)1no1dw6Aqaq! zzD_p5#1nh2Yjo6q{H?}72J6q{nI!eGPCEZlaHOgPpw8@Ts+6E&oZi1{(NX`hBtFm8 z=H#MpD`~2Yef*~&OK5Ve-=m|>5&fN(UIbp}+;C||Y`(p~%2QZRL70xr=Q@(gR=-6| zJefe(DyN4}NDHj<be<wf<8eRt4mq$M#&4F5V;z9)Jy$>A0DeN5(HwZO_r4otC!cPr zbzNWLH2HE6NqJ$&MTLg_IDIhLQpqeu=^8rdI;gRN?48M%-9w?V#<zEZuTMX-5L(zj zy@=AKt9=}1FDXo>ZGaf$+P(}Ri}+{MsKMy2WOwO9+?v+v3UB(TU@x4Ssly^;uAI-; zTjUA@#BM+|8cEH8?WewhxR3vskiPl5P(Pv6UZ!b}`k-)k`#HusYG^5u>nyOnC%*xc z7RJ8J+HHQlWywdd_NQy`{F{+ihcpy}PpiZqUvA_`7@fU-<;u|%a+Q<yYy%G+Opc<H z4900(XMxc>sl`TiDm|2bo>*yiRBf!Eo~A?C!(THc(;L&OJ+C`uzgOmO#E!+d9+b}z zO=Mg<b2)e5_Vy9amF^3HrsubcEbd@pWDy;(?tuL-$I<$xkp;_`m=Wo-mw!KjqyI0~ zA8bcB4^>n^nI`WXir3oQTc0t^*7EXwto)q@-0cCnrL5W1VIH*F!+&1?)VBv5`<YGH zKh?_okv=Xh)^B)kG93MCc1v=#=xdl<o68ef#;8uk8{JR-DSc4wUVb%P94)?v`I1;f zW74aW{2Yfo)M4m%L^YY%4|fsy0<mi^i@}&{9HIHmYDqebF<_t#>|*djzpwSyQ&y2m zN{HHF3uJ!RJ9Ex{1lUQQS1_A8>H|H#-hc{j-|<zNedhep@ky+?(f2@z?PU2nihrCU zOXYN&VZd()Y*phbb54BlLK|><)epCJZCPE>=(El30R?fty6JZmgTvjn66X4;3cdJ& zuXf#NfVBBWX6y-F)HDD8HbWJzW5ML>Q7%eu=_elHx01u`H+z(A+sK}O?HCjJrG*{J z3T<04l+tJEO3Z&b{;k*cG=&G<a2DWr9OiDFyv}QY-O%n*S>y@))ho=|aON2s#0kgQ zz$2Tl<5TokzI!;I=ie;dT*?b(u(+OnYPW>vpU{W^cHTbRPnA|{9I*3dUdb$cm7`nz z+OGdK`w7sa9}s=lsXlV7eUoEWFsG4ojNXGIQjD8rq(gao^T06!z`#{05bpjzN4>A+ zkNpoB*OH52^1v;5ecb8I$l`U4DJonIURuZ5kA`vOS#jMHE(Zgcx{t3&-F=-9V#0=m R2a<@0^t6mL8`T|O{STLR)H(nF diff --git a/script.plexmod/resources/skins/Main/media/script.plex/user_select/plex.png b/script.plexmod/resources/skins/Main/media/script.plex/user_select/plex.png index 2fbd92adff07dca33b6b5297f372c44fe9443850..74590fed031713282ad493ac2129ebacf02ec531 100644 GIT binary patch literal 4767 zcmdUzcTf}U+J}P_=^a#1q(}=*Kxr?%_nw3WsfI2^q&E?y_Zm9VTL=(D0RaI+7my-I zZ&D)xrAZM!-f=$Xopa{Q`TNY=vwJ<){+`|Ep51?*jn>yyqabA>1%W^m8tTf1AP^q^ z6~_|eUmd><8JAw22<#Pf6hNT*M6z>h!mBafGeb2+5Ni1L))imqYa6RvNo?)kb$Ryl zzt+Ks_kYd&4+Z|&^>6-T{=ii`|Kxvm_fP+aui$t6nfUMK_oaXLe<uD*;7{@o{L9U+ zhQI4S1^)OeINQQp)#dr$ecew!rMdb7Dm)E!jX-5jM`aSreryuFZWV7i!XrOrVY;Dl z;Y!4rJM%PjZHXg6VDg$xCDnWTJsL&lH)-c)V9QS=6OfIff^R5>`uUgvZ20ZLUc?Gq zTjHTgws1%Z&(D+2-B{v)P=leY{ex;#Iyuk#m=v8wDZR*jW5;h)4AOk8?ll8GZw*Dz zLRJ_PIr)HFO{J_-h8huHVv?Q3x(b7am3RDz?Vz89Mr%8{*1Sb~$w-@SdH(`|sA4sg z6^wmncJiWOMrt=YdchHyw8SL%XeFi$_A^R!Y!L&v1Y^o$YVc&#$xO@4?3=3DJE56h z*oEMY)(ga45;nJtzmA9QeH!1*ZB}4i<`mr>-W~SX%}Y)SLJVzhD#)+Eq8K!wy!?L9 zhv?gyPCYa%P(agGk`|f($>1DJvF%600W?1V1v2=x{s`N@)&Gn1-<cyAOEmv&Y%9bR zVB)K!I=g&|9_TvcEZ5@WbMsn2xtzfGs>HmD1>T1>Pw!?Ai@RMI!B1dj`;)ZVTZQ#n zkom?-O&x)W!w%uK`V;Y^0%XS6XkgRN_CnfCitzBWl1N35tqU4}lrhmxFw13Nu7Kcr zX>?0?5GQuplGh~AlncAPb}W4`7=};U9I(Xsx@n=ABa%VH7oGQW2^zrv3wIdis=_JZ zZQ*3PD1;us85^m5$7zjgt;{Z*Gbh7FX?uCuYrwX7^OZaLr#<xUCC>@Oj>3>#1FW-L zAYjY#RM|O@Y<yBwJ-HzhwchszeS4|C7>U~U48M;yTr4}vM^3-czI79*baPg8o>xgb zJU`ohQ4$(Dqs{<X=DrCCANTwnBoaH$KxTx_r?mCW_+|7SZVR<1rLzrNTMg01A^BYK z{gczrVJ!%_IhBE`kOiFc^0Pbskm&Ty6<U=JCvIhp$<-3@hcqIf-#+p<0V!#9yR%PI zX2TTgs0`=@5;M+7kTg1(`V$+ZJ{%jF7<o6M`O9Q~mjbYj&2_EVORY^dlfGj^@tsQ9 z%%{_aDonkE%#_;+O}in~^0q=FL#bHq8zB(SkOqFxT`@xwqbEyszu?E+kJRr8Vs_{U zmcCv+ZDpcZVRAT?<v9+{pl3MnIfS&B-H1aMHfuR}fuyJx(=`WSdLOV616?^*;Zp1X zWm|zL(7ot4!#eIxsWo#nr2sS2lZ|x1dR5L*HT5L>yT|e4an{9pc{}%8Smbj6Dvv+L zDHt#lpUz8Sip~rQtRjBK=)3ZTxRu5Ih2hjH<-OjZ^u2qYJH0uXL0<r6g*=hvJE>6^ zr+&T>Q&XPCEF|H`{*sL^fRDaq<?Gak<|GKJ<I9V>407Q^#54bhpJFf^6J)+j=`W{f zZXm(xrT$wsN0Da3!52vAwmI{FncU(B?rwA5;MiL$O4`jEl`-H2Xy7T7Sg&ZBM0Gp- zJF?%D8Y*E2Z8|et@mR-~>wbM$Hfuo1;qpM!#MaNWaE4OBcbp}bzmK${M-~=v=T6aZ zmLJSC*h}s^w=!_)B~)!FM6%kA$>G0Vks6gIKaYbD0x1wM%3b1?YtyH;#;1Pp!V*8} zS4fp@4f}PD#qLl3nwt&soSt-U=n_=aF#T7Ej=6JnRICfwvOSFf;E?rZr57x)6j(*= z<c3ryr)*ouD4m0!0SHYpikF!wYs_)sqC~-V+pL8B*LqCp(CcuaP1GFOU|6RVjI4bf z7o{GokaozV_OK*O?E@wW88d8ASY*Dosoq~)sxcY*itBhLt6(|Yz&^_IiSSCo(OqkY zAY8BsUIjs??T*HzJGb$uI=%|gz#INPCfbR#WP?&}Zdyo_yF*^Us8Qw{*%fkwu?}fA ze|YKQ{gSG!dIAwbtOyrY`H{k;G^2iN?M<2$?z!0Zt2I!__0qx1U{J<Tr~_lA6Eh^F zyAjC+tkQEiQy))U$Al}N4nc67LXRDSI_DGi*zBXkfc}LQ0@HD$7{}=&=3f!;bcj(B zGS#AUo75L2-1BHZKc6iktjoSn7cUOkZjo3uSqW`B$YcYw=<ij35PkWsaxc2hxHX;! z+srMB=>AC+%}9%n?un89@G8u>ep|*?9UAtvmwE#PZU&9mOt(X)sMSi{DMwi-ZnQd^ z-h})dEF0>J!6=}6SVsGpvhZe|GhMdigk9ROx?Zpf>fuo?Y?-cL*9a+kGlB+~;#G&1 z>N2=?VmVxU_FMAVyx+OWsYl5INh5SA%%oGQZ)pI()=T!F{Y0lVYjX=cv#^FAiv^!V zF{^1*8xAQC^-Ic;Xr@f0BnSGG75ycFD%GQ|Eu-1lqLcjlV{vNP+~DIW<wAaHq-GH> z%nF^M(--qn9<6!cR7WTdtMNYla97Aq5Q}JeM1igv^i2Pp0;-mpbC#c!BJ2lq1yisk zv-*++7R^UyvdIc0?B;-NUs#!s>qR+(HX2+%I3+<e*wBiiC#E8F*K(?dS*bMcV|Jry z0N7!=7u}IFiYduUbFcbwr?rcu;KV*e84zmiqx^`csNI(>rrtP*b7yrorRa0QKOfJh zVX5tXsXszhp!V7;<POb^C>lW3aSD$*_bEQQsI_5S-Lk6MA>Kr9NV?=SIFyHsr{c3R zu)_+hox&el5ZKHn<nw|j%VulMpV0I9gG4ci2RM4JYK$^)L*AX~pdVZoBViy2B|dlu za1r<?L)?mx<E(&MYhTr4>4CtstdZ^gH;UnR2KcNWP;K?{_otBbl+Y1yFR4K9<Tx%x zd2en`7Z$%((ySeXsEpsW7*61~OpZn`;PsRGCa(!bp}^=h4`vEBJrI-Hx#*y5^%rGe zemeOf222*UEoIEDL{P6J4`j++G(0&&&T<Vn4J9B~72zsb0_E1>3HgZ{<DE~`q3@&7 zRr2mLt$iLF{f#CC>A#ei#xA=&4;?3q3rAm6hp_?_7Vzf!sEk+CVTdtETk(2_B`W*o zvhzKx-(*rW+P|YJBOsZ<ORg{?ltk~rbx}`;_Du;tO`+Z8BLO9J54mR}DBzB(6`Yf- z@`!A@)@DZcLOz&sMfbqda5gh8o6CP9ia(NN3<l-><|VPC0<8-__KJbK97|r@F45K& zz0?qL{P7^=J}9*m`(kk@i?Gk+m^~JlTg2;^(m67eof^D0r+%uRJ=DkaQ{gSGd5m<M zjSza15z9;1C-olDatak4JyUlI>%V%r+d38=#xr;vm*FV%S4xS)fnz6x$@Xct%mifF zJ_;4Qy5f|yO3fXc;K-ty)WxXp6OxFNSGthCF^@+JO~mD)>r|E(h4y_?(|pMLuB9Y= zX7P3ReBY(!6QXVJjnn6TJ9#u!BQyS)J9{>t(T6W-(LpgI&69jE1<W3#&PwLN^zLi! z)v}vlEo1Y&MqB=LRLlo}hSEe-L^zCozeiYX3UA=lr>Wa)wb;Wsy0S~M5C5a+DlSWQ z0LoUT0c~+i44AUfX<UD=ri_Nyees>8PB)7cop|*1u};Ba&>Py$Itx$xx2R_pjW;3w zM5obT>?MCdyGf6W0MZ?C1)oD_vTdE<y!e`DB2_9G*pdSic19jV{USp@9B(!_Gwm%Y zDGr|9UF>c~6^8aJvk=woy#1(-b<DDA++KLLKRby;c@RBQGbjk6e336T5I%^p8{#jb zYcxp&Y93j?FWmBdKG=pU@nkk%fInT>O{bm6LJmL|?tuUg=_Cyqf$B1kg7mpJCHYV8 zkn(zU^A}l;#no6OxjmkVLViuuqNylq!~;jpiFWNQ0Oj<mstb8<I)<no4G*=G_wk zYt!Gr{7#px%>04mGfF-~QOLYt3#YjPW&*WltDQ%WN?D{^Y&JT{o8n2p$AG%cR<3^} z>nz!3zSc9^kE{}pRiWE&x1LpJeH&g#VK(r4mRU>?OOIdgy&UrDV;nUrUskJ7Kr@1i z=5E!<{L`PZb}y+2P^Gp+6t0=c=@$f+Bg>UlRo_P)^d*!)tg&~y&hb0G6TPGIzL%MF zv}*g{QBdTa1*S7Za$fnPAD!lH6Is0-Nw}k_B3@u`fO5ty6Sqb{ngF`6*`g0Ak%Q4l z&7T0Ga*&z%#YJ<!_E-2+4)=4$+9$LI*ku9>y3%F^Q%Yw9hTSS4b!@i)eR8SwXa*}S zn}>f9;x=Kq9fkM!UKb*8$MWhfPvy&*Hi!=lI;JtZ7d}fvKfAc34j&1s*3&VWTt5<l z>?C+~q}{7+E6=_)-<Db>v!poiQm>J1nr0_SE*UiAg4?Sf*QQ#0vGd+8AUvKyMK&H^ z#bXJJaxCL{-W5q>Rbcib;Jm`VfD<TGTK+)t(nmKTWRM+GWI|gTd-A|I2o;OZw32;h zy(yShPFQ=}qe)(;c*}t}9;DyCz?f?nHYYRH`*0AW--HO+sSBOXIb_cG(y?m;t}@8= zPCczD|2Sv_KHjCQkhoawjM84cpPjDXv2jg;t2dnZd9z7QI1QIA#P16Qv-GinJGK57 zHlHH=Pc4gl&+vsC!095~6=iowY2k+UixYFV^D>w>B{f}QMw6I{dEfu&P*v)T?J$y! zF3)>feONo%NjDg*Ugvu4Bk^;v@u~1Kn|O`Dnl#yKC95jT`Dx>r!l$@}3Tn0|le*WJ zEm?@MTw<+c#@~5@m0_ti`RV?pF6t7^%Cd`5;u>DJeYjtM@U+O^)%1K1q`ujrB4)Rj zZfAp^!o=r_70^tKkRSiG?OGQ>DMR~CT(E=uWJ{3UN`v{Wng78j8_U(LK#I}NLNQVc zN@~`Y$~sW1V_y{+^d`o3jxb0yPi_Jyd~Y*};cH&nW+nJJZ`Ed^4cwg534P5~vw#wS zWRom`IQNLoP_k8v_M@wTJ?@OEnI2mk)#Vbsb+UX6!HcG&9Mu}!*5X7$L43wpqrX11 zz~k?Ts6Xj2JnuTGN{xLpcdJ!owZSK<>w057K0JIqI4(zDBh^U;0RdCut(HsT&jWTh z6vj7L+!N^Jst=^x`+IV@*VaA1q-LJF(wbKmBx}Z~ewst9SKKf$@FQ0hf6%sJ&}$^m z8)WV6617e%C(9#nO|&5#)7XGfE_)epxIh?mbRII(nC=jH6!iYE8$reUwe7CV<w!(i zago~Qwe^ve@h_=#d+Vck9kmli7s#icP2RFN#_?iAoZnxyjw<Wbk8OrqeFXri{)}h7 zN_(Bf@E!7MY<W3R`957IB~wdg#mUl4-o?tds<E3nu|$6<wl{+Dd14bD>QU&D-wQ2F zXmS(rZ$)|VY9Hx|na(2Uo-$RrI>b}Y8G)16j@VQ<mRI)F-B9Vgq-w!^D=z&jddjBf zUkj4Z>fhJYUNsep1JJmB^uX_}Xa@4~Ia;=^YLpwB0*RLe)}Rkh;Sk{SW-3F&m8@Q< zQq4iiR^QS=)0cai8YJ1)=)W6L9AS71XWM8t>+E-G^dIFM6!aqR1J{{e(e^+HQnH#( z2F+6=X$L9FAi-7a_#hSac@yHP;)$-g9B<noYQ*$U?k-9NH2EVQyI=iE0BNY`Dx(yw GLjMo{Ox)4{ literal 5374 zcmV<a6anjrP)<h;3K|Lk000e1NJLTq00Arj003bK1^@s6Y|NZ<00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY4c7nw4c7reD4Tcy000McNliru-~<8^05!}AY*YXM6pKkj zK~#9!?VWj)74?<JKeu{;hGr9#RSha2qR~VLvzVM1of$J4O)`!elW2@4U{Jv|fTHa} z02c%oTtJN`(Ib;&vK*b9EG8x=ao_h95LsjymWCF(`@K7V)a&kg^{U>|{i@#5_j67k zs$bQs_xt_2eqZjr@BZ#jR8=V*TLJIq?*vu@8-NdiwZOX_KO(Z75~HfafQ?1I?e!w^ zBPtkG{W|a~s+Xrk<TJT0dV0=?e{ocv0BSN$3Wz8ozGFaAzq_x8A0vu%-U~$7sO_x> zO}M0aQwjd&mjMf6{K!AlmiQqU?E8HPFeb|YtpNT8`~`SiL{?%LWyIub*FW>@oRK%6 z%nZ=0;Nz4Kc||Gh*#Extb9*}Vb+-Yh#Vl6)09VEMk-LFuPK7-WV}Ub)p8zXV^?6mD zt*YZ}su<<MpsoFz5Z(+rC*3*r3z_d6aOyjYhn^I3H|GKUV*I>YMdV$l!k>*#0ds-3 zRrOg_JwsJ%ZORy>WZbRq?oOgp)50COtf+jgE01fLCSFc*$%>l?501&Y`Xcbn7>9Hn za1DS{MbF9M!2Q6Bs(PYL8>7Uo;p4!vAgie$t1C#zd~Z&P*QjKz%#A^;YJf#Kx>Rf~ z7m?;_6RZv<0l!hzKdI^=Hg$}W(YEVSU`?PHNe-*a_n!3khFD<^Q{TIN$WamZ>a3J! z6BkdX3=yhTusS#fcwSZKt7@Ii9wTm!Sg>WAzy*Z3dReWm)b+XE>$Acf5tgmE?-P9^ zvaSZFLNIZmz;qEw_6ETMs0Drm{9aXu+7vQkk5gQ??pNYV_sA#MP7XJb&>*}{kX>76 zN7S7wfxTiJzMqN6linAcUh>?08Tf~)j<G3Z#7&~6eVV`)S5>+Zc+d7NVW)-VIVa3o zarfZEifmmS44fb1ux$q}^}p!!qUUA;@Ml#WX;a9ElgUjR*9-C^$>IYRl<we9Ce5(E zwAMlI(&YiktKH}3l*bYm^F-vM-Yi%E<AFb_>L8m&Mw}dW&AMd*e-3p43$(7h@6U*L zrF8OxZG($q5vl4|fn#GFu6KZiK_{GE`0Pvq?p0N>X=KEOfND+RT!fFa<y#eEU6CaS z?;hyfRre0suZLpQCuLp5$)zIFYJ%0pH-ITNjf^<?)SQj)kV=3Ia|a7`6}<wLkxVMu zPgHO3VY8<L`^Pv;zZa3;gq?JH@$<7lRY%!0GU8-Q@}nC;pYO7mvb%tOiz+bP!7pU# z;&t4I_YM3`H?6Btz!fnLPaAMiwhMZ*U=0MWwkc%9$<a-;*C^jZX!8f*^GR{Yu&#pK zM8EZg-n{;S#_pse{1_Mz<M1pIkvB}R!a2(pP8)G^@Rb{0Qe|<FFr|x7xYd<4D?U@a zh9<PIIFza$37iq*uxtdHa$OX~*OZ%qm3dw}1n8goX)M9BQ<E}5&$Ve(maGGIlu27Y zDCW&}_N%{gz^>M>0S5$%Q4XssXsJ#}9IM0BI(^Mg20T3ayUoANL#!O&cH&(xc!h{; z&2^DPP{8j25jnG){_-T?Gr$SJ5iwbSEx=wPvNO+iS^>Y{afzaU->D+9yjs=xm3hOy zBqEQAAlZudWfc4?;MkK)iimzt*VgyoJ<s0Moa1lVQNk%Mo&}EdF2N~#mrz93ipU>D z<XRCq5*P>EfLnz$O8NoEn=xa=%^|Zk{Z)g6p@6`9Xh7a;iFKTVecJ1G&CMZJgNV0^ zXvTWMiV&;-0efFWF2l`G|4qan_g^-Bj8d?h_6vcvxpK1db`OKx#Lm|MhiM=EY{2KU zG-)<4JjNk-SVaDr@5N;wbQh5|z}E@LUnwI0ma6k(7_oB1%q`n+xG<+k`GW0PEv=0A zrdeK&N^;pdkJ2Z=x*8A6h_U-S30N;!(Snr{EftZgfLkK^h=G9B&N52Eq)Rt0NBMQS z8|M?FLaeUbLHGj)ZtFKQpeZ*3^)Yt+dJ*}s>IBQfCAbB>qTus3b&Qfx#}7qxtKUk> z<pQQzU4#_;BVG91b259~gN>6s*40;lug2KpmAEnLf~Y9L5|K9G0@AkzD;A%&S!0xn zgD%{(4mW<3TbR5qV20b6!%gfuS6}NS@6qMdqzYUvjJeB~ipa-REm$ehdJ1?vf?I#W zrj1cbCNyup3-s@~tfyR7S57yv>*SG}X*d@+4>&N!uKq<te$kybR%)jEgAv?wtW6oC zr2iQ=kyLfgL3CG6kt#IZAxOLcMdl@2KDZ{vZno2dLV%SjSW#G5d#5sd4WndCym-^w zLi+AEfg)9?r4=Mz?(dB|p1&Z@RVH_f$ZNeyutel-il1#>3pCi2F-pyvt()fy@<P5M z<v$@gzG3u>SNlhQpmlXD3ko*T!|D%}Y*DO;;GX?$x)`PA=qB17WeTE+Y$7EgLHIE1 ziY!6+mX|I@cW;WiYfU1urMC*!M-kk!pG_B|9N2%x=4Tu<Gw(29`Aw*x1sr?hSmKG3 zY1<}RUY!|bmtF?$?CDJ^S+H6nxTkG%Z<GxU_5H4J;Qch$Fq=q)6!;5FcktdI^?Tdu zpVPkKk5P4JhKMA3vtU(<2pUGW7&T>WOHz~HN75^*go;!a%PP!G><q%Ee*gHT^U(I9 zSM>R%i2S7(H>za8isGA%oi<I3a^isVw>>8C(+u}7i%6xre&MmMj37La{CE|+-zsXB zLko1RmF&%ewT}sw(Hp2wCN2`#;B^gy@b3yO*{m+_HPW?yQ3P67+(u%{Q^jijLJ?Wr zs|72SFIDW)##=<B-KK|8Zj3pvc{3t2$d=mRD@_wBXrTh;6}Tk3UY-WY)}A(f6>eSl zqEV?9)?}b>k?*<EriM|jjGemWA<*9z>>Bz4?-FwCy@3G99k0;({!Kk?_N?x#7pz9X z`ep?8Tw&9~C})z?oG;KEs!l<!A$g`d1i6Oq&Lg?wjqW!0ZzA$gvB#j|1WQ%>5>16r z6D*^w*?-EG4^(xwUv+|9!|ZDi11zl|*HCw}`<1Dn$wHf&AfiHmm6&(*LttbC_kG%? zMA@-ORj(`c^ClvHDwhG-cir|StH%sH6*wx;stPl?d_nkJ*L3`w-1Y=*tCv!@PeB`{ z-z$<@TGX2bOI7zLy3J4jVfs*Zj4XpT3@E1oktULB?$L7+$cuR6xB&t8AQ8(yN2_a* zbo)D(Q@hs*NZ--<G;u3%c~t$c7?)60_W*uJH2GI6Q?=s_qwE=dcJo^T^Zja*VL%1A zhF#VaIfL*Wziaz;T3?@*Z}YAek&RLHy&?olRrdw{2270TBObMBU{n&@2W+1Qyq47s z418Vl55m*2HzFi9JxXGI&YF9#0=Grk@3I#xRXq)O4tJB)s90`Oz^Ei9okA;cHg14B zw;LF=U!hmTf`ag!YY-I?rR~iN(YF7~)~p#(=Q5V1V5zF8>c6V$-+_mKp%H%ETHx<C z1&m5#@9%AYN<^3VEvUQ=t}G(vk7EI7+j`pG4&9*qcOvrVsQX+tf~BgBs`_PBor}9d z{SWxQ35keh`R+Pv80AKd^q++<B_}ABm5*x}<Q{e{l6GH9tht}W=8P{*cT>dmg4u}T zTf*_G`hy(T)Zqrt_W;J@?(RH}_`kK>L3Dc^8b;)dIOC(8>+T;oP0>elDp0P|VdZFW zx2bafRa##^mxj;12sNGcE*FW&dzC6!pGo~x0(XkYW_#?7N@nDl+y8g%1C0*?r{^V3 zIfN~6ouNwC-g+OeqV2uws2e{I+>lCaxpKX^9@dAzwf49hRY9#xr=y}n5lE}(5a3p} ztz1NM+jHQq7u*q7H+!>SO%;*t_M{utz^K!kH`NZB_*f)2586&z6SS?ksg-E9+%v)Q zv0OwRvB%t~8h7Dm4P)B3z40GKy=ls*QUz4f_gi=RP&e+Xdf*%rtY~=-_^v(TMm6Ci zojZYnJr$>nUsc>6-?_T6m*MoE05DfohsM^=UiNq02>fTUYxEdKNv*5<8&3u~9?dR9 zn(eg?aq_*U>i+JnD(^HNMBRR!`B-}Zb4;*`&sN|>5m{xAxKS;v`uU(Cg4|lTMHQUy z;JSbA`A(7Yx`xzHKk068>b-B9rmBaSU=@$Gz~@BdNqfYNYNEC+c|9;9i+AUWPnbA` zyidIrmUhLlYQ{{#88kVg8NkgZSjFL0;205k!ya#=npku1pkvitPngqk3Xf5d8Bka6 z>z<#!W2hS!nsRlFs-9$m)qNB<i~R@@dD9;6isV!&J^xdV1GD~t;r)}McjHR~)m-9~ zWwLa-f?n&&qhIw0EkSCtmIqsyst9a?RUj*YZ-~fr5!r3?-l#U(+FRzJj13i`(AOom zE9j43Db$QOg_>c<<!aV`L{u8NS_Nw-a20Tni2T|fYoi)jwRF(os&cVkaq@{>`CY+` zAiJiEmMT!UC-ny|%C~u!tLi8dtQ>#Cl(LTyk!vh%!KhZAy^A`L<URP-0c$|)N<9`* zkf4PH*}bBL3iT7_A@#%ZZDJ!u-ixqW1gi~r1b54?@glM~&NWSjQ3{4RgJ!5YhlaX= zS*$HIyJgiGu<sBp1!vf?)Q&!*&}N>Ysz*lA|4Q36XB}>_y}ts#h_ZIHVU!!Imkm51 zk>u*MdN1jRUE<_htn9re>#+(du8HN;Hqz(dCEaPN0Jp2^<YL#FD`&x43A~1zmhcMj zw1~W8kFC)gQAJiQm8C#~SA`UDcX#%SlXhu`dW!W0ij@kAdyT7guHe;;y8@?S-|jZ~ zaNyg(1LZDQ&j7#7^V(M2KzRbUG{$<|B+m^Z(q@mTVWj@|zGLurarlxr8te+D>>9td z<rlBCi&MwiQKT<bvrh$T1|C8E*b92v?CVwa*Tt-g5`|#BEFuf+5i^Y9@cz>N!?m3o zh3u}Nsvv0i`2g#xQ>0RsnktA>N8dy51gYt1(}x4IQa?q(vB$wM%AD5vTW}W{ce#R^ zrS@^h`5Zy^w0n4h?)Cf4pk`pvmIhv=s^d+t45JtD?yZBrrlO~W2~+5|f&m_5;B}rP zQB`mnC(?Jq6~*jAJ#f7VmSI#mD{dY<7-WfmtzSkymEW4mCRRa7qI4{T78*Wz3pjm> z-IbG6^|)f($OOwU%9LcS%taWP%@qtx2GvZrP(7lTktEvT3hsLrwZpy;Rd*JuYMlv| zVN@aSEgo`I5~c=<ljat$&|}|wI|NSpj;7(@A4l1xiNLugScXw;uHb#2=$k;6q2lCR zR+G(|@|KPX3e<b7u701q5vdy#b=R6yby!bsV1i{BWk&0^?Xz$<7xsvfghtl$3AlS} zwENc!){Q!m`q5vDqiaLx;nsR4ScXwXyuNtI!NAN=K?<^_@^Sxyg6s+^vbFzV3%A7B z#qX=?p(a>{QQ_!vYMg{~4=VM3fyru3X>K9we6K%#mC%_^!>B7`>}Cz_IzutRGK>o5 zt<^)P0h7}OMv50?SD$N$J~r&smb-yFaM$a`#pi*OO|T53LV5Fs;bT?h$6=OKzCrdN zD=U4E!A{F<m!q}kil8ErAmU1)0o<gj{Y<b7qXJ2ixE<(^zcv;572XRy4vAlBQm@_f zwC1-vE)$W*fH>>d?+sjHf@K&L#%l|PeGB+Xm^BsV7N)y?Ay!tJd+DB2cwzXcmZ0S_ z7X!Ou?D|YqEvSBt36^1$ke6;4z8A>iLdqE9*(cDuo-puwfBZ^GpgKj4rrqBb5m^B& zjIsL-z<d)d!>ABy+Y>heLpxlxAQvu3$bv*IXjx8%Ylti!`R$fxvfOSi@Ij12aGI)q z(FDsd%A8l{@AdC0@|{r2szY>w+`_P|b~5v}Ji_&!wlvSl)+P~Y0cOWM6pK_fui{&x zs#@d^zehyQsn&-qwX~qvwd55@mT8wi7LfsYjLX-7UlsYYlR1owIC)Y;jw;s8UTfO3 zF<CFKis-%wh@*&r2q0a@B5sAfe2-nx(bRoB=RnobW5=Aa<FP#cmI6Eud?Cj1{eg%q z&1sR^|8r%5;3m|SrPorz&vvSH91?YMjX+nxS>3vyZY5Ap`C?L4MDsXSx<sp^G;-%T z;ivhCRm#dzRh@xb?mVu)!CY1SZxPvQE}>zR5ieh}*Jpw0e)p|M=?k70{P8PQ*?@3S zLH~n_JP-UN#$nkL$eD3(f@K&n^6XvIsmNU@PS`hnd5cv*EGsAgk8t6bGn+Seqq(zy zZ7~kd`Kmg}1j{hWgqjV*F9QzAH^`p#*e7CXBGnOqSAM(qS=%4%R-8g)18`l;ZucS+ zEW;=Rp1XGBL`gD7yJ1a{hn0n|D4(h{*CuMt?_slV0p5ynn2uG|6HKrSql74klh8XA z+=A&jEGR-!8M0bg8A+mg`KT#ddX!ToBCWU?@Nu$8Rr{D=8AgeCp=sn4g)in~S><DC zrDwed#IKNl?6Y?J?Zs%jh&%#38sl*74_sh^Wf&#krKZtiNa_MYtRwOft1v6eXJMs2 zW4CJJ9BC?QZr^lZcZ|a}M^#6fU>Qctw7ah0z)TS;AjlpjY{BuX`D3Rvzgf&ah{(IZ zZ7~kp0NiClCRm0M7tdTV;$%gSFVywR+sYz6ekIClEkn0Pwf)W2z`7WR?@U#lY=UJN zG4S%teTE2fD<Q#jE%Z2>fVr<EN!FY_=@eR{=#Pjr19M^=LI*bhFD6)q5izYbZPx=M zx@Aofwrexl;#YT!J#X_<5qIl8;OQ8L@w33UOt1_iQde-)u?S~(3XbL$CDJUX04s~2 zf_$ClR<||O%!;~SB9g={ryS>^^!cjVXo6)J5%A9o$217K1b0!pM~J%i1kCCphFMu* z*C|MnsRy3DsX31RiO3VcLop8NXi{6BnP3@4k*RM?TnUWJbzLs^FDOYgFw0$dc>n2J z9*w!1mjOFs{Jcw4b({&7VHA;PXOH?c8oaqeK|%H)F$)&3P07}_^WyHOh^(Q&^2R-+ c53u0>0h05JzgcEuRsaA107*qoM6N<$f@>mnKL7v# diff --git a/script.plexmod/resources/skins/Main/media/script.plex/white-square-bl-rounded.png b/script.plexmod/resources/skins/Main/media/script.plex/white-square-bl-rounded.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce032a36ec40df73a7f70d7db3428cc5f532702 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^DIm<k3?!S*bfg0*mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIICy0X`wFK>9xh@Hn5#0+e7Y3GxeOIQjKdiF{(kNqeA(lc$SgNW|f{rws)e z6a`o|BtP5Oz`|0~$g<=?Jd@P6g<ij|bWUBQ(S<-Z8pitC`quio`n5-v?z7hsPd#<? UN1D<aNuX&Ap00i_>zopr03eV`U;qFB literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/white-square-bl-rounded_w.png b/script.plexmod/resources/skins/Main/media/script.plex/white-square-bl-rounded_w.png new file mode 100644 index 0000000000000000000000000000000000000000..7ecb50bd4983d906f89b392fbb0ac88025eea6c6 GIT binary patch literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^DIm<j1|$m}O$}jSU|jF%;uumf=j{zcuUJP0w}+o| zVw%bpB}_M(+dIK1VWKR@O^0g_m^LvgT5k~0VVzwv?Ip`mJw3&%yxVtt;0Rn(!~VQR zTH=SlvGMB6S!#<mhH_1BIw9h+Ou>kCqGpGWV+xm2u)xeACX~kaDgBF}&oc%8#r+9J z?3EI=ER!uytiR}PFthnipIy^QnJ4NWEPe@y6;H5!Q1nGnXIl9Q)(_QR40)z0m>=lh zxV#{ue&u}TaOM8Q4RTN9e%xD|z4_nY)4SNtb#1Z)hSR_DAL<XJKU7YTHJQh4WX-UT zY59S76_<04c{_?7KOp{q<wo`XV2eF!Cmsn{FxfH5H`FGu->Ca<yjSpne%3;j^LN!2 R@&IFy!PC{xWt~$(697D>w}t=! literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/white-square-right-rounded.png b/script.plexmod/resources/skins/Main/media/script.plex/white-square-right-rounded.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a70d2233afa9339854294fb37e8dbcd460e2bd GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^DIm<j3?$ucQqzExXn;?ME0F$=0X)v<vH&I6N`m}? z8RSb&p8Cr5eaS?i2xoyuWHAE+w=f7ZGR&GI0TfK|ba4#HxcBzfLEZxf91MoDSiZ^c z>_5jaRp~xc+=E3?r#CApt=j#UM`5e_gec(?GaZVUG&xw98XXh_uv1UiRo36Exu*I$ f^uNouw*~rElV5(Gp^^9lXcvR0tDnm{r-UW|$}3Lj literal 0 HcmV?d00001 diff --git a/script.plexmod/resources/skins/Main/media/script.plex/white-square-tr-bl-rounded.png b/script.plexmod/resources/skins/Main/media/script.plex/white-square-tr-bl-rounded.png new file mode 100644 index 0000000000000000000000000000000000000000..6547d64a8deda3df658e6393cd2cdd42f99fa6f3 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^DIm<k3?!S*bfg0*mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIICy0X`wFK>9xh@Hn5#0+e7Y3GxeOI9YP)tGpQN#%!QSsHcl#NW|f{r#A{V zC<rhdJT6(Rl&q{>pwoCmjOE#H{ex0{Kg{lXq|FiB@Z|fWNmHkvJN+Q_(<HI(qe&Yh tbfDC<sh27$D|S|B?s>zmxAE?VKYQwroUi`B>NL;-22WQ%mvv4FO#pVuTfhJS literal 0 HcmV?d00001 diff --git a/script.plexmod/service.py b/script.plexmod/service.py index 1698e97836..c5f10e8245 100644 --- a/script.plexmod/service.py +++ b/script.plexmod/service.py @@ -14,7 +14,8 @@ def main(): if xbmcaddon.Addon().getSetting('kiosk.mode') == 'true': xbmc.log('script.plex: Starting from service (Kiosk Mode)', xbmc.LOGINFO) - xbmc.executebuiltin('RunScript(script.plexmod)') + delay = xbmcaddon.Addon().getSetting('kiosk.delay') or "0" + xbmc.executebuiltin('RunScript(script.plexmod{})'.format(",{}".format(delay) if delay != "0" else "")) if __name__ == '__main__':