diff --git a/AGENT.md b/AGENT.md index 14f0cd6..792dc17 100644 --- a/AGENT.md +++ b/AGENT.md @@ -30,7 +30,7 @@ docker cp lampac:/lampac/module/<Имя> "mods/<Имя>" Сейчас в `mods/`: `AdminPanel`, `Tracks`, `Tg-notify.bot`, `TelegramAuth`, `TelegramAuthBot`. **`mods/Music` удалён** (remote-коммит `remove Music`): в образе у Music `manifest.enable: false`, поэтому модуль не грузится, `/music.js` → 404, секция `"Music"` и плагин убраны из `init.conf`. `mods/WatchTogether` тоже удалён (вернуть — той же механикой, он в списке «ещё можно включить» в README). -**Веб-клиент `lampa-main` — bind-mount из `./lampa-main/`** (в .gitignore). В образе его нет, `LampaCron` качает с GitHub; при пересоздании контейнера без mount клиент исчезает. См. `scripts/restore-lampa-main.sh`. +**Веб-клиент `lampa-main` — в git** (каталог `lampa-main/`), на сервере смонтирован bind-mountом в `/lampac/wwwroot/lampa-main` (override). В образе клиента нет, `LampaCron` из GitHub не докачивает (нет доступа к GitHub) — клиент держим в репозитории, чтобы переживал пересоздание контейнера. Обновление: архив https://github.com/yumata/lampa/archive/refs/heads/main.zip -> `lampa-main/` (топ `lampa-main-main` -> `lampa-main`), `chown -R 1000:1000`, коммит + `git pull` на сервере (перезапуск не нужен, статика). ### 2. Механика загрузки модуля (4 независимых фильтра) @@ -138,3 +138,11 @@ docker exec lampac sh -c '...' # осмотр состояния в конте - `owner_telegram_ids: [143672]` → владелец создаётся как `admin` при старте. `auto_provision_users: true` + `auto_provision_activate_immediately: false` → новые привязки ждут одобрения (`/users` в боте, кнопки Принять/Отклонить). - Данные: `database/tgauth/{users.json,admins.json,user_langs.json}` (том `lampac_database`, владелец `1000:1000`). Живые данные — не «чинить» руками. - Проверка: `GET /tg/auth/status?uid=x` → 200; `GET /tg/auth/admin/users` → 401 без заголовка, 200 с `X-TelegramAuth-Mutations-Secret`. + +## Размещение на сервере (обновлено 06.10.2026) + +- Проэкт живёт в **Proxmox VM 130 «lampac»** (Debian 13), IP **192.168.88.243/24**, статика в `/etc/network/interfaces` (ens18). Старый LXC-контейнер 122 отключён и более не используется. +- Логин для SSH: `prodik` (sudo без пароля). Проxmox-хост: `root@192.168.88.254`. +- `/mnt/torrents` — CIFS `//10.6.0.1/Torrents` (Synology), креды в `/etc/smb_cred`, mount в `/etc/fstab`. Добрается через маршрут `10.6.0.0/30 via 192.168.88.254` (строка `up ip route ...` в `/etc/network/interfaces`) — Synology видна только через Proxmox. +- Docker: пакет `docker.io` (Debian) + compose v2 в `/usr/local/lib/docker/cli-plugins/docker-compose`. +- Поднятие после ребута VM: всё авто (onboot=1, docker enabled, fstab nofail). Если контейнер не healthy — смотри «SQLite не может создать базу» в README: `chown -R 1000:1000 /var/lib/docker/volumes/lampac_{database,cache}/_data`. diff --git a/README.md b/README.md index 12ca73d..e741409 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# Lampac NextGen — локальный Docker-развёртывание + Lampac NextGen — локальный Docker-развёртывание + +> Сервер: Proxmox VM 130 «lampac», Debian 13, 192.168.88.243, логин prodik. Детали — AGENT.md (раздел Размещение на сервере). Локальное развёртывание [Lampac NextGen](https://github.com/lampac-nextgen/lampac) — самохостируемого бекенда для Lampa — в Docker. Официальная документация: [docs.lampac.dev](https://docs.lampac.dev). @@ -111,14 +113,14 @@ git commit -m "..." | `config/init.custom.conf` | Боевой конфиг (в .gitignore, монтируется в `/lampac/init.conf`) | | `config/secrets.env` | Токены ботов и `mutations_api_secret` (в .gitignore) | | `config/passwd` | Пароль root для `/adminpanel` и `/weblog` (в .gitignore) | -| `lampa-main/` | Веб-клиент Lampa (bind-mount в `/lampac/wwwroot/lampa-main`, в .gitignore, качается LampaCron) | +| `lampa-main/` | Веб-клиент Lampa (в git, bind-mount в `/lampac/wwwroot/lampa-main`) | | volume `lampac_cache` | Кеш (`/lampac/cache`) — Docker named volume | | volume `lampac_database` | SQLite-базы Sync, TimeCode, tg-notify, tracks, storage (`/lampac/database`) — Docker named volume | | `dlna/` | Локальные медиа для DLNA (`/lampac/data/dlna`) | | `plugins/extensions.json` | Каталог плагинов для веб-клиента (раздел «Плагины»), отдаётся через `/extensions` | | `mods/<Имя>/` | Пользовательские копии встроенных модулей с `enable: true` | -> Веб-клиент `lampa-main` **нет в образе**: `LampaCron` качает его с GitHub при старте, и он живёт только в writable-слое контейнера. При пересоздании контейнера (`docker compose up -d`) клиент исчезает, если не смонтирован как bind-mount. См. раздел «Секреты» и `scripts/restore-lampa-main.sh`. +> Веб-клиент `lampa-main` **хранится в git** (каталог `lampa-main/`) и смонтирован bind-mountом в `/lampac/wwwroot/lampa-main` (в `docker-compose.override.yml` на сервере), поэтому переживает пересоздание контейнера. В образе клиента нет, а `LampaCron` автообновление из GitHub не докачивает (на сервере нет доступа к GitHub) — поэтому клиент держим в репозитории. Обновить клиент: скачать архив с https://github.com/yumata/lampa/archive/refs/heads/main.zip, распаковать в `lampa-main/` (топ-каталог `lampa-main-main` переименовать в `lampa-main`), `chown -R 1000:1000 lampa-main`, закоммитить; на сервере `git pull` — перезапуск не нужен (статика). См. также `scripts/restore-lampa-main.sh`. ## Включённые модули из `mods/` diff --git a/config/init.conf b/config/init.conf index 9f5d326..b87fe92 100644 --- a/config/init.conf +++ b/config/init.conf @@ -22,7 +22,7 @@ }, "TelegramBot": { "enable": true, - "bot_token": "", + "bot_token": "1613262761:AAFgSjrybsT5dFouVD8U_zx4j54-oaf6pRs", "lampac_host": "http://127.0.0.1:80" }, "LampaWeb": { @@ -68,7 +68,7 @@ "legacy_import_path": "database/legacy_tgauth", "enable_import": true, "enable_cleanup": true, - "mutations_api_secret": "", + "mutations_api_secret": "b0cd2c8b8ac9482fb036abdd212f14f4b03ac1cf3871bf492025b36d8a44e1e1", "owner_telegram_ids": [ 143672 ], @@ -92,15 +92,15 @@ }, "TelegramAuthBot": { "enable": true, - "bot_token": "", + "bot_token": "7210933639:AAFemAjvfGpKU51l7x7WKgGIC1H8WLhGVqE", "lampac_base_url": "http://127.0.0.1:80", "request_timeout_sec": 10, "service_display_name": "Lampac NextGen", - "mutations_api_secret": "", + "mutations_api_secret": "b0cd2c8b8ac9482fb036abdd212f14f4b03ac1cf3871bf492025b36d8a44e1e1", "admin_chat_ids": [], "owner_telegram_ids": [ 143672 ], "notify_admins_on_pending_provision": true } -} \ No newline at end of file +} diff --git a/data/ts/TorrServer-linux b/data/ts/TorrServer-linux index d8a50f4..7b85b6e 100755 Binary files a/data/ts/TorrServer-linux and b/data/ts/TorrServer-linux differ diff --git a/docker-compose.yaml b/docker-compose.yaml index dcb8f33..383f0e3 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,23 +3,23 @@ name: lampac services: lampac: - image: ghcr.io/lampac-nextgen/lampac:1.68.1 + image: ghcr.io/lampac-nextgen/lampac:1.72.0 container_name: lampac ports: - 80:80 restart: unless-stopped - shm_size: 4096mb +# shm_size: 4096mb volumes: - ./config/passwd:/lampac/passwd - ./config/init.conf:/lampac/init.conf - ./plugins/extensions.json:/lampac/module/LampaWeb/plugins/extensions.json - ./plugins:/lampac/wwwroot/plugins - ./mods:/lampac/mods - - cache:/lampac/cache - - database:/lampac/database + - ./cache:/lampac/cache + - ./database:/lampac/database - ./dlna:/lampac/data/dlna - ./data/ts:/lampac/data/ts -volumes: - cache: - database: +#volumes: +# cache: +# database: diff --git a/lampa-main/.dockerignore b/lampa-main/.dockerignore new file mode 100644 index 0000000..544ddd1 --- /dev/null +++ b/lampa-main/.dockerignore @@ -0,0 +1,5 @@ +.git +.idea +.dockerignore +Dockerfile +README.md diff --git a/lampa-main/Dockerfile b/lampa-main/Dockerfile new file mode 100644 index 0000000..3d52e74 --- /dev/null +++ b/lampa-main/Dockerfile @@ -0,0 +1,6 @@ +FROM httpd:alpine3.15 +ARG domain +ARG prefix="http://" +RUN test -n "$domain" || (echo "ERROR: domain is not set" && false) +COPY . /usr/local/apache2/htdocs/ +RUN sed -i -e "s|{domain}|$domain|" -e "s|{PREFIX}|$prefix|" /usr/local/apache2/htdocs/msx/start.json \ No newline at end of file diff --git a/lampa-main/LICENSE b/lampa-main/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/lampa-main/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/lampa-main/README.md b/lampa-main/README.md new file mode 100644 index 0000000..0982f6d --- /dev/null +++ b/lampa-main/README.md @@ -0,0 +1,26 @@ +# Lampa + +Приложение полностью бесплатное и использует публичные ссылки для просмотра информации о фильмах, новинках, популярных фильмов и т.д. Вся доступная информация используется исключительно в познавательных целях, приложение не использует свои собственные серверы для распространения информации. + +Исходники лампы доступны тут: https://github.com/yumata/lampa-source + +#### Устройства +* LG WebOS +* Samsung Tizen +* MSX +* Android +* MacOS +* Windows + +## Установка для MSX + +На данный момент ручная установка, вам необходим свой собственный хостинг или локальный веб-сервер. + +1. Тут же нажмите на зеленую кнопку (Code) и выберите (Download ZIP) загрузите файлы на хостинг или веб-сервер. +2. Откройте файл `msx/start.json` и замените содержиое `{domain}` на свой домен или IP +3. Откройте MSX и выполните установку + +## Запуск в Docker'е + +1. Соберите образ `docker build --build-arg domain={domain} -t lampa . ` +2. Запустите контейнер `docker run -p 8080:80 -d --restart unless-stopped -it --name lampa lampa` diff --git a/lampa-main/SECURITY.md b/lampa-main/SECURITY.md new file mode 100644 index 0000000..1f65fba --- /dev/null +++ b/lampa-main/SECURITY.md @@ -0,0 +1,6 @@ +# Security Policy + +:x: Этот проект не обеспечивает безопасность ваших данных. + +Проект поддерживает возможность подключать сторонние плагины. Непроверенные плагины могут содержать в себе вредоносный код, который может пагубно повлиять на работу приложения. +Устанавливайте только проверенные плагины. diff --git a/lampa-main/app.min.js b/lampa-main/app.min.js new file mode 100644 index 0000000..1bb7e3d --- /dev/null +++ b/lampa-main/app.min.js @@ -0,0 +1,56844 @@ +(function () { + 'use strict'; + + if (!Object.assign) { + Object.defineProperty(Object, 'assign', { + enumerable: false, + configurable: true, + writable: true, + value: function value(target, firstSource) { + + if (target === undefined || target === null) { + throw new TypeError('Cannot convert first argument to object'); + } + + var to = Object(target); + + for (var i = 1; i < arguments.length; i++) { + var nextSource = arguments[i]; + + if (nextSource === undefined || nextSource === null) { + continue; + } + + var keysArray = Object.keys(Object(nextSource)); + + for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) { + var nextKey = keysArray[nextIndex]; + var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); + + if (desc !== undefined && desc.enumerable) { + to[nextKey] = nextSource[nextKey]; + } + } + } + + return to; + } + }); + } + + if (!('remove' in Element.prototype)) { + Element.prototype.remove = function () { + if (this.parentNode) this.parentNode.removeChild(this); + }; + } + + if (!('find' in Element.prototype)) { + Element.prototype.find = function (query) { + return this.querySelector(query); + }; + } + + if (!('text' in Element.prototype)) { + Element.prototype.text = function (text) { + this.innerText = text; + return this; + }; + } + + if (!('html' in Element.prototype)) { + Element.prototype.html = function (html) { + if (typeof html == 'string') this.innerHTML = html;else { + this.innerHTML = ''; + this.append(html); + } + return this; + }; + } + + if (!('after' in Element.prototype)) { + Element.prototype.after = function (newElem) { + this.parentNode.insertBefore(newElem instanceof jQuery ? newElem[0] : newElem, this.nextSibling); + return this; + }; + } + + if (!('removeClass' in Element.prototype)) { + Element.prototype.removeClass = function (classes) { + var _this = this; + + classes.split(' ').forEach(function (c) { + _this.classList.remove(c); + }); + return this; + }; + } + + if (!('addClass' in Element.prototype)) { + Element.prototype.addClass = function (classes) { + var _this2 = this; + + classes.split(' ').forEach(function (c) { + _this2.classList.add(c); + }); + return this; + }; + } + + if (!('toggleClass' in Element.prototype)) { + Element.prototype.toggleClass = function (classes, status) { + var _this3 = this; + + classes.split(' ').forEach(function (c) { + var has = _this3.classList.contains(c); + + if (status && !has) _this3.classList.add(c);else if (!status && has) _this3.classList.remove(c); + }); + return this; + }; + } + + if (!('replaceWith' in Element.prototype)) { + Element.prototype.replaceWith = function (newElem) { + if (this.parentNode) this.parentNode.replaceChild(newElem instanceof jQuery ? newElem[0] : newElem, this); + return this; + }; + } + + if (!('empty' in Element.prototype)) { + Element.prototype.empty = function () { + this.innerHTML = ''; + return this; + }; + } + + Element.prototype.append = function (child) { + var _this4 = this; + + if (Object.prototype.toString.call(child) === '[object Array]') { + child.forEach(function (c) { + _this4.appendChild(c instanceof jQuery ? c[0] : c); + }); + } else this.appendChild(child instanceof jQuery ? child[0] : child); + + return this; + }; + + Element.prototype.prepend = function (child) { + var _this5 = this; + + if (Object.prototype.toString.call(child) === '[object Array]') { + child.forEach(function (c) { + _this5.insertBefore(c instanceof jQuery ? c[0] : c, _this5.firstChild); + }); + } else this.insertBefore(child instanceof jQuery ? child[0] : child, this.firstChild); + + return this; + }; + + Element.prototype.hasClass = function (className) { + return this.classList.contains(className); + }; + + if (!('on' in Element.prototype)) { + Element.prototype.on = function (on, call, options) { + var _this6 = this; + + on.split(' ').forEach(function (e) { + _this6.addEventListener(e, call, options); + }); + return this; + }; + } + + Number.prototype.pad = function (zeros) { + var numberString = String(this); + var zerosToAdd = zeros - numberString.length; + var leadingZeros = ""; + + for (var i = 0; i < zerosToAdd; i++) { + leadingZeros += "0"; + } + + return leadingZeros + numberString; + }; + + if (!Math.trunc) { + Math.trunc = function (v) { + v = +v; + return v - v % 1 || (!isFinite(v) || v === 0 ? v : v < 0 ? -0 : 0); + }; + } // Polyfill для requestAnimationFrame + + + window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { + return setTimeout(function () { + callback(Date.now()); + }, 1000 / 60); + }; + + if (!Array.from) { + Array.from = function () { + var toStr = Object.prototype.toString; + + var isCallable = function isCallable(fn) { + return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; + }; + + var toInteger = function toInteger(value) { + var number = Number(value); + + if (isNaN(number)) { + return 0; + } + + if (number === 0 || !isFinite(number)) { + return number; + } + + return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); + }; + + var maxSafeInteger = Math.pow(2, 53) - 1; + + var toLength = function toLength(value) { + var len = toInteger(value); + return Math.min(Math.max(len, 0), maxSafeInteger); + }; // Свойство length метода from равно 1. + + + return function from(arrayLike + /* , mapFn, thisArg */ + ) { + // 1. Положим C равным значению this. + var C = this; // 2. Положим items равным ToObject(arrayLike). + + var items = Object(arrayLike); // 3. ReturnIfAbrupt(items). + + if (arrayLike == null) { + throw new TypeError('Array.from requires an array-like object - not null or undefined'); + } // 4. Если mapfn равен undefined, положим mapping равным false. + + + var mapFn = arguments.length > 1 ? arguments[1] : void undefined; + var T; + + if (typeof mapFn !== 'undefined') { + // 5. иначе + // 5. a. Если вызов IsCallable(mapfn) равен false, выкидываем + // исключение TypeError. + if (!isCallable(mapFn)) { + throw new TypeError('Array.from: when provided, the second argument must be a function'); + } // 5. b. Если thisArg присутствует, положим T равным thisArg; + // иначе положим T равным undefined. + + + if (arguments.length > 2) { + T = arguments[2]; + } + } // 10. Положим lenValue равным Get(items, "length"). + // 11. Положим len равным ToLength(lenValue). + + + var len = toLength(items.length); // 13. Если IsConstructor(C) равен true, то + // 13. a. Положим A равным результату вызова внутреннего метода + // [[Construct]] + // объекта C со списком аргументов, содержащим единственный элемент + // len. + // 14. a. Иначе, положим A равным ArrayCreate(len). + + var A = isCallable(C) ? Object(new C(len)) : new Array(len); // 16. Положим k равным 0. + + var k = 0; // 17. Пока k < len, будем повторять... (шаги с a по h) + + var kValue; + + while (k < len) { + kValue = items[k]; + + if (mapFn) { + A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); + } else { + A[k] = kValue; + } + + k += 1; + } // 18. Положим putStatus равным Put(A, "length", len, true). + + + A.length = len; // 20. Вернём A. + + return A; + }; + }(); + } // https://tc39.github.io/ecma262/#sec-array.prototype.find + + + if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + value: function value(predicate) { + // 1. Let O be ? ToObject(this value). + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + + var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). + + var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError + // exception. + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } // 4. If thisArg was supplied, let T be thisArg; else let T be + // undefined. + + + var thisArg = arguments[1]; // 5. Let k be 0. + + var k = 0; // 6. Repeat, while k < len + + while (k < len) { + // a. Let Pk be ! ToString(k). + // b. Let kValue be ? Get(O, Pk). + // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, + // k, O »)). + // d. If testResult is true, return kValue. + var kValue = o[k]; + + if (predicate.call(thisArg, kValue, k, o)) { + return kValue; + } // e. Increase k by 1. + + + k++; + } // 7. Return undefined. + + + return undefined; + }, + configurable: true, + writable: true + }); + } // https://tc39.github.io/ecma262/#sec-array.prototype.includes + + + if (!Array.prototype.includes) { + Object.defineProperty(Array.prototype, 'includes', { + value: function value(searchElement, fromIndex) { + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } // 1. Let O be ? ToObject(this value). + + + var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). + + var len = o.length >>> 0; // 3. If len is 0, return false. + + if (len === 0) { + return false; + } // 4. Let n be ? ToInteger(fromIndex). + // (If fromIndex is undefined, this step produces the value 0.) + + + var n = fromIndex | 0; // 5. If n ≥ 0, then + // a. Let k be n. + // 6. Else n < 0, + // a. Let k be len + n. + // b. If k < 0, let k be 0. + + var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); + + function sameValueZero(x, y) { + return x === y || typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y); + } // 7. Repeat, while k < len + + + while (k < len) { + // a. Let elementK be the result of ? Get(O, ! ToString(k)). + // b. If SameValueZero(searchElement, elementK) is true, return + // true. + if (sameValueZero(o[k], searchElement)) { + return true; + } // c. Increase k by 1. + + + k++; + } // 8. Return false + + + return false; + } + }); + } + + if (!String.prototype.includes) { + String.prototype.includes = function (search, start) { + + if (search instanceof RegExp) { + throw TypeError('first argument must not be a RegExp'); + } + + if (start === undefined) { + start = 0; + } + + return this.indexOf(search, start) !== -1; + }; + } + + if (!Object.entries) { + Object.entries = function (obj) { + var ownProps = Object.keys(obj), + i = ownProps.length, + resArray = new Array(i); // preallocate the Array + + while (i--) { + resArray[i] = [ownProps[i], obj[ownProps[i]]]; + } + + return resArray; + }; + } + + if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + // ближайший аналог внутренней функции + // IsCallable в ECMAScript 5 + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function fNOP() {}, + fBound = function fBound() { + return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; + } + + (function () { + + var _slice = Array.prototype.slice; + + try { + // Не может использоваться с элементами DOM в IE < 9 + _slice.call(document.documentElement); + } catch (e) { + // В IE < 9 кидается исключение + // Функция будет работать для истинных массивов, массивоподобных объектов, + // NamedNodeMap (атрибуты, сущности, примечания), + // NodeList (например, getElementsByTagName), HTMLCollection (например, childNodes) + // и не будет падать на других объектах DOM (как это происходит на элементах DOM в IE < 9) + Array.prototype.slice = function (begin, end) { + // IE < 9 будет недоволен аргументом end, равным undefined + end = typeof end !== 'undefined' ? end : this.length; // Для родных объектов Array мы используем родную функцию slice + + if (Object.prototype.toString.call(this) === '[object Array]') { + return _slice.call(this, begin, end); + } // Массивоподобные объекты мы обрабатываем самостоятельно + + + var i, + cloned = [], + size, + len = this.length; // Обрабатываем отрицательное значение begin + + var start = begin || 0; + start = start >= 0 ? start : len + start; // Обрабатываем отрицательное значение end + + var upTo = end ? end : len; + + if (end < 0) { + upTo = len + end; + } // Фактически ожидаемый размер среза + + + size = upTo - start; + + if (size > 0) { + cloned = new Array(size); + + if (this.charAt) { + for (i = 0; i < size; i++) { + cloned[i] = this.charAt(start + i); + } + } else { + for (i = 0; i < size; i++) { + cloned[i] = this[start + i]; + } + } + } + + return cloned; + }; + } + })(); + /*! + * Shim for MutationObserver interface + * Author: Graeme Yeates (github.com/megawac) + * Repository: https://github.com/megawac/MutationObserver.js + * License: WTFPL V2, 2004 (wtfpl.net). + * Though credit and staring the repo will make me feel pretty, you can modify and redistribute as you please. + * Attempts to follow spec (https://www.w3.org/TR/dom/#mutation-observers) as closely as possible for native javascript + * See https://github.com/WebKit/webkit/blob/master/Source/WebCore/dom/MutationObserver.cpp for current webkit source c++ implementation + */ + + /** + * prefix bugs: + - https://bugs.webkit.org/show_bug.cgi?id=85161 + - https://bugzilla.mozilla.org/show_bug.cgi?id=749920 + * Don't use WebKitMutationObserver as Safari (6.0.5-6.1) use a buggy implementation + */ + + + if (!window.MutationObserver) { + window.MutationObserver = function (undefined$1) { + /** + * @param {function(Array., MutationObserver)} listener + * @constructor + */ + + function MutationObserver(listener) { + /** + * @type {Array.} + * @private + */ + this._watched = []; + /** @private */ + + this._listener = listener; + } + /** + * Start a recursive timeout function to check all items being observed for mutations + * @type {MutationObserver} observer + * @private + */ + + + function startMutationChecker(observer) { + (function check() { + var mutations = observer.takeRecords(); + + if (mutations.length) { + // fire away + // calling the listener with context is not spec but currently consistent with FF and WebKit + observer._listener(mutations, observer); + } + /** @private */ + + + observer._timeout = setTimeout(check, MutationObserver._period); + })(); + } + /** + * Period to check for mutations (~32 times/sec) + * @type {number} + * @expose + */ + + + MutationObserver._period = 30 + /*ms+runtime*/ + ; + /** + * Exposed API + * @expose + * @final + */ + + MutationObserver.prototype = { + /** + * see https://dom.spec.whatwg.org/#dom-mutationobserver-observe + * not going to throw here but going to follow the current spec config sets + * @param {Node|null} $target + * @param {Object|null} config : MutationObserverInit configuration dictionary + * @expose + * @return undefined + */ + observe: function observe($target, config) { + /** + * Using slightly different names so closure can go ham + * @type {!Object} : A custom mutation config + */ + var settings = { + attr: !!(config.attributes || config.attributeFilter || config.attributeOldValue), + // some browsers enforce that subtree must be set with childList, attributes or characterData. + // We don't care as spec doesn't specify this rule. + kids: !!config.childList, + descendents: !!config.subtree, + charData: !!(config.characterData || config.characterDataOldValue) + }; + var watched = this._watched; // remove already observed target element from pool + + for (var i = 0; i < watched.length; i++) { + if (watched[i].tar === $target) watched.splice(i, 1); + } + + if (config.attributeFilter) { + /** + * converts to a {key: true} dict for faster lookup + * @type {Object.} + */ + settings.afilter = reduce(config.attributeFilter, function (a, b) { + a[b] = true; + return a; + }, {}); + } + + watched.push({ + tar: $target, + fn: createMutationSearcher($target, settings) + }); // reconnect if not connected + + if (!this._timeout) { + startMutationChecker(this); + } + }, + + /** + * Finds mutations since last check and empties the "record queue" i.e. mutations will only be found once + * @expose + * @return {Array.} + */ + takeRecords: function takeRecords() { + var mutations = []; + var watched = this._watched; + + for (var i = 0; i < watched.length; i++) { + watched[i].fn(mutations); + } + + return mutations; + }, + + /** + * @expose + * @return undefined + */ + disconnect: function disconnect() { + this._watched = []; // clear the stuff being observed + + clearTimeout(this._timeout); // ready for garbage collection + + /** @private */ + + this._timeout = null; + } + }; + /** + * Simple MutationRecord pseudoclass. No longer exposing as its not fully compliant + * @param {Object} data + * @return {Object} a MutationRecord + */ + + function MutationRecord(data) { + var settings = { + // technically these should be on proto so hasOwnProperty will return false for non explicitly props + type: null, + target: null, + addedNodes: [], + removedNodes: [], + previousSibling: null, + nextSibling: null, + attributeName: null, + attributeNamespace: null, + oldValue: null + }; + + for (var prop in data) { + if (has(settings, prop) && data[prop] !== undefined$1) settings[prop] = data[prop]; + } + + return settings; + } + /** + * Creates a func to find all the mutations + * + * @param {Node} $target + * @param {!Object} config : A custom mutation config + */ + + + function createMutationSearcher($target, config) { + /** type {Elestuct} */ + var $oldstate = clone($target, config); // create the cloned datastructure + + /** + * consumes array of mutations we can push to + * + * @param {Array.} mutations + */ + + return function (mutations) { + var olen = mutations.length, + dirty; + + if (config.charData && $target.nodeType === 3 && $target.nodeValue !== $oldstate.charData) { + mutations.push(new MutationRecord({ + type: "characterData", + target: $target, + oldValue: $oldstate.charData + })); + } // Alright we check base level changes in attributes... easy + + + if (config.attr && $oldstate.attr) { + findAttributeMutations(mutations, $target, $oldstate.attr, config.afilter); + } // check childlist or subtree for mutations + + + if (config.kids || config.descendents) { + dirty = searchSubtree(mutations, $target, $oldstate, config); + } // reclone data structure if theres changes + + + if (dirty || mutations.length !== olen) { + /** type {Elestuct} */ + $oldstate = clone($target, config); + } + }; + } + /* attributes + attributeFilter helpers */ + // Check if the environment has the attribute bug (#4) which cause + // element.attributes.style to always be null. + + + var hasAttributeBug = document.createElement("i"); + hasAttributeBug.style.top = 0; + hasAttributeBug = hasAttributeBug.attributes.style.value != "null"; + /** + * Gets an attribute value in an environment without attribute bug + * + * @param {Node} el + * @param {Attr} attr + * @return {String} an attribute value + */ + + function getAttributeSimple(el, attr) { + // There is a potential for a warning to occur here if the attribute is a + // custom attribute in IE<9 with a custom .toString() method. This is + // just a warning and doesn't affect execution (see #21) + return attr.value; + } + /** + * Gets an attribute value with special hack for style attribute (see #4) + * + * @param {Node} el + * @param {Attr} attr + * @return {String} an attribute value + */ + + + function getAttributeWithStyleHack(el, attr) { + // As with getAttributeSimple there is a potential warning for custom attribtues in IE7. + return attr.name !== "style" ? attr.value : el.style.cssText; + } + + var getAttributeValue = hasAttributeBug ? getAttributeSimple : getAttributeWithStyleHack; + /** + * fast helper to check to see if attributes object of an element has changed + * doesnt handle the textnode case + * + * @param {Array.} mutations + * @param {Node} $target + * @param {Object.} $oldstate : Custom attribute clone data structure from clone + * @param {Object} filter + */ + + function findAttributeMutations(mutations, $target, $oldstate, filter) { + var checked = {}; + var attributes = $target.attributes; + var attr; + var name; + var i = attributes.length; + + while (i--) { + attr = attributes[i]; + name = attr.name; + + if (!filter || has(filter, name)) { + if (getAttributeValue($target, attr) !== $oldstate[name]) { + // The pushing is redundant but gzips very nicely + mutations.push(MutationRecord({ + type: "attributes", + target: $target, + attributeName: name, + oldValue: $oldstate[name], + attributeNamespace: attr.namespaceURI // in ie<8 it incorrectly will return undefined + + })); + } + + checked[name] = true; + } + } + + for (name in $oldstate) { + if (!checked[name]) { + mutations.push(MutationRecord({ + target: $target, + type: "attributes", + attributeName: name, + oldValue: $oldstate[name] + })); + } + } + } + /** + * searchSubtree: array of mutations so far, element, element clone, bool + * synchronous dfs comparision of two nodes + * This function is applied to any observed element with childList or subtree specified + * Sorry this is kind of confusing as shit, tried to comment it a bit... + * codereview.stackexchange.com/questions/38351 discussion of an earlier version of this func + * + * @param {Array} mutations + * @param {Node} $target + * @param {!Object} $oldstate : A custom cloned node from clone() + * @param {!Object} config : A custom mutation config + */ + + + function searchSubtree(mutations, $target, $oldstate, config) { + // Track if the tree is dirty and has to be recomputed (#14). + var dirty; + /* + * Helper to identify node rearrangment and stuff... + * There is no gaurentee that the same node will be identified for both added and removed nodes + * if the positions have been shuffled. + * conflicts array will be emptied by end of operation + */ + + function resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes) { + // the distance between the first conflicting node and the last + var distance = conflicts.length - 1; // prevents same conflict being resolved twice consider when two nodes switch places. + // only one should be given a mutation event (note -~ is used as a math.ceil shorthand) + + var counter = -~((distance - numAddedNodes) / 2); + var $cur; + var oldstruct; + var conflict; + + while (conflict = conflicts.pop()) { + $cur = $kids[conflict.i]; + oldstruct = $oldkids[conflict.j]; // attempt to determine if there was node rearrangement... won't gaurentee all matches + // also handles case where added/removed nodes cause nodes to be identified as conflicts + + if (config.kids && counter && Math.abs(conflict.i - conflict.j) >= distance) { + mutations.push(MutationRecord({ + type: "childList", + target: node, + addedNodes: [$cur], + removedNodes: [$cur], + // haha don't rely on this please + nextSibling: $cur.nextSibling, + previousSibling: $cur.previousSibling + })); + counter--; // found conflict + } // Alright we found the resorted nodes now check for other types of mutations + + + if (config.attr && oldstruct.attr) findAttributeMutations(mutations, $cur, oldstruct.attr, config.afilter); + + if (config.charData && $cur.nodeType === 3 && $cur.nodeValue !== oldstruct.charData) { + mutations.push(MutationRecord({ + type: "characterData", + target: $cur, + oldValue: oldstruct.charData + })); + } // now look @ subtree + + + if (config.descendents) findMutations($cur, oldstruct); + } + } + /** + * Main worker. Finds and adds mutations if there are any + * @param {Node} node + * @param {!Object} old : A cloned data structure using internal clone + */ + + + function findMutations(node, old) { + var $kids = node.childNodes; + var $oldkids = old.kids; + var klen = $kids.length; // $oldkids will be undefined for text and comment nodes + + var olen = $oldkids ? $oldkids.length : 0; // if (!olen && !klen) return; // both empty; clearly no changes + // we delay the intialization of these for marginal performance in the expected case (actually quite signficant on large subtrees when these would be otherwise unused) + // map of checked element of ids to prevent registering the same conflict twice + + var map; // array of potential conflicts (ie nodes that may have been re arranged) + + var conflicts; + var id; // element id from getElementId helper + + var idx; // index of a moved or inserted element + + var oldstruct; // current and old nodes + + var $cur; + var $old; // track the number of added nodes so we can resolve conflicts more accurately + + var numAddedNodes = 0; // iterate over both old and current child nodes at the same time + + var i = 0, + j = 0; // while there is still anything left in $kids or $oldkids (same as i < $kids.length || j < $oldkids.length;) + + while (i < klen || j < olen) { + // current and old nodes at the indexs + $cur = $kids[i]; + oldstruct = $oldkids[j]; + $old = oldstruct && oldstruct.node; + + if ($cur === $old) { + // expected case - optimized for this case + // check attributes as specified by config + if (config.attr && oldstruct.attr) + /* oldstruct.attr instead of textnode check */ + findAttributeMutations(mutations, $cur, oldstruct.attr, config.afilter); // check character data if node is a comment or textNode and it's being observed + + if (config.charData && oldstruct.charData !== undefined$1 && $cur.nodeValue !== oldstruct.charData) { + mutations.push(MutationRecord({ + type: "characterData", + target: $cur, + oldValue: oldstruct.charData + })); + } // resolve conflicts; it will be undefined if there are no conflicts - otherwise an array + + + if (conflicts) resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes); // recurse on next level of children. Avoids the recursive call when there are no children left to iterate + + if (config.descendents && ($cur.childNodes.length || oldstruct.kids && oldstruct.kids.length)) findMutations($cur, oldstruct); + i++; + j++; + } else { + // (uncommon case) lookahead until they are the same again or the end of children + dirty = true; + + if (!map) { + // delayed initalization (big perf benefit) + map = {}; + conflicts = []; + } + + if ($cur) { + // check id is in the location map otherwise do a indexOf search + if (!map[id = getElementId($cur)]) { + // to prevent double checking + // mark id as found + map[id] = true; // custom indexOf using comparitor checking oldkids[i].node === $cur + + if ((idx = indexOfCustomNode($oldkids, $cur, j)) === -1) { + if (config.kids) { + mutations.push(MutationRecord({ + type: "childList", + target: node, + addedNodes: [$cur], + // $cur is a new node + nextSibling: $cur.nextSibling, + previousSibling: $cur.previousSibling + })); + numAddedNodes++; + } + } else { + conflicts.push({ + // add conflict + i: i, + j: idx + }); + } + } + + i++; + } + + if ($old && // special case: the changes may have been resolved: i and j appear congurent so we can continue using the expected case + $old !== $kids[i]) { + if (!map[id = getElementId($old)]) { + map[id] = true; + + if ((idx = indexOf($kids, $old, i)) === -1) { + if (config.kids) { + mutations.push(MutationRecord({ + type: "childList", + target: old.node, + removedNodes: [$old], + nextSibling: $oldkids[j + 1], + // praise no indexoutofbounds exception + previousSibling: $oldkids[j - 1] + })); + numAddedNodes--; + } + } else { + conflicts.push({ + i: idx, + j: j + }); + } + } + + j++; + } + } // end uncommon case + + } // end loop + // resolve any remaining conflicts + + + if (conflicts) resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes); + } + + findMutations($target, $oldstate); + return dirty; + } + /** + * Utility + * Cones a element into a custom data structure designed for comparision. https://gist.github.com/megawac/8201012 + * + * @param {Node} $target + * @param {!Object} config : A custom mutation config + * @return {!Object} : Cloned data structure + */ + + + function clone($target, config) { + var recurse = true; // set true so childList we'll always check the first level + + return function copy($target) { + var elestruct = { + /** @type {Node} */ + node: $target + }; // Store current character data of target text or comment node if the config requests + // those properties to be observed. + + if (config.charData && ($target.nodeType === 3 || $target.nodeType === 8)) { + elestruct.charData = $target.nodeValue; + } // its either a element, comment, doc frag or document node + else { + // Add attr only if subtree is specified or top level and avoid if + // attributes is a document object (#13). + if (config.attr && recurse && $target.nodeType === 1) { + /** + * clone live attribute list to an object structure {name: val} + * @type {Object.} + */ + elestruct.attr = reduce($target.attributes, function (memo, attr) { + if (!config.afilter || config.afilter[attr.name]) { + memo[attr.name] = getAttributeValue($target, attr); + } + + return memo; + }, {}); + } // whether we should iterate the children of $target node + + + if (recurse && (config.kids || config.charData || config.attr && config.descendents)) { + /** @type {Array.} : Array of custom clone */ + elestruct.kids = map($target.childNodes, copy); + } + + recurse = config.descendents; + } + + return elestruct; + }($target); + } + /** + * indexOf an element in a collection of custom nodes + * + * @param {NodeList} set + * @param {!Object} $node : A custom cloned node + * @param {number} idx : index to start the loop + * @return {number} + */ + + + function indexOfCustomNode(set, $node, idx) { + return indexOf(set, $node, idx, JSCompiler_renameProperty("node")); + } // using a non id (eg outerHTML or nodeValue) is extremely naive and will run into issues with nodes that may appear the same like
  • + + + var counter = 1; // don't use 0 as id (falsy) + + /** @const */ + + var expando = "mo_id"; + /** + * Attempt to uniquely id an element for hashing. We could optimize this for legacy browsers but it hopefully wont be called enough to be a concern + * + * @param {Node} $ele + * @return {(string|number)} + */ + + function getElementId($ele) { + try { + return $ele.id || ($ele[expando] = $ele[expando] || counter++); + } catch (o_O) { + // ie <8 will throw if you set an unknown property on a text node + try { + return $ele.nodeValue; // naive + } catch (shitie) { + // when text node is removed: https://gist.github.com/megawac/8355978 :( + return counter++; + } + } + } + /** + * **map** Apply a mapping function to each item of a set + * @param {Array|NodeList} set + * @param {Function} iterator + */ + + + function map(set, iterator) { + var results = []; + + for (var index = 0; index < set.length; index++) { + results[index] = iterator(set[index], index, set); + } + + return results; + } + /** + * **Reduce** builds up a single result from a list of values + * @param {Array|NodeList|NamedNodeMap} set + * @param {Function} iterator + * @param {*} [memo] Initial value of the memo. + */ + + + function reduce(set, iterator, memo) { + for (var index = 0; index < set.length; index++) { + memo = iterator(memo, set[index], index, set); + } + + return memo; + } + /** + * **indexOf** find index of item in collection. + * @param {Array|NodeList} set + * @param {Object} item + * @param {number} idx + * @param {string} [prop] Property on set item to compare to item + */ + + + function indexOf(set, item, idx, prop) { + for (; idx < set.length; idx++) { + // start idx is always given as this is internal + if ((prop ? set[idx][prop] : set[idx]) === item) return idx; + } + + return -1; + } + /** + * @param {Object} obj + * @param {(string|number)} prop + * @return {boolean} + */ + + + function has(obj, prop) { + return obj[prop] !== undefined$1; // will be nicely inlined by gcc + } // GCC hack see https://stackoverflow.com/a/23202438/1517919 + + + function JSCompiler_renameProperty(a) { + return a; + } + + return MutationObserver; + }(void 0); + } + /** + * map-polyfill - A Map polyfill written in TypeScript, unit tested using Jasmine and Karma. + * + * @author Brenden Palmer + * @version v0.0.1-alpha.2 + * @license MIT + */ + + + !function () { + + var t; + !function (t) { + var e = function () { + function t(t, e) { + this.index = 0, this.map = null, this.done = !1, this.map = t, this.type = e; + } + + return t.prototype.next = function () { + var t; + return this.map.keyArray.length > this.index ? ("entries" === this.type ? t = [this.map.keyArray[this.index], this.map.get(this.map.keyArray[this.index])] : "keys" === this.type ? t = this.map.keyArray[this.index] : "values" === this.type && (t = this.map.get(this.map.keyArray[this.index])), this.index++) : this.done = !0, { + value: t, + done: this.done + }; + }, t; + }(); + + t.MapIterator = e; + }(t || (t = {})); + var t; + !function (t) { + var e = function () { + function t() {} + + return Object.defineProperty(t, "MAP_KEY_IDENTIFIER", { + get: function get() { + return "MAP_KEY_IDENTIFIER_OZAbzyeCu3_spF91dwX14"; + }, + enumerable: !0, + configurable: !0 + }), Object.defineProperty(t, "MAP_SET_THROWABLE_MESSAGE", { + get: function get() { + return "Invalid value used as map key"; + }, + enumerable: !0, + configurable: !0 + }), t; + }(); + + t.MapConstants = e; + }(t || (t = {})); + var t; + !function (t) { + var e = function () { + function t() { + if (null !== t.instance) throw "Get the instance of the MapSequencer using the getInstance method."; + this.identifier = 0; + } + + return t.getInstance = function () { + return null === t.instance && (t.instance = new t()), t.instance; + }, t.prototype.next = function () { + return "Map_CJPOYUrpwK_aHBtMHXsTM" + String(this.identifier++); + }, t.instance = null, t; + }(); + + t.MapSequencer = e; + }(t || (t = {})); + var t; + !function (t) { + var e = function () { + function e() {} + + return e.defineProperty = function (n) { + var r; + if (e.isValidObject(n) === !1) throw new TypeError(t.MapConstants.MAP_SET_THROWABLE_MESSAGE); + + if ("undefined" == typeof n[t.MapConstants.MAP_KEY_IDENTIFIER]) { + r = t.MapSequencer.getInstance().next(); + + try { + Object.defineProperty(n, t.MapConstants.MAP_KEY_IDENTIFIER, { + enumerable: !1, + configurable: !1, + get: function get() { + return r; + } + }); + } catch (i) { + throw new TypeError(t.MapConstants.MAP_SET_THROWABLE_MESSAGE); + } + } else r = n[t.MapConstants.MAP_KEY_IDENTIFIER]; + + return r; + }, e.getProperty = function (n) { + return e.isValidObject(n) === !0 ? n[t.MapConstants.MAP_KEY_IDENTIFIER] : void 0; + }, e.isValidObject = function (t) { + return t === Object(t); + }, e; + }(); + + t.MapUtils = e; + }(t || (t = {})); + var t; + !function (t) { + var e = function () { + function e(t) { + void 0 === t && (t = []), this.map = {}, this.keyArray = []; + + for (var e = 0; e < t.length; e++) { + var n = t[e]; + n && n.length >= 2 && this.set(n[0], n[1]); + } + } + + return e.prototype.get = function (e) { + if (this.has(e) === !0) { + var n = t.MapUtils.getProperty(e); + return void 0 === n && (n = String(e)), this.map[n]; + } + }, e.prototype.has = function (e) { + var n = t.MapUtils.getProperty(e); + return void 0 === n && (n = String(e)), void 0 !== n && "undefined" != typeof this.map[n]; + }, e.prototype["delete"] = function (e) { + if (this.has(e) === !0) { + var n = t.MapUtils.getProperty(e); + return void 0 === n && (n = String(e)), this.keyArray.splice(this.keyArray.indexOf(e), 1), delete this.map[n], !0; + } + + return !1; + }, e.prototype.set = function (e, n) { + this["delete"](e); + var r; + + try { + r = String(t.MapUtils.defineProperty(e)); + } catch (i) { + r = String(e); + } + + this.keyArray.push(e), this.map[r] = n; + }, e.prototype.entries = function () { + return new t.MapIterator(this, "entries"); + }, e.prototype.keys = function () { + return new t.MapIterator(this, "keys"); + }, e.prototype.values = function () { + return new t.MapIterator(this, "values"); + }, e.prototype.forEach = function (t, e) { + for (var n = 0, r = this.keyArray; n < r.length; n++) { + var i = r[n]; + e ? t.call(e, this.get(i), i, this) : t(this.get(i), i, this); + } + }, e.prototype.clear = function () { + this.map = {}, this.keyArray = []; + }, e; + }(); + + t.Map = e; + }(t || (t = {})); + var t; + !function (t) { + window.Map || (window.Map = t.Map); + }(t || (t = {})); + }(); + + function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + + if (enumerableOnly) { + symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + } + + keys.push.apply(keys, symbols); + } + + return keys; + } + + function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(Object(source), true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; + } + + function _typeof(obj) { + "@babel/helpers - typeof"; + + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }); + if (superClass) _setPrototypeOf(subClass, superClass); + } + + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + return true; + } catch (e) { + return false; + } + } + + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; + } + + function _possibleConstructorReturn(self, call) { + if (call && (typeof call === "object" || typeof call === "function")) { + return call; + } else if (call !== void 0) { + throw new TypeError("Derived constructors may only return object or undefined"); + } + + return _assertThisInitialized(self); + } + + function _createSuper(Derived) { + var hasNativeReflectConstruct = _isNativeReflectConstruct(); + + return function _createSuperInternal() { + var Super = _getPrototypeOf(Derived), + result; + + if (hasNativeReflectConstruct) { + var NewTarget = _getPrototypeOf(this).constructor; + + result = Reflect.construct(Super, arguments, NewTarget); + } else { + result = Super.apply(this, arguments); + } + + return _possibleConstructorReturn(this, result); + }; + } + + function _superPropBase(object, property) { + while (!Object.prototype.hasOwnProperty.call(object, property)) { + object = _getPrototypeOf(object); + if (object === null) break; + } + + return object; + } + + function _get(target, property, receiver) { + if (typeof Reflect !== "undefined" && Reflect.get) { + _get = Reflect.get; + } else { + _get = function _get(target, property, receiver) { + var base = _superPropBase(target, property); + + if (!base) return; + var desc = Object.getOwnPropertyDescriptor(base, property); + + if (desc.get) { + return desc.get.call(receiver); + } + + return desc.value; + }; + } + + return _get(target, property, receiver || target); + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) return _arrayLikeToArray(arr); + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArray(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); + } + + function _iterableToArrayLimit(arr, i) { + var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; + + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; + + var _s, _e; + + try { + for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + function _createForOfIteratorHelper(o, allowArrayLike) { + var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; + + if (!it) { + if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { + if (it) o = it; + var i = 0; + + var F = function () {}; + + return { + s: F, + n: function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }, + e: function (e) { + throw e; + }, + f: F + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var normalCompletion = true, + didErr = false, + err; + return { + s: function () { + it = it.call(o); + }, + n: function () { + var step = it.next(); + normalCompletion = step.done; + return step; + }, + e: function (e) { + didErr = true; + err = e; + }, + f: function () { + try { + if (!normalCompletion && it.return != null) it.return(); + } finally { + if (didErr) throw err; + } + } + }; + } + + /** + * @this {Promise} + */ + function finallyConstructor(callback) { + var constructor = this.constructor; + return this.then(function (value) { + // @ts-ignore + return constructor.resolve(callback()).then(function () { + return value; + }); + }, function (reason) { + // @ts-ignore + return constructor.resolve(callback()).then(function () { + // @ts-ignore + return constructor.reject(reason); + }); + }); + } + + function allSettled(arr) { + var P = this; + return new P(function (resolve, reject) { + if (!(arr && typeof arr.length !== 'undefined')) { + return reject(new TypeError(_typeof(arr) + ' ' + arr + ' is not iterable(cannot read property Symbol(Symbol.iterator))')); + } + + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + if (val && (_typeof(val) === 'object' || typeof val === 'function')) { + var then = val.then; + + if (typeof then === 'function') { + then.call(val, function (val) { + res(i, val); + }, function (e) { + args[i] = { + status: 'rejected', + reason: e + }; + + if (--remaining === 0) { + resolve(args); + } + }); + return; + } + } + + args[i] = { + status: 'fulfilled', + value: val + }; + + if (--remaining === 0) { + resolve(args); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + } + /** + * @constructor + */ + + + function AggregateError(errors, message) { + this.name = 'AggregateError', this.errors = errors; + this.message = message || ''; + } + + AggregateError.prototype = Error.prototype; + + function any$1(arr) { + var P = this; + return new P(function (resolve, reject) { + if (!(arr && typeof arr.length !== 'undefined')) { + return reject(new TypeError('Promise.any accepts an array')); + } + + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return reject(); + var rejectionReasons = []; + + for (var i = 0; i < args.length; i++) { + try { + P.resolve(args[i]).then(resolve)["catch"](function (error) { + rejectionReasons.push(error); + + if (rejectionReasons.length === args.length) { + reject(new AggregateError(rejectionReasons, 'All promises were rejected')); + } + }); + } catch (ex) { + reject(ex); + } + } + }); + } // Store setTimeout reference so promise-polyfill will be unaffected by + // other code modifying setTimeout (like sinon.useFakeTimers()) + + + var setTimeoutFunc = setTimeout; + + function isArray$1(x) { + return Boolean(x && typeof x.length !== 'undefined'); + } + + function noop() {} // Polyfill for Function.prototype.bind + + + function bind$5(fn, thisArg) { + return function () { + fn.apply(thisArg, arguments); + }; + } + /** + * @constructor + * @param {Function} fn + */ + + + function Promise$1(fn) { + if (!(this instanceof Promise$1)) throw new TypeError('Promises must be constructed via new'); + if (typeof fn !== 'function') throw new TypeError('not a function'); + /** @type {!number} */ + + this._state = 0; + /** @type {!boolean} */ + + this._handled = false; + /** @type {Promise|undefined} */ + + this._value = undefined; + /** @type {!Array} */ + + this._deferreds = []; + doResolve(fn, this); + } + + function handle(self, deferred) { + while (self._state === 3) { + self = self._value; + } + + if (self._state === 0) { + self._deferreds.push(deferred); + + return; + } + + self._handled = true; + + Promise$1._immediateFn(function () { + var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; + + if (cb === null) { + (self._state === 1 ? resolve : reject)(deferred.promise, self._value); + return; + } + + var ret; + + try { + ret = cb(self._value); + } catch (e) { + reject(deferred.promise, e); + return; + } + + resolve(deferred.promise, ret); + }); + } + + function resolve(self, newValue) { + try { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.'); + + if (newValue && (_typeof(newValue) === 'object' || typeof newValue === 'function')) { + var then = newValue.then; + + if (newValue instanceof Promise$1) { + self._state = 3; + self._value = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(bind$5(then, newValue), self); + return; + } + } + + self._state = 1; + self._value = newValue; + finale(self); + } catch (e) { + reject(self, e); + } + } + + function reject(self, newValue) { + self._state = 2; + self._value = newValue; + finale(self); + } + + function finale(self) { + if (self._state === 2 && self._deferreds.length === 0) { + Promise$1._immediateFn(function () { + if (!self._handled) { + Promise$1._unhandledRejectionFn(self._value); + } + }); + } + + for (var i = 0, len = self._deferreds.length; i < len; i++) { + handle(self, self._deferreds[i]); + } + + self._deferreds = null; + } + /** + * @constructor + */ + + + function Handler(onFulfilled, onRejected, promise) { + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; + } + /** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ + + + function doResolve(fn, self) { + var done = false; + + try { + fn(function (value) { + if (done) return; + done = true; + resolve(self, value); + }, function (reason) { + if (done) return; + done = true; + reject(self, reason); + }); + } catch (ex) { + if (done) return; + done = true; + reject(self, ex); + } + } + + Promise$1.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); + }; + + Promise$1.prototype.then = function (onFulfilled, onRejected) { + // @ts-ignore + var prom = new this.constructor(noop); + handle(this, new Handler(onFulfilled, onRejected, prom)); + return prom; + }; + + Promise$1.prototype['finally'] = finallyConstructor; + + Promise$1.all = function (arr) { + return new Promise$1(function (resolve, reject) { + if (!isArray$1(arr)) { + return reject(new TypeError('Promise.all accepts an array')); + } + + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + try { + if (val && (_typeof(val) === 'object' || typeof val === 'function')) { + var then = val.then; + + if (typeof then === 'function') { + then.call(val, function (val) { + res(i, val); + }, reject); + return; + } + } + + args[i] = val; + + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + }; + + Promise$1.any = any$1; + Promise$1.allSettled = allSettled; + + Promise$1.resolve = function (value) { + if (value && _typeof(value) === 'object' && value.constructor === Promise$1) { + return value; + } + + return new Promise$1(function (resolve) { + resolve(value); + }); + }; + + Promise$1.reject = function (value) { + return new Promise$1(function (resolve, reject) { + reject(value); + }); + }; + + Promise$1.race = function (arr) { + return new Promise$1(function (resolve, reject) { + if (!isArray$1(arr)) { + return reject(new TypeError('Promise.race accepts an array')); + } + + for (var i = 0, len = arr.length; i < len; i++) { + Promise$1.resolve(arr[i]).then(resolve, reject); + } + }); + }; // Use polyfill for setImmediate for performance gains + + + Promise$1._immediateFn = // @ts-ignore + typeof setImmediate === 'function' && function (fn) { + // @ts-ignore + setImmediate(fn); + } || function (fn) { + setTimeoutFunc(fn, 0); + }; + + Promise$1._unhandledRejectionFn = function _unhandledRejectionFn(err) { + if (typeof console !== 'undefined' && console) { + console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console + } + }; + /** @suppress {undefinedVars} */ + + + var globalNS = function () { + // the only reliable means to get the global object is + // `Function('return this')()` + // However, this causes CSP violations in Chrome apps. + if (typeof self !== 'undefined') { + return self; + } + + if (typeof window !== 'undefined') { + return window; + } + + if (typeof global !== 'undefined') { + return global; + } + + throw new Error('unable to locate global object'); + }(); // Expose the polyfill if Promise is undefined or set to a + // non-function value. The latter can be due to a named HTMLElement + // being exposed by browsers for legacy reasons. + // https://github.com/taylorhakes/promise-polyfill/issues/114 + + + if (typeof globalNS['Promise'] !== 'function') { + globalNS['Promise'] = Promise$1; + } else { + if (!globalNS.Promise.prototype['finally']) { + globalNS.Promise.prototype['finally'] = finallyConstructor; + } + + if (!globalNS.Promise.allSettled) { + globalNS.Promise.allSettled = allSettled; + } + + if (!globalNS.Promise.any) { + globalNS.Promise.any = any$1; + } + } + + var object$2 = { + author: 'Yumata', + github: 'https://github.com/yumata/lampa-source', + css_version: '3.3.4', + app_version: '3.3.5', + cub_site: 'cub.best', + apk_link_download: 'https://github.com/lampa-app/LAMPA/releases/download/v1.12.3/app-lite-release.apk' + }; + var plugins$1 = []; + Object.defineProperty(object$2, 'app_digital', { + get: function get() { + return parseInt(object$2.app_version.replace(/\./g, '')); + } + }); + Object.defineProperty(object$2, 'css_digital', { + get: function get() { + return parseInt(object$2.css_version.replace(/\./g, '')); + } + }); + /** + * Ссылка на сайт CUB, которая зависит от региона пользователя + */ + + Object.defineProperty(object$2, 'cub_site', { + get: function get() { + return window.vpn_region == 'ru' ? 'cub.black' : 'cub.best'; + } + }); + /** + * Список подключенных плагинов + */ + + Object.defineProperty(object$2, 'plugins', { + get: function get() { + return plugins$1; + }, + set: function set(plugin) { + if (_typeof(plugin) == 'object' && typeof plugin.type == 'string') { + plugins$1.push(plugin); + } + } + }); + /** + * Ссылка на GitHub с файлами приложения + */ + + Object.defineProperty(object$2, 'github_lampa', { + get: function get() { + return window.lampa_settings.fix_widget ? 'http://lampa.mx/' : 'https://yumata.github.io/lampa/'; + }, + set: function set() {} + }); + /** + * Старые зеркала, которые не используются больше, но могут быть полезны для обратной совместимости + */ + + Object.defineProperty(object$2, 'old_mirrors', { + get: function get() { + return ['cub.red', 'cub.rip', 'standby.cub.red', 'kurwa-bober.ninja', 'nackhui.com']; + }, + set: function set() {} + }); + /** + * Список актуальных зеркал + */ + + Object.defineProperty(object$2, 'cub_mirrors', { + get: function get() { + var lampa = ['cub.best', 'cub.black', 'durex.monster', 'cubnotrip.top']; + var users = localStorage.getItem('cub_mirrors') || '[]'; + + try { + users = JSON.parse(users); + } catch (e) { + users = []; + } + + if (Object.prototype.toString.call(users) === '[object Array]' && users.length) { + return lampa.concat(users); + } + + return lampa; + }, + set: function set() {} + }); + /** + * Список зеркал для сокета, вынесены отдельно, так как могут отличаться от обычных зеркал + */ + + Object.defineProperty(object$2, 'soc_mirrors', { + get: function get() { + return ['cub.best', 'kurwa-bober.ninja', 'nackhui.com']; + }, + set: function set() {} + }); + /** + * Текущее доменное имя, которое используется для работы с CUB + */ + + Object.defineProperty(object$2, 'cub_domain', { + get: function get() { + var use = localStorage.getItem('cub_domain') || ''; + return object$2.cub_mirrors.indexOf(use) > -1 ? use : object$2.cub_mirrors[0]; + } + }); + /** + * Текущее живое зеркало с протоколом http|https + */ + + Object.defineProperty(object$2, 'cub_alive', { + get: function get() { + return localStorage.getItem('cub_alive') || 'https://' + object$2.cub_domain; + } + }); + /** + * Ссылка на сайт CUB + */ + + Object.defineProperty(object$2, 'qr_site', { + get: function get() { + return object$2.cub_domain + '/img/other/qr-code-strong.png'; + } + }); + /** + * Ссылка на QR для добавления устройства + */ + + Object.defineProperty(object$2, 'qr_device_add', { + get: function get() { + return object$2.cub_domain + '/img/other/qr-add-device.png'; + } + }); + + /** + * Подписка на события + */ + function Subscribe$1() { + this.add = function (type, listener) { + if (this._listeners === undefined) this._listeners = {}; + var listeners = this._listeners; + if (listeners[type] === undefined) listeners[type] = []; + if (listeners[type].indexOf(listener) === -1) listeners[type].push(listener); + return this; + }; + + this.follow = function (type, listener) { + var _this = this; + + type.split(',').forEach(function (name) { + _this.add(name, listener); + }); + return this; + }; + + this.has = function (type, listener) { + if (this._listeners === undefined) return false; + var listeners = this._listeners; + return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; + }; + + this.remove = function (type, listener) { + if (this._listeners === undefined) return this; + var listeners = this._listeners; + var listenerArray = listeners[type]; + + if (listenerArray !== undefined) { + var index = listenerArray.indexOf(listener); + + if (index !== -1) { + listenerArray.splice(index, 1); + } + } + + return this; + }; + + this.send = function (type) { + var event = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (this._listeners === undefined) return this; + + try { + var listeners = this._listeners; + var listenerArray = listeners[type]; + + if (listenerArray !== undefined) { + var array = listenerArray.slice(0); + + for (var i = 0, l = array.length; i < l; i++) { + array[i].call(this, event); + } + } + } catch (e) { + console.error('Subscribe', 'send error:', e.message, e.stack); + } + + return this; + }; + + this.destroy = function () { + this._listeners = {}; + }; + } + + var Subscribe$2 = (function () { + return new Subscribe$1(); + }); + + function toObject(a) { + if (Object.prototype.toString.call(a) === '[object Object]') return a;else { + a = {}; + return a; + } + } + + function toArray(a) { + if (Object.prototype.toString.call(a) === '[object Object]') { + var b = []; + + for (var i in a) { + b.push(a[i]); + } + + return b; + } else if (typeof a == 'string' || a == null || typeof a == 'number' || typeof a == 'undefined') return [];else return a; + } + + function decodeJson(string, empty) { + var json = empty || {}; + + if (string) { + try { + json = JSON.parse(string); + } catch (e) {} + } + + return json; + } + + function isObject(a) { + return Object.prototype.toString.call(a) === '[object Object]'; + } + + function isArray(a) { + return Object.prototype.toString.call(a) === '[object Array]'; + } + + function extend(a, b, replase) { + for (var i in b) { + if (isObject(b[i])) { + if (a[i] == undefined) a[i] = {}; + this.extend(a[i], b[i], replase); + } else if (a[i] == undefined || replase) a[i] = b[i]; + } + } + + function empty$1(a, b) { + for (var i in b) { + if (!a[i]) a[i] = b[i]; + } + } + + function getKeys(a, add) { + var k = add || []; + + for (var i in a) { + k.push(i); + } + + return k; + } + + function getValues(a, add) { + var k = add || []; + + for (var i in a) { + k.push(a[i]); + } + + return k; + } + + function remove$7(from, need) { + var inx = from.indexOf(need); + if (inx >= 0) from.splice(inx, 1); + } + + function clone$2(a) { + return JSON.parse(JSON.stringify(a)); + } + + function insert(where, index, item) { + where.splice(index, 0, item); + } + + function destroy$r(arr) { + var call_function = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'destroy'; + var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; + var where = toArray(arr); + + for (var i = where.length - 1; i >= 0; i--) { + if (where[i] && where[i][call_function]) where[i][call_function](value); + } + } + + function groupBy(xs, key) { + return xs.reduce(function (rv, x) { + (rv[x[key]] = rv[x[key]] || []).push(x); + return rv; + }, {}); + } + + function removeNoIncludes(where, items) { + for (var i = where.length - 1; i >= 0; i--) { + if (items.indexOf(where[i]) === -1) remove$7(where, where[i]); + } + + return where; + } + + function shuffle(array) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + + return array; + } + + function shuffleArrayFromIndex(array, startIndex) { + if (startIndex < 0 || startIndex >= array.length) { + return; + } + + for (var i = array.length - 1; i > startIndex; i--) { + // Выбираем случайный индекс от startIndex до i + var j = Math.floor(Math.random() * (i - startIndex + 1)) + startIndex; // Меняем местами элементы array[i] и array[j] + + var _ref = [array[j], array[i]]; + array[i] = _ref[0]; + array[j] = _ref[1]; + } + } + + function removeDuplicates(array, key) { + var seen = []; + return array.filter(function (a) { + if (seen.indexOf(a[key]) == -1) { + seen.push(a[key]); + return true; + } else return false; + }); + } + + function flatMap(arr, add) { + var result = []; + + for (var i = 0; i < arr.length; i++) { + result.push(arr[i]); + + if (i < arr.length - 1) { + if (add && typeof add == 'function') { + result.push(add(arr[i], arr[i + 1])); + } else { + result.push(add || null); + } + } + } + + return result; + } + + function unique(arr) { + return arr.filter(function (item, pos) { + return arr.indexOf(item) === pos; + }); + } + + var Arrays = { + toObject: toObject, + toArray: toArray, + decodeJson: decodeJson, + isObject: isObject, + isArray: isArray, + extend: extend, + getKeys: getKeys, + getValues: getValues, + insert: insert, + clone: clone$2, + remove: remove$7, + destroy: destroy$r, + empty: empty$1, + groupBy: groupBy, + removeNoIncludes: removeNoIncludes, + shuffle: shuffle, + shuffleArrayFromIndex: shuffleArrayFromIndex, + removeDuplicates: removeDuplicates, + flatMap: flatMap, + unique: unique + }; + + var html$2t = "
    \n
    \n
    \n \n
    \n\n
    \n \n
    \n\n
    \n \n
    \n
    \n \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$2s = "
    \n
    \n
    \n
    "; + + var html$2r = "
    \n\n
    \n
      \n \n
    \n
    \n\n
    \n\n
    \n
      \n
    • \n
      \n \n
      \n
      #{menu_settings}
      \n
    • \n\n
    • \n
      \n \n
      \n
      #{menu_about}
      \n
    • \n\n
    • \n
      \n \n
      \n
      #{menu_console}
      \n
    • \n
    \n
    \n\n
    \n\n
    \n
      \n
    • \n
      \n \n
      \n
      #{extensions_edit}
      \n
    • \n
    \n
    \n
    "; + + var html$2q = "
    \n
    \n
    "; + + var html$2p = "
    \n
    \n
    \n
    "; + + var html$2o = "
    \n
    \u041E\u0436\u0438\u0434\u0430\u044E
    \n
    \u041D\u0430\u0436\u043C\u0438\u0442\u0435 (\u0432\u043D\u0438\u0437) \u0434\u043B\u044F \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442\u0438.
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$2n = "
    \n
    \n
    \n \n
    \n
    \n
    "; + + var html$2m = "
    \n
    \n
    \n
    \n
    #{title_settings}
    \n
    \n
    \n
    \n
    "; + + var html$2l = "
    \n
    \n
    \n \n \n \n \n \n \n
    \n
    #{settings_cub_sync}
    \n
    \n
    \n
    \n \n \n \n
    \n
    #{settings_main_interface}
    \n
    \n
    \n
    \n \n
    \n
    #{settings_main_player}
    \n
    \n
    \n
    \n \n
    \n
    #{settings_main_parser}
    \n
    \n
    \n
    \n \n
    \n
    #{settings_main_torrserver}
    \n
    \n
    \n
    \n \n \n \n
    \n
    TMDB
    \n
    \n
    \n
    \n \n \n \n \n \n
    \n
    #{settings_main_plugins}
    \n
    \n
    \n
    \n \n \n \n \n
    \n
    #{title_parental_control}
    \n
    \n
    \n
    \n \n
    \n
    #{settings_main_rest}
    \n
    \n
    "; + + var html$2k = "
    \n
    \n
    #{settings_interface_lang}
    \n
    \n
    \n\n
    \n
    #{settings_interface_type}
    \n
    \n
    \n\n
    \n
    #{settings_interface_size}
    \n
    \n
    \n\n
    \n
    #{settings_interface_menu_always}
    \n
    \n
    \n\n
    #{settings_interface_background}
    \n\n
    \n
    #{settings_interface_background_use}
    \n
    \n
    \n\n
    \n
    #{settings_interface_background_type}
    \n
    \n
    \n\n
    \n
    #{settings_interface_black_style}
    \n
    \n
    \n\n
    #{title_card}
    \n\n
    \n
    #{settings_interface_card_poster}
    \n
    \n
    \n\n
    \n
    #{settings_interface_card_cover}
    \n
    \n
    \n\n
    \n
    #{settings_interface_card_reactions}
    \n
    \n
    \n\n
    #{settings_interface_glass}
    \n\n
    \n
    #{settings_interface_glass}
    \n
    \n
    #{settings_interface_glass_descr}
    \n
    \n\n
    \n
    #{settings_interface_glass_opacity}
    \n
    \n
    \n\n
    \n
    #{settings_interface_sound}
    \n\n
    \n
    #{settings_interface_sound_play}
    \n
    \n
    \n\n
    \n
    #{settings_interface_sound_level}
    \n
    \n
    \n
    \n\n
    #{settings_interface_performance}
    \n\n\n
    \n
    #{settings_interface_animation}
    \n
    \n
    #{settings_interface_animation_descr}
    \n
    \n\n
    \n
    #{settings_interface_advanced_animation}
    \n
    \n
    \n\n
    \n
    #{settings_interface_attenuation}
    \n
    \n
    #{settings_interface_attenuation_descr}
    \n
    \n\n
    \n
    #{settings_interface_scroll}
    \n
    \n
    \n
    "; + + var html$2j = "
    \n
    \n
    #{settings_parser_use}
    \n
    \n
    #{settings_parser_use_descr}
    \n
    \n
    \n
    \n
    #{settings_parser_type}
    \n
    \n
    \n\n
    \n
    #{settings_server_link}
    \n
    \n
    \n\n
    \n
    #{settings_param_link_use_one}
    \n\n
    \n
    #{settings_parser_jackett_link}
    \n
    \n
    #{settings_parser_jackett_link_descr}
    \n
    \n\n
    \n
    #{settings_parser_jackett_key}
    \n
    \n
    #{settings_parser_jackett_key_descr}
    \n
    \n\n
    #{settings_param_link_use_two}
    \n\n
    \n
    #{settings_parser_jackett_link}
    \n
    \n
    #{settings_parser_jackett_link_descr}
    \n
    \n\n
    \n
    #{settings_parser_jackett_key}
    \n
    \n
    #{settings_parser_jackett_key_descr}
    \n
    \n\n
    \n
    #{settings_parser_jackett_interview}
    \n
    \n
    \n
    \n \n
    \n
    #{settings_param_link_use_one}
    \n\n
    \n
    #{settings_parser_jackett_link}
    \n
    \n
    #{settings_parser_prowlarr_link_descr}
    \n
    \n\n
    \n
    #{settings_parser_jackett_key}
    \n
    \n
    #{settings_parser_prowlarr_key_descr}
    \n
    \n\n
    #{settings_param_link_use_two}
    \n\n
    \n
    #{settings_parser_jackett_link}
    \n
    \n
    #{settings_parser_prowlarr_link_descr}
    \n
    \n\n
    \n
    #{settings_parser_jackett_key}
    \n
    \n
    #{settings_parser_prowlarr_key_descr}
    \n
    \n
    \n\n
    \n
    \n
    #{settings_server_search_type}
    \n
    \n
    #{settings_server_search_type_descr}
    \n
    \n
    \n\n
    #{more}
    \n\n
    \n
    #{settings_parser_search}
    \n
    \n
    #{settings_parser_search_descr}
    \n
    \n
    \n
    #{settings_parser_timeout_title}
    \n
    \n
    #{settings_parser_timeout_descr}
    \n
    \n
    \n
    #{settings_parser_in_search}
    \n
    \n
    #{settings_parser_in_search_descr}
    \n
    \n
    \n
    "; + + var html$2i = "
    \n
    \n
    #{settings_server_client}
    \n
    \n
    #{settings_server_client_descr}
    \n
    \n\n
    \n
    \n
    #{settings_server_link}
    \n
    \n
    \n\n
    #{settings_server_links}
    \n\n
    \n
    #{settings_server_link_one}
    \n
    \n
    #{settings_server_link_one_descr}
    \n
    \n
    \n\n
    \n
    #{settings_server_link_two}
    \n
    \n
    #{settings_server_link_two_descr}
    \n
    \n
    \n \n \n
    #{settings_server_additionally}
    \n\n
    \n
    #{settings_server_base}
    \n
    \n
    #{settings_server_base_descr}
    \n
    \n \n
    \n
    #{settings_server_preload}
    \n
    \n
    #{settings_server_preload_descr}
    \n
    \n\n
    \n
    #{settings_server_gts}
    \n
    \n
    #{settings_server_gts_descr}
    \n
    \n\n\t\t
    \n
    #{settings_server_tracktimecode}
    \n
    \n
    #{settings_server_tracktimecode_descr}
    \n
    \n\n
    #{settings_server_auth}
    \n\n
    \n
    #{settings_server_password_use}
    \n
    \n
    \n \n
    \n
    \n
    #{settings_server_login}
    \n
    \n
    \n\n
    \n
    #{settings_server_password}
    \n
    \n
    \n
    \n
    \n
    "; + + var html$2h = "
    \n
    \n
    #{settings_player_type}
    \n
    \n
    #{settings_player_type_descr}
    \n
    \n\n
    \n
    #{settings_player_iptv_type}
    \n
    \n
    #{settings_player_iptv_type_descr}
    \n
    \n\n
    \n
    #{settings_player_torrent_type}
    \n
    \n
    #{settings_player_torrent_type_descr}
    \n
    \n\n
    \n
    \n
    #{settings_infuse_launch_mode}
    \n
    \n
    #{settings_infuse_launch_mode_descr}
    \n
    \n
    \n\n
    \n
    #{settings_player_launch_trailers}
    \n
    \n
    \n \n
    \n
    #{settings_player_reset}
    \n
    \n
    #{settings_player_reset_descr}
    \n
    \n\n
    \n
    #{settings_player_path}
    \n
    \n
    #{settings_player_path_descr}
    \n
    \n \n
    \n
    #{settings_player_external_header}
    \n \n
    \n
    #{settings_player_external_fullscreen}
    \n
    \n
    \n
    \n\n
    \n
    #{settings_player_normalization}
    \n
    \n
    #{settings_player_normalization_descr}
    \n
    \n \n
    \n
    #{settings_player_next_episode}
    \n
    \n
    #{settings_player_next_episode_descr}
    \n
    \n\n
    \n
    #{settings_player_timecode}
    \n
    \n
    #{settings_player_timecode_descr}
    \n
    \n\n
    \n
    #{settings_player_scale}
    \n
    \n
    #{settings_player_scale_descr}
    \n
    \n\n
    \n
    #{settings_player_hls_title}
    \n
    \n
    #{settings_player_hls_descr}
    \n
    \n\n
    \n
    #{settings_player_rewind_title}
    \n
    \n
    #{settings_player_rewind_descr}
    \n
    \n \n
    \n
    #{settings_player_subs}
    \n\n
    \n
    #{settings_player_subs_use}
    \n
    \n
    #{settings_player_subs_use_descr}
    \n
    \n\n
    \n
    #{settings_player_subs_lang}
    \n
    \n
    #{settings_player_subs_lang_descr}
    \n
    \n
    \n\n
    #{more}
    \n\n
    \n
    #{settings_player_quality}
    \n
    \n
    #{settings_player_quality_descr}
    \n
    \n
    "; + + var html$2g = "
    \n
    \n
    #{settings_rest_start}
    \n
    \n
    #{settings_rest_start_descr}
    \n
    \n\n
    \n
    #{settings_rest_source_use}
    \n
    \n
    #{settings_rest_source_descr}
    \n
    \n\n
    \n
    #{settings_rest_protocol_use}
    \n
    \n
    #{settings_rest_protocol_descr}
    \n
    \n\n
    \n
    #{settings_request_caching_use}
    \n
    \n
    #{settings_request_caching_descr}
    \n
    \n\n
    #{settings_rest_screensaver}
    \n\n
    \n
    #{settings_rest_screensaver_use}
    \n
    \n
    \n\n
    \n
    #{settings_rest_screensaver_type}
    \n
    \n
    \n\n
    \n
    #{settings_rest_screensaver_time}
    \n
    \n
    \n\n \n
    #{more}
    \n\n
    \n
    #{settings_rest_pages}
    \n
    \n
    #{settings_rest_pages_descr}
    \n
    \n\n
    \n
    #{settings_rest_time}
    \n
    \n
    \n\n
    \n
    #{settings_rest_navigation}
    \n
    \n
    \n\n
    \n
    #{settings_rest_keyboard}
    \n
    \n
    \n\n\n
    \n
    #{settings_rest_card_quality}
    \n
    \n
    #{settings_rest_card_quality_descr}
    \n
    \n\n
    \n
    #{settings_rest_card_episodes}
    \n
    \n
    #{settings_rest_card_episodes_descr}
    \n
    \n\n
    \n
    #{settings_rest_device}
    \n
    \n
    \n
    "; + + var html$2f = "
    \n
    \n
    TMDB
    \n
    \n
    #{settings_rest_tmdb_lang}
    \n
    \n\n
    \n
    #{settings_rest_tmdb_posters}
    \n
    \n
    \n\n
    \n
    #{settings_rest_tmdb_prox_auto}
    \n
    \n
    \n\n
    \n
    #{settings_rest_tmdb_prox}
    \n
    \n
    \n\n
    \n
    Api
    \n
    \n
    #{settings_rest_tmdb_api_descr}
    \n
    \n\n
    \n
    Image
    \n
    \n
    #{settings_rest_tmdb_image_descr}
    \n
    \n
    "; + + var html$2e = "
    \n
    \n
    #{settings_plugins_add}
    \n
    #{settings_plugins_add_descr}
    \n
    \n
    \n
    #{settings_plugins_install}
    \n
    #{settings_plugins_install_descr}
    \n
    \n
    "; + + var html$2d = "
    \n
    \n
    \n
    https://{site}
    \n #{settings_cub_sync_descr}\n
    \n
    \n
    \n
    \n\n
    \n
    #{settings_cub_sync}
    \n
    \n
    \n\n
    #{settings_cub_account} Premium
    \n\n
    \n
    #{settings_cub_domain}
    \n
    \n
    \n\n
    \n
    #{settings_cub_logged_in_as}
    \n
    \n
    \n\n
    \n
    #{settings_cub_profile}
    \n
    \n
    \n\n
    \n
    #{settings_cub_logout}
    \n
    \n\n
    #{settings_cub_signin}
    \n\n
    \n
    #{settings_cub_signin_button}
    \n
    \n
    \n\n
    #{more}
    \n\n
    \n
    #{settings_cub_sync_btn}
    \n
    #{settings_cub_sync_btn_descr}
    \n
    \n\n
    \n
    #{settings_cub_backup}
    \n
    #{settings_cub_backup_descr}
    \n
    \n
    "; + + var html$2c = "
    \n
    \n
    {title}
    \n
    \n
    \n
    "; + + var html$2b = "
    \n
    \n \n\n
    \n
    \n \n
    \n
    \n
    \n\n
    {title}
    \n
    {release_year}
    \n
    "; + + var html$2a = "
    \n
    {Title}
    \n\n
    \n
    \n
    #{torrent_item_seeds}: {Seeders}
    \n
    #{torrent_item_grabs}: {Peers}
    \n
    \n
    {size}
    \n
    \n
    "; + + var html$29 = "
    \n
    \n
    \n
    \n
    "; + + var html$28 = "
    \n
    \n
    \n
    \n \n
    \n\n
    \n
    {num}
    \n
    {name}
    \n
    {date}
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n
    \n\n
    \n
    {title}
    \n
    {release_year}
    \n
    \n
    \n
    "; + + var html$27 = "
    \n\n
    \n
    \n
    \n \n
    \n
    \n\n
    \n
    \n
    {title}
    \n
    {tagline}
    \n
    \n
    {rating}
    TMDB
    \n
    IMDB
    \n
    KP
    \n\n
    \n
    \n
    \n
    \n
    \n
    #{reactions_none}
    \n
    \n\n
    \n
    \n \n\n #{title_watch}\n
    \n\n
    \n \n \n \n\n #{settings_input_links}\n
    \n\n
    \n \n\n #{title_reactions}\n
    \n\n
    \n \n \n \n \n\n #{title_subscribe}\n
    \n\n
    \n \n
    \n
    \n
    \n
    \n\n
    \n
    \n \n\n #{full_torrents}\n
    \n\n
    \n \n\n #{full_trailers}\n
    \n
    \n
    "; + + var html$26 = "
    \n
    \n
    {text}
    \n\n
    \n
    \n
    #{full_date_of_release}
    \n
    {relise}
    \n
    \n\n
    \n
    #{full_budget}
    \n
    {budget}
    \n
    \n\n
    \n
    #{full_countries}
    \n
    {countries}
    \n
    \n
    \n\n
    \n
    \n\n \n
    "; + + var html$25 = "
    \n
    \n \n
    \n\n
    \n
    {name}
    \n
    {role}
    \n
    \n
    "; + + var html$24 = "
    \n
    {text}
    \n\n
    #{full_like}: {like_count}
    \n
    "; + + var html$23 = "
    \n
    \n \n
    \n\n
    \n
    {num}
    \n
    {name}
    \n
    {date}
    \n
    \n
    "; + + var html$22 = "
    \n \n
    "; + + var html$21 = "
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n \n \n \n
    \n
    001
    \n
    \n \n \n \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n \n
    #{player_playlist}
    \n
    \n
    \n \n
    #{torrent_error_next}
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    auto
    \n
    \n
    \n
    \n \n
    #{player_flow}
    \n
    \n
    \n \n
    #{player_subs}
    \n
    \n
    \n \n
    #{player_tracks}
    \n
    \n
    \n
    \n
    \n \n
    #{title_settings}
    \n
    \n
    \n \n
    #{player_pip}
    \n
    \n
    \n \n
    #{player_volume}
    \n
    \n \n
    \n
    \n
    \n \n
    #{player_size_cover_title}
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$20 = "
    \n
    \n
    \n
    \n
    \n \n \n \n \n
    \n
    \n \u25C0\u25C0\u25C0\n
    \n
    \n \u25B6\u25B6\u25B6\n
    \n
    \n
    \n
    \n
    "; + + var html$1$ = "
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n #{loading}...\n
    \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n
    \n\n
    \n
    \n
    "; + + var html$1_ = "
    \n \n
    "; + + var html$1Z = ""; + + var html$1Y = "
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$1X = "
    \n
    {title}
    \n
    {subtitle}
    \n
    "; + + var html$1W = "
    \n
    {icon}
    \n
    \n
    {title}
    \n
    {subtitle}
    \n
    \n
    "; + + var html$1V = "
    \n
    \n
    \n
    \n
    \n \n \n \n \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$1U = "
    \n
    \n \n
    \n
    \n
    \n #{filter_sorted}
    \n
    \n\n
    \n #{filter_filtred}
    \n
    \n
    "; + + var html$1T = "
    \n
    \n
    \n #{more}\n
    \n
    \n
    "; + + var html$1S = "
    \n
    #{search_input}...
    \n
    \n
    \n
    \n
    \n
    "; + + var html$1R = "
    \n
    \n
    \n\n
    \n\n
    #{settings_input_links}
    \n
    \n
    "; + + var html$1Q = "
    \n
    \n
    \n
    {title}
    \n
    \n
    \n \n
    \n
    \n
    "; + + var html$1P = "
    \n
    \n
    \n \n
    \n
    \n\n
    \n
    {name}
    \n
    {place}
    \n
    \n
    "; + + var html$1O = "
    \n \n
    "; + + var html$1N = "
    \n
    \n
    {text}
    \n
    "; + + var html$1M = "
    \n
    \n \n
    \n
    {qr_text}
    \n
    \n\n
    \n
    {title}
    \n
    {text}
    \n
    \n
    "; + + var html$1L = "
    \n\n
    \n
    \n
    \n \n
    \n
    \n\n
    \n
    \n
    \n
    {birthday}
    \n
    \n
    \n \n
    {name}
    \n
    {place}
    \n\n
    \n
    \n \n \n \n
    \n\n
    \n \n \n \n \n \n
    \n
    \n
    \n
    \n
    "; + + var html$1K = "
    \n
    \n
    \n
    {title}
    \n
    {descr}
    \n
    "; + + var html$1J = "
    \n
    {title}
    \n
    {text}
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$1I = "
    \n
    \n
    {title}
    \n
    {time}
    \n
    \n \n
    {descr}
    \n
    "; + + var html$1H = "
    \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    {title}
    \n
    {time}
    \n
    \n \n
    {descr}
    \n
    \n
    "; + + var html$1G = "
    \n
    {title}
    \n
    \n
    \n
    {date}
    \n
    {tracker}
    \n\n
    #{torrent_item_bitrate}: {bitrate} #{torrent_item_mb}
    \n
    #{torrent_item_seeds}: {seeds}
    \n
    #{torrent_item_grabs}: {grabs}
    \n \n
    {size}
    \n
    \n
    "; + + var html$1F = "
    \n
    {title}.{exe}
    \n
    {size}
    \n
    "; + + var html$1E = "
    \n
    \n
    \n \n
    \n\n
    \n
    {title}
    \n
    {original_title}
    \n
    \n
    \n
    \n \n
    \n
    "; + + var html$1D = "
    \n
    #{about_text}
    \n\n\n
    \n
    \n
    \n #{about_channel}
    \n @lampa_channel\n
    \n\n
    \n #{about_group}
    \n @lampa_group\n
    \n\n
    \n #{about_version}
    \n \n
    \n\n
    \n #{about_version} Android APK
    \n \n
    \n\n
    \n Hash
    \n 25ee3b0d1c845b4c71b87e7f3af98637\n
    \n\n
    \n Builded
    \n 2026-10-04 19:56\n
    \n
    \n
    \n\n
    \n

    #{termsofuse_t_01}

    \n\n

    #{termsofuse_t_02}

    \n\n
      \n
    1. \n
      #{termsofuse_t_03}
      \n\n
        \n
      1. #{termsofuse_t_04}

      2. \n\n
      3. #{termsofuse_t_05}

      4. \n\n
      5. #{termsofuse_t_06}

      6. \n\n
      7. #{termsofuse_t_07}

      8. \n
      \n \n
    2. \n\n
    3. \n
      #{termsofuse_t_08}
      \n\n
        \n
      1. #{termsofuse_t_09}

      2. \n
      3. #{termsofuse_t_10}

      4. \n
      \n
    4. \n\n
    5. \n
      #{termsofuse_t_11}
      \n\n
        \n
      1. #{termsofuse_t_12}

      2. \n
      3. #{termsofuse_t_13}

      4. \n
      \n
    6. \n
    \n
    \n
    "; + + var html$1C = "
    \n
    \n
    \n
    {title}
    \n
    {text}
    \n
    \n
    "; + + var html$1B = "
    \n
    \n \"\"\n
    \n
    \n
    \n
    \n
    {title}
    \n
    {time}
    \n
    \n\n
    \n\n
    \n
    {info}
    \n
    {quality}
    \n
    \n
    \n
    "; + + var html$1A = "
    \n \n {rate}\n
    "; + + var html$1z = "
    \n
    {name}
    \n
    {head}
    \n
    {overview}
    \n
    "; + + var html$1y = "
    \n
    \n
    \n
    {title}
    \n
    {text}
    \n
    \n
    \n\n
    \n
    \n
    \u041F\u0440\u0438\u0447\u0438\u043D\u044B
    \n
      \n
    • \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0441\u044F \u0430\u0434\u0440\u0435\u0441: {ip}
    • \n
    • \u0422\u0435\u043A\u0443\u0449\u0438\u0439 \u0430\u0434\u0440\u0435\u0441 {ip} \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u043D\u0435\u0432\u0435\u0440\u043D\u044B\u043C!
    • \n
    • \u0422\u0435\u043A\u0443\u0449\u0438\u0439 \u043E\u0442\u0432\u0435\u0442: {echo}
    • \n
    \n
    \n\n
    \n
    \u041A\u0430\u043A \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E?
    \n
      \n
    • \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0430\u0434\u0440\u0435\u0441: 192.168.0.\u0445\u0445\u0445:8090
    • \n
    • \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044E Matrix
    • \n
    \n
    \n\n
    \n
    \u041A\u0430\u043A \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C?
    \n
      \n
    • \u041D\u0430 \u044D\u0442\u043E\u043C \u0436\u0435 \u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432\u0435, \u043E\u0442\u043A\u0440\u043E\u0439\u0442\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438 \u0437\u0430\u0439\u0434\u0438\u0442\u0435 \u043F\u043E \u0430\u0434\u0440\u0435\u0441\u0443 {ip}/echo
    • \n
    • \u0415\u0441\u043B\u0438 \u0436\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043D\u0435 \u043E\u0442\u0432\u0435\u0442\u0438\u0442, \u043F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u0437\u0430\u043F\u0443\u0449\u0435\u043D \u043B\u0438 TorrServe, \u0438\u043B\u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0435\u0433\u043E.
    • \n
    • \u0415\u0441\u043B\u0438 \u0436\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043E\u0442\u0432\u0435\u0442\u0438\u043B, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C \u0447\u0442\u043E \u0432 \u043E\u0442\u0432\u0435\u0442\u0435 \u0435\u0441\u0442\u044C \u0441\u0442\u0440\u043E\u043A\u0430 MatriX
    • \n
    \n
    \n
    "; + + var html$1x = "
    \n
    \n
    \n
    {title}
    \n
    {text}
    \n
    \n
    \n\n
    \n
    \n
    \u041F\u0440\u0438\u0447\u0438\u043D\u044B
    \n
      \n
    • \u0417\u0430\u043F\u0440\u043E\u0441 \u043D\u0430 \u043F\u0438\u043D\u0433 \u0432\u0435\u0440\u043D\u0443\u043B \u043D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442
    • \n
    • \u041E\u0442\u0432\u0435\u0442 \u043E\u0442 TorServer: {echo}
    • \n
    \n
    \n\n
    \n
    \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C?
    \n
      \n
    • \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C \u0447\u0442\u043E \u0443 \u0432\u0430\u0441 \u0441\u0442\u043E\u0438\u0442 \u0432\u0435\u0440\u0441\u0438\u044F Matrix
    • \n
    \n
    \n\n
    \n
    \u041A\u0430\u043A \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C?
    \n
      \n
    • \u041E\u0442\u043A\u0440\u043E\u0439\u0442\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438 \u0437\u0430\u0439\u0434\u0438\u0442\u0435 \u043F\u043E \u0430\u0434\u0440\u0435\u0441\u0443 {ip}/echo
    • \n
    • \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C \u0447\u0442\u043E \u0432 \u043E\u0442\u0432\u0435\u0442\u0435 \u0435\u0441\u0442\u044C \u043D\u0430\u043B\u0438\u0447\u0438\u0435 \u043A\u043E\u0434\u0430 MatriX
    • \n
    \n
    \n
    "; + + var html$1w = "
    \n
    \n
    \n
    {title}
    \n
    {text}
    \n
    \n
    \n\n
    \n
    \n
    #{torent_nohash_reasons}
    \n
      \n
    • #{torent_nohash_reason_one}
    • \n
    • #{torent_nohash_reason_two}: {echo}
    • \n
    • #{torent_nohash_reason_three}: {url}
    • \n
    \n
    \n\n
    \n
    #{torent_nohash_do}
    \n
      \n
    • #{torent_nohash_do_one}
    • \n
    • #{torent_nohash_do_two}
    • \n
    • #{torent_nohash_do_three}
    • \n
    \n
    \n\n
    \n
    #{torent_nohash_do}
    \n
      \n
    • #{torent_nohash_do_four}
    • \n
    • #{torent_nohash_do_five}
    • \n
    \n
    \n
    "; + + var html$1v = "
    \n
    \n \n
    \n
    \n
    #{torrent_install_need}
    \n
    #{torrent_install_text}
    \n \n
    #{torrent_install_contact}
    \n\n
    \n
    \n
    LG - Samsung
    \n
    @lampa_group
    \n
    \n
    \n
    \n
    "; + + var html$1u = "
    \n
    #{torrent_error_text}
    \n\n
    \n
    \n
    \n
    \n\n
    \n
    \n
      \n
    • #{torrent_error_step_1}
    • \n
    • #{torrent_error_step_2}
    • \n
    • #{torrent_error_step_3}
    • \n
    • #{torrent_error_step_4}
    • \n
    • #{torrent_error_step_5}
    • \n
    • #{torrent_error_step_6}
    • \n
    \n
    \n\n
    \n
    #{torrent_error_info_1}
    \n
    #{torrent_error_info_2}
    \n
    #{torrent_error_info_3}
    \n
    #{torrent_error_info_4}
    \n
    #{torrent_error_info_5}
    \n
    #{torrent_error_info_6}
    \n
    #{torrent_error_info_7}
    \n
    \n
    \n\n
    \n
    #{torrent_error_start}
    \n
    \n
    "; + + var html$1t = "
    \n \n
    \n
    \n
    {fname}
    \n
    #{torrent_serial_season} - {season}#{torrent_serial_date} - {air_date}
    \n
    \n
    \n
    {size}
    \n
    .{exe}
    \n
    \n
    \n
    \n
    {episode}
    \n
    "; + + var html$1s = "
    \n
    \n
    \n
    "; + + var html$1r = "
    \n
    \n
    \n
    "; + + var html$1q = "\n\n"; + + var html$1p = "\n\n"; + + var html$1o = "\n\n"; + + var html$1n = "\n\n"; + + var html$1m = "\n \n \n \n \n \n \n \n"; + + var html$1l = "\n \n \n \n"; + + var html$1k = "\n\n"; + + var html$1j = "\n\n"; + + var html$1i = "\n\n"; + + var html$1h = "\n\n"; + + var html$1g = "\n\n"; + + var html$1f = "\n\n"; + + var html$1e = "\n\n"; + + var html$1d = "\n\n\n\n\n"; + + var html$1c = "\n\n"; + + var html$1b = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + + var html$1a = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + + var html$19 = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + + var html$18 = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + + var html$17 = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + + var html$16 = "\n\n\n\n\n"; + + var html$15 = "\n\n \n \n\n"; + + var html$14 = "
    \n
    \n
    "; + + var html$13 = "\n#{time_viewed} - {time} #{time_from} {duration} / {percent}\n"; + + var html$12 = "
    \n
    #{empty_title}
    \n
    #{empty_text}
    \n
    "; + + var html$11 = "
    \n
    \n \n \n
    \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$10 = "
    \n\n
    \n
    #{plugins_catalog_work}
    \n
    #{plugins_catalog_work_descr}
    \n
    \n \n
    \n
    \n\n
    \n
    #{plugins_catalog_popular}
    \n
    #{plugins_catalog_popular_descr}
    \n
    \n \n
    \n
    \n
    "; + + var html$$ = "
    \n
    {text}
    \n\n
    \n\n
    \n \n
    \n
    "; + + var html$_ = "
    \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$Z = "
    \n
    \n
    "; + + var html$Y = "
    \n
    \n
    {title}
    \n
    \n
    \n
    "; + + var html$X = "
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n \n \n \n
    \n
    \n
    \n
    #{player_disabled}
    \n
    \n
    "; + + var html$W = "
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    #{player_disabled}
    \n
    \n
    \n
    "; + + var html$V = "
    \n
    \n
    \n\n
    \n
    "; + + var html$U = "
    \n
    \n \n
    \n
    \n
    \n
    \n
    "; + + var html$T = "
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$S = "
    \n
    \n \n
    \n
    "; + + var html$R = "
    \n
    \n \n \n \n \n
    \n\n
    \n #{account_create}\n
    \n
    "; + + var html$Q = "
    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    \n\n
    \n #{account_limited}\n
    \n
    "; + + var html$P = "
    \n
    \n \n
    \n
    #{account_qr_create}
    \n
    \n\n
    \n
    #{account_none_title}
    \n
    #{account_create}
    \n
    - #{account_none_include_1}\n
    - #{account_none_include_2}\n
    - #{account_none_include_3}\n
    - #{account_none_include_4}\n
    \n\n
    #{settings_cub_signin_button}
    \n
    \n
    "; + + var html$O = "
    \n
    \n \n
    \n
    #{account_qr_premium}
    \n
    \n\n
    \n
    CUB Premium
    \n
    #{account_premium}
    \n
    - #{account_premium_include_1}\n
    - #{account_premium_include_2}\n
    - #{account_premium_include_4}\n
    \n
    \n
    "; + + var html$N = "
    \n
    CUB Premium
    \n
    \n #{account_premium}\n
    \n
    #{account_premium_more}
    \n
    {site}/premium
    \n
    "; + + var html$M = "
    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n CUB Premium\n
    \n
    \n #{account_premium}\n
    \n
    \n
    \n
    #{account_premium_include_1}#{account_premium_include_text_1}
    \n
    #{filter_rating_from} 360 #{filter_rating_to} 5 040
    \n
    \n
    \n
    #{account_premium_include_2}#{account_premium_include_text_2}
    \n
    #{filter_rating_from} 100 #{filter_rating_to} 500
    \n
    \n
    \n
    #{account_premium_include_3}#{account_premium_include_text_3}
    \n
    #{filter_rating_from} 1 000 #{filter_rating_to} 10 000
    \n
    \n
    \n
    #{account_premium_include_4}#{account_premium_include_text_4}
    \n
    #{filter_rating_from} 3 #{filter_rating_to} 8
    \n
    \n
    \n
    #{account_premium_include_5}#{account_premium_include_text_5}
    \n
    \n
    \n
    \n
    #{account_premium_include_6}#{account_premium_include_text_6}
    \n
    \n
    \n
    \n
    #{account_premium_more}
    \n
    {site}/premium
    \n
    "; + + var html$L = "
    \n
    \n
    \n
    \n
    \n
    \n
    \n \"\"\n
    \n
    \n
    \n
    \n
    \n \n \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n
    "; + + var html$K = "
    \n \n \n \n \n \n \n
    "; + + var html$J = "
    \n
    \n \n \n \n \n \n \n \n \n \n
    \n
    \n #{https_text}\n
    \n
    "; + + var html$I = "
    \n
    \n
    \n
    \n \n
    \n
    #{back}
    \n
    \n\n
    \n
    \n \n
    \n
    #{title_main}
    \n
    \n\n
    \n
    \n \n
    \n
    #{search}
    \n
    \n\n
    \n
    \n \n
    \n
    #{menu_settings}
    \n
    \n
    \n
    "; + + var html$H = "
    \n
    \n \n
    \n
    {title}
    \n
    "; + + var html$G = "
    \n \n\n
    \n #{account_code_where}\n
    \n\n
    #{account_code_input}
    \n
    "; + + var html$F = "
    \n
    \n \n
    \n
    #{account_qr_code}
    \n
    \n\n
    \n
    #{account_add_device_title}
    \n
    #{account_add_device_text}
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    "; + + var html$E = "
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n\n
    \n
    \n \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$D = "
    \n
    \n \n
    \n\n
    \n
    \n
    \n
    \n
    "; + + var html$C = "
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n\n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    "; + + var html$B = "
    \n
    \n
    \n
    "; + + var html$A = "
    \n
    \n \n \n \n \n \n \n \n \n\n \n 0\n \n \n 5\n \n \n 10\n \n \n 15\n \n \n 20\n \n \n 30\n \n \n 60\n \n \n 100\n \n \n 200\n \n \n 500\n \n \n 0.000\n Mbps\n \n \n\n \n \n \n
    \n
    "; + + var html$z = "
    \n
    \n\n \n\n
    \n\n
    \n \n \n \n \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n\n
    \n\n
    \n
    "; + + var html$y = "
    \n
    \n
    \n #{discuss_rules_title}\n
    \n\n
    \n
    #{discuss_rules_rule_1}
    \n
    #{discuss_rules_rule_2}
    \n
    #{discuss_rules_rule_3}
    \n
    #{discuss_rules_rule_4}
    \n
    #{discuss_rules_rule_5}
    \n
    #{discuss_rules_rule_6}
    \n
    #{discuss_rules_rule_7}
    \n
    \n
    \n
    "; + + var html$x = "
    \n
    \n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    "; + + var html$w = "
    \n
    {icon}
    \n
    \n \n \n \n \n
    \n
    "; + + var html$v = "
    \n
    \n
    \n \n
    \n
    "; + + var html$u = "
    \n
    #{install_extension_rule_2}
    \n\n

    #{install_extension_rule_3}

    \n\n

    #{install_extension_rule_4}

    \n\n

    #{install_extension_rule_5}

    \n\n

    #{install_extension_rule_7}

    \n
    "; + + var html$t = "
    \n
    \n
    {text}
    \n
    \n
    \n \n \n \n \n \n \n \n \n \n \n
    \n
    "; + + var html$s = "
    \n
    \n \n
    \n
    \n \n
    \n
    "; + + var html$r = "\n\n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n\n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n"; + + var html$q = "
    \n
    {icon}
    \n
    \n
    {title}
    \n
    {text}
    \n
    \n
    \n
    "; + + var templates = { + head: html$2t, + wrap: html$2s, + menu: html$2r, + activitys: html$2q, + activity: html$2p, + activity_wait_refresh: html$2o, + settings: html$2m, + settings_main: html$2l, + settings_interface: html$2k, + settings_parser: html$2j, + settings_server: html$2i, + settings_player: html$2h, + settings_more: html$2g, + settings_tmdb: html$2f, + settings_plugins: html$2e, + settings_account: html$2d, + scroll: html$2n, + items_line: html$2c, + card: html$2b, + card_parser: html$2a, + card_watched: html$29, + card_episode: html$28, + full_start_new: html$27, + full_descr: html$26, + full_person: html$25, + full_review: html$24, + full_episode: html$23, + player: html$22, + player_panel: html$21, + player_video: html$20, + player_info: html$1$, + player_footer: html$1_, + player_footer_card: html$1Z, + selectbox: html$1Y, + selectbox_item: html$1X, + info: html$1V, + more: html$1T, + search: html$1S, + settings_input: html$1R, + modal: html$1Q, + company: html$1P, + modal_loading: html$1O, + modal_pending: html$1N, + modal_qr: html$1M, + person_start: html$1L, + empty: html$1K, + empty_filter: html$1J, + notice: html$1I, + notice_card: html$1H, + torrent: html$1G, + torrent_file: html$1F, + files: html$1E, + about: html$1D, + error: html$1C, + torrent_noconnect: html$1y, + torrent_file_serial: html$1t, + torrent_nocheck: html$1x, + torrent_nohash: html$1w, + torrent_install: html$1v, + torrent_error: html$1u, + filter: html$1U, + search_box: html$1s, + console: html$1r, + icon_star: html$1q, + icon_viewed: html$1p, + icon_lock: html$1o, + icon_like: html$1n, + icon_text: html$1m, + icon_card: html$1l, + icon_top: html$1k, + icon_fire: html$1j, + icon_hd: html$1i, + icon_collection: html$1h, + icon_search: html$1g, + icon_settings: html$1f, + icon_bell: html$1e, + icon_bell_plus: html$1d, + icon_broadcast: html$1c, + icon_create_account: html$1b, + icon_empty_subscribe: html$1a, + icon_empty_bookmarks: html$19, + icon_empty_history: html$18, + icon_empty_torrents: html$17, + icon_profile: html$16, + icon_back: html$15, + timeline: html$14, + timeline_details: html$13, + list_empty: html$12, + screensaver: html$11, + plugins_catalog: html$10, + broadcast: html$$, + lang_choice: html$_, + extensions: html$Z, + extensions_block: html$Y, + extensions_item: html$X, + extensions_recomend: html$W, + extensions_info: html$V, + extensions_theme: html$U, + extensions_screensaver: html$T, + iframe: html$S, + account: html$R, + account_limited: html$Q, + account_none: html$P, + account_premium: html$O, + cub_premium: html$N, + cub_premium_modal: html$M, + selectbox_icon: html$1W, + explorer: html$L, + explorer_button_back: html$K, + https: html$J, + navigation_bar: html$I, + head_backward: html$H, + account_add_device: html$G, + account_add_device_new: html$F, + feed_item: html$E, + feed_head: html$D, + feed_episode: html$C, + register: html$B, + speedtest: html$A, + season_episode: html$1B, + season_episode_rate: html$1A, + season_info: html$1z, + ad_video_block: html$z, + discuss_rules: html$y, + bookmarks_folder: html$x, + ai_search_animation: html$w, + ai_agent: html$v, + plugins_rules: html$u, + remote_helper: html$t, + watched_history: html$s, + icons_sprite: html$r, + warning: html$q + }; + var created = {}; + /** + * Получить шаблон + * @param {string} name - имя шаблона + * @param {object} [vars] - переменные для подстановки + * @param {boolean} [like_static=false] - вернуть как строку, а не jQuery объект + * @returns {jQuery|string} - jQuery объект или строка + */ + + function get$g(name) { + var vars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var like_static = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var tpl = templates[name]; + if (!tpl) throw 'Template [' + name + '] not found'; + tpl = Lang.translate(tpl); + + for (var n in vars) { + tpl = tpl.replace(new RegExp('{' + n + '}', 'g'), vars[n]); + } + + tpl = tpl.replace(/{\@([a-z_-]+)}/g, function (e, s) { + return templates[s] || ''; + }); + return like_static ? tpl : $(tpl); + } + /** + * Получить шаблон как DOM элемент с возможностью подстановки переменных и вложенных DOM элементов + * @param {string} name - имя шаблона + * @param {object} [vars] - переменные для подстановки. Если значение - DOM элемент, он будет вставлен в шаблон + * @returns {HTMLElement} - DOM элемент + */ + + + function js(name) { + var vars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (!created[name]) { + // создаём чистый шаблон без переменных + var raw = get$g(name, {}, false)[0]; + created[name] = raw.cloneNode(true); // кэшируем "чистый" DOM + } // клонируем кэш + + + var cloned = created[name].cloneNode(true); // подставим значения + + if (vars && Object.keys(vars).length > 0) { + replaceVars(cloned, vars); + } + + return cloned; + } + + function getValueFromPath(obj, path) { + return path.split('.').reduce(function (acc, key) { + return acc && acc[key] != null ? acc[key] : ''; + }, obj); + } + + function replaceVars(root, vars) { + var varRegex = /\{\{([a-zA-Z0-9_.]+)\}\}|\{([a-zA-Z0-9_]+)\}/g; + + function processNode(node) { + // Если это текстовый узел и в нём есть подстановки + if (node.nodeType === Node.TEXT_NODE) { + var text = node.textContent; + var matches = []; + var m; // эквивалент [...text.matchAll(varRegex)] + + while ((m = varRegex.exec(text)) !== null) { + matches.push(m); + } + + if (matches.length > 0) { + var parent = node.parentNode; // создаём новый документ-фрагмент для вставки + + var fragment = document.createDocumentFragment(); + var lastIndex = 0; + + var _iterator = _createForOfIteratorHelper(matches), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var match = _step.value; + var index = match.index; + var raw = match[0]; + var key = match[1] || match[2]; + var value = getValueFromPath(vars, key); // Добавляем текст до переменной + + if (index > lastIndex) { + fragment.appendChild(document.createTextNode(text.slice(lastIndex, index))); + } // Вставляем значение + + + if (value instanceof Node) { + fragment.appendChild(value.cloneNode(true)); // вставляем DOM + } else { + fragment.appendChild(document.createTextNode(String(value))); + } + + lastIndex = index + raw.length; + } // Добавляем оставшийся текст + + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + if (lastIndex < text.length) { + fragment.appendChild(document.createTextNode(text.slice(lastIndex))); + } // заменяем оригинальный текстовый узел + + + parent.replaceChild(fragment, node); + return; // больше не обрабатывать + } + } // Если есть атрибуты — заменим только строки + // Не работает на старых браузерах, и не помню что оно делает + // if (node.attributes) { + // for (let attr of node.attributes) { + // attr.value = attr.value.replace(varRegex, (_, nested, flat) => { + // const key = nested || flat; + // const value = getValueFromPath(vars, key); + // return value instanceof Node ? '' : String(value); + // }); + // } + // } + // Рекурсивно обрабатываем детей + + + for (var _i = 0, _Array$from = Array.from(node.childNodes); _i < _Array$from.length; _i++) { + var child = _Array$from[_i]; + processNode(child); + } + } + + processNode(root); + } + /** + * Найти элементы по префиксу класса + * @param {HTMLElement|jQuery} root - корневой элемент для поиска + * @param {string} pref - префикс класса + * @return {object} - объект с найденными элементами, ключи - части классов после префикса + */ + + + function prefix(root, pref) { + var result = {}; // поддержка и для jQuery, и для обычного DOM + + var base = root instanceof jQuery ? root[0] : root; + Array.from(base.querySelectorAll("[class*=\"".concat(pref, "__\"]"))).forEach(function (elem) { + Array.from(elem.classList).forEach(function (cls) { + if (cls.indexOf(pref + '__') === 0) { + var key = cls.slice(pref.length + 2); // удалить pref__ + + result[key] = elem; + } + }); + }); + return result; + } + /** + * Создать DOM элемент с возможностью добавления классов, атрибутов, текста, HTML и детей + * @param {string} tag - имя тега + * @param {object} [options] - опции для создания элемента + * @param {string|string[]} [options.class] - класс или массив классов + * @param {object} [options.attrs] - атрибуты в формате {имя: значение} + * @param {string} [options.text] - текстовое содержимое + * @param {string} [options.html] - HTML содержимое + * @param {HTMLElement|jQuery|Array} [options.children] - дочерний элемент, jQuery объект или массив из них + * @returns {HTMLElement} - созданный DOM элемент + */ + + + function elem$1(tag) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var element = document.createElement(tag); // Добавляем классы + + if (options["class"]) { + element.addClass(options["class"]); + } // Добавляем атрибуты + + + if (options.attrs) { + for (var _i2 = 0, _Object$entries = Object.entries(options.attrs); _i2 < _Object$entries.length; _i2++) { + var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2), + key = _Object$entries$_i[0], + value = _Object$entries$_i[1]; + + element.setAttribute(key, value); + } + } // Текст + + + if (options.text) { + element.textContent = options.text; + } // HTML + + + if (options.html) { + element.innerHTML = options.html; + } // Дети + + + if (options.children) { + var children = Array.isArray(options.children) ? options.children : [options.children]; + + var _iterator2 = _createForOfIteratorHelper(children), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var child = _step2.value; + element.appendChild(child); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } + + return element; + } + /** + * Добавить или обновить шаблон + * @param {string} name - имя шаблона + * @param {string} html - HTML шаблона + * @returns {void} + */ + + + function add$h(name, html) { + delete created[name]; + templates[name] = html; + } + /** + * Получить все шаблоны + * @returns {object} - объект со всеми шаблонами + */ + + + function all$5() { + return templates; + } + /** + * Получить строковое представление шаблона + * @param {string} name - имя шаблона + * @returns {string} - HTML шаблона + */ + + + function string(name) { + return templates[name] || ''; + } + + var Template = { + get: get$g, + js: js, + add: add$h, + all: all$5, + string: string, + prefix: prefix, + elem: elem$1 + }; + + var Base64 = { + // private property + _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + // public method for encoding + encode: function encode(input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + input = Base64._utf8_encode(input); + + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = (chr1 & 3) << 4 | chr2 >> 4; + enc3 = (chr2 & 15) << 2 | chr3 >> 6; + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); + } + + return output; + }, + // public method for decoding + decode: function decode(input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + chr1 = enc1 << 2 | enc2 >> 4; + chr2 = (enc2 & 15) << 4 | enc3 >> 2; + chr3 = (enc3 & 3) << 6 | enc4; + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + } + + output = Base64._utf8_decode(output); + return output; + }, + // private method for UTF-8 encoding + _utf8_encode: function _utf8_encode(string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } else if (c > 127 && c < 2048) { + utftext += String.fromCharCode(c >> 6 | 192); + utftext += String.fromCharCode(c & 63 | 128); + } else { + utftext += String.fromCharCode(c >> 12 | 224); + utftext += String.fromCharCode(c >> 6 & 63 | 128); + utftext += String.fromCharCode(c & 63 | 128); + } + } + + return utftext; + }, + // private method for UTF-8 decoding + _utf8_decode: function _utf8_decode(utftext) { + var string = ""; + var i = 0; + var c = 0; + var c2 = 0; + var c3 = 0; + + while (i < utftext.length) { + c = utftext.charCodeAt(i); + + if (c < 128) { + string += String.fromCharCode(c); + i++; + } else if (c > 191 && c < 224) { + c2 = utftext.charCodeAt(i + 1); + string += String.fromCharCode((c & 31) << 6 | c2 & 63); + i += 2; + } else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode((c & 15) << 12 | (c2 & 63) << 6 | c3 & 63); + i += 3; + } + } + + return string; + } + }; + + var html$p = $('
    '), + body$2 = html$p.find('.noty__text'), + time$4; + /** + * Отображает уведомление + * @param {string} text - текст уведомления + * @param {Object} [params] - дополнительные параметры + * @param {string} [params.style] - стиль уведомления, например 'error', 'success' и т.д. + * @param {number} [params.time=3000] - время отображения уведомления в миллисекундах + * @returns {void} + */ + + function show$f(text) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + clearTimeout(time$4); + html$p.attr('class', 'noty'); + if (params.style) html$p.addClass('noty--style--' + params.style); + time$4 = setTimeout(function () { + html$p.removeClass('noty--visible'); + }, params.time || 3000); + body$2.html(text); + html$p.addClass('noty--visible'); + } + + function render$n() { + return html$p; + } + + var Noty = { + show: show$f, + render: render$n + }; + + var widgetAPI, + tvKey, + pluginAPI, + loader$2, + orsay_loaded, + orsay_call = Date.now(); + + function init$1q() { + $('body').append($("
    \n \n \n \n
    ")); + Utils$1.putScript(['$MANAGER_WIDGET/Common/API/Widget.js', '$MANAGER_WIDGET/Common/API/TVKeyValue.js', '$MANAGER_WIDGET/Common/API/Plugin.js', '$MANAGER_WIDGET/Common/webapi/1.0/webapis.js', '$MANAGER_WIDGET/Common/IME_XT9/ime.js', '$MANAGER_WIDGET/Common/IME_XT9/inputCommon/ime_input.js'], function () { + try { + if (typeof Common !== 'undefined' && Common.API && Common.API.TVKeyValue && Common.API.Plugin && Common.API.Widget) { + widgetAPI = new Common.API.Widget(); + tvKey = new Common.API.TVKeyValue(); + pluginAPI = new Common.API.Plugin(); + window.onShow = orsayOnshow; + setTimeout(function () { + orsayOnshow(); + }, 2000); + widgetAPI.sendReadyEvent(); + } else { + if (orsay_call + 5 * 1000 > Date.now()) setTimeout(orsayOnLoad, 50); + } + } catch (e) {} + }); + /** + * Скрывает ненужные параметры для плеера + */ + + if (Platform.is('orsay')) { + var hidePlayerParams = function hidePlayerParams() { + $('[data-name="player_normalization"],[data-name="player_scale_method"],[data-name="player_hls_method"]').toggleClass('hide', Lampa.Storage.field('player') == 'orsay'); + }; + /* Подписываемся на открытие настроек плера*/ + + + Lampa.Settings.listener.follow('open', function (e) { + if (e.name == 'player') hidePlayerParams(); + }); + /* Подписываемся на изменение плера*/ + + Lampa.Storage.listener.follow('change', function (e) { + if (e.name == 'player') hidePlayerParams(); + }); + } + } + + function orsayOnshow() { + if (orsay_loaded) return; + orsay_loaded = true; + + try { + //Включает анимацию изменения громкости на ТВ и т.д. + pluginAPI.SetBannerState(1); //Отключает перехват кнопок, этими кнопками управляет система ТВ + + pluginAPI.unregistKey(tvKey.KEY_INFO); + pluginAPI.unregistKey(tvKey.KEY_TOOLS); + pluginAPI.unregistKey(tvKey.KEY_MENU); + pluginAPI.unregistKey(tvKey.KEY_VOL_UP); + pluginAPI.unregistKey(tvKey.KEY_VOL_DOWN); + pluginAPI.unregistKey(tvKey.KEY_MUTE); // Отключаем заставку ТВ + + pluginAPI.setOffScreenSaver(); + console.log('App', 'Version widget ', Platform.version('orsay')); + } catch (e) {} + } + + function isNewWidget() { + if (typeof window.top.WidgetLoader != 'undefined') { + loader$2 = window.top.WidgetLoader; + return true; + } else { + return false; + } + } + + function getLoaderUrl() { + if (isNewWidget()) { + return loader$2.getUrl(); + } + } + + function setLoaderUrl(_url) { + if (isNewWidget()) { + return loader$2.setUrl(_url); + } + } + + function changeLoaderUrl() { + if (isNewWidget()) { + return loader$2.changeUrl(); + } + } + + function exit$1() { + if (widgetAPI) widgetAPI.sendReturnEvent(); + } + + var Orsay = { + init: init$1q, + isNewWidget: isNewWidget, + getLoaderUrl: getLoaderUrl, + setLoaderUrl: setLoaderUrl, + changeLoaderUrl: changeLoaderUrl, + exit: exit$1 + }; + + var sounds = {}; + + function Sound(option) { + this.option = option; + this.loaded = false; + this.audio = new Audio(); + this.audio.src = option.url; + this.audio.volume = option.volume || 1; + this.audio.load(); + var volume = option.volume || 1; + var isplay = false; + this.audio.addEventListener("playing", function (event) { + isplay = true; + }); + this.audio.addEventListener("pause", function (event) { + isplay = false; + }); + + this.play = function () { + this.stop(); + var playPromise; + + try { + this.audio.currentTime = 0; + this.audio.volume = volume * (Lampa.Storage.field('interface_sound_level') / 100); + playPromise = this.audio.play(); + } catch (e) {} + + if (playPromise !== undefined) { + playPromise.then(function () {})["catch"](function (e) { + console.log('Sound', 'play promise error:', e.message); + }); + } + + return this; + }; + + this.stop = function () { + if (!isplay) return this; + var stopPromise; + + try { + stopPromise = this.audio.pause(); + } catch (e) {} + + if (stopPromise !== undefined) { + stopPromise.then(function () {})["catch"](function (e) { + console.log('Sound', 'stop promise error:', e.message); + }); + } + + return this; + }; + + return this; + } + + function init$1p() { + if (Platform.is('android') || Platform.is('browser') || Platform.is('apple_tv') || Platform.desktop()) { + add$g('hover', { + url: object$2.github_lampa + 'sound/hover.ogg' + }); + add$g('enter', { + url: object$2.github_lampa + 'sound/hover.ogg' + }); + add$g('bell', { + url: object$2.github_lampa + 'sound/bell.ogg' + }); + } + } + + function play$4(name) { + if (sounds[name] && Storage.field('interface_sound_play')) sounds[name].play(); + } + + function add$g(name, params) { + try { + sounds[name] = new Sound(params); + return sounds[name]; + } catch (e) { + return false; + } + } + + var Sound$1 = { + init: init$1p, + add: add$g, + play: play$4 + }; + + var philipse = { + play: typeof VK_PLAY !== 'undefined' ? VK_PLAY : typeof KEYCODE_MEDIA_PLAY !== 'undefined' ? KEYCODE_MEDIA_PLAY : -1, + stop: typeof VK_STOP !== 'undefined' ? VK_STOP : typeof KEYCODE_MEDIA_STOP !== 'undefined' ? KEYCODE_MEDIA_STOP : -1, + pause: typeof VK_PAUSE !== 'undefined' ? VK_PAUSE : typeof KEYCODE_MEDIA_PAUSE !== 'undefined' ? KEYCODE_MEDIA_PAUSE : -1, + play_pause: typeof VK_PLAY_PAUSE !== 'undefined' ? VK_PLAY_PAUSE : typeof KEYCODE_MEDIA_PLAY_PAUSE !== 'undefined' ? KEYCODE_MEDIA_PLAY_PAUSE : -1 + }; + var enabled$2 = false; + var listener$m = Subscribe$2(); + var time$3 = 0; + var lastdown = 0; + var timer$9; + var longpress; + + function toggle$d(new_status) { + enabled$2 = new_status; + listener$m.send('toggle', { + status: enabled$2 + }); + } + + function enable$1() { + toggle$d(true); + } + + function disable() { + toggle$d(false); + } + + function isEnter(keycode) { + return keycode == 13 || keycode == 29443 || keycode == 117 || keycode == 65385; + } + + function keyCode(e) { + var keycode; + + if (window.event) { + keycode = e.keyCode; + } else if (e.which) { + keycode = e.which; + } + + return keycode; + } + + function keydownTrigger(e) { + var keycode = keyCode(e); + if (time$3 > Date.now() - 100) return; + time$3 = Date.now(); + listener$m.send('keydown', { + code: keycode, + enabled: enabled$2, + event: e + }); + if (e.defaultPrevented) return; + if (isEnter(keycode)) return; + if (!enabled$2) return; //отключить все + //4 - Samsung orsay + + if (keycode == 37 || keycode == 4) { + Sound$1.play('hover'); + listener$m.send('left', { + code: keycode, + enabled: enabled$2, + event: e + }); + Controller.move('left'); + } //29460 - Samsung orsay + + + if (keycode == 38 || keycode == 29460) { + Sound$1.play('hover'); + listener$m.send('up', { + code: keycode, + enabled: enabled$2, + event: e + }); + Controller.move('up'); + } //5 - Samsung orsay + + + if (keycode == 39 || keycode == 5) { + Sound$1.play('hover'); + listener$m.send('right', { + code: keycode, + enabled: enabled$2, + event: e + }); + Controller.move('right'); + } //5 - Samsung orsay + //29461 - Samsung orsay + + + if (keycode == 40 || keycode == 29461) { + Sound$1.play('hover'); + listener$m.send('down', { + code: keycode, + enabled: enabled$2, + event: e + }); + Controller.move('down'); + } //33 - LG; 427 - Samsung + + + if (keycode == 33 || keycode == 427) { + Sound$1.play('hover'); + listener$m.send('toup', { + code: keycode, + enabled: enabled$2, + event: e + }); + Controller.move('toup'); + } //34 - LG; 428 - Samsung + + + if (keycode == 34 || keycode == 428) { + Sound$1.play('hover'); + listener$m.send('todown', { + code: keycode, + enabled: enabled$2, + event: e + }); + Controller.move('todown'); + } //Абсолютный Enter + //10252 - Samsung tizen + + + if (keycode == 32 || keycode == 179 || keycode == 10252 || keycode == philipse.play_pause) { + Controller.trigger('playpause'); + } //Samsung media + //71 - Samsung orsay + + + if (keycode == 415 || keycode == 71 || keycode == philipse.play) { + Controller.trigger('play'); + } //Samsung stop + //70 - Samsung orsay + + + if (keycode == 413 || keycode == philipse.stop || keycode == 70) { + Controller.trigger('stop'); + } //69 - Samsung orsay + + + if (keycode == 412 || keycode == 69 || keycode == 177) { + Controller.trigger('rewindBack'); + } //72 - Samsung orsay + + + if (keycode == 418 || keycode == 417 || keycode == 72 || keycode == 176) { + Controller.trigger('rewindForward'); + } //74 - Samsung orsay + + + if (keycode == 19 || keycode == 74 || keycode == philipse.pause) { + Controller.trigger('pause'); + } + + if (keycode == 457) { + Controller.trigger('info'); + } //E-Manual + + + if (keycode == 10146) { + e.preventDefault(); + } + + if (keycode == 10133) { + Controller.toggle('settings'); + } //Кнопка назад + //8 - браузер + //27 + //461 - LG + //10009 - Samsung + //88 - Samsung orsay + + + if (keycode == 8 || keycode == 27 || keycode == 461 || keycode == 10009 || keycode == 88) { + e.preventDefault(); + listener$m.send('back', { + code: keycode, + enabled: enabled$2, + event: e + }); + if (window.appready) Controller.back(); + return false; + } //Exit orsay + + + if (keycode == 45) { + Orsay.exit(); + } //Кнопка pre-ch вызывает окно смены адреса в Loader + //259 - Samsung orsay + + + if (keycode == 259) { + if (Orsay.isNewWidget()) { + Orsay.changeLoaderUrl(); + } + } + + if (!(keycode == 122 || keycode == 123)) e.preventDefault(); + } + + function init$1o() { + window.addEventListener("keydown", function (e) { + lastdown = keyCode(e); + + if (!timer$9) { + timer$9 = setTimeout(function () { + if (isEnter(lastdown)) { + longpress = true; + listener$m.send('longdown', { + code: lastdown, + enabled: enabled$2, + event: e + }); + Controller["long"](); + } + }, 800); + } + }); + window.addEventListener("keyup", function (e) { + clearTimeout(timer$9); + time$3 = 0; + timer$9 = null; + listener$m.send('keyup', { + code: keyCode(e), + enabled: enabled$2, + event: e + }); + + if (!longpress) { + if (isEnter(keyCode(e)) && !e.defaultPrevented) { + Sound$1.play('enter'); + listener$m.send('enter', { + code: keyCode(e), + enabled: enabled$2, + event: e + }); + Controller.enter(); + } + } else longpress = false; + }); + window.addEventListener("keydown", keydownTrigger); + } + + var Keypad = { + listener: listener$m, + init: init$1o, + enable: enable$1, + disable: disable + }; + + var timers$2 = []; + var paused$1 = false; + + function init$1n() { + setInterval(function () { + var now = Date.now(); + timers$2.forEach(function (t) { + if (paused$1 && !t.background) return; + + if (now - t.last >= t.interval) { + t.last = now; + + try { + t.call(); + } catch (e) { + console.error('Timer', 'call error:', e); + } + } + }); + }, 1000); + document.addEventListener('visibilitychange', function () { + paused$1 = document.visibilityState !== 'visible'; + console.log('Timer', 'visibility change:', document.visibilityState, 'paused:', paused$1); + update$h(); + }); // Разблокировка по клику или нажатию клавиши + + document.addEventListener('click', unpaused); + Keypad.listener.follow('keydown', unpaused); + } + /** + * Добавить таймер + * @param {integer} interval - интервал в миллисекундах + * @param {boolean} immediate - если true, то таймер будет вызван сразу при добавлении + * @param {boolean} background - если true, то таймер будет работать в фоне, даже если вкладка не активна + * @param {function} call - функция для вызова + * @returns {void} + */ + + + function add$f(interval, call) { + var immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var background = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + timers$2.push({ + interval: interval, + call: call, + last: Date.now(), + immediate: immediate, + background: background + }); + } + /** + * Обновить таймеры + * @returns {void} + */ + + + function update$h() { + // Обновить метки времени, чтобы таймеры не "догоняли" + timers$2.forEach(function (t) { + return t.last = Date.now(); + }); // Вызвать отложенные таймеры + + if (!paused$1) timers$2.forEach(function (t) { + return t.immediate && t.call(); + }); + } + /** + * Разблокировать таймеры + * @returns {void} + */ + + + function unpaused() { + if (paused$1) { + paused$1 = false; + console.log('Timer', 'unpaused by action'); + update$h(); + } + } + /** + * Удалить таймер + * @param {function} call - функция для вызова + * @returns {void} + */ + + + function remove$6(call) { + timers$2 = timers$2.filter(function (t) { + return t.call !== call; + }); + } + + var Timer = { + init: init$1n, + add: add$f, + remove: remove$6, + update: update$h + }; + + var card_fields = ['poster_path', 'overview', 'release_date', 'genre_ids', 'id', 'original_title', 'original_language', 'title', 'backdrop_path', 'popularity', 'vote_count', 'vote_average', 'imdb_id', 'kinopoisk_id', 'original_name', 'name', 'first_air_date', 'origin_country', 'status', 'pg', 'release_quality', 'imdb_rating', 'kp_rating', 'source', 'number_of_seasons', 'number_of_episodes', 'next_episode_to_air', 'img', 'poster', 'background_image']; + /** + * Преобразование секунд в формат времени + * @doc + * @name secondsToTime + * @alias Utils + * @param {integer} sec время в секундах + * @param {boolean} short короткое время + * @returns {string} (hours : minutes : seconds) или (minutes : seconds) + */ + + function secondsToTime(sec, _short) { + var sec_num = parseInt(sec, 10); + var hours = Math.floor(sec_num / 3600); + var minutes = Math.floor((sec_num - hours * 3600) / 60); + var seconds = sec_num - hours * 3600 - minutes * 60; + + if (hours < 10) { + hours = "0" + hours; + } + + if (minutes < 10) { + minutes = "0" + minutes; + } + + if (seconds < 10) { + seconds = "0" + seconds; + } + + if (isNaN(hours)) hours = '00'; + if (isNaN(minutes)) minutes = '00'; + if (isNaN(seconds)) seconds = '00'; + if (_short) return hours + ':' + minutes; + return hours + ':' + minutes + ':' + seconds; + } + /** + * Преабразует первую букву строки в верхний регистр + * @doc + * @name capitalizeFirstLetter + * @alias Utils + * @param {string} string значение + * @returns {string} + */ + + + function capitalizeFirstLetter(string) { + string = string + ''; + return string.charAt(0).toUpperCase() + string.slice(1); + } + /** + * Сокращает строку до указанной длины + * @doc + * @name substr + * @alias Utils + * @param {string} txt текст + * @param {integer} len длина + * @returns {string} + */ + + + function substr(txt, len) { + txt = txt || ''; + return txt.length > len ? txt.substr(0, len) + '...' : txt; + } + + function numberWithSpaces(x) { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); + } + + function bytesToSize(bytes, speed) { + if (bytes == 0) { + return Lang.translate('size_zero'); + } + + var unitMultiple = 1024; + var unitNames = [Lang.translate('size_byte'), Lang.translate('size_kb'), Lang.translate('size_mb'), Lang.translate('size_gb'), Lang.translate('size_tb'), Lang.translate('size_pp')]; + + if (speed) { + unitMultiple = 1000; + unitNames = [Lang.translate('speed_bit'), Lang.translate('speed_kb'), Lang.translate('speed_mb'), Lang.translate('speed_gb'), Lang.translate('speed_tb'), Lang.translate('speed_pp')]; + } + + var unitChanges = Math.floor(Math.log(bytes) / Math.log(unitMultiple)); + return parseFloat((bytes / Math.pow(unitMultiple, unitChanges)).toFixed(2)) + ' ' + unitNames[unitChanges]; + } + + function sizeToBytes(str) { + var gsize = str.match(/([0-9\\.,]+)\s+(Mb|МБ|GB|ГБ|TB|ТБ)/i); + + if (gsize) { + var size = parseFloat(gsize[1].replace(',', '.')); + if (/gb|гб/.test(gsize[2].toLowerCase())) size *= 1024; + if (/tb|тб/.test(gsize[2].toLowerCase())) size *= 1048576; + return size * 1048576; + } + + return 0; + } + + function calcBitrate(byteSize, minutes) { + if (!minutes) return 0; + var sec = minutes * 60; + var bitSize = byteSize * 8; + return (bitSize / Math.pow(1000, 2) / sec).toFixed(2); + } + + function getMoths(ended) { + var need = ended ? '_e' : ''; + var all = []; + + for (var i = 1; i <= 12; i++) { + all.push(Lang.translate('month_' + i + need)); + } + + return all; + } + + function time$2(html) { + var create = function create() { + var _this = this; + + var where = html instanceof jQuery ? html[0] : html; + var months = getMoths(); + var months_end = getMoths(true); + var days = [Lang.translate('day_7'), Lang.translate('day_1'), Lang.translate('day_2'), Lang.translate('day_3'), Lang.translate('day_4'), Lang.translate('day_5'), Lang.translate('day_6')]; + var elem_clock = where.querySelector('.time--clock'); + var elem_week = where.querySelector('.time--week'); + var elem_day = where.querySelector('.time--day'); + var elem_moth = where.querySelector('.time--moth'); + var elem_full = where.querySelector('.time--full'); + + var listenTimeOffset = function listenTimeOffset(e) { + if (e.name == 'time_offset') _this.tik(); + }; + + Lampa.Storage.listener.follow('change', listenTimeOffset); + + this.tik = function () { + var date = new Date(), + time = date.getTime(), + ofst = parseInt((localStorage.getItem('time_offset') == null ? 'n0' : localStorage.getItem('time_offset')).replace('n', '')); + date = new Date(time + ofst * 1000 * 60 * 60); + time = [date.getHours(), date.getMinutes(), date.getSeconds(), date.getFullYear()]; + + if (time[0] < 10) { + time[0] = "0" + time[0]; + } + + if (time[1] < 10) { + time[1] = "0" + time[1]; + } + + if (time[2] < 10) { + time[2] = "0" + time[2]; + } + + var current_time = [time[0], time[1]].join(':'), + current_week = date.getDay(), + current_day = date.getDate(); + if (elem_clock) elem_clock.innerText = current_time; + if (elem_week) elem_week.innerText = days[current_week]; + if (elem_day) elem_day.innerText = current_day; + if (elem_moth) elem_moth.innerText = months[date.getMonth()]; + if (elem_full) elem_full.innerText = current_day + ' ' + months_end[date.getMonth()] + ' ' + time[3]; + }; + + this.destroy = function () { + Timer.remove(this.tik); + Lampa.Storage.listener.remove('change', listenTimeOffset); + }; + + Timer.add(60000, this.tik, true); + this.tik(); + }; + + return new create(); + } + + function parseToDate(str) { + if (typeof str == 'string') { + str = str.toLowerCase().split('t')[0].replace(/-/g, '/'); + } + + return new Date(str); + } + + function parseTime(str) { + var months = getMoths(); + var months_end = getMoths(true); + var days = [Lang.translate('day_7'), Lang.translate('day_1'), Lang.translate('day_2'), Lang.translate('day_3'), Lang.translate('day_4'), Lang.translate('day_5'), Lang.translate('day_6')]; + var date = parseToDate(str); + var time = [date.getHours(), date.getMinutes(), date.getSeconds(), date.getFullYear()]; + + if (time[0] < 10) { + time[0] = "0" + time[0]; + } + + if (time[1] < 10) { + time[1] = "0" + time[1]; + } + + if (time[2] < 10) { + time[2] = "0" + time[2]; + } + + var current_time = [time[0], time[1]].join(':'), + current_week = date.getDay(), + current_day = date.getDate(); + return { + time: current_time, + time_full: [time[0], time[1], time[2]].join(':'), + week: days[current_week], + day: current_day, + mouth: months[date.getMonth()], + full: current_day + ' ' + months_end[date.getMonth()] + (new Date().getFullYear() == time[3] ? '' : ' ' + time[3]), + "short": current_day + ' ' + months_end[date.getMonth()], + briefly: current_day + ' ' + months_end[date.getMonth()] + ' ' + current_time + }; + } // function secondsToTimeHuman(sec_num) { + // let hours = Math.trunc(sec_num / 3600) + // let minutes = Math.floor((sec_num - hours * 3600) / 60) + // return (hours ? hours + ' '+Lang.translate('time_h')+' ' : '') + (minutes ? minutes + ' '+Lang.translate('time_m')+' ' : Math.round(sec_num) + ' '+Lang.translate('time_s')) + // } + + + function secondsToTimeHuman(sec_num) { + var hours = Math.trunc(sec_num / 3600); + var minutes = Math.trunc(sec_num % 3600 / 60); // Остаток от деления используется для вычисления минут + + var seconds = Math.round(sec_num % 60); // Остаток от деления для секунд + + return (hours ? hours + ' ' + Lang.translate('time_h') + ' ' : '') + (minutes ? minutes + ' ' + Lang.translate('time_m') + ' ' : '') + (hours === 0 && minutes === 0 ? seconds + ' ' + Lang.translate('time_s') : ''); + } + + function strToTime(str) { + var date = new Date(str); + return date.getTime(); + } + + function checkHttp(url, http_only) { + url = url + ''; + if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) return url; + url = (http_only ? 'http://' : protocol()) + url; + return url; + } + + function checkEmptyUrl(url) { + url = url + ''; + if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) return url; + url = (window.location.protocol == 'https:' ? 'https://' : 'http://') + url; + return url; + } + + function rewriteIfHTTPS(u) { + return window.location.protocol == 'https:' ? u.replace(/^(http:\/\/|https:\/\/)/, 'https://') : u; + } + + function fixProtocolLink(u) { + return rewriteIfHTTPS((localStorage.getItem('protocol') || 'https') + '://' + u.replace(/^(http:\/\/|https:\/\/)/, '')); + } + + function fixMirrorLink(u) { + object$2.old_mirrors.forEach(function (mirror) { + u = u.replace('://' + mirror, '://' + object$2.cub_domain); + }); + return u; + } + + function shortText(fullStr, strLen, separator) { + fullStr = fullStr + ''; + if (fullStr.length <= strLen) return fullStr; + separator = separator || '...'; + var sepLen = separator.length, + charsToShow = strLen - sepLen, + frontChars = Math.ceil(charsToShow / 2), + backChars = Math.floor(charsToShow / 2); + return fullStr.substr(0, frontChars) + separator + fullStr.substr(fullStr.length - backChars); + } + + function protocol() { + var prot = Storage.get('protocol') || 'https'; + return window.location.protocol == 'https:' ? 'https://' : prot + '://'; + } + + function addUrlComponent(url, params) { + return url + (/\?/.test(url) ? '&' : '?') + params; + } + + function putScript(items, complite, error, success, show_logs) { + var p = 0; + var l = typeof show_logs !== 'undefined' ? show_logs : true; + + function next() { + if (p == items.length) return complite(); + var u = items[p]; + + if (!u) { + p++; + return next(); + } + + u = u.replace('cub.watch', Lampa.Manifest.cub_domain); + if (l) console.log('Script', 'create:', u); + var s = document.createElement('script'); + + s.onload = function () { + if (l) console.log('Script', 'include:', u); + if (success) success(u); + next(); + }; + + s.onerror = function () { + if (l) console.warn('Script', 'error:', u); + if (error) error(u); + next(); + }; + + s.async = true; + s.setAttribute('src', u); + document.body.appendChild(s); + p++; + } + + next(); + } + + function putScriptAsync(items, complite, error, success, show_logs) { + var p = 0; + var l = typeof show_logs !== 'undefined' ? show_logs : true; + + function check() { + p++; + if (p == items.length && complite) complite(); + } + + function put(u) { + u = u.replace('cub.watch', Lampa.Manifest.cub_domain); + if (l) console.log('Script', 'create:', u); + var t = setTimeout(function () { + s.onerror(); + s.onload = null; + s.onerror = null; + }, 1000 * 60); + var s = document.createElement('script'); + + s.onload = function () { + if (l) console.log('Script', 'include:', u); + clearTimeout(t); + if (success) success(u); + check(); + }; + + s.onerror = function () { + if (l) console.warn('Script', 'error:', u); + clearTimeout(t); + if (error) error(u); + check(); + }; + + s.async = true; + s.setAttribute('src', u); + document.body.appendChild(s); + } + + for (var i = 0; i < items.length; i++) { + put(items[i]); + } + } + + function putScriptOfMirrors(items, complite, error, success, show_logs) { + var mirrors = Lampa.Manifest && Lampa.Manifest.cub_mirrors || []; + var l = typeof show_logs !== 'undefined' ? show_logs : true; + var p = 0; + + function nextItem() { + if (p >= items.length) { + if (complite) complite(); + return; + } + + var url = items[p++]; + + if (!url) { + nextItem(); + return; + } + + var current = mirrors.find(function (m) { + return url.includes(m); + }); + + if (!current || !mirrors.length) { + putScriptAsync([url], nextItem, function (u) { + if (error) error(u); + }, function (u) { + if (success) success(u); + }, show_logs); + return; + } + + var idx = mirrors.indexOf(current); + var ordered = mirrors.slice(idx).concat(mirrors.slice(0, idx)); + var i = 0; + var loaded = false; + + function tryMirror() { + if (i >= ordered.length) { + if (l) console.warn('Script', 'all mirrors failed:', url); + if (error) error(url); + nextItem(); + return; + } + + var mirror = ordered[i++]; + var tryUrl = url.replace(current, mirror); + if (l) console.log('Script', 'mirror try [' + i + '/' + ordered.length + ']:', tryUrl); + putScriptAsync([tryUrl], null, function () { + if (!loaded) tryMirror(); + }, function (u) { + loaded = true; + if (success) success(u); + nextItem(); + }, show_logs); + } + + tryMirror(); + } + + nextItem(); + } + + function putStyle(items, complite, error) { + var p = 0; + + function next() { + if (p >= items.length) return complite(); + var u = items[p]; + $.get(u, function (css) { + css = css.replace(/\.\.\//g, './'); + var style = document.createElement('style'); + style.type = 'text/css'; + + if (style.styleSheet) { + // This is required for IE8 and below. + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } + + document.body.appendChild(style); + next(); + }, function () { + if (error) error(u); + next(); + }, 'TEXT'); + p++; + } + + next(items[0]); + } + + function clearTitle(title) { + return title.replace(/[^a-zа-я0-9\s]/gi, ''); + } + + function cardImgBackground(card_data) { + if (Storage.field('background')) { + if (Storage.field('background_type') == 'poster' && window.innerWidth > 790) { + return card_data.backdrop_path ? Api.img(card_data.backdrop_path, 'w1280') : card_data.background_image ? card_data.background_image : ''; + } + + return card_data.poster_path || card_data.profile_path ? Api.img(card_data.poster_path || card_data.profile_path) : card_data.poster || card_data.img || ''; + } + + return ''; + } + + function cardImgBackgroundBlur(card_data) { + var uri = card_data.poster_path || card_data.profile_path ? Api.img(card_data.poster_path || card_data.profile_path, 'w200') : card_data.poster || card_data.img || ''; + var pos = window.innerWidth > 400 && Storage.field('background_type') == 'poster' && !Storage.field('card_interfice_cover'); + + if (Storage.field('background')) { + if (card_data.backdrop_path) uri = Api.img(card_data.backdrop_path, pos ? 'w1280' : 'w200');else if (card_data.background_image && pos) uri = card_data.background_image; + } + + return uri; + } + + function stringToHslColor(str, s, l) { + var hash = 0; + + for (var i = 0; i < str.length; i++) { + hash = str.charCodeAt(i) + ((hash << 5) - hash); + } + + var h = hash % 360; + return 'hsl(' + h + ', ' + s + '%, ' + l + '%)'; + } + + function pathToNormalTitle(path) { + var add_exe = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var name = path.split('.'); + var exe = name[name.length - 1]; + name = name.join('.'); + return (name + '').replace(/_|\./g, ' ') + (add_exe ? ' .' + exe + '' : ''); + } + + function hash$2(input) { + var str = (input || '') + ''; + var hash = 0; + if (str.length == 0) return hash; + + for (var i = 0; i < str.length; i++) { + var _char = str.charCodeAt(i); + + hash = (hash << 5) - hash + _char; + hash = hash & hash; // Convert to 32bit integer + } + + return Math.abs(hash) + ''; + } + + function uid(len) { + var ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + var ID_LENGTH = len || 8; + var id = ''; + + for (var i = 0; i < ID_LENGTH; i++) { + id += ALPHABET.charAt(Math.floor(Math.random() * ALPHABET.length)); + } + + return id; + } + + function copyTextToClipboard(text, succes, error) { + if (!text) return error && error(); + var textArea = document.createElement("textarea"); + textArea.value = text; + textArea.style.top = "0"; + textArea.style.left = "0"; + textArea.style.position = "fixed"; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + var successful = document.execCommand('copy'); + if (successful) succes();else error(); + } catch (err) { + error(); + } + + document.body.removeChild(textArea); + } + + function imgLoad(image, src, onload, onerror) { + var img = image instanceof jQuery ? image[0] : image; + + img.onload = function () { + onload && onload(img); + }; + + img.onerror = function () { + img.src = './img/img_broken.svg'; + onerror && onerror(img); + }; + + img.src = src; + } + + function isTouchDevice() { + if (!('ontouchstart' in window)) return false; + var points = navigator.maxTouchPoints > 0 && navigator.maxTouchPoints !== 256 || navigator.msMaxTouchPoints > 0 && navigator.msMaxTouchPoints !== 256; + var win = navigator.userAgent.toLowerCase().indexOf('windows nt') !== -1; + return points && !win; + } + + function canFullScreen() { + var doc = window.document; + var elem = doc.documentElement; + return elem.requestFullscreen || elem.mozRequestFullScreen || elem.webkitRequestFullScreen || elem.msRequestFullscreen; + } + + function toggleFullscreen() { + // Check if the User-Agent string contains the word "Tesla" + if (navigator.userAgent.indexOf("Tesla") >= 0) { + // Get the current domain from the URL + var currentDomain = window.location.hostname; // Construct the YouTube redirect URL with the current domain + + var targetURL = "https://www.youtube.com/redirect?q=".concat(currentDomain); // If it's Tesla's browser, redirect to the YouTube URL (which will open the current domain in full-screen, thank you Elon, sarcasm) + + location.href = targetURL; + } else { + var doc = window.document; + var elem = doc.documentElement; + var requestFullScreen = elem.requestFullscreen || elem.mozRequestFullScreen || elem.webkitRequestFullScreen || elem.msRequestFullscreen; + var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen; + + if (!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) { + requestFullScreen.call(elem); + } else { + cancelFullScreen.call(doc); + } + } + } + + function countSeasons(movie) { + var seasons = movie.seasons || []; + var count = 0; + + for (var i = 0; i < seasons.length; i++) { + if (seasons[i].episode_count > 0) count++; + } + + if (count > movie.number_of_seasons) count = movie.number_of_seasons; + return count; + } + + function countDays(time_a, time_b) { + var d1 = new Date(time_a); + var d2 = new Date(time_b); + var days = (d2 - d1) / (1000 * 60 * 60 * 24); + days = Math.round(days); + return days <= 0 ? 0 : days; + } + + function decodePG(pg) { + var lang = Storage.field('language'); + var keys = { + 'G': '3+', + 'PG': '6+', + 'PG-13': '13+', + 'R': '17+', + 'NC-17': '18+', + 'TV-Y': '0+', + 'TV-Y7': '7+', + 'TV-G': '3+', + 'TV-PG': '6+', + 'TV-14': '14+', + 'TV-MA': '17+' + }; + + if (lang == 'ru' || lang == 'uk' || lang == 'be') { + for (var key in keys) { + if (pg == key) return keys[key]; + } + } + + return pg; + } + /** + * Проверяет можно ли показывать контент с указанным возрастным ограничением + * @param {string|integer} pg возрастное ограничение (например, '16+', 'R', 18) + * @param {integer} limit возраст профиля (по умолчанию 12) + * @returns {boolean} + */ + + + function canWatchChildren(pg, limit) { + var age = (pg + '').indexOf('+') >= 0 ? parseInt(pg.replace('+', '')) : 18; + var age_limit = limit || 12; + return Lampa.Account.Permit.child ? age_limit >= age : true; + } + + function trigger$2(element, event_name) { + var event = document.createEvent('Event'); + event.initEvent(event_name, false, true); + element.dispatchEvent(event); + } + + function isPWA() { + var pwa = false; + + try { + pwa = window.matchMedia('(display-mode: standalone)').matches; + } catch (e) {} + + return pwa; + } + + function bigNumberToShort(number) { + var suffixes = ['', 'K', 'M', 'M']; // Суффиксы для различных форматов + + var absoluteNumber = Math.abs(number); // Получаем абсолютное значение числа + + var suffixIndex = Math.floor((absoluteNumber.toFixed(0).length - 1) / 3); // Определение индекса суффикса + // Проверяем, если число меньше 1000, возвращаем его без изменений + + if (absoluteNumber < 1000) { + return number.toString(); + } // Округление числа и преобразование в строку + + + var roundedNumber = (number / Math.pow(1000, suffixIndex)).toFixed(1).replace('.0', ''); + return roundedNumber + suffixes[suffixIndex]; // Возвращаем округленное число с суффиксом + } + + function gup(name, url) { + if (!url) url = location.href; + name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); + var regexS = "[\\?&]" + name + "=([^&#]*)"; + var regex = new RegExp(regexS); + var results = regex.exec(url); + return results == null ? null : results[1]; + } + + function dcma(media, id) { + return window.lampa_settings.dcma && window.lampa_settings.dcma.find(function (a) { + return a.cat == media && a.id == id; + }); + } + + function inputDisplay(value) { + var f = value.trim(); + var d = f.length - value.length; + var e = d < 0 ? value.slice(d).replace(/\s/g, ' ') : ''; + return f + e; + } + + function filterCardsByType(items, need) { + var filtred = []; + + var genres = function genres(card, id) { + var gen = card.genres || card.genre_ids; + + if (gen && Object.prototype.toString.call(gen) === '[object Array]') { + return gen.find(function (g) { + if (_typeof(g) == 'object') return g.id == id; + }); + } + + return false; + }; + + if (need == 'movies') filtred = items.filter(function (a) { + return !a.name && !genres(a, 16); + }); + if (need == 'tv') filtred = items.filter(function (a) { + return a.name && !genres(a, 16); + }); + if (need == 'multmovie') filtred = items.filter(function (a) { + return !a.name && genres(a, 16); + }); + if (need == 'multtv') filtred = items.filter(function (a) { + return a.name && genres(a, 16); + }); + return filtred; + } + + function buildUrl$1(baseUrl, path, queryParams) { + // Убираем /ts на конце, если он есть (для совместимости с TorrServer) + var cleanUrl = baseUrl.replace(/\/ts\/?$/, ''); // Убираем лишние "/" в начале и конце пути, сохраняя subpath + + var url = cleanUrl.replace(/\/+$/, '') + '/' + path.replace(/^\/+/, ''); // Формируем строку запроса из массива объектов + + var queryString = queryParams.map(function (param) { + return encodeURIComponent(param.name) + '=' + encodeURIComponent(param.value); + }).join('&'); // Добавляем строку запроса к URL, если есть параметры + + return url + (queryString ? '?' + queryString : ''); + } + + function simpleMarkdownParser(input) { + // Удаление заголовков с маркером списка + input = input.replace(/\* #{1,} /gim, '* '); // Жирный текст первым, чтобы ** не мешал распознаванию * как маркера списка + + input = input.replace(/\*\*(.*?)\*\*/gim, '$1'); // Маркер списка + заголовок: "* #### текст" или " * #### текст" + + input = input.replace(/^[ \t]*\*[ \t]*#{1,6}[ \t]+(.*$)/gim, '

    $1

    '); // Обычные заголовки + + input = input.replace(/^# (.*$)/gim, '

    $1

    '); + input = input.replace(/^#{2,}[ \t]+(.*$)/gim, '

    $1

    '); // Маркированные списки с любым отступом и любым кол-вом пробелов после * + + input = input.replace(/^[ \t]*\*[ \t]+(.*$)/gim, '

    $1

    '); // Курсивный текст *текст* (после списков, чтобы одиночный * маркера не захватывался) + + input = input.replace(/\*(.*?)\*/gim, '$1'); // Оборачивание незатронутых строк в

    + + input = input.replace(/^(?!

    |

    |

    ||)(.+)$/gim, '

    $1

    '); // Удаление лишних переносов строк + + input = input.replace(/\n/gim, ''); + return input; + } + + function callWaiting(needCall, emergencyCall) { + var time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10000; + var timer = setTimeout(emergencyCall, time); + needCall(function () { + clearTimeout(timer); + }); + } + + function clearCard(card) { + var new_card = {}; + var empty = ['original_name', 'name', 'first_air_date']; + var num = ['popularity', 'vote_count', 'vote_average', 'imdb_rating', 'kp_rating', 'number_of_episodes', 'number_of_seasons']; + card_fields.forEach(function (f) { + if (typeof card[f] !== 'undefined') { + var val = card[f]; + if (val == null || val == 'NaN') val = ''; + if (num.indexOf(f) >= 0 && !val) val = 0; + new_card[f] = val; + if (empty.indexOf(f) >= 0 && !val) delete new_card[f]; + } + }); + if (new_card.poster_path) new_card.img = Lampa.Api.img(new_card.poster_path, 'w300'); + return new_card; + } + + function resolutionToQuality(width, height, symbol) { + var quality = 0; + if (width >= 3830) quality = 2160;else if (width >= 2550) quality = 1440;else if (width >= 1910) quality = 1080;else if (width >= 1014) quality = 720;else if (width >= 710) quality = 480;else if (width >= 630) quality = 360; + if (symbol) quality += symbol; + return quality; + } + + function qualityToText(quality) { + var text = ''; + + switch (quality) { + case '2160p': + text = '4K'; + break; + + case '1440p': + text = '2K'; + break; + + case '1080p': + text = 'FHD'; + break; + + case '720p': + text = 'HD'; + break; + + case '480p': + text = 'SD'; + break; + + case '360p': + text = 'SD'; + break; + + default: + text = quality; + break; + } + + return text; + } + + function guid() { + var hex = "0123456789ABCDEF"; + var gi = ""; + + for (var i = 0; i < 36; i++) { + if (i === 8 || i === 13 || i === 18 || i === 23) { + gi += "-"; + } else { + var r = Math.floor(Math.random() * 16); // Устанавливаем версию и variant по UUIDv4 спецификации + + if (i === 14) r = 4; // версия 4 + + if (i === 19) r = r & 0x3 | 0x8; // variant + + gi += hex[r]; + } + } + + return gi; + } + + function createInstance(BaseClass, element) { + var add_params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var replace = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + Arrays.extend(element, { + params: {} + }); + Arrays.extend(element.params, add_params, replace); + var item = typeof element.params.createInstance == 'function' ? element.params.createInstance(element) : new BaseClass(element); + if (!item) return console.error('createInstance function must return class', element); + + if (element.params.emit && _typeof(element.params.emit) == 'object' && typeof item.use == 'function') { + item.use(element.params.emit); + + if (typeof element.params.emit.onInit == 'function') { + element.params.emit.onInit(item); + } + } + + return item; + } + + function extendParams(element) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var replace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + Arrays.extend(element, { + params: {} + }); + Arrays.extend(element.params, params, replace); + } + + function extendItemsParams(items) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var replace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + if (!items || !items.length) return; + + for (var i = 0; i < items.length; i++) { + if (!items[i]) continue; + extendParams(items[i], params, replace); + } + } + + function qrcode(text, element, error) { + try { + var qr = window.qrcode(0, 'H'); + qr.addData(text, 'Byte'); + qr.make(); + if (element instanceof jQuery) element = element[0]; + element.innerHTML = qr.createSvgTag({ + cellSize: 8, + margin: 10 + }); + } catch (e) { + error && error(e); + } + } + + function onceInit(func) { + var inited = false; + return function () { + if (inited) return; + inited = true; + return func.apply(void 0, arguments); + }; + } + + function containsJapanese(text) { + return /[\u3040-\u30FF\u31F0-\u31FF\uFF66-\uFF9F\u4E00-\u9FFF]/.test(text); + } + + function randomMinMax(min, max) { + return Math.floor(Math.random() * (max - min + 1) + min); + } + /** + * Добавляет источник к элементам данных + * @doc + * @name addSource + * @alias Utils + * @param {object|array} data данные или массив данных + * @param {string} source источник + */ + + + function addSource$1(data, source) { + if (Arrays.isObject(data) && Arrays.isArray(data.results)) { + data.results.forEach(function (item) { + if (!item.source) item.source = source; + }); + } else if (Arrays.isArray(data)) { + data.forEach(function (item) { + if (!item.source) item.source = source; + }); + } + + return data; + } + + function clearHtmlTags(str) { + return str.replace(/<\/?[^>]+(>|$)/g, ""); + } + /** + * Разбивает эпизоды на сезоны на основе даты выхода (air_date) + * gap — минимальный разрыв между эпизодами (в днях), чтобы считать новым сезоном + */ + + + function splitEpisodesIntoSeasons(episodes) { + var gap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 90; + if (!Array.isArray(episodes) || episodes.length === 0) return {}; // --- Вспомогательная функция: дата → число дней --- + + function dateToDays(date) { + if (!date || typeof date !== 'string') return 0; + var parts = date.split("-"); + if (parts.length !== 3) return 0; + return parseInt(parts[0], 10) * 365 + parseInt(parts[1], 10) * 30 + parseInt(parts[2], 10); + } // Сортируем по исходному номеру + + + episodes = _toConsumableArray(episodes).sort(function (a, b) { + return a.episode_number - b.episode_number; + }); + var seasons = {}; // { seasonNumber: [episodes] } + + var seasonNum = 1; // текущий сезон + + var lastDay = 0; // день последнего эпизода + + var _iterator = _createForOfIteratorHelper(episodes), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var ep = _step.value; + var day = dateToDays(ep.air_date); // Проверяем разрыв > gap → новый сезон + + if (day > 0 && lastDay > 0 && day - lastDay > gap) { + seasonNum++; + } + + if (day > 0) lastDay = day; + if (!seasons[seasonNum]) seasons[seasonNum] = []; // Копируем эпизод и перенумеровываем + + var newEp = _objectSpread2({}, ep); + + newEp.season_number = seasonNum; + newEp.episode_number = seasons[seasonNum].length + 1; + newEp.id = 900000 + seasonNum * 1000 + newEp.episode_number; + seasons[seasonNum].push(newEp); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return seasons; + } + + var Utils$1 = { + secondsToTime: secondsToTime, + secondsToTimeHuman: secondsToTimeHuman, + capitalizeFirstLetter: capitalizeFirstLetter, + substr: substr, + numberWithSpaces: numberWithSpaces, + time: time$2, + bytesToSize: bytesToSize, + calcBitrate: calcBitrate, + parseTime: parseTime, + parseToDate: parseToDate, + checkHttp: checkHttp, + shortText: shortText, + protocol: protocol, + addUrlComponent: addUrlComponent, + sizeToBytes: sizeToBytes, + putScript: putScript, + putScriptAsync: putScriptAsync, + putScriptOfMirrors: putScriptOfMirrors, + putStyle: putStyle, + clearTitle: clearTitle, + cardImgBackground: cardImgBackground, + cardImgBackgroundBlur: cardImgBackgroundBlur, + strToTime: strToTime, + stringToHslColor: stringToHslColor, + pathToNormalTitle: pathToNormalTitle, + hash: hash$2, + uid: uid, + guid: guid, + copyTextToClipboard: copyTextToClipboard, + imgLoad: imgLoad, + isTouchDevice: isTouchDevice, + toggleFullscreen: toggleFullscreen, + canFullScreen: canFullScreen, + countSeasons: countSeasons, + countDays: countDays, + decodePG: decodePG, + trigger: trigger$2, + isPWA: isPWA, + bigNumberToShort: bigNumberToShort, + rewriteIfHTTPS: rewriteIfHTTPS, + checkEmptyUrl: checkEmptyUrl, + gup: gup, + dcma: dcma, + inputDisplay: inputDisplay, + filterCardsByType: filterCardsByType, + buildUrl: buildUrl$1, + simpleMarkdownParser: simpleMarkdownParser, + fixProtocolLink: fixProtocolLink, + fixMirrorLink: fixMirrorLink, + callWaiting: callWaiting, + clearCard: clearCard, + qualityToText: qualityToText, + resolutionToQuality: resolutionToQuality, + createInstance: createInstance, + extendParams: extendParams, + extendItemsParams: extendItemsParams, + qrcode: qrcode, + onceInit: onceInit, + containsJapanese: containsJapanese, + randomMinMax: randomMinMax, + addSource: addSource$1, + clearHtmlTags: clearHtmlTags, + splitEpisodesIntoSeasons: splitEpisodesIntoSeasons, + canWatchChildren: canWatchChildren + }; + + var WorkerClass = null; + + try { + var WorkerThreads = + typeof module !== 'undefined' && typeof module.require === 'function' && module.require('worker_threads') || + typeof __non_webpack_require__ === 'function' && __non_webpack_require__('worker_threads') || + typeof require === 'function' && require('worker_threads'); + WorkerClass = WorkerThreads.Worker; + } catch(e) {} // eslint-disable-line + + function decodeBase64$1(base64, enableUnicode) { + return Buffer.from(base64, 'base64').toString(enableUnicode ? 'utf16' : 'utf8'); + } + + function createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg) { + var sourcemap = sourcemapArg === undefined ? null : sourcemapArg; + var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg; + var source = decodeBase64$1(base64, enableUnicode); + var start = source.indexOf('\n', 10) + 1; + var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : ''); + return function WorkerFactory(options) { + return new WorkerClass(body, Object.assign({}, options, { eval: true })); + }; + } + + function decodeBase64(base64, enableUnicode) { + var binaryString = atob(base64); + if (enableUnicode) { + var binaryView = new Uint8Array(binaryString.length); + for (var i = 0, n = binaryString.length; i < n; ++i) { + binaryView[i] = binaryString.charCodeAt(i); + } + return String.fromCharCode.apply(null, new Uint16Array(binaryView.buffer)); + } + return binaryString; + } + + function createURL(base64, sourcemapArg, enableUnicodeArg) { + var sourcemap = sourcemapArg === undefined ? null : sourcemapArg; + var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg; + var source = decodeBase64(base64, enableUnicode); + var start = source.indexOf('\n', 10) + 1; + var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : ''); + var blob = new Blob([body], { type: 'application/javascript' }); + return URL.createObjectURL(blob); + } + + function createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg) { + var url; + return function WorkerFactory(options) { + url = url || createURL(base64, sourcemapArg, enableUnicodeArg); + return new Worker(url, options); + }; + } + + var kIsNodeJS = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'; + + function isNodeJS() { + return false; + } + + function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) { + if (isNodeJS()) { + return createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg); + } + return createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg); + } + + var WorkerFactory$2 = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgLyogZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSAtLSB1c2VkIGZvciBjYWxjdWxhdGlvbnMgKi8KCiAgLyogZXNsaW50LWRpc2FibGUgdW5pY29ybi9wcmVmZXItcXVlcnktc2VsZWN0b3IgLS0gYWltaW5nIGF0DQogICAgYmFja3dhcmQtY29tcGF0aWJpbGl0eSAqLwoKICAvKioNCiAgKiBTdGFja0JsdXIgLSBhIGZhc3QgYWxtb3N0IEdhdXNzaWFuIEJsdXIgRm9yIENhbnZhcw0KICAqDQogICogSW4gY2FzZSB5b3UgZmluZCB0aGlzIGNsYXNzIHVzZWZ1bCAtIGVzcGVjaWFsbHkgaW4gY29tbWVyY2lhbCBwcm9qZWN0cyAtDQogICogSSBhbSBub3QgdG90YWxseSB1bmhhcHB5IGZvciBhIHNtYWxsIGRvbmF0aW9uIHRvIG15IFBheVBhbCBhY2NvdW50DQogICogbWFyaW9AcXVhc2ltb25kby5kZQ0KICAqDQogICogT3Igc3VwcG9ydCBtZSBvbiBmbGF0dHI6DQogICoge0BsaW5rIGh0dHBzOi8vZmxhdHRyLmNvbS90aGluZy83Mjc5MS9TdGFja0JsdXItYS1mYXN0LWFsbW9zdC1HYXVzc2lhbi1CbHVyLUVmZmVjdC1mb3ItQ2FudmFzSmF2YXNjcmlwdH0uDQogICoNCiAgKiBAbW9kdWxlIFN0YWNrQmx1cg0KICAqIEBhdXRob3IgTWFyaW8gS2xpbmdlbWFubg0KICAqIENvbnRhY3Q6IG1hcmlvQHF1YXNpbW9uZG8uY29tDQogICogV2Vic2l0ZToge0BsaW5rIGh0dHA6Ly93d3cucXVhc2ltb25kby5jb20vU3RhY2tCbHVyRm9yQ2FudmFzL1N0YWNrQmx1ckRlbW8uaHRtbH0NCiAgKiBUd2l0dGVyOiBAcXVhc2ltb25kbw0KICAqDQogICogQGNvcHlyaWdodCAoYykgMjAxMCBNYXJpbyBLbGluZ2VtYW5uDQogICoNCiAgKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbg0KICAqIG9idGFpbmluZyBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uDQogICogZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dA0KICAqIHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLA0KICAqIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsDQogICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlDQogICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcNCiAgKiBjb25kaXRpb25zOg0KICAqDQogICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUNCiAgKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4NCiAgKg0KICAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELA0KICAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUw0KICAqIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EDQogICogTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQNCiAgKiBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwNCiAgKiBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcNCiAgKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SDQogICogT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLg0KICAqLwogIHZhciBCbHVyU3RhY2sgPSBmdW5jdGlvbiBCbHVyU3RhY2soKSB7CiAgICB0aGlzLnIgPSAwOwogICAgdGhpcy5nID0gMDsKICAgIHRoaXMuYiA9IDA7CiAgICB0aGlzLmEgPSAwOwogICAgdGhpcy5uZXh0ID0gbnVsbDsKICB9OwoKICB2YXIgbXVsVGFibGUgPSBbNTEyLCA1MTIsIDQ1NiwgNTEyLCAzMjgsIDQ1NiwgMzM1LCA1MTIsIDQwNSwgMzI4LCAyNzEsIDQ1NiwgMzg4LCAzMzUsIDI5MiwgNTEyLCA0NTQsIDQwNSwgMzY0LCAzMjgsIDI5OCwgMjcxLCA0OTYsIDQ1NiwgNDIwLCAzODgsIDM2MCwgMzM1LCAzMTIsIDI5MiwgMjczLCA1MTIsIDQ4MiwgNDU0LCA0MjgsIDQwNSwgMzgzLCAzNjQsIDM0NSwgMzI4LCAzMTIsIDI5OCwgMjg0LCAyNzEsIDI1OSwgNDk2LCA0NzUsIDQ1NiwgNDM3LCA0MjAsIDQwNCwgMzg4LCAzNzQsIDM2MCwgMzQ3LCAzMzUsIDMyMywgMzEyLCAzMDIsIDI5MiwgMjgyLCAyNzMsIDI2NSwgNTEyLCA0OTcsIDQ4MiwgNDY4LCA0NTQsIDQ0MSwgNDI4LCA0MTcsIDQwNSwgMzk0LCAzODMsIDM3MywgMzY0LCAzNTQsIDM0NSwgMzM3LCAzMjgsIDMyMCwgMzEyLCAzMDUsIDI5OCwgMjkxLCAyODQsIDI3OCwgMjcxLCAyNjUsIDI1OSwgNTA3LCA0OTYsIDQ4NSwgNDc1LCA0NjUsIDQ1NiwgNDQ2LCA0MzcsIDQyOCwgNDIwLCA0MTIsIDQwNCwgMzk2LCAzODgsIDM4MSwgMzc0LCAzNjcsIDM2MCwgMzU0LCAzNDcsIDM0MSwgMzM1LCAzMjksIDMyMywgMzE4LCAzMTIsIDMwNywgMzAyLCAyOTcsIDI5MiwgMjg3LCAyODIsIDI3OCwgMjczLCAyNjksIDI2NSwgMjYxLCA1MTIsIDUwNSwgNDk3LCA0ODksIDQ4MiwgNDc1LCA0NjgsIDQ2MSwgNDU0LCA0NDcsIDQ0MSwgNDM1LCA0MjgsIDQyMiwgNDE3LCA0MTEsIDQwNSwgMzk5LCAzOTQsIDM4OSwgMzgzLCAzNzgsIDM3MywgMzY4LCAzNjQsIDM1OSwgMzU0LCAzNTAsIDM0NSwgMzQxLCAzMzcsIDMzMiwgMzI4LCAzMjQsIDMyMCwgMzE2LCAzMTIsIDMwOSwgMzA1LCAzMDEsIDI5OCwgMjk0LCAyOTEsIDI4NywgMjg0LCAyODEsIDI3OCwgMjc0LCAyNzEsIDI2OCwgMjY1LCAyNjIsIDI1OSwgMjU3LCA1MDcsIDUwMSwgNDk2LCA0OTEsIDQ4NSwgNDgwLCA0NzUsIDQ3MCwgNDY1LCA0NjAsIDQ1NiwgNDUxLCA0NDYsIDQ0MiwgNDM3LCA0MzMsIDQyOCwgNDI0LCA0MjAsIDQxNiwgNDEyLCA0MDgsIDQwNCwgNDAwLCAzOTYsIDM5MiwgMzg4LCAzODUsIDM4MSwgMzc3LCAzNzQsIDM3MCwgMzY3LCAzNjMsIDM2MCwgMzU3LCAzNTQsIDM1MCwgMzQ3LCAzNDQsIDM0MSwgMzM4LCAzMzUsIDMzMiwgMzI5LCAzMjYsIDMyMywgMzIwLCAzMTgsIDMxNSwgMzEyLCAzMTAsIDMwNywgMzA0LCAzMDIsIDI5OSwgMjk3LCAyOTQsIDI5MiwgMjg5LCAyODcsIDI4NSwgMjgyLCAyODAsIDI3OCwgMjc1LCAyNzMsIDI3MSwgMjY5LCAyNjcsIDI2NSwgMjYzLCAyNjEsIDI1OV07CiAgdmFyIHNoZ1RhYmxlID0gWzksIDExLCAxMiwgMTMsIDEzLCAxNCwgMTQsIDE1LCAxNSwgMTUsIDE1LCAxNiwgMTYsIDE2LCAxNiwgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE4LCAxOCwgMTgsIDE4LCAxOCwgMTgsIDE4LCAxOCwgMTgsIDE5LCAxOSwgMTksIDE5LCAxOSwgMTksIDE5LCAxOSwgMTksIDE5LCAxOSwgMTksIDE5LCAxOSwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNF07CiAgLyoqDQogICAqIEBwYXJhbSB7SW1hZ2VEYXRhfSBpbWFnZURhdGENCiAgICogQHBhcmFtIHtJbnRlZ2VyfSB0b3BYDQogICAqIEBwYXJhbSB7SW50ZWdlcn0gdG9wWQ0KICAgKiBAcGFyYW0ge0ludGVnZXJ9IHdpZHRoDQogICAqIEBwYXJhbSB7SW50ZWdlcn0gaGVpZ2h0DQogICAqIEBwYXJhbSB7RmxvYXR9IHJhZGl1cw0KICAgKiBAcmV0dXJucyB7SW1hZ2VEYXRhfQ0KICAgKi8KCgogIGZ1bmN0aW9uIHByb2Nlc3NJbWFnZURhdGFSR0IoaW1hZ2VEYXRhLCB0b3BYLCB0b3BZLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpIHsKICAgIHZhciBwaXhlbHMgPSBpbWFnZURhdGEgPyBpbWFnZURhdGEuZGF0YSA6IFtdOwogICAgdmFyIGRpdiA9IDIgKiByYWRpdXMgKyAxOyAvLyBjb25zdCB3NCA9IHdpZHRoIDw8IDI7CgogICAgdmFyIHdpZHRoTWludXMxID0gd2lkdGggLSAxOwogICAgdmFyIGhlaWdodE1pbnVzMSA9IGhlaWdodCAtIDE7CiAgICB2YXIgcmFkaXVzUGx1czEgPSByYWRpdXMgKyAxOwogICAgdmFyIHN1bUZhY3RvciA9IHJhZGl1c1BsdXMxICogKHJhZGl1c1BsdXMxICsgMSkgLyAyOwogICAgdmFyIHN0YWNrU3RhcnQgPSBuZXcgQmx1clN0YWNrKCk7CiAgICB2YXIgc3RhY2sgPSBzdGFja1N0YXJ0OwogICAgdmFyIHN0YWNrRW5kOwoKICAgIGZvciAodmFyIGkgPSAxOyBpIDwgZGl2OyBpKyspIHsKICAgICAgc3RhY2sgPSBzdGFjay5uZXh0ID0gbmV3IEJsdXJTdGFjaygpOwoKICAgICAgaWYgKGkgPT09IHJhZGl1c1BsdXMxKSB7CiAgICAgICAgc3RhY2tFbmQgPSBzdGFjazsKICAgICAgfQogICAgfQoKICAgIHN0YWNrLm5leHQgPSBzdGFja1N0YXJ0OwogICAgdmFyIHN0YWNrSW4gPSBudWxsOwogICAgdmFyIHN0YWNrT3V0ID0gbnVsbDsKICAgIHZhciBtdWxTdW0gPSBtdWxUYWJsZVtyYWRpdXNdOwogICAgdmFyIHNoZ1N1bSA9IHNoZ1RhYmxlW3JhZGl1c107CiAgICB2YXIgcCwgcmJzOwogICAgdmFyIHl3ID0gMCwKICAgICAgICB5aSA9IDA7CgogICAgZm9yICh2YXIgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICB2YXIgcHIgPSBwaXhlbHNbeWldLAogICAgICAgICAgcGcgPSBwaXhlbHNbeWkgKyAxXSwKICAgICAgICAgIHBiID0gcGl4ZWxzW3lpICsgMl0sCiAgICAgICAgICByT3V0U3VtID0gcmFkaXVzUGx1czEgKiBwciwKICAgICAgICAgIGdPdXRTdW0gPSByYWRpdXNQbHVzMSAqIHBnLAogICAgICAgICAgYk91dFN1bSA9IHJhZGl1c1BsdXMxICogcGIsCiAgICAgICAgICByU3VtID0gc3VtRmFjdG9yICogcHIsCiAgICAgICAgICBnU3VtID0gc3VtRmFjdG9yICogcGcsCiAgICAgICAgICBiU3VtID0gc3VtRmFjdG9yICogcGI7CiAgICAgIHN0YWNrID0gc3RhY2tTdGFydDsKCiAgICAgIGZvciAodmFyIF9pNSA9IDA7IF9pNSA8IHJhZGl1c1BsdXMxOyBfaTUrKykgewogICAgICAgIHN0YWNrLnIgPSBwcjsKICAgICAgICBzdGFjay5nID0gcGc7CiAgICAgICAgc3RhY2suYiA9IHBiOwogICAgICAgIHN0YWNrID0gc3RhY2submV4dDsKICAgICAgfQoKICAgICAgdmFyIHJJblN1bSA9IDAsCiAgICAgICAgICBnSW5TdW0gPSAwLAogICAgICAgICAgYkluU3VtID0gMDsKCiAgICAgIGZvciAodmFyIF9pNiA9IDE7IF9pNiA8IHJhZGl1c1BsdXMxOyBfaTYrKykgewogICAgICAgIHAgPSB5aSArICgod2lkdGhNaW51czEgPCBfaTYgPyB3aWR0aE1pbnVzMSA6IF9pNikgPDwgMik7CiAgICAgICAgclN1bSArPSAoc3RhY2suciA9IHByID0gcGl4ZWxzW3BdKSAqIChyYnMgPSByYWRpdXNQbHVzMSAtIF9pNik7CiAgICAgICAgZ1N1bSArPSAoc3RhY2suZyA9IHBnID0gcGl4ZWxzW3AgKyAxXSkgKiByYnM7CiAgICAgICAgYlN1bSArPSAoc3RhY2suYiA9IHBiID0gcGl4ZWxzW3AgKyAyXSkgKiByYnM7CiAgICAgICAgckluU3VtICs9IHByOwogICAgICAgIGdJblN1bSArPSBwZzsKICAgICAgICBiSW5TdW0gKz0gcGI7CiAgICAgICAgc3RhY2sgPSBzdGFjay5uZXh0OwogICAgICB9CgogICAgICBzdGFja0luID0gc3RhY2tTdGFydDsKICAgICAgc3RhY2tPdXQgPSBzdGFja0VuZDsKCiAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgIHBpeGVsc1t5aV0gPSByU3VtICogbXVsU3VtID4+IHNoZ1N1bTsKICAgICAgICBwaXhlbHNbeWkgKyAxXSA9IGdTdW0gKiBtdWxTdW0gPj4gc2hnU3VtOwogICAgICAgIHBpeGVsc1t5aSArIDJdID0gYlN1bSAqIG11bFN1bSA+PiBzaGdTdW07CiAgICAgICAgclN1bSAtPSByT3V0U3VtOwogICAgICAgIGdTdW0gLT0gZ091dFN1bTsKICAgICAgICBiU3VtIC09IGJPdXRTdW07CiAgICAgICAgck91dFN1bSAtPSBzdGFja0luLnI7CiAgICAgICAgZ091dFN1bSAtPSBzdGFja0luLmc7CiAgICAgICAgYk91dFN1bSAtPSBzdGFja0luLmI7CiAgICAgICAgcCA9IHl3ICsgKChwID0geCArIHJhZGl1cyArIDEpIDwgd2lkdGhNaW51czEgPyBwIDogd2lkdGhNaW51czEpIDw8IDI7CiAgICAgICAgckluU3VtICs9IHN0YWNrSW4uciA9IHBpeGVsc1twXTsKICAgICAgICBnSW5TdW0gKz0gc3RhY2tJbi5nID0gcGl4ZWxzW3AgKyAxXTsKICAgICAgICBiSW5TdW0gKz0gc3RhY2tJbi5iID0gcGl4ZWxzW3AgKyAyXTsKICAgICAgICByU3VtICs9IHJJblN1bTsKICAgICAgICBnU3VtICs9IGdJblN1bTsKICAgICAgICBiU3VtICs9IGJJblN1bTsKICAgICAgICBzdGFja0luID0gc3RhY2tJbi5uZXh0OwogICAgICAgIHJPdXRTdW0gKz0gcHIgPSBzdGFja091dC5yOwogICAgICAgIGdPdXRTdW0gKz0gcGcgPSBzdGFja091dC5nOwogICAgICAgIGJPdXRTdW0gKz0gcGIgPSBzdGFja091dC5iOwogICAgICAgIHJJblN1bSAtPSBwcjsKICAgICAgICBnSW5TdW0gLT0gcGc7CiAgICAgICAgYkluU3VtIC09IHBiOwogICAgICAgIHN0YWNrT3V0ID0gc3RhY2tPdXQubmV4dDsKICAgICAgICB5aSArPSA0OwogICAgICB9CgogICAgICB5dyArPSB3aWR0aDsKICAgIH0KCiAgICBmb3IgKHZhciBfeDIgPSAwOyBfeDIgPCB3aWR0aDsgX3gyKyspIHsKICAgICAgeWkgPSBfeDIgPDwgMjsKCiAgICAgIHZhciBfcHIyID0gcGl4ZWxzW3lpXSwKICAgICAgICAgIF9wZzIgPSBwaXhlbHNbeWkgKyAxXSwKICAgICAgICAgIF9wYjIgPSBwaXhlbHNbeWkgKyAyXSwKICAgICAgICAgIF9yT3V0U3VtMiA9IHJhZGl1c1BsdXMxICogX3ByMiwKICAgICAgICAgIF9nT3V0U3VtMiA9IHJhZGl1c1BsdXMxICogX3BnMiwKICAgICAgICAgIF9iT3V0U3VtMiA9IHJhZGl1c1BsdXMxICogX3BiMiwKICAgICAgICAgIF9yU3VtMiA9IHN1bUZhY3RvciAqIF9wcjIsCiAgICAgICAgICBfZ1N1bTIgPSBzdW1GYWN0b3IgKiBfcGcyLAogICAgICAgICAgX2JTdW0yID0gc3VtRmFjdG9yICogX3BiMjsKCiAgICAgIHN0YWNrID0gc3RhY2tTdGFydDsKCiAgICAgIGZvciAodmFyIF9pNyA9IDA7IF9pNyA8IHJhZGl1c1BsdXMxOyBfaTcrKykgewogICAgICAgIHN0YWNrLnIgPSBfcHIyOwogICAgICAgIHN0YWNrLmcgPSBfcGcyOwogICAgICAgIHN0YWNrLmIgPSBfcGIyOwogICAgICAgIHN0YWNrID0gc3RhY2submV4dDsKICAgICAgfQoKICAgICAgdmFyIF9ySW5TdW0yID0gMCwKICAgICAgICAgIF9nSW5TdW0yID0gMCwKICAgICAgICAgIF9iSW5TdW0yID0gMDsKCiAgICAgIGZvciAodmFyIF9pOCA9IDEsIHlwID0gd2lkdGg7IF9pOCA8PSByYWRpdXM7IF9pOCsrKSB7CiAgICAgICAgeWkgPSB5cCArIF94MiA8PCAyOwogICAgICAgIF9yU3VtMiArPSAoc3RhY2suciA9IF9wcjIgPSBwaXhlbHNbeWldKSAqIChyYnMgPSByYWRpdXNQbHVzMSAtIF9pOCk7CiAgICAgICAgX2dTdW0yICs9IChzdGFjay5nID0gX3BnMiA9IHBpeGVsc1t5aSArIDFdKSAqIHJiczsKICAgICAgICBfYlN1bTIgKz0gKHN0YWNrLmIgPSBfcGIyID0gcGl4ZWxzW3lpICsgMl0pICogcmJzOwogICAgICAgIF9ySW5TdW0yICs9IF9wcjI7CiAgICAgICAgX2dJblN1bTIgKz0gX3BnMjsKICAgICAgICBfYkluU3VtMiArPSBfcGIyOwogICAgICAgIHN0YWNrID0gc3RhY2submV4dDsKCiAgICAgICAgaWYgKF9pOCA8IGhlaWdodE1pbnVzMSkgewogICAgICAgICAgeXAgKz0gd2lkdGg7CiAgICAgICAgfQogICAgICB9CgogICAgICB5aSA9IF94MjsKICAgICAgc3RhY2tJbiA9IHN0YWNrU3RhcnQ7CiAgICAgIHN0YWNrT3V0ID0gc3RhY2tFbmQ7CgogICAgICBmb3IgKHZhciBfeTIgPSAwOyBfeTIgPCBoZWlnaHQ7IF95MisrKSB7CiAgICAgICAgcCA9IHlpIDw8IDI7CiAgICAgICAgcGl4ZWxzW3BdID0gX3JTdW0yICogbXVsU3VtID4+IHNoZ1N1bTsKICAgICAgICBwaXhlbHNbcCArIDFdID0gX2dTdW0yICogbXVsU3VtID4+IHNoZ1N1bTsKICAgICAgICBwaXhlbHNbcCArIDJdID0gX2JTdW0yICogbXVsU3VtID4+IHNoZ1N1bTsKICAgICAgICBfclN1bTIgLT0gX3JPdXRTdW0yOwogICAgICAgIF9nU3VtMiAtPSBfZ091dFN1bTI7CiAgICAgICAgX2JTdW0yIC09IF9iT3V0U3VtMjsKICAgICAgICBfck91dFN1bTIgLT0gc3RhY2tJbi5yOwogICAgICAgIF9nT3V0U3VtMiAtPSBzdGFja0luLmc7CiAgICAgICAgX2JPdXRTdW0yIC09IHN0YWNrSW4uYjsKICAgICAgICBwID0gX3gyICsgKChwID0gX3kyICsgcmFkaXVzUGx1czEpIDwgaGVpZ2h0TWludXMxID8gcCA6IGhlaWdodE1pbnVzMSkgKiB3aWR0aCA8PCAyOwogICAgICAgIF9yU3VtMiArPSBfckluU3VtMiArPSBzdGFja0luLnIgPSBwaXhlbHNbcF07CiAgICAgICAgX2dTdW0yICs9IF9nSW5TdW0yICs9IHN0YWNrSW4uZyA9IHBpeGVsc1twICsgMV07CiAgICAgICAgX2JTdW0yICs9IF9iSW5TdW0yICs9IHN0YWNrSW4uYiA9IHBpeGVsc1twICsgMl07CiAgICAgICAgc3RhY2tJbiA9IHN0YWNrSW4ubmV4dDsKICAgICAgICBfck91dFN1bTIgKz0gX3ByMiA9IHN0YWNrT3V0LnI7CiAgICAgICAgX2dPdXRTdW0yICs9IF9wZzIgPSBzdGFja091dC5nOwogICAgICAgIF9iT3V0U3VtMiArPSBfcGIyID0gc3RhY2tPdXQuYjsKICAgICAgICBfckluU3VtMiAtPSBfcHIyOwogICAgICAgIF9nSW5TdW0yIC09IF9wZzI7CiAgICAgICAgX2JJblN1bTIgLT0gX3BiMjsKICAgICAgICBzdGFja091dCA9IHN0YWNrT3V0Lm5leHQ7CiAgICAgICAgeWkgKz0gd2lkdGg7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaW1hZ2VEYXRhOwogIH0KCiAgb25tZXNzYWdlID0gZnVuY3Rpb24gb25tZXNzYWdlKGUpIHsKICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgdmFyIGltYWdlRGF0YTsKCiAgICB0cnkgewogICAgICBpbWFnZURhdGEgPSBwcm9jZXNzSW1hZ2VEYXRhUkdCKGRhdGEuaW1hZ2VEYXRhLCBkYXRhLnRvcFgsIGRhdGEudG9wWSwgZGF0YS53aWR0aCwgZGF0YS5oZWlnaHQsIGRhdGEucmFkaXVzKTsKICAgICAgcG9zdE1lc3NhZ2UoaW1hZ2VEYXRhKTsKICAgIH0gY2F0Y2ggKGUpIHt9CiAgfTsKCn0pKCk7Cgo=', null, false); + /* eslint-enable */ + + var WorkerFactory$1 = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGZ1bmN0aW9uIHBhcnNlKHN0cmluZywgZW1wdHkpIHsKICAgICAgdmFyIGpzb24gPSBlbXB0eSB8fCB7fTsKCiAgICAgIGlmIChzdHJpbmcpIHsKICAgICAgICB0cnkgewogICAgICAgICAganNvbiA9IEpTT04ucGFyc2Uoc3RyaW5nKTsKICAgICAgICB9IGNhdGNoIChlKSB7fQogICAgICB9CgogICAgICByZXR1cm4ganNvbjsKICAgIH0KCiAgICBmdW5jdGlvbiBzdHJpbmdpZnkoZGF0YSkgewogICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZGF0YSk7CiAgICB9CgogICAgb25tZXNzYWdlID0gZnVuY3Rpb24gb25tZXNzYWdlKGUpIHsKICAgICAgdmFyIG1zZyA9IGUuZGF0YTsKCiAgICAgIGlmIChtc2cudHlwZSA9PSAnc3RyaW5naWZ5JykgewogICAgICAgIHBvc3RNZXNzYWdlKHN0cmluZ2lmeShtc2cuZGF0YSkpOwogICAgICB9IGVsc2UgaWYgKG1zZy50eXBlID09ICdwYXJzZScpIHsKICAgICAgICBwb3N0TWVzc2FnZShwYXJzZShtc2cuZGF0YSwgbXNnLmVtcHR5KSk7CiAgICAgIH0KICAgIH07Cgp9KSgpOwoK', null, false); + /* eslint-enable */ + + var WorkerFactory = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIG9ubWVzc2FnZSA9IGZ1bmN0aW9uIG9ubWVzc2FnZShlKSB7CiAgICAgIHZhciBtc2cgPSBlLmRhdGE7CgogICAgICBpZiAobXNnLnR5cGUgPT0gJ2FjY291bnRfYm9va21hcmtzX3BhcnNlJykgewogICAgICAgIHZhciBib29rbWFya3MgPSBtc2cuZGF0YS5tYXAoZnVuY3Rpb24gKGVsZW0pIHsKICAgICAgICAgIGlmICh0eXBlb2YgZWxlbS5kYXRhID09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgIGVsZW0uZGF0YSA9IEpTT04ucGFyc2UoZWxlbS5kYXRhKTsKICAgICAgICAgICAgZGVsZXRlIGVsZW0uZGF0YS5yZWxlYXNlX3F1YWxpdHk7CiAgICAgICAgICAgIGRlbGV0ZSBlbGVtLmRhdGEucXVhbGl0eTsKICAgICAgICAgIH0KCiAgICAgICAgICByZXR1cm4gZWxlbTsKICAgICAgICB9KS5yZXZlcnNlKCk7CiAgICAgICAgcG9zdE1lc3NhZ2UoYm9va21hcmtzKTsKICAgICAgfQogICAgfTsKCn0pKCk7Cgo=', null, false); + /* eslint-enable */ + + var agent$1 = navigator.userAgent.toLowerCase(); + + function WebWorker(worker, nosuport) { + var callback = false; + var timer; + + worker.onmessage = function (data) { + clearTimeout(timer); + + if (callback) { + callback(data); + callback = false; + } + }; + + this.call = function (data, call) { + callback = call; + worker.postMessage(data); + timer = setTimeout(function () { + nosuport.call(data, call); + }, 1500); + }; + } + + function createWorker(extend, nosuport) { + var worker; + if (agent$1.indexOf("netcast") > -1 || agent$1.indexOf("maple") > -1) return nosuport || { + call: function call() {} + }; + + try { + worker = new WebWorker(new extend(), nosuport || { + call: function call() {} + }); + } catch (e) { + worker = nosuport || { + call: function call() {} + }; + } + + return worker; + } + + var blurWorker = createWorker(WorkerFactory$2, { + call: function call(msg, _call) { + var imageData = Blur.imageDataRGB(msg.imageData, msg.topX, msg.topY, msg.width, msg.height, msg.radius); + + _call({ + data: imageData + }); + } + }); + var jsonWorker = createWorker(WorkerFactory$1, { + call: function call(msg, _call2) { + _call2({ + data: msg.type == 'parse' ? Arrays.decodeJson(msg.data, msg.empty) : JSON.stringify(msg.data) + }); + } + }); + var utilsWorker = createWorker(WorkerFactory, { + call: function call(msg, _call3) { + if (msg.type == 'account_bookmarks_parse') { + var bookmarks = msg.data.map(function (elem) { + if (typeof elem.data == 'string') { + elem.data = JSON.parse(elem.data); + delete elem.data.release_quality; + delete elem.data.quality; + } + + return elem; + }).reverse(); + + _call3({ + data: bookmarks + }); + } + } + }); + var AppWorker = { + blur: blurWorker.call, + json: jsonWorker.call, + utils: utilsWorker.call + }; + + /* eslint-disable no-bitwise -- used for calculations */ + + /* eslint-disable unicorn/prefer-query-selector -- aiming at + backward-compatibility */ + + /** + * StackBlur - a fast almost Gaussian Blur For Canvas + * + * In case you find this class useful - especially in commercial projects - + * I am not totally unhappy for a small donation to my PayPal account + * mario@quasimondo.de + * + * Or support me on flattr: + * {@link https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript}. + * + * @module StackBlur + * @author Mario Klingemann + * Contact: mario@quasimondo.com + * Website: {@link http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html} + * Twitter: @quasimondo + * + * @copyright (c) 2010 Mario Klingemann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + var mulTable = [512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259]; + var shgTable = [9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]; + /** + * @param {string|HTMLImageElement} img + * @param {string|HTMLCanvasElement} canvas + * @param {Float} radius + * @param {boolean} blurAlphaChannel + * @param {boolean} useOffset + * @param {boolean} skipStyles + * @returns {undefined} + */ + + function processImage(img, canvas, radius, blurAlphaChannel, useOffset, skipStyles) { + if (typeof img === 'string') { + img = document.getElementById(img); + } + + if (!img || !('naturalWidth' in img)) { + return; + } + + var dimensionType = useOffset ? 'offset' : 'natural'; + var w = img[dimensionType + 'Width']; + var h = img[dimensionType + 'Height']; + + if (typeof canvas === 'string') { + canvas = document.getElementById(canvas); + } + + if (!canvas || !('getContext' in canvas)) { + return; + } + + if (!skipStyles) { + canvas.style.width = w + 'px'; + canvas.style.height = h + 'px'; + } + + canvas.width = w; + canvas.height = h; + var context = canvas.getContext('2d'); + context.clearRect(0, 0, w, h); + context.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, w, h); + + if (isNaN(radius) || radius < 1) { + return; + } + + if (blurAlphaChannel) { + processCanvasRGBA(canvas, 0, 0, w, h, radius); + } else { + processCanvasRGB(canvas, 0, 0, w, h, radius); + } + } + /** + * @param {string|HTMLCanvasElement} canvas + * @param {Integer} topX + * @param {Integer} topY + * @param {Integer} width + * @param {Integer} height + * @throws {Error|TypeError} + * @returns {ImageData} See {@link https://html.spec.whatwg.org/multipage/canvas.html#imagedata} + */ + + + function getImageDataFromCanvas(canvas, topX, topY, width, height) { + if (typeof canvas === 'string') { + canvas = document.getElementById(canvas); + } + + if (!canvas || _typeof(canvas) !== 'object' || !('getContext' in canvas)) ; + + var context = canvas.getContext('2d'); + + try { + return context.getImageData(topX, topY, width, height); + } catch (e) {//throw new Error('unable to access image data: ' + e); + } + } + /** + * @param {HTMLCanvasElement} canvas + * @param {Integer} topX + * @param {Integer} topY + * @param {Integer} width + * @param {Integer} height + * @param {Float} radius + * @returns {undefined} + */ + + + function processCanvasRGBA(canvas, topX, topY, width, height, radius) { + if (isNaN(radius) || radius < 1) { + return; + } + + radius |= 0; + var imageData = getImageDataFromCanvas(canvas, topX, topY, width, height); + + if (imageData) { + imageData = processImageDataRGBA(imageData, topX, topY, width, height, radius); + + try { + canvas.getContext('2d').putImageData(imageData, topX, topY); + } catch (e) {} + } + } + /** + * @param {ImageData} imageData + * @param {Integer} topX + * @param {Integer} topY + * @param {Integer} width + * @param {Integer} height + * @param {Float} radius + * @returns {ImageData} + */ + + + function processImageDataRGBA(imageData, topX, topY, width, height, radius) { + var pixels = imageData ? imageData.data : []; + var div = 2 * radius + 1; // const w4 = width << 2; + + var widthMinus1 = width - 1; + var heightMinus1 = height - 1; + var radiusPlus1 = radius + 1; + var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; + var stackStart = new BlurStack(); + var stack = stackStart; + var stackEnd; + + for (var i = 1; i < div; i++) { + stack = stack.next = new BlurStack(); + + if (i === radiusPlus1) { + stackEnd = stack; + } + } + + stack.next = stackStart; + var stackIn = null, + stackOut = null, + yw = 0, + yi = 0; + var mulSum = mulTable[radius]; + var shgSum = shgTable[radius]; + + for (var y = 0; y < height; y++) { + stack = stackStart; + var pr = pixels[yi], + pg = pixels[yi + 1], + pb = pixels[yi + 2], + pa = pixels[yi + 3]; + + for (var _i = 0; _i < radiusPlus1; _i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; + } + + var rInSum = 0, + gInSum = 0, + bInSum = 0, + aInSum = 0, + rOutSum = radiusPlus1 * pr, + gOutSum = radiusPlus1 * pg, + bOutSum = radiusPlus1 * pb, + aOutSum = radiusPlus1 * pa, + rSum = sumFactor * pr, + gSum = sumFactor * pg, + bSum = sumFactor * pb, + aSum = sumFactor * pa; + + for (var _i2 = 1; _i2 < radiusPlus1; _i2++) { + var p = yi + ((widthMinus1 < _i2 ? widthMinus1 : _i2) << 2); + var r = pixels[p], + g = pixels[p + 1], + b = pixels[p + 2], + a = pixels[p + 3]; + var rbs = radiusPlus1 - _i2; + rSum += (stack.r = r) * rbs; + gSum += (stack.g = g) * rbs; + bSum += (stack.b = b) * rbs; + aSum += (stack.a = a) * rbs; + rInSum += r; + gInSum += g; + bInSum += b; + aInSum += a; + stack = stack.next; + } + + stackIn = stackStart; + stackOut = stackEnd; + + for (var x = 0; x < width; x++) { + var paInitial = aSum * mulSum >> shgSum; + pixels[yi + 3] = paInitial; + + if (paInitial !== 0) { + var _a2 = 255 / paInitial; + + pixels[yi] = (rSum * mulSum >> shgSum) * _a2; + pixels[yi + 1] = (gSum * mulSum >> shgSum) * _a2; + pixels[yi + 2] = (bSum * mulSum >> shgSum) * _a2; + } else { + pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; + } + + rSum -= rOutSum; + gSum -= gOutSum; + bSum -= bOutSum; + aSum -= aOutSum; + rOutSum -= stackIn.r; + gOutSum -= stackIn.g; + bOutSum -= stackIn.b; + aOutSum -= stackIn.a; + + var _p = x + radius + 1; + + _p = yw + (_p < widthMinus1 ? _p : widthMinus1) << 2; + rInSum += stackIn.r = pixels[_p]; + gInSum += stackIn.g = pixels[_p + 1]; + bInSum += stackIn.b = pixels[_p + 2]; + aInSum += stackIn.a = pixels[_p + 3]; + rSum += rInSum; + gSum += gInSum; + bSum += bInSum; + aSum += aInSum; + stackIn = stackIn.next; + var _stackOut = stackOut, + _r = _stackOut.r, + _g = _stackOut.g, + _b = _stackOut.b, + _a = _stackOut.a; + rOutSum += _r; + gOutSum += _g; + bOutSum += _b; + aOutSum += _a; + rInSum -= _r; + gInSum -= _g; + bInSum -= _b; + aInSum -= _a; + stackOut = stackOut.next; + yi += 4; + } + + yw += width; + } + + for (var _x = 0; _x < width; _x++) { + yi = _x << 2; + + var _pr = pixels[yi], + _pg = pixels[yi + 1], + _pb = pixels[yi + 2], + _pa = pixels[yi + 3], + _rOutSum = radiusPlus1 * _pr, + _gOutSum = radiusPlus1 * _pg, + _bOutSum = radiusPlus1 * _pb, + _aOutSum = radiusPlus1 * _pa, + _rSum = sumFactor * _pr, + _gSum = sumFactor * _pg, + _bSum = sumFactor * _pb, + _aSum = sumFactor * _pa; + + stack = stackStart; + + for (var _i3 = 0; _i3 < radiusPlus1; _i3++) { + stack.r = _pr; + stack.g = _pg; + stack.b = _pb; + stack.a = _pa; + stack = stack.next; + } + + var yp = width; + var _gInSum = 0, + _bInSum = 0, + _aInSum = 0, + _rInSum = 0; + + for (var _i4 = 1; _i4 <= radius; _i4++) { + yi = yp + _x << 2; + + var _rbs = radiusPlus1 - _i4; + + _rSum += (stack.r = _pr = pixels[yi]) * _rbs; + _gSum += (stack.g = _pg = pixels[yi + 1]) * _rbs; + _bSum += (stack.b = _pb = pixels[yi + 2]) * _rbs; + _aSum += (stack.a = _pa = pixels[yi + 3]) * _rbs; + _rInSum += _pr; + _gInSum += _pg; + _bInSum += _pb; + _aInSum += _pa; + stack = stack.next; + + if (_i4 < heightMinus1) { + yp += width; + } + } + + yi = _x; + stackIn = stackStart; + stackOut = stackEnd; + + for (var _y = 0; _y < height; _y++) { + var _p2 = yi << 2; + + pixels[_p2 + 3] = _pa = _aSum * mulSum >> shgSum; + + if (_pa > 0) { + _pa = 255 / _pa; + pixels[_p2] = (_rSum * mulSum >> shgSum) * _pa; + pixels[_p2 + 1] = (_gSum * mulSum >> shgSum) * _pa; + pixels[_p2 + 2] = (_bSum * mulSum >> shgSum) * _pa; + } else { + pixels[_p2] = pixels[_p2 + 1] = pixels[_p2 + 2] = 0; + } + + _rSum -= _rOutSum; + _gSum -= _gOutSum; + _bSum -= _bOutSum; + _aSum -= _aOutSum; + _rOutSum -= stackIn.r; + _gOutSum -= stackIn.g; + _bOutSum -= stackIn.b; + _aOutSum -= stackIn.a; + _p2 = _x + ((_p2 = _y + radiusPlus1) < heightMinus1 ? _p2 : heightMinus1) * width << 2; + _rSum += _rInSum += stackIn.r = pixels[_p2]; + _gSum += _gInSum += stackIn.g = pixels[_p2 + 1]; + _bSum += _bInSum += stackIn.b = pixels[_p2 + 2]; + _aSum += _aInSum += stackIn.a = pixels[_p2 + 3]; + stackIn = stackIn.next; + _rOutSum += _pr = stackOut.r; + _gOutSum += _pg = stackOut.g; + _bOutSum += _pb = stackOut.b; + _aOutSum += _pa = stackOut.a; + _rInSum -= _pr; + _gInSum -= _pg; + _bInSum -= _pb; + _aInSum -= _pa; + stackOut = stackOut.next; + yi += width; + } + } + + return imageData; + } + /** + * @param {HTMLCanvasElement} canvas + * @param {Integer} topX + * @param {Integer} topY + * @param {Integer} width + * @param {Integer} height + * @param {Float} radius + * @returns {undefined} + */ + + + function processCanvasRGB(canvas, topX, topY, width, height, radius, callback) { + if (isNaN(radius) || radius < 1) { + return; + } + + radius |= 0; + var imageData = getImageDataFromCanvas(canvas, topX, topY, width, height); + AppWorker.blur({ + imageData: imageData, + topX: topX, + topY: topY, + width: width, + height: height, + radius: radius + }, function (imageBlurData) { + try { + canvas.getContext('2d').putImageData(imageBlurData.data, topX, topY); + } catch (e) {} + + callback(); + }); + /* + imageData = processImageDataRGB( + imageData, topX, topY, width, height, radius + ); + try{ + canvas.getContext('2d').putImageData(imageData, topX, topY); + } + catch(e){} + */ + } + /** + * @param {ImageData} imageData + * @param {Integer} topX + * @param {Integer} topY + * @param {Integer} width + * @param {Integer} height + * @param {Float} radius + * @returns {ImageData} + */ + + + function processImageDataRGB(imageData, topX, topY, width, height, radius) { + var pixels = imageData ? imageData.data : []; + var div = 2 * radius + 1; // const w4 = width << 2; + + var widthMinus1 = width - 1; + var heightMinus1 = height - 1; + var radiusPlus1 = radius + 1; + var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; + var stackStart = new BlurStack(); + var stack = stackStart; + var stackEnd; + + for (var i = 1; i < div; i++) { + stack = stack.next = new BlurStack(); + + if (i === radiusPlus1) { + stackEnd = stack; + } + } + + stack.next = stackStart; + var stackIn = null; + var stackOut = null; + var mulSum = mulTable[radius]; + var shgSum = shgTable[radius]; + var p, rbs; + var yw = 0, + yi = 0; + + for (var y = 0; y < height; y++) { + var pr = pixels[yi], + pg = pixels[yi + 1], + pb = pixels[yi + 2], + rOutSum = radiusPlus1 * pr, + gOutSum = radiusPlus1 * pg, + bOutSum = radiusPlus1 * pb, + rSum = sumFactor * pr, + gSum = sumFactor * pg, + bSum = sumFactor * pb; + stack = stackStart; + + for (var _i5 = 0; _i5 < radiusPlus1; _i5++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack = stack.next; + } + + var rInSum = 0, + gInSum = 0, + bInSum = 0; + + for (var _i6 = 1; _i6 < radiusPlus1; _i6++) { + p = yi + ((widthMinus1 < _i6 ? widthMinus1 : _i6) << 2); + rSum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - _i6); + gSum += (stack.g = pg = pixels[p + 1]) * rbs; + bSum += (stack.b = pb = pixels[p + 2]) * rbs; + rInSum += pr; + gInSum += pg; + bInSum += pb; + stack = stack.next; + } + + stackIn = stackStart; + stackOut = stackEnd; + + for (var x = 0; x < width; x++) { + pixels[yi] = rSum * mulSum >> shgSum; + pixels[yi + 1] = gSum * mulSum >> shgSum; + pixels[yi + 2] = bSum * mulSum >> shgSum; + rSum -= rOutSum; + gSum -= gOutSum; + bSum -= bOutSum; + rOutSum -= stackIn.r; + gOutSum -= stackIn.g; + bOutSum -= stackIn.b; + p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; + rInSum += stackIn.r = pixels[p]; + gInSum += stackIn.g = pixels[p + 1]; + bInSum += stackIn.b = pixels[p + 2]; + rSum += rInSum; + gSum += gInSum; + bSum += bInSum; + stackIn = stackIn.next; + rOutSum += pr = stackOut.r; + gOutSum += pg = stackOut.g; + bOutSum += pb = stackOut.b; + rInSum -= pr; + gInSum -= pg; + bInSum -= pb; + stackOut = stackOut.next; + yi += 4; + } + + yw += width; + } + + for (var _x2 = 0; _x2 < width; _x2++) { + yi = _x2 << 2; + + var _pr2 = pixels[yi], + _pg2 = pixels[yi + 1], + _pb2 = pixels[yi + 2], + _rOutSum2 = radiusPlus1 * _pr2, + _gOutSum2 = radiusPlus1 * _pg2, + _bOutSum2 = radiusPlus1 * _pb2, + _rSum2 = sumFactor * _pr2, + _gSum2 = sumFactor * _pg2, + _bSum2 = sumFactor * _pb2; + + stack = stackStart; + + for (var _i7 = 0; _i7 < radiusPlus1; _i7++) { + stack.r = _pr2; + stack.g = _pg2; + stack.b = _pb2; + stack = stack.next; + } + + var _rInSum2 = 0, + _gInSum2 = 0, + _bInSum2 = 0; + + for (var _i8 = 1, yp = width; _i8 <= radius; _i8++) { + yi = yp + _x2 << 2; + _rSum2 += (stack.r = _pr2 = pixels[yi]) * (rbs = radiusPlus1 - _i8); + _gSum2 += (stack.g = _pg2 = pixels[yi + 1]) * rbs; + _bSum2 += (stack.b = _pb2 = pixels[yi + 2]) * rbs; + _rInSum2 += _pr2; + _gInSum2 += _pg2; + _bInSum2 += _pb2; + stack = stack.next; + + if (_i8 < heightMinus1) { + yp += width; + } + } + + yi = _x2; + stackIn = stackStart; + stackOut = stackEnd; + + for (var _y2 = 0; _y2 < height; _y2++) { + p = yi << 2; + pixels[p] = _rSum2 * mulSum >> shgSum; + pixels[p + 1] = _gSum2 * mulSum >> shgSum; + pixels[p + 2] = _bSum2 * mulSum >> shgSum; + _rSum2 -= _rOutSum2; + _gSum2 -= _gOutSum2; + _bSum2 -= _bOutSum2; + _rOutSum2 -= stackIn.r; + _gOutSum2 -= stackIn.g; + _bOutSum2 -= stackIn.b; + p = _x2 + ((p = _y2 + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; + _rSum2 += _rInSum2 += stackIn.r = pixels[p]; + _gSum2 += _gInSum2 += stackIn.g = pixels[p + 1]; + _bSum2 += _bInSum2 += stackIn.b = pixels[p + 2]; + stackIn = stackIn.next; + _rOutSum2 += _pr2 = stackOut.r; + _gOutSum2 += _pg2 = stackOut.g; + _bOutSum2 += _pb2 = stackOut.b; + _rInSum2 -= _pr2; + _gInSum2 -= _pg2; + _bInSum2 -= _pb2; + stackOut = stackOut.next; + yi += width; + } + } + + return imageData; + } + /** + * + */ + + + var BlurStack = + /** + * Set properties. + */ + function BlurStack() { + _classCallCheck(this, BlurStack); + + this.r = 0; + this.g = 0; + this.b = 0; + this.a = 0; + this.next = null; + }; + var Blur = { + /** + * @function module:StackBlur.image + * @see module:StackBlur~processImage + */ + image: processImage, + + /** + * @function module:StackBlur.canvasRGBA + * @see module:StackBlur~processCanvasRGBA + */ + canvasRGBA: processCanvasRGBA, + + /** + * @function module:StackBlur.canvasRGB + * @see module:StackBlur~processCanvasRGB + */ + canvasRGB: processCanvasRGB, + + /** + * @function module:StackBlur.imageDataRGBA + * @see module:StackBlur~processImageDataRGBA + */ + imageDataRGBA: processImageDataRGBA, + + /** + * @function module:StackBlur.imageDataRGB + * @see module:StackBlur~processImageDataRGB + */ + imageDataRGB: processImageDataRGB + }; + + var canvas = document.createElement('canvas'), + ctx = canvas.getContext('2d'); + canvas.width = 30; + canvas.height = 17; + var canvas_poster = document.createElement('canvas'), + ctx_poster = canvas_poster.getContext('2d'); + + function extract$2(img_data) { + var data = img_data.data, + colors = []; + + for (var i = 0, n = data.length; i < n; i += 4) { + colors.push([data[i], data[i + 1], data[i + 2]]); + } + + return colors; + } + + function palette(palette) { + var colors = { + bright: [0, 0, 0], + average: [127, 127, 127], + dark: [255, 255, 255] + }; + var ar = 0, + ag = 0, + ab = 0, + at = palette.length; + var bg = 0, + dk = 765; + + for (var i = 0; i < palette.length; i++) { + var p = palette[i], + a = p[0] + p[1] + p[2]; + ar += p[0]; + ag += p[1]; + ab += p[2]; + + if (a > bg) { + bg = a; + colors.bright = p; + } + + if (a < dk) { + dk = a; + colors.dark = p; + } + } + + colors.average = [Math.round(ar / at), Math.round(ag / at), Math.round(ab / at)]; + return colors; + } + + function rgba(c) { + var o = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return 'rgba(' + c.join(',') + ',' + o + ')'; + } + + function tone(c) { + var o = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + var s = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 30; + var l = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 80; + var hls = rgbToHsl(c[0], c[1], c[2]); + var rgb = hslToRgb$1(hls[0], Math.min(s, hls[1]), l); + return rgba(rgb, o); + } + /** + * Converts an RGB color value to HSL. + * + * @param {number} r The red color value + * @param {number} g The green color value + * @param {number} b The blue color value + * @return {Array} The HSL representation + */ + + + function rgbToHsl(r, g, b) { + var rabs, gabs, babs, rr, gg, bb, h, s, v, diff, diffc, percentRoundFn; + rabs = r / 255; + gabs = g / 255; + babs = b / 255; + v = Math.max(rabs, gabs, babs), diff = v - Math.min(rabs, gabs, babs); + + diffc = function diffc(c) { + return (v - c) / 6 / diff + 1 / 2; + }; + + percentRoundFn = function percentRoundFn(num) { + return Math.round(num * 100) / 100; + }; + + if (diff == 0) { + h = s = 0; + } else { + s = diff / v; + rr = diffc(rabs); + gg = diffc(gabs); + bb = diffc(babs); + + if (rabs === v) { + h = bb - gg; + } else if (gabs === v) { + h = 1 / 3 + rr - bb; + } else if (babs === v) { + h = 2 / 3 + gg - rr; + } + + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + + return [Math.round(h * 360), percentRoundFn(s * 100), percentRoundFn(v * 100)]; + } + /** + * Converts an HSL color value to RGB. + * + * @param {number} h The hue + * @param {number} s The saturation + * @param {number} l The lightness + * @return {Array} The RGB representation + */ + + + function hslToRgb$1(h, s, l) { + s /= 100; + l /= 100; + var C = (1 - Math.abs(2 * l - 1)) * s; + var hue = h / 60; + var X = C * (1 - Math.abs(hue % 2 - 1)); + var r = 0, + g = 0, + b = 0; + + if (hue >= 0 && hue < 1) { + r = C; + g = X; + } else if (hue >= 1 && hue < 2) { + r = X; + g = C; + } else if (hue >= 2 && hue < 3) { + g = C; + b = X; + } else if (hue >= 3 && hue < 4) { + g = X; + b = C; + } else if (hue >= 4 && hue < 5) { + r = X; + b = C; + } else { + r = C; + b = X; + } + + var m = l - C / 2; + r += m; + g += m; + b += m; + r *= 255.0; + g *= 255.0; + b *= 255.0; + return [Math.round(r), Math.round(g), Math.round(b)]; + } + + function reset$2(width, height) { + canvas.width = width; + canvas.height = height; + } + + function get$f(img) { + reset$2(30, 17); + var ratio = Math.max(canvas.width / img.width, canvas.height / img.height); + var nw = img.width * ratio, + nh = img.height * ratio; + ctx.drawImage(img, -(nw - canvas.width) / 2, -(nh - canvas.height) / 2, nw, nh); + return extract$2(ctx.getImageData(0, 0, canvas.width, canvas.height)); + } + + function blur$1(img, callback) { + reset$2(200, 130); + var ratio = Math.max(canvas.width / img.width, canvas.height / img.height); + var nw = img.width * ratio, + nh = img.height * ratio; + ctx.drawImage(img, -(nw - canvas.width) / 2, -(nh - canvas.height) / 2, nw, nh); + Blur.canvasRGB(canvas, 0, 0, canvas.width, canvas.height, 80, function () { + var nimg = new Image(); + + try { + nimg.src = canvas.toDataURL(); + } catch (e) {} + + setTimeout(function () { + callback(nimg); + }, 100); + }); + } + + function getImg(callback) { + var im = new Image(); + + try { + im.src = canvas_poster.toDataURL(); + } catch (e) {} + + setTimeout(function () { + callback(im); + }, 100); + } + + function blurPoster(img, w, h, callback) { + canvas_poster.width = w; + canvas_poster.height = h; + var ratio = Math.max(canvas_poster.width / img.width, canvas_poster.height / img.height); + var nw = img.width * ratio, + nh = img.height * ratio; + setTimeout(function () { + ctx_poster.drawImage(img, -(nw - canvas_poster.width) / 2, -(nh - canvas_poster.height) / 2, nw, nh); + Blur.canvasRGB(canvas_poster, 0, 0, canvas_poster.width, canvas_poster.height, 50, function () { + var gradient = ctx_poster.createLinearGradient(0, 0, 0, canvas_poster.height); + gradient.addColorStop(0.5, 'rgba(0, 0, 0, 1)'); + gradient.addColorStop(0.6, 'rgba(0, 0, 0, 0)'); + gradient.addColorStop(1, 'rgba(0, 0, 0, 1)'); + ctx_poster.globalCompositeOperation = 'destination-out'; + ctx_poster.fillStyle = gradient; + ctx_poster.fillRect(0, 0, canvas_poster.width, canvas_poster.height); + ctx_poster.globalCompositeOperation = 'source-over'; + getImg(function (blured) { + canvas_poster.width = w; + canvas_poster.height = h; + ctx_poster.drawImage(img, -(nw - canvas_poster.width) / 2, -(nh - canvas_poster.height) / 2, nw, nh); + var gradient = ctx_poster.createLinearGradient(0, 0, 0, canvas_poster.height); + gradient.addColorStop(0, 'rgba(0, 0, 0, 1)'); + gradient.addColorStop(0.6, 'rgba(0, 0, 0, 1)'); + gradient.addColorStop(0.65, 'rgba(0, 0, 0, 0)'); + gradient.addColorStop(1, 'rgba(0, 0, 0, 0)'); + ctx_poster.globalCompositeOperation = 'destination-in'; + ctx_poster.fillStyle = gradient; + ctx_poster.fillRect(0, 0, canvas_poster.width, canvas_poster.height); + ctx_poster.globalCompositeOperation = 'source-over'; + ctx_poster.drawImage(blured, 0, 0); + getImg(callback); + }); + }); + }, 100); + } + + function rgbToHex(r, g, b) { + return "#" + (1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1); + } + + function circlePattern() { + var size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 20; + var w = 200; + var h = 200; + reset$2(w, h); + var r = size / 2; + + for (var y = 0; y < h; y += size) { + var offset = y / size % 2 ? r : 0; + + for (var x = 0; x < w; x += size) { + ctx.beginPath(); + ctx.arc(x + r + offset, y + r, r, 0, Math.PI * 2); + ctx.fillStyle = Math.random() > 0.5 ? '#000' : '#fff'; + ctx.fill(); + } + } + + return canvas.toDataURL(); + } + + var Color = { + get: get$f, + extract: extract$2, + palette: palette, + rgba: rgba, + blur: blur$1, + tone: tone, + rgbToHsl: rgbToHsl, + rgbToHex: rgbToHex, + hslToRgb: hslToRgb$1, + blurPoster: blurPoster, + circlePattern: circlePattern + }; + + var lifecycleEvents = Subscribe$2(); + var restoring = false; + var deferred = []; + function whenRestored(call) { + if (restoring) deferred.push(call);else call(); + } // AVPlay forbids further calls until restoreAsync has invoked a callback. + + function lifecycle(av, doc, onError, getUrl) { + var saved; + var disposed = false; + var phase = 'active'; + var settleTimer; + var settleDeadline; + var readyStarted = false; + + function report(type) { + var details = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + lifecycleEvents.send('event', Object.assign({ + type: type + }, details)); + } + + function release() { + restoring = false; + var calls = deferred; + deferred = []; + calls.forEach(function (call) { + return call(); + }); + } + + function fail(type, error) { + clearTimeout(settleTimer); + phase = 'active'; + report(type, { + error: error && error.name || 'Error' + }); + saved = undefined; + if (!disposed) onError(); + } + + function settle() { + if (disposed || phase !== 'resuming') return; + + try { + var state = av.getState(); // On this TV the restore callback precedes completion of buffering. + + if (state !== 'PLAYING' && state !== 'PAUSED') { + if (Date.now() >= settleDeadline) throw { + name: 'RestoreTimeoutError' + }; + + if (state === 'READY' && !readyStarted) { + readyStarted = true; + av.play(); + } + + settleTimer = setTimeout(settle, 100); + return; + } + + if (saved.paused && state === 'PLAYING') av.pause();else if (!saved.paused && state === 'PAUSED') av.play(); + state = av.getState(); + report('restored', { + state: state, + positionMs: av.getCurrentTime(), + beforeState: saved.state, + beforePositionMs: saved.positionMs + }); + phase = 'active'; + saved = undefined; + if (doc.hidden) hide(); + } catch (error) { + fail('restore-error', error); + } + } + + function hide() { + if (disposed || restoring || phase !== 'active') return; + + try { + var state = av.getState(); + if (state !== 'PLAYING' && state !== 'PAUSED') return; + + if (typeof av.suspend !== 'function' || typeof av.restoreAsync !== 'function' && typeof av.restore !== 'function') { + report('suspend-unavailable'); + return; + } + + saved = { + state: state, + positionMs: av.getCurrentTime(), + paused: state === 'PAUSED' + }; + + try { + saved.durationMs = av.getDuration(); + } catch (error) { + saved.durationMs = 0; + } + + av.suspend(); + phase = 'suspended'; + report('suspended', { + state: saved.state, + positionMs: saved.positionMs + }); + } catch (error) { + fail('suspend-error', error); + } + } + + function show() { + if (disposed || restoring || phase !== 'suspended') return; + phase = 'restoring'; + restoring = true; + report('restore-start', { + state: saved.state, + positionMs: saved.positionMs + }); + var settled = false; + + function success() { + if (settled) return; + settled = true; // This callback is the first point at which AVPlay calls are safe. + + if (disposed) { + release(); + return; + } + + phase = 'resuming'; + readyStarted = false; + settleDeadline = Date.now() + 15000; + + try { + report('restore-callback', { + state: av.getState() + }); + } catch (error) { + fail('restore-error', error); + } + + release(); + settle(); + } + + function failure(error) { + if (settled) return; + settled = true; + fail('restore-error', error); + release(); + } + + try { + // Some TV bindings reject null optional arguments with TypeMismatchError. + // Keep the URL private and pass the captured position as an unsigned integer. + var url = getUrl(); + if (typeof url !== 'string' || !url) throw { + name: 'InvalidValuesError' + }; + var position = Math.max(0, Math.min(4294967295, Math.round(saved.positionMs))); + if (saved.durationMs <= 0 && position === 0) position = 1; + if (typeof av.restoreAsync === 'function') av.restoreAsync(url, position, false, success, failure);else { + av.restore(url, position, false); + success(); + } + } catch (error) { + failure(error); + } + } + + function visibility() { + if (doc.hidden) hide();else show(); + } + + doc.addEventListener('visibilitychange', visibility); + return { + blocked: function blocked() { + return restoring || phase === 'suspended' || phase === 'resuming'; + }, + position: function position() { + return saved ? saved.positionMs / 1000 : 0; + }, + duration: function duration() { + return saved ? saved.durationMs / 1000 : 0; + }, + paused: function paused() { + return saved ? saved.paused : false; + }, + intent: function intent(paused) { + if (saved) saved.paused = paused; + }, + visibility: visibility, + destroy: function destroy() { + disposed = true; + clearTimeout(settleTimer); + doc.removeEventListener('visibilitychange', visibility); + saved = undefined; + } + }; + } + + function AVPlay$1(call_video) { + var stream_url, loaded; + console.log('Player', 'run Tizen'); + var object = $(''); + var video = object[0]; + var listener = Subscribe$2(); + var destroyed = false; + var lifecycle$1 = lifecycle(webapis.avplay, document, function () { + video.error = { + code: 'tizen', + message: 'Failed to restore playback. Please reopen the video.' + }; + listener.send('error', { + error: video.error + }); + }, function () { + return stream_url; + }); + var change_scale_later; + var change_speed_later; + object.width(window.innerWidth); + object.height(window.innerHeight); + /** + * Установить урл + */ + + Object.defineProperty(video, "src", { + set: function set(url) { + whenRestored(function () { + if (url && !destroyed) { + stream_url = url; + + try { + webapis.avplay.open(url); + webapis.avplay.setDisplayRect(0, 0, window.innerWidth, window.innerHeight); + webapis.avplay.setDisplayMethod('PLAYER_DISPLAY_MODE_LETTER_BOX'); + } catch (e) { + listener.send('error', { + error: { + code: 'tizen', + message: 'failed to initialize player' + } + }); + } + + try { + webapis.avplay.setSilentSubtitle(false); + } catch (e) {} + } + }); + }, + get: function get() {} + }); + /** + * Позиция + */ + + Object.defineProperty(video, "currentTime", { + set: function set(t) { + if (lifecycle$1.blocked()) return; + + try { + webapis.avplay.seekTo(t * 1000); + } catch (e) {} + }, + get: function get() { + if (lifecycle$1.blocked()) return lifecycle$1.position(); + var d = 0; + + try { + d = webapis.avplay.getCurrentTime(); + } catch (e) {} + + return d ? d / 1000 : 0; + } + }); + /** + * Длительность + */ + + Object.defineProperty(video, "duration", { + set: function set() {}, + get: function get() { + if (lifecycle$1.blocked()) return lifecycle$1.duration(); + var d = 0; + + try { + d = webapis.avplay.getDuration(); + } catch (e) {} + + return d ? d / 1000 : 0; + } + }); + /** + * Пауза + */ + + Object.defineProperty(video, "paused", { + set: function set() {}, + get: function get() { + if (lifecycle$1.blocked()) return lifecycle$1.paused(); + + try { + return webapis.avplay.getState() == 'PAUSED'; + } catch (e) { + return false; + } + } + }); + /** + * Аудиодорожки + */ + + Object.defineProperty(video, "audioTracks", { + set: function set() {}, + get: function get() { + if (lifecycle$1.blocked()) return []; + + try { + var totalTrackInfo = webapis.avplay.getTotalTrackInfo(); + var tracks = totalTrackInfo.filter(function (track) { + return track.type === 'AUDIO'; + }).map(function (track) { + var info = JSON.parse(track.extra_info); + var item = { + extra: JSON.parse(track.extra_info), + index: parseInt(track.index), + language: info.language + }; + Object.defineProperty(item, "enabled", { + set: function set(v) { + if (lifecycle$1.blocked()) return; + + if (v) { + try { + webapis.avplay.setSelectTrack('AUDIO', item.index); + } catch (e) { + console.log('Player', 'no change audio:', e.message); + } + } + }, + get: function get() {} + }); + return item; + }).sort(function (a, b) { + return a.index - b.index; + }); + return tracks; + } catch (e) { + return []; + } + } + }); + /** + * Субтитры + */ + + Object.defineProperty(video, "textTracks", { + set: function set() {}, + get: function get() { + if (lifecycle$1.blocked()) return []; + + try { + var totalTrackInfo = webapis.avplay.getTotalTrackInfo(); + var tracks = totalTrackInfo.filter(function (track) { + return track.type === 'TEXT'; + }).map(function (track) { + var info = JSON.parse(track.extra_info), + item = { + extra: JSON.parse(track.extra_info), + index: parseInt(track.index), + language: info.track_lang + }; + Object.defineProperty(item, "mode", { + set: function set(v) { + if (lifecycle$1.blocked()) return; + + if (v == 'showing') { + try { + webapis.avplay.setSelectTrack('TEXT', item.index); + } catch (e) { + console.log('Player', 'no change text:', e.message); + } + } + }, + get: function get() {} + }); + return item; + }).sort(function (a, b) { + return a.index - b.index; + }); + console.log('Tizen', 'tracks', tracks); + console.log('Tizen', 'tracks index', tracks.map(function (a) { + return a.index; + })); + return tracks; + } catch (e) { + return []; + } + } + }); + /** + * Ширина видео + */ + + Object.defineProperty(video, "videoWidth", { + set: function set() {}, + get: function get() { + var info = videoInfo(); + return info.Width || 0; + } + }); + /** + * Высота видео + */ + + Object.defineProperty(video, "videoHeight", { + set: function set() {}, + get: function get() { + var info = videoInfo(); + return info.Height || 0; + } + }); + /** + * Получить информацию о видео + * @returns {object} + */ + + function videoInfo() { + if (lifecycle$1.blocked()) return {}; + + try { + var info = webapis.avplay.getCurrentStreamInfo(), + json = {}; + + for (var i = 0; i < info.length; i++) { + var detail = info[i]; + + if (detail.type == 'VIDEO') { + json = JSON.parse(detail.extra_info); + } + } + + return json; + } catch (e) { + return {}; + } + } + /** + * Меняем размер видео + * @param {string} scale - default|cover + */ + + + function changeScale(scale) { + if (lifecycle$1.blocked()) return; + + try { + if (scale == 'cover') { + webapis.avplay.setDisplayMethod('PLAYER_DISPLAY_MODE_FULL_SCREEN'); + } else { + webapis.avplay.setDisplayMethod('PLAYER_DISPLAY_MODE_LETTER_BOX'); + } + } catch (e) { + change_scale_later = scale; + } + } + + function changeSpeed(speed) { + if (lifecycle$1.blocked()) return; + + try { + webapis.avplay.setSpeed(speed); + } catch (e) { + change_speed_later = speed; + } + } + /** + * Всегда говорим да, мы можем играть + */ + + + video.canPlayType = function () { + return true; + }; + /** + * Вешаем кастомные события + */ + + + video.addEventListener = listener.follow.bind(listener); + /** + * Вешаем события от плеера тайзен + */ + + whenRestored(function () { + if (destroyed) return; + webapis.avplay.setListener({ + onbufferingstart: function onbufferingstart() { + listener.send('progress', { + percent: 0 + }); + listener.send('waiting'); + }, + onbufferingprogress: function onbufferingprogress(percent) { + listener.send('progress', { + percent: percent + }); + }, + onbufferingcomplete: function onbufferingcomplete() { + listener.send('progress', { + percent: 0 + }); + listener.send('playing'); + }, + onstreamcompleted: function onstreamcompleted() { + if (lifecycle$1.blocked()) return; + webapis.avplay.stop(); + listener.send('ended'); + }, + oncurrentplaytime: function oncurrentplaytime() { + listener.send('timeupdate'); + + if (change_scale_later) { + change_scale_later = false; + changeScale(change_scale_later); + } + + if (change_speed_later) { + change_speed_later = false; + changeSpeed(change_speed_later); + } + }, + onerror: function onerror(eventType) { + listener.send('error', { + error: { + code: 'tizen', + message: eventType + } + }); + }, + onevent: function onevent(eventType, eventData) { + console.log('Player', 'event type:', eventType, 'data:', eventData); + }, + onsubtitlechange: function onsubtitlechange(duration, text, data3, data4) { + listener.send('subtitle', { + text: text + }); + }, + ondrmevent: function ondrmevent(drmEvent, drmData) {} + }); + }); + /** + * Загрузить + */ + + video.load = function () { + whenRestored(function () { + if (stream_url && !destroyed) { + webapis.avplay.prepareAsync(function () { + if (destroyed) return; + loaded = true; + webapis.avplay.play(); + + try { + webapis.avplay.setSilentSubtitle(false); + } catch (e) {} + + listener.send('canplay'); + listener.send('playing'); + listener.send('loadeddata'); + lifecycle$1.visibility(); + }, function (e) { + listener.send('error', { + error: 'code [' + e.code + '] ' + e.message + }); + }); + } + }); + }; + /** + * Играть + */ + + + video.play = function () { + if (lifecycle$1.blocked()) { + lifecycle$1.intent(false); + return; + } + + if (loaded) webapis.avplay.play(); + }; + /** + * Пауза + */ + + + video.pause = function () { + if (lifecycle$1.blocked()) { + lifecycle$1.intent(true); + return; + } + + if (loaded) webapis.avplay.pause(); + }; + /** + * Установить масштаб + */ + + + video.size = function (type) { + changeScale(type); + }; + /** + * Установить скорость + */ + + + video.speed = function (speed) { + changeSpeed(speed); + }; + /** + * Уничтожить + */ + + + video.destroy = function () { + destroyed = true; + lifecycle$1.destroy(); + whenRestored(function () { + try { + webapis.avplay.close(); + } catch (e) {} + }); + video.remove(); + listener.destroy(); + }; + + call_video(video); + return object; + } + + /** + * Возможность управлять внутренними субтитрами на webos через пульт + */ + + var subparams; + + var listener$l = function listener(e) { + if (e.code == 405) getWebosmediaId(setSubtitleColor); + if (e.code == 406) getWebosmediaId(setSubtitleBackgroundColor); + if (e.code == 403) getWebosmediaId(setSubtitleFontSize); + if (e.code == 404) getWebosmediaId(setSubtitlePosition); + if (e.code == 55) getWebosmediaId(setSubtitleBackgroundOpacity); + if (e.code == 57) getWebosmediaId(setSubtitleCharacterOpacity); + }; + + Keypad.listener.follow('keydown', listener$l); + + function luna$1(params, call, fail) { + if (call) params.onSuccess = call; + + params.onFailure = function (result) { + console.log('WebOS', params.method + " [fail][" + result.errorCode + "] " + result.errorText); + if (fail) fail(); + }; + + webOS.service.request("luna://com.webos.media", params); + } + + function initStorage() { + if (!subparams) { + subparams = Storage.get('webos_subs_params', '{}'); + Arrays.extend(subparams, { + color: 2, + font_size: 1, + bg_color: 'black', + position: -1, + bg_opacity: 0, + char_opacity: 255 + }); + } + } + + function subCallParams(mediaId, method, func_params) { + var parameters = { + mediaId: mediaId + }; + Arrays.extend(parameters, func_params); + luna$1({ + parameters: parameters, + method: method + }); + Storage.set('webos_subs_params', subparams); + } + + function getWebosmediaId(func) { + var video = document.querySelector('video'); + + if (video && video.mediaId) { + initStorage(); + setTimeout(function () { + subCallParams(video.mediaId, func.name, func()); + }, 300); + } + } + + function setSubtitleColor() { + subparams.color++; + if (subparams.color == 6) subparams.color = 0; + return { + color: subparams.color + }; + } + + function setSubtitleBackgroundColor() { + var bgcolors = ['black', 'white', 'yellow', 'red', 'green', 'blue']; + var ixcolors = bgcolors.indexOf(subparams.bg_color); + ixcolors++; + if (ixcolors == -1) ixcolors = 0; + subparams.bg_color = bgcolors[ixcolors]; + return { + bgColor: subparams.bg_color + }; + } + + function setSubtitleFontSize() { + subparams.font_size++; + if (subparams.font_size == 5) subparams.font_size = 0; + return { + fontSize: subparams.font_size + }; + } + + function setSubtitlePosition() { + subparams.position++; + if (subparams.position == 5) subparams.position = -3; + return { + position: subparams.position + }; + } + + function setSubtitleBackgroundOpacity() { + subparams.bg_opacity += 15; + if (subparams.bg_opacity > 255) subparams.bg_opacity = 0; + return { + bgOpacity: subparams.bg_opacity + }; + } + + function setSubtitleCharacterOpacity() { + subparams.char_opacity += 15; + if (subparams.char_opacity > 255) subparams.char_opacity = 45; + return { + charOpacity: subparams.char_opacity + }; + } + + function initialize() { + var video = document.querySelector('video'); + + if (video && video.mediaId) { + initStorage(); + var methods = ['setSubtitleColor', 'setSubtitleBackgroundColor', 'setSubtitleFontSize', 'setSubtitlePosition', 'setSubtitleBackgroundOpacity', 'setSubtitleCharacterOpacity']; + var parameters = { + mediaId: video.mediaId, + color: subparams.color, + bgColor: subparams.bg_color, + position: subparams.position, + fontSize: subparams.font_size, + bgOpacity: subparams.bg_opacity, + charOpacity: subparams.char_opacity + }; + Arrays.extend(parameters, subparams); + methods.forEach(function (method) { + luna$1({ + parameters: parameters, + method: method + }); + }); + } + } + + var Subtitles$1 = { + initialize: initialize + }; + + /** + * Для запросов в луну + * @param {object} params + * @param {function} call + * @param {function} fail + */ + + function luna(params, call, fail) { + if (call) params.onSuccess = call; + + params.onFailure = function (result) { + console.log('WebOS', params.method + " [fail][" + result.errorCode + "] " + result.errorText); + if (fail) fail(); + }; + + webOS.service.request("luna://com.webos.media", params); + } + + function create$c(_video) { + var video = _video; + var media_id; + var subtitle_visible = false; + var timer; + var timer_repet; + var count = 0; + var count_message = 0; + var data = { + subs: [], + tracks: [] + }; + this.listener = Subscribe$2(); + this.subscribed = false; + this.repeted = false; + /** + * Начинаем поиск видео + */ + + this.start = function () { + timer = setInterval(this.search.bind(this), 300); + }; + /** + * Включить/выключить сабы + * @param {boolean} status + */ + + + this.toggleSubtitles = function (status) { + subtitle_visible = status; + luna({ + method: 'setSubtitleEnable', + parameters: { + 'mediaId': media_id, + 'enable': status + } + }); + if (status) Subtitles$1.initialize(); + }; + /** + * Получили сабы, выводим в панель + * @param {object} info + */ + + + this.subtitles = function (info) { + var _this = this; + + if (info.numSubtitleTracks) { + var all = []; + + var add = function add(sub, index) { + sub.index = index; + sub.language = sub.language == '(null)' ? '' : sub.language; + Object.defineProperty(sub, 'mode', { + set: function set(v) { + if (v == 'showing') { + _this.toggleSubtitles(sub.index == -1 ? false : true); + + console.log('WebOS', 'change subtitles for id: ', media_id, ' index:', sub.index); + + if (sub.index !== -1) { + setTimeout(function () { + luna({ + method: 'selectTrack', + parameters: { + 'type': 'text', + 'mediaId': media_id, + 'index': sub.index + } + }); + }, 500); + } + } + }, + get: function get() {} + }); + all.push(sub); + }; + + add({ + title: Lang.translate('player_disabled'), + selected: true + }, -1); + + for (var i = 0; i < info.subtitleTrackInfo.length; i++) { + add(info.subtitleTrackInfo[i], i); + } + + data.subs = all; + this.listener.send('webos_subs', { + subs: data.subs + }); // Video.listener.send('webos_subs',{subs:data.subs}) + // Panel.setSubs(data.subs) + } + }; + /** + * Получили дорожки, выводим в панель + * @param {object} info + */ + + + this.tracks = function (info) { + if (info.numAudioTracks) { + var all = []; + + var add = function add(track, index) { + track.index = index; + track.selected = index == -1; + track.extra = { + channels: track.channels, + fourCC: track.codec + }; + Object.defineProperty(track, 'enabled', { + set: function set(v) { + if (v) { + console.log('WebOS', 'change audio for id:', media_id, ' index:', track.index); + luna({ + method: 'selectTrack', + parameters: { + 'type': 'audio', + 'mediaId': media_id, + 'index': track.index + } + }); + + if (video.audioTracks) { + for (var i = 0; i < video.audioTracks.length; i++) { + video.audioTracks[i].enabled = false; + } + + if (video.audioTracks[track.index]) { + video.audioTracks[track.index].enabled = true; + console.log('WebOS', 'change audio two method:', track.index); + } + } + } + }, + get: function get() {} + }); + all.push(track); + }; + + for (var i = 0; i < info.audioTrackInfo.length; i++) { + add(info.audioTrackInfo[i], i); + } + + data.tracks = all; + this.listener.send('webos_tracks', { + tracks: data.tracks + }); // Video.listener.send('webos_tracks',{tracks:data.tracks}) + // Panel.setTracks(data.tracks, true) + } + }; + /** + * Подписываемся на видео и ждем события + */ + + + this.subscribe = function () { + var _this2 = this; + + this.subscribed = true; + luna({ + method: 'subscribe', + parameters: { + 'mediaId': media_id, + 'subscribe': true + } + }, function (result) { + if (result.sourceInfo && !_this2.sourceInfo) { + _this2.sourceInfo = true; + var info = result.sourceInfo.programInfo[0]; + + _this2.subtitles(info); + + _this2.tracks(info); + + _this2.unsubscribe(); + + _this2.call(); + } + + if (result.bufferRange) { + count_message++; + + if (count_message == 30) { + _this2.unsubscribe(); + + _this2.call(); + } + } + }, function () { + _this2.call(); + }); + }; + /** + * Отписка от видео + */ + + + this.unsubscribe = function () { + luna({ + method: 'unload', + parameters: { + 'mediaId': media_id + } + }); + }; + /** + * Сканируем наличия видео + */ + + + this.search = function () { + var _this3 = this; + + count++; + + if (count > 3) { + clearInterval(timer); + clearInterval(timer_repet); + } + + var rootSubscribe = function rootSubscribe() { + console.log('WebOS', 'Run root', 'version:', webOS.sdk_version); + + _this3.toggleSubtitles(false); + + if (_this3.subscribed) clearInterval(timer_repet); + if (!_this3.subscribed) _this3.subscribe();else { + if (data.tracks.length) { + _this3.listener.send('webos_tracks', { + tracks: data.tracks + }); // Video.listener.send('webos_tracks',{tracks:data.tracks}) + // Panel.setTracks(data.tracks,true) + + } + + if (data.subs.length) { + _this3.listener.send('webos_subs', { + subs: data.subs + }); // Video.listener.send('webos_subs',{subs:data.subs}) + // Panel.setSubs(data.subs) + + } + } + clearInterval(timer); + }; + + console.log('WebOS', 'try get id:', video.mediaId); + + if (video.mediaId) { + media_id = video.mediaId; + console.log('WebOS', 'video id:', media_id); + rootSubscribe(); + } + }; + /** + * Вызываем и завершаем работу + */ + + + this.call = function () { + if (this.callback) this.callback(); + this.callback = false; + }; + + this.speed = function (v) { + luna({ + method: 'setPlayRate', + parameters: { + 'mediaId': media_id, + 'playRate': v, + 'audioOutput': true + } + }); + }; + /** + * Создаем новое видео + * @param {object} new_video + */ + + + this.repet = function (new_video) { + video = new_video; + console.log('WebOS', 'repeat to new video', new_video ? true : false); + media_id = ''; + clearInterval(timer); + count = 0; + this.repeted = true; + timer_repet = setInterval(this.search.bind(this), 300); + }; + /** + * После перемотки включаем состояние сабов + */ + + + this.rewinded = function () { + this.toggleSubtitles(subtitle_visible); + }; + /** + * Уничтожить + */ + + + this.destroy = function () { + clearInterval(timer); + clearInterval(timer_repet); + if (media_id) this.unsubscribe(); + data = null; + this.subscribed = false; + this.callback = false; + }; + } + + var keydown_time = 0; + var duble_click_time = 0; + var move_time = 0; + var touch = false; + + function init$1m() { + Keypad.listener.follow('keydown', function () { + keydown_time = Date.now(); + move_time = 0; + }); + $(window).on('mousemove', function (e) { + move_time = Date.now(); + }).on('touchstart', function () { + touch = true; + }); + Storage.listener.follow('change', function (e) { + if (e.name == 'navigation_type') { + Storage.set('is_true_mobile', Boolean(e.value == 'touch'), true); + Controller.toContent(); + window.location.reload(); + } + }); + } + + function canClick(e) { + return Date.now() - keydown_time < 200 ? false : touch || Platform.is('browser') || Platform.tv() || Platform.desktop() || Date.now() - move_time < 200; + } + + function noDubleClick(e) { + if (Date.now() - duble_click_time < 200) { + e.preventDefault(); + e.stopPropagation(); + return false; + } + + duble_click_time = Date.now(); + return true; + } + + var DeviceInput = { + init: init$1m, + canClick: canClick, + noDubleClick: noDubleClick + }; + + var html$o; + var scroll$4; + var active$8; + var listener$k = Subscribe$2(); + /** + * Инициализирует селектбокс + * @returns {void} + */ + + function init$1l() { + html$o = Template.get('selectbox'); + scroll$4 = new Scroll({ + mask: true, + over: true + }); + html$o.find('.selectbox__body').append(scroll$4.render()); + html$o.find('.selectbox__layer').on('click', function (e) { + if (DeviceInput.canClick(e.originalEvent)) Controller.back(); + }); + scroll$4.addSwipeDown(function () { + html$o.addClass('animate-down'); + setTimeout(function () { + Controller.back(); + }, 200); + }); + $('body').append(html$o); + } + /** + * Заполняет селектбокс элементами + * @returns {void} + */ + + + function bind$4() { + scroll$4.clear(); + scroll$4.reset(); + html$o.find('.selectbox__title').text(active$8.title); + html$o.toggleClass('selectbox--fullsize', active$8.fullsize ? true : false); + var need_first_scroll = true; + active$8.items.forEach(function (element) { + if (element.hide) return; + element.title = Utils$1.capitalizeFirstLetter(element.title || ''); + + if (element.separator) { + var _item = $('
    ' + element.title + '
    '); + + return scroll$4.append(_item); + } + + var item = element.html || Template.get(element.template || (element.thumbnail ? 'selectbox_icon' : 'selectbox_item'), element); + if (!element.subtitle) item.find('.selectbox-item__subtitle').remove(); + + if (element.thumbnail) { + item.find('.selectbox-item__icon').empty().append(''); + } + + if (element.checkbox) { + item.addClass('selectbox-item--checkbox'); + item.append('
    '); + if (element.checked) item.addClass('selectbox-item--checked'); + } + + if (element.ghost) item.css('opacity', 0.5); + item.on('hover:focus', function (e) { + // Первый скролл делаем мгновенным, чтобы не было анимации при открытии + if (need_first_scroll) scroll$4.immediate($(e.target), true);else scroll$4.update($(e.target), true); + need_first_scroll = false; + if (active$8.onFocus) active$8.onFocus(element, e.target); + }); + + if (!element.noenter) { + var goclose = function goclose() { + if (!active$8.nohide) hide$4();else { + scroll$4.render().find('.selected').removeClass('selected'); + item.addClass('selected'); + } + if (element.onSelect) element.onSelect(element, item);else if (active$8.onSelect) active$8.onSelect(element, item); + }; + + item.on('hover:enter', function () { + if (element.checkbox) { + element.checked = !element.checked; + item.toggleClass('selectbox-item--checked', element.checked); + if (element.onCheck) element.onCheck(element, item);else if (active$8.onCheck) active$8.onCheck(element, item); + } else if (active$8.onBeforeClose) { + if (active$8.onBeforeClose()) goclose(); + } else goclose(); + }).on('hover:long', function (e) { + if (active$8.onLong) active$8.onLong(element, e.target); + }); + } + + if (element.selected) item.addClass('selected'); + if (element.picked) item.addClass('picked'); + if (active$8.nomark) item.addClass('nomark'); + if (element.onDraw) element.onDraw(item, element);else if (active$8.onDraw) active$8.onDraw(item, element); + scroll$4.append(item); + }); + if (active$8.onFullDraw) active$8.onFullDraw(scroll$4); + } + /** + * Отображает селектбокс + * @param {object} object - параметры селектбокса + * @param {string} object.title - заголовок селектбокса + * @param {boolean} [object.fullsize=false] - использовать весь экран + * @param {Array} object.items - массив элементов + * @param {boolean} [object.nomark=false] - не выделять выбранный элемент + * @param {boolean} [object.nohide=false] - не закрывать селектбокс после выбора элемента + * @param {function} [object.onSelect] - вызывается при выборе элемента + * @param {function} [object.onCheck] - вызывается при изменении состояния чекбокса + * @param {function} [object.onFocus] - вызывается при фокусе на элементе + * @param {function} [object.onLong] - вызывается при долгом нажатии на элемент + * @param {function} [object.onBack] - вызывается при закрытии селектбокса + * @param {function} [object.onDraw] - вызывается при отрисовке элемента + * @param {function} [object.onFullDraw] - вызывается после полной отрисовки всех элементов + * @param {function} [object.onBeforeClose] - вызывается перед закрытием селектбокса, если возвращает true, селектбокс закроется + * @param {boolean} [object.noenter=false] - отключить выбор элемента по кнопке ОК/Enter + * @returns {void} + */ + + + function show$e(object) { + active$8 = object; + scroll$4.body().toggleClass('notransition', true); + listener$k.send('preshow', { + active: active$8 + }); + bind$4(); + $('body').toggleClass('selectbox--open', true); + html$o.find('.selectbox__body').addClass('layer--wheight').css('max-height', window.innerWidth <= 480 ? window.innerHeight * 0.6 : 'unset').data('mheight', html$o.find('.selectbox__head')); + html$o.addClass('animate'); + Activity.mixState('select=open'); + listener$k.send('fullshow', { + active: active$8, + html: html$o + }); + toggle$c(); + } + /** + * Переключает контроллер на селектбокс + * @returns {void} + */ + + + function toggle$c() { + Controller.add('select', { + toggle: function toggle() { + var selected = scroll$4.render().find('.selected'); + Controller.collectionSet(html$o); + Controller.collectionFocus(selected.length ? selected[0] : false, html$o); + listener$k.send('toggle', { + active: active$8, + html: html$o + }); + }, + up: function up() { + Navigator.move('up'); + }, + down: function down() { + Navigator.move('down'); + }, + left: close$a, + back: close$a + }); + Controller.toggle('select'); + } + /** + * Скрывает селектбокс + * @returns {void} + */ + + + function hide$4() { + $('body').toggleClass('selectbox--open', false); + html$o.removeClass('animate animate-down'); + listener$k.send('hide', { + active: active$8 + }); + } + /** + * Проверяет, открыт ли селектбокс + * @returns {boolean} - true, если селектбокс открыт, иначе false + */ + + + function opened$3() { + return $('body').hasClass('selectbox--open'); + } + /** + * Закрывает селектбокс + * @returns {void} + */ + + + function close$a() { + hide$4(); + Activity.mixState(); + if (active$8.onBack) active$8.onBack(); + listener$k.send('close', { + active: active$8 + }); + } + /** + * Возвращает HTML селектбокса + * @param {boolean} [js=false] - вернуть DOM-элемент вместо jQuery + * @returns {jQuery|HTMLElement} - HTML селектбокса + */ + + + function render$m(js) { + return js ? html$o[0] : html$o; + } + + var Select = { + listener: listener$k, + init: init$1l, + show: show$e, + opened: opened$3, + hide: hide$4, + close: close$a, + render: render$m + }; + + var elems$1; + var html$n; + + function init$1k() { + html$n = Template.get('player_panel'); + elems$1 = { + peding: $('.player-panel__peding', html$n), + position: $('.player-panel__position', html$n), + time: $('.player-panel__time', html$n), + timenow: $('.player-panel__timenow', html$n), + timeend: $('.player-panel__timeend', html$n), + title: $('.player-panel__filename', html$n), + tracks: $('.player-panel__tracks', html$n), + subs: $('.player-panel__subs', html$n), + timeline: $('.player-panel__timeline', html$n), + quality: $('.player-panel__quality', html$n), + flow: $('.player-panel__flow', html$n), + episode: $('.player-panel__next-episode-name', html$n), + rewind_touch: $('.player-panel__time-touch-zone', html$n), + playlist: html$n.find('.player-panel__playlist'), + next: html$n.find('.player-panel__next'), + prev: html$n.find('.player-panel__prev'), + playpause: html$n.find('.player-panel__playpause'), + rprev: html$n.find('.player-panel__rprev'), + rnext: html$n.find('.player-panel__rnext'), + tstart: html$n.find('.player-panel__tstart'), + tend: html$n.find('.player-panel__tend'), + fullscreen: html$n.find('.player-panel__fullscreen'), + settings: html$n.find('.player-panel__settings'), + pip: html$n.find('.player-panel__pip'), + volume: html$n.find('.player-panel__volume'), + left: html$n.find('.player-panel__left'), + right: html$n.find('.player-panel__right'), + center: html$n.find('.player-panel__center'), + playlist_buttons: html$n.find('.player-panel__playlist-buttons'), + mobile_more: $('.player-panel__mobile-more', html$n), + iptv_channel: $('.player-panel-iptv__channel', html$n), + iptv_arrow_up: $('.player-panel-iptv__arrow-up', html$n), + iptv_arrow_down: $('.player-panel-iptv__arrow-down', html$n), + iptv_position: $('.player-panel-iptv__position', html$n), + segments: $('.player-panel__timeline-segments', html$n) + }; + } + + function elem(name) { + return elems$1[name]; + } + + function render$l() { + return html$n; + } + + var Html = { + init: init$1k, + render: render$l, + elem: elem + }; + + var listener$j = Subscribe$2(); + + var tracks = []; + var subs = []; + var flows = false; + var qualitys = false; + var translates = {}; + + function normalName(name) { + return name.replace(/^[0-9]+(\.)?([\t ]+)?/, '').replace(/\s#[0-9]+/, ''); + } + + function init$1j() { + /** + * Выбор потока + */ + Html.elem('flow').on('hover:enter', function () { + if (flows) { + var enabled = Controller.enabled().name; + Select.show({ + title: Lang.translate('player_flow'), + items: flows, + onSelect: function onSelect(a) { + flows.forEach(function (element) { + element.enabled = false; + element.selected = false; + }); + a.enabled = true; + a.selected = true; + Controller.toggle(enabled); + listener$j.send('flow', { + url: a.url + }); + }, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + } + }); + /** + * Выбор качества + */ + + Html.elem('quality').text('auto').on('hover:enter', function () { + if (qualitys) { + var qs = []; + var nw = Html.elem('quality').text(); + + if (Arrays.isArray(qualitys)) { + qs = qualitys; + } else { + for (var i in qualitys) { + var qa = qualitys[i]; + var qu = _typeof(qa) == 'object' ? qa.url : typeof qa == 'string' ? qa : ''; + var lb = _typeof(qa) == 'object' ? qa.label : ''; + qs.push({ + quality: i, + title: i + (lb ? '' + lb + '' : ''), + url: qu, + selected: nw == Utils$1.qualityToText(i), + call: _typeof(qa) == 'object' ? qa.call : false, + instance: qa + }); + } + } + + if (!qs.length) return; + var enabled = Controller.enabled().name; + Select.show({ + title: Lang.translate('player_quality'), + items: qs, + onSelect: function onSelect(a) { + if (a.call) { + Controller.toggle(enabled); + a.call(a.instance, function (url) { + Html.elem('quality').text(Utils$1.qualityToText(a.quality)); + qs.forEach(function (q) { + return q.selected = false; + }); + a.selected = true; + listener$j.send('quality', { + name: a.quality, + url: url + }); + if (a.instance && a.instance.trigger) a.instance.trigger(); + }); + } else { + Html.elem('quality').text(Utils$1.qualityToText(a.quality)); + qs.forEach(function (q) { + return q.selected = false; + }); + a.enabled = true; + a.selected = true; + if (!Arrays.isArray(qualitys) || a.change_quality) listener$j.send('quality', { + name: a.quality, + url: a.url + }); + if (a.instance && a.instance.trigger) a.instance.trigger(); + Controller.toggle(enabled); + } + }, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + } + }); + /** + * Выбор аудиодорожки + */ + + Html.elem('tracks').on('hover:enter', function (e) { + if (tracks.length) { + tracks.forEach(function (element, p) { + var name = []; + var from = translates.tracks && Arrays.isArray(translates.tracks) && translates.tracks[p] ? translates.tracks[p] : element; + name.push(p + 1); + name.push(normalName(from.language || from.name || Lang.translate('player_unknown'))); + if (from.label) name.push(normalName(from.label)); + + if (from.extra) { + if (from.extra.channels) name.push(from.extra.channels + ' Ch'); + if (from.extra.fourCC) name.push(from.extra.fourCC); + } + + element.title = name.join(' / '); + }); + var enabled = Controller.enabled().name; + Select.show({ + title: Lang.translate('player_tracks'), + items: tracks, + onSelect: function onSelect(a) { + tracks.forEach(function (element) { + element.enabled = false; + element.selected = false; + }); + a.enabled = true; + a.selected = true; + Controller.toggle(enabled); + if (a.onSelect) a.onSelect(a); + }, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + } + }); + /** + * Выбор субтитров + */ + + Html.elem('subs').on('hover:enter', function (e) { + if (subs.length) { + if (subs[0].index !== -1) { + var any_select = subs.find(function (s) { + return s.selected; + }); + Arrays.insert(subs, 0, { + title: Lang.translate('player_disabled'), + selected: any_select ? false : true, + index: -1 + }); + } + + subs.forEach(function (element, p) { + if (element.index !== -1) { + var track_num = element.extra && element.extra.track_num ? parseInt(element.extra.track_num) : element.index; + var from = translates.subs && Arrays.isArray(translates.subs) && translates.subs[track_num] ? translates.subs[track_num] : element; + element.title = p + ' / ' + normalName(from.language && from.label ? from.language + ' / ' + from.label : from.language || from.label || Lang.translate('player_unknown')); + } + }); + var enabled = Controller.enabled().name; + Select.show({ + title: Lang.translate('player_subs'), + items: subs, + onSelect: function onSelect(a) { + subs.forEach(function (element) { + element.mode = 'disabled'; + element.selected = false; + }); + a.mode = 'showing'; + a.selected = true; + listener$j.send('subsview', { + status: a.index > -1 + }); + Controller.toggle(enabled); + if (a.onSelect) a.onSelect(a); + }, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + } + }); + Html.elem('mobile_more').on('hover:enter', function (e) { + var enabled = Controller.enabled().name; + var items = []; + items.push({ + title: Lang.translate('player_quality'), + template: 'selectbox_icon', + icon: '', + onSelect: function onSelect() { + Controller.toggle(enabled); + Html.elem('quality').trigger('hover:enter'); + } + }); + Html.render().find('.player-panel__tv-visible .button:not(.hide, .player-panel__fullscreen)').each(function (i, el) { + var btn = $(el); + var icon = btn.find('svg').clone().wrap('
    ').parent().html(); + var title = btn.find('.tooltip').text(); + if (!title) return; + items.push({ + title: title, + template: 'selectbox_icon', + icon: icon, + onSelect: function onSelect() { + Controller.toggle(enabled); + btn.trigger('hover:enter'); + } + }); + }); + Select.show({ + title: Lang.translate('more'), + items: items, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + }); + } + /** + * Установить субтитры + * @param {Array} su - массив субтитров + */ + + + function setSubtitles(su) { + if (!su) return; + subs = su; + Html.elem('subs').toggleClass('hide', false); + } + /** + * Установить аудиодорожки + * @param {Array} tr - массив аудиодорожек + */ + + + function setTracks(tr) { + if (!tr) return; + tracks = tr; + Html.elem('tracks').toggleClass('hide', false); + } + /** + * Установить уровни качества из HLS + * @param {Object} levels + * @param {String} current + */ + + + function setLevels(levels, current) { + if (qualitys && Object.keys(qualitys).length) return; + qualitys = levels; + Html.elem('quality').text(Utils$1.qualityToText(current)); + } + /** + * Установить выбор качества + * @param {Object|Array} qs + * @param {String} url + */ + + + function setQualitys(qs, url) { + if (qs) { + Html.elem('quality').toggleClass('hide', false); + qualitys = qs; + + for (var i in qs) { + var qa = qs[i]; + var qu = _typeof(qa) == 'object' ? qa.url : typeof qa == 'string' ? qa : ''; + + if (qu == url) { + Html.elem('quality').text(Utils$1.qualityToText(i)); + break; + } + } + } + } + /** + * Установить переводы дорожек и субтитров + * @param {Object} data - объект переводов + */ + + + function setTranslates(data) { + if (_typeof(data) == 'object') translates = data; + } + /** + * Обновить переводы дорожек и субтитров + * @param {String} where - tracks/subs + * @param {Array} data - массив переводов + */ + + + function updateTranslate(where, data) { + if (!translates[where]) translates[where] = data; + } + /** + * Установить потоки + * @param {Object} data - объект потоков + */ + + + function setFlows(data) { + flows = _typeof(data) == 'object' ? data : false; + Html.elem('flow').toggleClass('hide', flows ? false : true); + } + /** + * Проверить наличие качества + * @returns {Boolean|Object|Array} - false если нет качества, иначе объект или массив качества + */ + + + function hasQuality() { + return qualitys; + } + + function destroy$q() { + tracks = []; + subs = []; + qualitys = false; + flows = false; + translates = {}; + Html.elem('quality').text('auto'); + Html.elem('subs').toggleClass('hide', true); + Html.elem('tracks').toggleClass('hide', true); + Html.elem('flow').toggleClass('hide', true); + } + + var Option = { + init: init$1j, + setSubtitles: setSubtitles, + setTracks: setTracks, + setLevels: setLevels, + setQualitys: setQualitys, + setTranslates: setTranslates, + updateTranslate: updateTranslate, + setFlows: setFlows, + hasQuality: hasQuality, + destroy: destroy$q + }; + + var language_codes = { + ara: 'ar', + arm: 'hy', + hye: 'hy', + aze: 'az', + bel: 'be', + bul: 'bg', + chi: 'zh', + zho: 'zh', + cze: 'cs', + ces: 'cs', + dan: 'da', + dut: 'nl', + nld: 'nl', + eng: 'en', + est: 'et', + fin: 'fi', + fre: 'fr', + fra: 'fr', + geo: 'ka', + kat: 'ka', + ger: 'de', + deu: 'de', + gre: 'el', + ell: 'el', + heb: 'he', + hin: 'hi', + hun: 'hu', + ice: 'is', + isl: 'is', + ita: 'it', + jpn: 'ja', + kaz: 'kk', + kor: 'ko', + lav: 'lv', + lit: 'lt', + mac: 'mk', + mkd: 'mk', + nor: 'no', + per: 'fa', + fas: 'fa', + pol: 'pl', + por: 'pt', + rum: 'ro', + ron: 'ro', + rus: 'ru', + slo: 'sk', + slk: 'sk', + slv: 'sl', + spa: 'es', + swe: 'sv', + tur: 'tr', + ukr: 'uk', + uzb: 'uz', + vie: 'vi' + }; + + function languageCode$1(value) { + var code = String(value || '').trim().toLowerCase().replace(/_/g, '-').split('-')[0]; + if (code == 'ua') code = 'uk'; + return language_codes[code] || code; + } + /** + * Выбрать субтитры для автозапуска: сначала дорожки нужного языка, среди них «Полные», иначе первая + * @param {array} subs - список субтитров + * @param {string} code - код языка (ru, en, es, spa, es-ES...) + * @returns {object|undefined} + */ + + + function preferredSubtitle(subs, code) { + var list = subs.filter(function (s) { + return s; + }); + var lang = languageCode$1(code); + var same = list.filter(function (s) { + return languageCode$1(s.language || s.lang || s.srclang) == lang; + }); + var pool = same.length ? same : list; + + var full = function full(s) { + return (s.label || '').indexOf('олные') >= 0; + }; + + return lang == 'ru' && list.find(full) || pool.find(full) || pool[0]; + } + + function usefulDescription(tags) { + var title = tags && (tags.title || tags.TITLE); + var handler = tags && (tags.handler_name || tags.HANDLER_NAME); + var description = String(title || handler || '').trim(); + return /^(sound|audio)\s*handler$/i.test(description) ? '' : description; + } + + function tracksFromFfprobe(streams) { + if (!Array.isArray(streams)) return []; + return streams.filter(function (stream) { + return stream && stream.codec_type == 'audio'; + }).map(function (stream) { + var tags = stream.tags || {}; + return { + language: tags.language || tags.LANGUAGE || '', + label: usefulDescription(tags), + extra: { + channels: stream.channel_layout || stream.channels, + fourCC: stream.codec_name || stream.codec_long_name || '' + } + }; + }); + } + + var _webos = null; + + function convertToArray$1(arr) { + if (!Arrays.isArray(arr)) { + var new_arr = []; + + for (var index = 0; index < arr.length; index++) { + new_arr.push(arr[index]); + } + + arr = new_arr; + } + + return arr; + } + + function loadSubs(params, subsview) { + if (!_webos.parsed_subtitles) return; + var subs = _webos.parsed_subtitles; + PlayerVideo.video().webos_subs = subs; + var inx = params.sub + 1; + + if (typeof params.sub !== 'undefined' && subs[inx]) { + subs.forEach(function (e) { + e.mode = 'disabled'; + e.selected = false; + }); + subs[inx].mode = 'showing'; + subs[inx].selected = true; + console.log('WebOS', 'enable subs', inx); + subsview(true); + } else if (Storage.field('subtitles_start')) { + var code = Storage.field('subtitles_lang'); + var pick = preferredSubtitle(subs.slice(1), code == 'auto' ? Storage.get('language', 'ru') : code); + subs[0].selected = false; + + if (pick) { + pick.mode = 'showing'; + pick.selected = true; + } + + subsview(true); + } + } + + function loadTracks(params) { + if (!_webos.parsed_tracks) return; + var tracks = _webos.parsed_tracks; + PlayerVideo.video().webos_tracks = tracks; + + if (typeof params.track !== 'undefined' && tracks[params.track]) { + tracks.forEach(function (e) { + return e.selected = false; + }); + console.log('WebOS', 'enable tracks', params.track); + tracks[params.track].enabled = true; + tracks[params.track].selected = true; + } + } + /** + * Инициализация WebOS + */ + + + function setup() { + if (!Platform.is('webos') || _webos || Player.playdata().voiceovers) return; + _webos = new create$c(PlayerVideo.video()); + + _webos.callback = function () { + var currentVideo = PlayerVideo.video(); + var src = currentVideo.src; + var sub = currentVideo.customSubs; + console.log('WebOS', 'video loaded'); + $(currentVideo).remove(); + var norm = PlayerVideo.normalization(); + if (norm) norm.destroy(); + PlayerVideo.url(src, true); + var newVideo = PlayerVideo.video(); + newVideo.customSubs = sub; + + _webos.repet(newVideo); + + PlayerVideo.listener.send('reset_continue', {}); + }; + + _webos.listener.follow('webos_subs', function (e) { + PlayerVideo.listener.send('webos_subs', e); // Для совместимости с плагинами, которые используют старый способ получения субтитров + + _webos.parsed_subtitles = convertToArray$1(e.subs); + Option.setSubtitles(e.subs); + }); + + _webos.listener.follow('webos_tracks', function (e) { + PlayerVideo.listener.send('webos_tracks', e); // Для совместимости с плагинами, которые используют старый способ получения аудиодорожек + + _webos.parsed_tracks = convertToArray$1(e.tracks); + Option.setTracks(e.tracks); + }); + + _webos.start(); + } + + function handleLoaded(params, subsview) { + if (!_webos || !_webos.sourceInfo) return false; + if (_webos.parsed_tracks) loadTracks(params); + if (_webos.parsed_subtitles) loadSubs(params, subsview); + return true; + } + + function audioTracks$2() { + if (_webos && _webos.sourceInfo) return PlayerVideo.video().webos_tracks || []; + return null; + } + + function rewinded() { + if (_webos) _webos.rewinded(); + } + + function speed$1(value) { + if (_webos) _webos.speed(value); + } + + function isActive$3() { + return !!_webos; + } + + function destroy$p() { + if (_webos) _webos.destroy(); + _webos = null; + } + + var WebOSManager = { + setup: setup, + handleLoaded: handleLoaded, + audioTracks: audioTracks$2, + rewinded: rewinded, + speed: speed$1, + isActive: isActive$3, + destroy: destroy$p + }; + + var video_tube = []; + + function register(params) { + if (typeof params.verify === 'function' && typeof params.create === 'function') { + if (video_tube.indexOf(params) == -1) video_tube.push(params); + return true; + } + + return false; + } + + function verify(src) { + var find = video_tube.find(function (e) { + return e.verify(src); + }); + return find ? find : false; + } + + function remove$5(params) { + Arrays.remove(video_tube, params); + } + + var Tube = { + register: register, + verify: verify, + remove: remove$5 + }; + + function parse$c(data) { + var result = { + hash_string: '', + season: null, + episode: null, + serial: !!data.movie.number_of_seasons + }; + var regexps = [[/\bs(\d+)\.?ep?(\d+)\b/i, 'season', 'episode'], [/\b(\d{1,2})[x\-](\d+)\b/i, 'season', 'episode'], [/\bs(\d{2})(\d{2,3})\b/i, 'season', 'episode'], [/season (\d+) episode (\d+)/i, 'season', 'episode'], [/сезон (\d+) серия (\d+)/i, 'season', 'episode'], [/(\d+) season (\d+) episode/i, 'season', 'episode'], [/(\d+) сезон (\d+) серия/i, 'season', 'episode'], [/episode (\d+)/i, 'episode'], [/серия (\d+)/i, 'episode'], [/(\d+) episode/i, 'episode'], [/(\d+) серия/i, 'episode'], [/season (\d+)/i, 'season'], [/сезон (\d+)/i, 'season'], [/(\d+) season/i, 'season'], [/(\d+) сезон/i, 'season'], [/\bs(\d+)\b/i, 'season'], [/\bep?\.?(\d+)\b/i, 'episode'], [/\b(\d{1,3}) of (\d+)/i, 'episode'], [/\b(\d{1,3}) из (\d+)/i, 'episode'], [/ - (\d{1,3})\b/i, 'episode'], [/\[(\d{1,3})\]/i, 'episode'], [/(\d+) сер/i, 'episode']]; + var folder_regexps = [[/season (\d+)/i, 'season'], [/сезон (\d+)/i, 'season'], [/(\d+) season/i, 'season'], [/(\d+) сезон/i, 'season'], [/\bs(\d+)\b/i, 'season']]; + var parts = data.path.replace(/_/g, ' ').split('/'); + var fname = parts.pop(); + var folder = parts.pop(); + regexps.forEach(function (regexp) { + var match = fname.match(regexp[0]); + + if (match) { + var arr = regexp.slice(1); + arr.forEach(function (a, i) { + var v = match[i + 1]; + if (v && result[a] == null) result[a] = parseInt(v); + }); + } + }); + + if (folder && result.season == null) { + folder_regexps.forEach(function (regexp) { + var match = folder.match(regexp[0]); + + if (match) { + var arr = regexp.slice(1); + arr.forEach(function (a, i) { + var v = match[i + 1]; + if (v && result[a] == null) result[a] = parseInt(v); + }); + } + }); + } + + if (result.season == null) result.season = data.movie.number_of_seasons ? 1 : 0; + + if (result.episode == null) { + var match = data.filename.replace(/_/g, ' ').trim().match(/^(\d{1,3})\b/i); + result.episode = match ? parseInt(match[1]) : 0; + } + + if (!data.is_file) { + if (data.movie.number_of_seasons) { + result.hash_string = [result.season, result.season > 10 ? ':' : '', result.episode, data.movie.original_title].join(''); + } else if (data.movie.original_title && !result.serial) { + result.hash_string = data.movie.original_title; + } else { + result.hash_string = data.path; + } + } else { + result.hash_string = data.path; + } + + return result; + } + + var EpisodeParser = { + parse: parse$c + }; + + var network$b = new Request(); + var gst_work = false; + /** + * Возвращает url сервера + * @returns {string} + */ + + function url$5() { + var u = ip(); + return u ? Utils$1.checkEmptyUrl(u) : u; + } + /** + * Возвращает ip сервера + * @returns {string} + */ + + + function ip() { + var one = Storage.get('torrserver_url'); + var two = Storage.get('torrserver_url_two'); + return Storage.field('torrserver_use_link') == 'two' ? two || one : one || two; + } + /** + * Возвращает список торрентов + * @param {function} success - функция при успешном получении списка + * @param {function} fail - функция при ошибке получения списка + * @returns {void} + */ + + + function my(success, fail) { + var data = JSON.stringify({ + action: 'list' + }); + clear$d(); + network$b.silent(url$5() + '/torrents', function (result) { + if (result.length) success(result);else fail(); + }, fail, data); + } + /** + * Возвращает статистику загрузки торрента по хэшу + * @param {string} hash - хэш торрента + * @param {function} success - функция при успешном получении статистики + */ + + + function cache$1(hash, success, fail) { + var data = JSON.stringify({ + action: 'get', + hash: hash + }); + network$b.silent(url$5() + '/cache', success, fail, data); + } + + function viewed$2(hash, success, fail) { + var data = JSON.stringify({ + action: 'list', + hash: hash + }); + clear$d(); + network$b.timeout(5000); + network$b.silent(url$5() + '/viewed', success, fail, data); + } + + function viewedSet(hash, file_index, timecode, success, fail) { + var data = JSON.stringify({ + action: 'set', + hash: hash, + file_index: file_index, + timecode: timecode + }); + network$b.silent(url$5() + '/viewed', success, fail, data); + } + /** + * Добавляет торрент на сервер + * @param {object} object - объект с данными торрента + * @param {function} success - функция при успешном добавлении + * @param {function} fail - функция при ошибке добавления + */ + + + function add$e(object, success, fail) { + var send_data = object.data ? Arrays.clone(object.data) : false; + var category = 'movie'; + + if (send_data && send_data.movie) { + category = send_data.movie.name ? 'tv' : 'movie'; + send_data.movie = Utils$1.clearCard(send_data.movie); + } + + var json = { + action: 'add', + link: object.link, + title: '[LAMPA] ' + (object.title + '').replace('??', '?'), + poster: object.poster, + data: send_data ? JSON.stringify(send_data) : '', + save_to_db: true, + category: category + }; + var data = JSON.stringify(json); + clear$d(); + network$b.silent(url$5() + '/torrents', success, fail, data); + } + /** + * Добавляет торрент на сервер с проверкой хэша + * @param {object} object - объект с данными торрента + * @param {function} success - функция при успешном добавлении + * @param {function} fail - функция при ошибке добавления + */ + + + function hash$1(object, success, fail) { + var send_data = object.data ? Arrays.clone(object.data) : false; + var category = 'movie'; + + if (send_data && send_data.movie) { + category = send_data.movie.name ? 'tv' : 'movie'; + send_data.movie = Utils$1.clearCard(send_data.movie); + } + + var json = { + action: 'add', + link: object.link, + title: '[LAMPA] ' + (object.title + '').replace('??', '?'), + poster: object.poster, + data: send_data ? JSON.stringify(send_data) : '', + save_to_db: Storage.get('torrserver_savedb', 'false'), + category: category + }; + var data = JSON.stringify(json); + clear$d(); + network$b.silent(url$5() + '/torrents', success, function (a, c) { + fail(network$b.errorDecode(a, c)); + }, data); + } + /** + * Возвращает список файлов торрента по хэшу + * @param {string} hash - хэш торрента + * @param {function} success - функция при успешном получении списка файлов + * @param {function} fail - функция при ошибке получения списка файлов + */ + + + function files$1(hash, success, fail) { + var data = JSON.stringify({ + action: 'get', + hash: hash + }); + clear$d(); + network$b.timeout(2000); + network$b.silent(url$5() + '/torrents', function (json) { + if (json.file_stats) { + success(json); + } + }, fail, data); + } + /** + * Проверяет соединение с сервером + * @param {function} success - функция при успешном соединении + * @param {function} fail - функция при ошибке соединения + */ + + + function connected(success, fail) { + clear$d(); + network$b.timeout(5000); + network$b.silent(url$5() + '/settings', function (json) { + if (typeof json.CacheSize == 'undefined') { + fail(Lang.translate('torrent_error_nomatrix')); + } else { + success(json); + } + + gstCheck(); + }, function (a, c) { + fail(network$b.errorDecode(a, c)); + }, JSON.stringify({ + action: 'get' + })); + } + /** + * Проверяет работу gstreamer на сервере + * @returns {void} + */ + + + function gstCheck() { + network$b.silent(url$5() + '/gst/echo', function (json) { + gst_work = true; + }, function (a, c) { + gst_work = false; + }); + } + /** + * Возвращает true, если gstreamer работает на сервере + * @returns {boolean} + */ + + + function gstWork() { + return Storage.field('torrserver_gts') && gst_work; + } + /** + * Возвращает ссылку на потоковое воспроизведение файла торрента + * @param {string} path - путь к файлу торрента + * @param {string} hash - хэш торрента + * @param {number} id - индекс файла в торрента + * @returns {string} - ссылка на потоковое воспроизведение + */ + + + function stream(path, hash, id) { + if (gstWork()) return url$5() + '/gst/' + encodeURIComponent(hash) + '/master.m3u8?index=' + id + '&audio=0'; + return url$5() + '/stream/' + encodeURIComponent(path.split('\\').pop().split('/').pop()) + '?link=' + hash + '&index=' + id + '&' + (Storage.field('torrserver_preload') ? 'preload' : 'play'); + } + /** + * Возвращает ссылку на потоковое воспроизведение файла торрента с заменой параметра preload на play + * @param {string} url - ссылка на потоковое воспроизведение + * @returns {string} - ссылка на потоковое воспроизведение с заменой параметра preload на play + */ + + + function toPlayUrl(url) { + return ip() && url.indexOf(ip()) >= 0 ? url.replace('&preload', '&play') : url; + } + /** + * Дропает торрент с сервера + * @param {string} hash - хэш торрента + * @param {function} success - функция при успешном удалении + * @param {function} fail - функция при ошибке удаления + */ + + + function drop(hash, success, fail) { + if (gstWork()) return network$b.silent(url$5() + '/gst/remove?hash=' + encodeURIComponent(hash), success, fail, data, { + dataType: 'text' + }); + var data = JSON.stringify({ + action: 'drop', + hash: hash + }); + clear$d(); + network$b.silent(url$5() + '/torrents', success, fail, data, { + dataType: 'text' + }); + } + /** + * Удаляет торрент с сервера + * @param {string} hash - хэш торрента + * @param {function} success - функция при успешном удалении + * @param {function} fail - функция при ошибке удаления + */ + + + function remove$4(hash, success, fail) { + var data = JSON.stringify({ + action: 'rem', + hash: hash + }); + clear$d(); + network$b.silent(url$5() + '/torrents', success, fail, data, { + dataType: 'text' + }); + } + /** + * Парсит данные торрента и возвращает объект с информацией о нем + * @param {object} data - данные торрента + * @returns {object} - объект с информацией о торрента + */ + + + function parse$b(data) { + var result = EpisodeParser.parse(data); + result.hash = Utils$1.hash(result.hash_string); + return result; + } + /** + * Очищает имена файлов торрента от лишних символов и возвращает массив с объектами файлов + * @param {array} files - массив с объектами файлов торрента + * @returns {array} - массив с объектами файлов торрента с очищенными именами + */ + + + function clearFileName(files) { + var combo = []; + files.forEach(function (element) { + var spl = element.path.split('/'); + var nam = spl[spl.length - 1].split('.'); + if (nam.length > 1) nam.pop(); + nam = nam.join('.'); + element.path_human = Utils$1.pathToNormalTitle(nam, false).trim(); + + if (spl.length > 1) { + spl.pop(); + element.folder_name = Utils$1.pathToNormalTitle(spl.pop(), false).trim(); + } + }); + + if (files.length > 1) { + files.forEach(function (element) { + var spl = element.path_human.split(' '); + + for (var i = spl.length - 1; i >= 0; i--) { + var com = spl.join(' '); + if (combo.indexOf(com) == -1) combo.push(com); + spl.pop(); + } + }); + combo.sort(function (a, b) { + return a.length > b.length ? -1 : a.length < b.length ? 1 : 0; + }); + + var _loop = function _loop(i) { + var com = combo[i]; + var len = files.filter(function (f) { + return f.path_human.slice(0, com.length) == com; + }).length; + if (len < files.length) Arrays.remove(combo, com); + }; + + for (var i = combo.length - 1; i >= 0; i--) { + _loop(i); + } + + files.forEach(function (element) { + for (var _i = 0; _i < combo.length; _i++) { + var com = combo[_i]; + var inx = element.path_human.indexOf(com); + + if (inx >= 0 && com !== element.path_human) { + element.path_human = element.path_human.slice(com.length).trim(); + break; + } + } + }); + } + + return files; + } + /** + * Очищает очередь запросов к серверу + * @returns {void} + */ + + + function clear$d() { + network$b.clear(); + } + /** + * Показывает модальное окно с информацией об ошибке соединения с сервером + * @returns {void} + */ + + + function error$3() { + var temp = Template.get('torrent_error', { + ip: ip() + }); + var list = temp.find('.torrent-checklist__list > li'); + var info = temp.find('.torrent-checklist__info > div'); + var next = temp.find('.torrent-checklist__next-step'); + var prog = temp.find('.torrent-checklist__progress-bar > div'); + var comp = temp.find('.torrent-checklist__progress-steps'); + var btn = temp.find('.selector'); + var position = -2; + + function makeStep() { + position++; + list.slice(0, position + 1).addClass('wait'); + var total = list.length; + comp.text(Lang.translate('torrent_error_made') + ' ' + Math.max(0, position) + ' ' + Lang.translate('torrent_error_from') + ' ' + total); + + if (position > list.length) { + Modal.close(); + Controller.toggle('content'); + } else if (position >= 0) { + info.addClass('hide'); + info.eq(position).removeClass('hide'); + var next_step = list.eq(position + 1); + prog.css('width', Math.round(position / total * 100) + '%'); + list.slice(0, position).addClass('check'); + btn.text(position < total ? Lang.translate('torrent_error_next') : Lang.translate('torrent_error_complite')); + next.text(next_step.length ? '- ' + next_step.text() : ''); + } + } + + makeStep(); + btn.on('hover:enter', function () { + makeStep(); + }); + Modal.title(Lang.translate('torrent_error_connect')); + Modal.update(temp); + Controller.add('modal', { + invisible: true, + toggle: function toggle() { + Controller.collectionSet(temp); + Controller.collectionFocus(false, temp); + }, + back: function back() { + Modal.close(); + Controller.toggle('content'); + } + }); + Controller.toggle('modal'); + } + + var Torserver = { + ip: ip, + my: my, + add: add$e, + url: url$5, + hash: hash$1, + files: files$1, + clear: clear$d, + drop: drop, + stream: stream, + remove: remove$4, + connected: connected, + parse: parse$b, + error: error$3, + cache: cache$1, + gstWork: gstWork, + clearFileName: clearFileName, + toPlayUrl: toPlayUrl, + viewed: viewed$2, + viewedSet: viewedSet + }; + + /** + * Добавляет шапку с кнопкой назад + * @param {string} title - заголовок шапки + * @param {boolean} js - возвращать HTMLElement объект + * @returns {HTMLElement|jQuery} - элемент шапки + */ + + function HeadBackward (title, js) { + var head = Template[js ? 'js' : 'get']('head_backward', { + title: title + }); + head.find('.head-backward__button').on('click', Controller.back.bind(Controller)); + return head; + } + + /** + * Статическая машина состояний + * @param {Object} object - Объект состояний и переходов + * @example + let fsm = new StateMachine({ + state: 'idle', //начальное состояние + transitions: { + idle: function() { + console.log('idle') + this.state = 'loading' + this.dispath(this.state) + }, + loading: function() { + console.log('loading') + this.state = 'complete' + this.dispath(this.state) + }, + complete: function() { + console.log('complete') + } + } + }) + fsm.start() // запустить машину + */ + function StateMachine(object) { + this.state = object.state; + + this.start = function () { + this.dispath(this.state); + }; + + this.dispath = function (action_name) { + var action = object.transitions[action_name]; + + if (action) { + action.call(this); + } else { + console.log('invalid action'); + } + }; + } + + var components$1 = {}; + var params$3 = {}; + /** + * Добавить компонент + * @param {{component:string, icon:string, name:string}} data + */ + + function addComponent(data) { + components$1[data.component] = data; + Template.add('settings_' + data.component, '
    '); + } + /** + * Получить компонент + * @param {string} component + * @returns {{component:string, icon:string, name:string}} + */ + + + function getComponent(component) { + return components$1[component]; + } + /** + * Удалить компонент + * @param {string} component + */ + + + function removeComponent(component) { + delete components$1[component]; + delete params$3[component]; + } + /** + * Добавить параметр + * @param {{component:string, param:{name:string, type:string, values:string|object, default:string|boolean}, field:{name:string, description:string|undefined}, onRender:((item)=>void)|undefined, onChange?:((e)=>void)|undefined}} data + */ + + + function addParam(data) { + if (!params$3[data.component]) params$3[data.component] = []; + params$3[data.component].push(data); + if (data.param.type == 'select' || data.param.type == 'input') Params.select(data.param.name, data.param.values, data.param["default"]); + if (data.param.type == 'trigger') Params.trigger(data.param.name, data.param["default"]); + } + /** + * Получить параметры + * @param {string} component + * @returns {[{component:string, param:{name:string, type:string, values:string|object, default:string|boolean}, field:{name:string, description:string|undefined}, onRender:((item)=>void)|undefined, onChange?:((e)=>void)|undefined}]} + */ + + + function getParam(component) { + return params$3[component]; + } + /** + * Удалить параметры + * @param {string} component + */ + + + function removeParams(component) { + delete params$3[component]; + } + /** + * Получить все компоненты + * @returns {{name:{component:string, icon:string, name:string}}} + */ + + + function allComponents() { + return components$1; + } + /** + * Получить все параметры + * @returns {{component:[{component:string, param:{name:string, type:string, values:string|object, default:string|boolean}, field:{name:string, description:string|undefined}, onRender:((item)=>void)|undefined, onChange?:((e)=>void)|undefined}]}} + */ + + + function allParams() { + return params$3; + } + + var SettingsApi = { + allComponents: allComponents, + allParams: allParams, + addComponent: addComponent, + addParam: addParam, + getParam: getParam, + getComponent: getComponent, + removeComponent: removeComponent, + removeParams: removeParams + }; + + function Component$2(name) { + var component_params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var scrl = new Scroll({ + mask: true, + over: true, + step: 200 + }); + var comp = Template.get('settings_' + name); + var last; + scrl.addSwipeDown(function () { + Controller.back(); + }); + /** + * Обновить скролл + */ + + function updateScroll() { + comp.find('.selector').unbind('hover:focus').on('hover:focus', function (e) { + last = e.target; + scrl.update($(e.target), true); + }).unbind('hover:hover hover:touch').on('hover:hover hover:touch', function (e) { + last = e.target; + }); + } + /** + * Билдим все события + */ + + + function buildEvents() { + if (!Platform.is('android')) { + comp.find('.is--android').remove(); + } + + if (!Platform.any()) { + comp.find('.is--player').remove(); + } + + if (!Platform.is('apple') && !Platform.is('apple_tv') && !Platform.macOS()) { + comp.find('.is--infuse').remove(); + } + + if (!Platform.desktop() || Platform.macOS()) { + comp.find('.is--nw').remove(); + } + + if (!(Platform.is('android') || Platform.is('browser') || Platform.is('apple_tv') || Platform.desktop())) { + comp.find('.is--sound').remove(); + } + + if (!Platform.screen('tv')) { + comp.find('.is--tv').remove(); + } + + if (!window.lampa_settings.lang_use) comp.find('[data-name="light_version"]').prev().remove(); + scrl.render().find('.scroll__content').addClass('layer--wheight').data('mheight', $('.settings__head')); + scrl.render().css('max-height', window.innerWidth <= 480 ? window.innerHeight * 0.6 : 'unset'); + Params.bind(comp.find('.selector'), comp); + Params.listener.follow('update_scroll', updateScroll); + Params.listener.follow('update_scroll_position', function () { + if (last) scrl.update(last, true); + }); + updateScroll(); + } + /** + * Добавляем пользовательские параметры + */ + + + function addParams() { + var params = SettingsApi.getParam(name); + + if (params) { + params.forEach(function (data) { + var item; + + if (data.param.type == 'select') { + item = $("
    \n
    ").concat(data.field.name, "
    \n
    \n
    ")); + } + + if (data.param.type == 'trigger') { + item = $("
    \n
    ").concat(data.field.name, "
    \n
    \n
    ")); + } + + if (data.param.type == 'input') { + item = $("
    \n
    ").concat(data.field.name, "
    \n
    \n
    ")); + } + + if (data.param.type == 'title') { + item = $("
    ".concat(data.field.name, "
    ")); + } + + if (data.param.type == 'static') { + item = $("
    \n
    ".concat(data.field.name, "
    \n
    ")); + } + + if (data.param.type == 'button') { + item = $("
    \n
    ").concat(data.field.name, "
    \n
    ")); + } + + if (item) { + if (data.field.description) item.append("
    ".concat(data.field.description, "
    ")); + if (typeof data.onRender == 'function') data.onRender(item); + if (typeof data.onChange == 'function') item.data('onChange', data.onChange); + comp.append(item); + } + }); + } + } + /** + * Стартуем + */ + + + function start() { + addParams(); + buildEvents(); + if (typeof component_params.last_index !== 'undefined' && component_params.last_index > 0) last = comp.find('.selector').eq(component_params.last_index)[0]; + Controller.add('settings_component', { + toggle: function toggle() { + Controller.collectionSet(comp); + Controller.collectionFocus(last, comp); + }, + up: function up() { + Navigator.move('up'); + }, + down: function down() { + Navigator.move('down'); + }, + back: function back() { + scrl.destroy(); + comp.remove(); + Params.listener.remove('update_scroll', updateScroll); + if (component_params.onBack) component_params.onBack();else Controller.toggle('settings'); + } + }); + } + + start(); + /** + * Уничтожить + */ + + this.destroy = function () { + scrl.destroy(); + comp.remove(); + comp = null; + Params.listener.remove('update_scroll', updateScroll); + }; + /** + * Рендер + * @returns {object} + */ + + + this.render = function () { + scrl.append(comp); + return scrl.render(); + }; + } + + function Main$2() { + var _this = this; + + var comp; + var scrl = new Scroll({ + mask: true, + over: true, + step: 200 + }); + var last; + /** + * Создать + */ + + this.create = function () { + comp = Template.get('settings_main'); + if (!window.lampa_settings.account_use) comp.find('[data-component="account"]').remove(); + if (!window.lampa_settings.plugins_use) comp.find('[data-component="plugins"]').remove(); + if (!Lampa.Platform.is('apple_tv')) comp.find('[data-component="appletv"]').remove(); + + if (!window.lampa_settings.torrents_use) { + comp.find('[data-component="parser"]').remove(); + comp.find('[data-component="server"]').remove(); + } + + scrl.render().css('max-height', window.innerWidth <= 480 ? window.innerHeight * 0.6 : 'unset'); + scrl.append(comp); + scrl.addSwipeDown(_this.swipeAction); + + _this.update(); + }; + /** + * Обновить события + */ + + + this.update = function () { + var components = SettingsApi.allComponents(); + + for (var name in components) { + var aded = components[name]; + + if (!comp.find('[data-component="' + name + '"]').length) { + var item = $("
    \n
    \n ").concat(aded.icon, "\n
    \n
    ").concat(aded.name, "
    \n
    ")); + if (aded.before) comp.find('[data-component="' + aded.before + '"]').before(item);else if (aded.after) comp.find('[data-component="' + aded.after + '"]').after(item);else comp.append(item); + } + } + + comp.find('.selector').unbind('hover:focus').on('hover:focus', function (event) { + last = event.target; + scrl.update($(event.target), true); + }).unbind('hover:hover hover:touch').on('hover:hover hover:touch', function (event) { + last = event.target; + Navigator.focused(event.target); + }).not('[data-static]').unbind('hover:enter').on('hover:enter', function (event) { + _this.render().detach(); + + _this.onCreate($(event.target).data('component')); + }); + }; + /** + * Сделать активным + */ + + + this.active = function () { + Controller.collectionSet(comp); + Controller.collectionFocus(last, comp); + scrl.height($('.settings__head')); + }; + /** + * Рендер + * @returns {object} + */ + + + this.render = function () { + return scrl.render(); + }; + } + + var permit = {}; // Получить аккаунт + + Object.defineProperty(permit, 'account', { + get: function get() { + return Storage.get('account', '{}'); + } + }); // Получить профиль аккаунта + + Object.defineProperty(permit, 'profile', { + get: function get() { + return permit.account.profile || {}; + } + }); // Получить данные пользователя + + Object.defineProperty(permit, 'user', { + get: function get() { + return Storage.get('account_user', '{}'); + } + }); // Получить токен аккаунта + + Object.defineProperty(permit, 'token', { + get: function get() { + return permit.account.token; + } + }); // Пользователь залогинен и разрешено использование аккаунта + + Object.defineProperty(permit, 'access', { + get: function get() { + return permit.token && window.lampa_settings.account_use; + } + }); // Пользователь включил синхронизацию + + Object.defineProperty(permit, 'use', { + get: function get() { + return permit.access && Storage.field('account_use'); + } + }); // Синхронизация включена и разрешено использование синхронизации + + Object.defineProperty(permit, 'sync', { + get: function get() { + return permit.use && window.lampa_settings.account_sync; + } + }); // Детский профиль + + Object.defineProperty(permit, 'child', { + get: function get() { + return permit.access && permit.profile.child; + } + }); // Детский профиль - маленький ребенок (до 14 лет) + + Object.defineProperty(permit, 'child_small', { + get: function get() { + return permit.child ? permit.profile.age <= 14 : false; + } + }); + + var data$3 = {}; + data$3.type = { + title: '#{title_type}', + items: [{ + title: '#{menu_movies}', + selected: true, + cat: 'movie' + }, { + title: '#{menu_multmovie}', + cat: 'multmovie' + }, { + title: '#{menu_tv}', + cat: 'tv' + }, { + title: '#{menu_multtv}', + cat: 'multtv' + }, { + title: '#{menu_anime}', + cat: 'anime' + }] + }; + data$3.rating = { + title: '#{title_rating}', + items: [{ + title: '#{filter_any}' + }, { + title: '#{filter_rating_from} 8', + start: 8 + }, { + title: '#{filter_rating_from} 6', + start: 6 + }, { + title: '#{filter_rating_from} 4', + start: 4 + }, { + title: '#{filter_rating_from} 2', + start: 2 + }, { + title: '#{filter_rating_from} 1 #{filter_rating_to} 3', + voite: '1-3' + }, { + title: '#{filter_rating_from} 3 #{filter_rating_to} 6', + voite: '3-6' + }, { + title: '#{filter_rating_from} 6 #{filter_rating_to} 8', + voite: '6-8' + }, { + title: '#{filter_rating_from} 8 #{filter_rating_to} 9', + voite: '8-9' + }] + }; + data$3.pgrating = { + title: '#{title_pgrating}', + items: [{ + title: '#{filter_any}' + }] + }; + data$3.language = { + title: '#{title_language}', + items: [{ + title: '#{filter_lang_ru}', + code: 'ru' + }, { + title: '#{filter_lang_uk}', + code: 'uk' + }, { + title: '#{filter_lang_en}', + code: 'en' + }, { + title: '#{filter_lang_be}', + code: 'be' + }, { + title: '#{filter_lang_zh}', + code: 'zh|cn' + }, { + title: '#{filter_lang_ja}', + code: 'ja' + }, { + title: '#{filter_lang_ko}', + code: 'ko' + }, { + title: '#{filter_lang_af}', + code: 'af' + }, { + title: '#{filter_lang_sq}', + code: 'sq' + }, { + title: '#{filter_lang_ar}', + code: 'ar' + }, { + title: '#{filter_lang_az}', + code: 'az' + }, { + title: '#{filter_lang_hy}', + code: 'hy' + }, { + title: '#{filter_lang_ba}', + code: 'ba' + }, { + title: '#{filter_lang_bg}', + code: 'bg' + }, { + title: '#{filter_lang_bn}', + code: 'bn' + }, { + title: '#{filter_lang_bs}', + code: 'bs' + }, { + title: '#{filter_lang_ca}', + code: 'ca' + }, { + title: '#{filter_lang_ce}', + code: 'ce' + }, { + title: '#{filter_lang_cs}', + code: 'cs' + }, { + title: '#{filter_lang_da}', + code: 'da' + }, { + title: '#{filter_lang_ka}', + code: 'ka' + }, { + title: '#{filter_lang_de}', + code: 'de' + }, { + title: '#{filter_lang_el}', + code: 'el' + }, { + title: '#{filter_lang_es}', + code: 'es' + }, { + title: '#{filter_lang_et}', + code: 'et' + }, { + title: '#{filter_lang_fa}', + code: 'fa' + }, { + title: '#{filter_lang_fi}', + code: 'fi' + }, { + title: '#{filter_lang_fr}', + code: 'fr' + }, { + title: '#{filter_lang_ga}', + code: 'ga' + }, { + title: '#{filter_lang_gl}', + code: 'gl' + }, { + title: '#{filter_lang_gn}', + code: 'gn' + }, { + title: '#{filter_lang_he}', + code: 'he' + }, { + title: '#{filter_lang_hi}', + code: 'hi' + }, { + title: '#{filter_lang_hr}', + code: 'hr' + }, { + title: '#{filter_lang_hu}', + code: 'hu' + }, { + title: '#{filter_lang_id}', + code: 'id' + }, { + title: '#{filter_lang_is}', + code: 'is' + }, { + title: '#{filter_lang_it}', + code: 'it' + }, { + title: '#{filter_lang_kk}', + code: 'kk' + }, { + title: '#{filter_lang_ks}', + code: 'ks' + }, { + title: '#{filter_lang_ku}', + code: 'ku' + }, { + title: '#{filter_lang_ky}', + code: 'ky' + }, { + title: '#{filter_lang_lt}', + code: 'lt' + }, { + title: '#{filter_lang_lv}', + code: 'lv' + }, { + title: '#{filter_lang_mi}', + code: 'mi' + }, { + title: '#{filter_lang_mk}', + code: 'mk' + }, { + title: '#{filter_lang_mn}', + code: 'mn' + }, { + title: '#{filter_lang_mt}', + code: 'mt' + }, { + title: '#{filter_lang_no}', + code: 'no|nb|nn' + }, { + title: '#{filter_lang_ne}', + code: 'ne' + }, { + title: '#{filter_lang_nl}', + code: 'nl' + }, { + title: '#{filter_lang_pa}', + code: 'pa' + }, { + title: '#{filter_lang_pl}', + code: 'pl' + }, { + title: '#{filter_lang_ps}', + code: 'ps' + }, { + title: '#{filter_lang_pt}', + code: 'pt' + }, { + title: '#{filter_lang_ro}', + code: 'ro' + }, { + title: '#{filter_lang_si}', + code: 'si' + }, { + title: '#{filter_lang_sk}', + code: 'sk' + }, { + title: '#{filter_lang_sl}', + code: 'sl' + }, { + title: '#{filter_lang_sm}', + code: 'sm' + }, { + title: '#{filter_lang_so}', + code: 'so' + }, { + title: '#{filter_lang_sr}', + code: 'sr' + }, { + title: '#{filter_lang_sv}', + code: 'sv' + }, { + title: '#{filter_lang_sw}', + code: 'sw' + }, { + title: '#{filter_lang_ta}', + code: 'ta' + }, { + title: '#{filter_lang_tg}', + code: 'tg' + }, { + title: '#{filter_lang_th}', + code: 'th' + }, { + title: '#{filter_lang_tk}', + code: 'tk' + }, { + title: '#{filter_lang_tr}', + code: 'tr' + }, { + title: '#{filter_lang_tt}', + code: 'tt' + }, { + title: '#{filter_lang_ur}', + code: 'ur' + }, { + title: '#{filter_lang_uz}', + code: 'uz' + }, { + title: '#{filter_lang_vi}', + code: 'vi' + }, { + title: '#{filter_lang_yi}', + code: 'yi' + }] + }; + data$3.genres_movie = { + title: '#{title_genre}', + items: [{ + "id": 28, + "title": "#{filter_genre_ac}", + checkbox: true + }, { + "id": 12, + "title": "#{filter_genre_ad}", + checkbox: true + }, { + "id": 16, + "title": "#{filter_genre_mv}", + checkbox: true + }, { + "id": 35, + "title": "#{filter_genre_cm}", + checkbox: true + }, { + "id": 80, + "title": "#{filter_genre_cr}", + checkbox: true + }, { + "id": 99, + "title": "#{filter_genre_dc}", + checkbox: true + }, { + "id": 18, + "title": "#{filter_genre_dr}", + checkbox: true + }, { + "id": 10751, + "title": "#{filter_genre_fm}", + checkbox: true + }, { + "id": 14, + "title": "#{filter_genre_fe}", + checkbox: true + }, { + "id": 36, + "title": "#{filter_genre_hi}", + checkbox: true + }, { + "id": 27, + "title": "#{filter_genre_ho}", + checkbox: true + }, { + "id": 10402, + "title": "#{filter_genre_mu}", + checkbox: true + }, { + "id": 9648, + "title": "#{filter_genre_de}", + checkbox: true + }, { + "id": 10749, + "title": "#{filter_genre_md}", + checkbox: true + }, { + "id": 878, + "title": "#{filter_genre_fa}", + checkbox: true + }, { + "id": 10770, + "title": "#{filter_genre_tv}", + checkbox: true + }, { + "id": 53, + "title": "#{filter_genre_tr}", + checkbox: true + }, { + "id": 10752, + "title": "#{filter_genre_mi}", + checkbox: true + }, { + "id": 37, + "title": "#{filter_genre_ve}", + checkbox: true + }] + }; + data$3.genres_tv = { + title: '#{title_genre}', + items: [{ + "id": 10759, + "title": "#{filter_genre_aa}", + checkbox: true + }, { + "id": 16, + "title": "#{filter_genre_mv}", + checkbox: true + }, { + "id": 35, + "title": "#{filter_genre_cm}", + checkbox: true + }, { + "id": 80, + "title": "#{filter_genre_cr}", + checkbox: true + }, { + "id": 99, + "title": "#{filter_genre_dc}", + checkbox: true + }, { + "id": 18, + "title": "#{filter_genre_dr}", + checkbox: true + }, { + "id": 10751, + "title": "#{filter_genre_fm}", + checkbox: true + }, { + "id": 10762, + "title": "#{filter_genre_ch}", + checkbox: true + }, { + "id": 9648, + "title": "#{filter_genre_de}", + checkbox: true + }, { + "id": 10763, + "title": "#{filter_genre_nw}", + checkbox: true + }, { + "id": 10764, + "title": "#{filter_genre_rs}", + checkbox: true + }, { + "id": 10765, + "title": "#{filter_genre_hf}", + checkbox: true + }, { + "id": 10766, + "title": "#{filter_genre_op}", + checkbox: true + }, { + "id": 10767, + "title": "#{filter_genre_tc}", + checkbox: true + }, { + "id": 10768, + "title": "#{filter_genre_mp}", + checkbox: true + }, { + "id": 37, + "title": "#{filter_genre_ve}", + checkbox: true + }] + }; + data$3.sort = { + title: '#{filter_sorted}', + items: [{ + title: '#{filter_any}' + }, { + title: '#{title_new}', + sort: 'now' + }, { + title: '#{title_now_watch}', + sort: 'now_playing' + }, { + title: '#{title_in_top}', + sort: 'top' + }, { + title: '#{title_ongoing}', + sort: 'airing' + }] + }; + data$3.quality = { + title: '#{player_quality}', + items: [{ + title: '#{filter_any}' + }, { + title: '#{title_in_high_quality}', + uhd: true + }] + }; + data$3.year = { + title: '#{title_year}', + items: [{ + title: '#{filter_any}', + any: true + }] + }; + var i = 100, + y = new Date().getFullYear(); + + for (var a = 0; a < 5; a++) { + data$3.year.items.push({ + title: y - a + }); + } + + while (i -= 5) { + var end = y - (99 - i); + data$3.year.items.push({ + title: end + 5 + '-' + end + }); + } + + for (var _a = 18; _a >= 0; _a -= 3) { + data$3.pgrating.items.push({ + title: _a + '+', + pg: _a + }); + } + + for (var _a2 = 15; _a2 >= 0; _a2 -= 3) { + data$3.pgrating.items.push({ + title: '#{filter_rating_from} ' + _a2 + ' #{filter_rating_to} ' + (_a2 + 3), + pg: _a2 + '-' + (_a2 + 3) + }); + } + + data$3.language.items.forEach(function (i) { + return i.checkbox = true; + }); + + /** + * Главное меню фильтрации + */ + + function main$3() { + for (var i in data$3) { + selected$1(data$3[i]); + } + + var cat = data$3.type.items.find(function (s) { + return s.selected; + }).cat; + var type = cat.indexOf('movie') >= 0 ? 'movie' : 'tv'; + var items = [{ + title: Lang.translate('search_start'), + search: true + }, data$3.type, data$3.rating, data$3['genres_' + type], data$3.language, data$3.year]; + if (Storage.field('source') == 'cub') items.push(data$3.pgrating, data$3.sort, data$3.quality); + items.forEach(function (itm) { + itm.title = Lang.translate(itm.title); + if (itm.subtitle) itm.subtitle = Lang.translate(itm.subtitle); + + if (itm.items) { + itm.items.forEach(function (inr) { + inr.title = Lang.translate(inr.title); + }); + } + }); + Select.show({ + title: Lang.translate('title_filter'), + items: items, + onBack: function onBack() { + Controller.toggle('content'); + }, + onSelect: function onSelect(a) { + if (a.search) search$6();else submenu$1(a); + } + }); + } + /** + * Запрос для TMDB + * @returns {string} - строка запроса + */ + + + function queryForTMDB() { + var query = []; + var cat = data$3.type.items.find(function (s) { + return s.selected; + }).cat; + var type = cat.indexOf('movie') >= 0 ? 'movie' : 'tv'; + var genres = []; + var languages = []; + data$3.rating.items.forEach(function (a) { + if (a.selected && (a.voite || a.start)) { + if (a.start) { + query.push('vote_average.gte=' + a.start); + } else { + query.push('vote_average.gte=' + a.voite.split('-')[0]); + query.push('vote_average.lte=' + a.voite.split('-')[1]); + } + } + }); + data$3.language.items.forEach(function (a) { + if (a.checked) languages.push(a.code); + }); + data$3.year.items.forEach(function (a) { + if (a.selected && !a.any) { + var need = type == 'movie' ? 'primary_release_date' : 'first_air_date'; + + if (a.title.indexOf('-') >= 0) { + query.push(need + '.lte=' + a.title.split('-')[0] + '-12-31'); + query.push(need + '.gte=' + a.title.split('-')[1] + '-01-01'); + } else { + query.push((type == 'movie' ? 'primary_release_year' : 'first_air_date_year') + '=' + a.title); + } + } + }); + data$3['genres_' + type].items.forEach(function (a) { + if (a.checked) genres.push(a.id); + }); + if (cat == 'multmovie' || cat == 'multtv' && genres.indexOf(16) == -1) genres.push(16); + if (cat == 'movie' || cat == 'tv') query.push('without_genres=16'); + + if (genres.length) { + query.push('with_genres=' + genres.join(',')); + } + + if (cat == 'anime' && languages.indexOf('ja') == -1) languages.push('ja'); + + if (languages.length) { + query.push('with_original_language=' + languages.join('|')); + } + + return 'discover/' + type + '?' + query.join('&'); + } + /** + * Запрос для CUB + * @returns {string} - строка запроса + */ + + + function queryForCUB() { + var query = []; + var cat = data$3.type.items.find(function (s) { + return s.selected; + }).cat; + var type = cat.indexOf('movie') >= 0 ? 'movie' : 'tv'; + var genres = []; + var sort = data$3.sort.items.find(function (s) { + return s.selected && s.sort; + }); + var quality = data$3.quality.items.find(function (s) { + return s.selected && s.uhd; + }); + var languages = []; + data$3.rating.items.forEach(function (a) { + if (a.selected && (a.voite || a.start)) { + if (a.start) { + query.push('vote=' + a.start); + } else { + query.push('vote=' + a.voite.split('-')[0] + '-' + a.voite.split('-')[1]); + } + } + }); + data$3.language.items.forEach(function (a) { + if (a.checked) languages.push(a.code.split('|')[0]); + }); + data$3.year.items.forEach(function (a) { + if (a.selected && !a.any) { + if (a.title.indexOf('-') >= 0) { + query.push('airdate=' + a.title.split('-')[1] + '-' + a.title.split('-')[0]); + } else { + query.push('airdate=' + a.title); + } + } + }); + data$3.pgrating.items.forEach(function (a) { + if (a.selected) { + if (a.title.indexOf('-') >= 0) { + query.push('pgrating=' + a.pg.split('-')[0] + '-' + a.pg.split('-')[1]); + } else { + query.push('pgrating=' + a.pg); + } + } + }); + data$3['genres_' + type].items.forEach(function (a) { + if (a.checked) genres.push(a.id); + }); + if ((cat == 'multmovie' || cat == 'multtv' || permit.child_small) && genres.indexOf(16) == -1) genres.push(16); + if ((cat == 'movie' || cat == 'tv') && !permit.child_small) query.push('without_genres=16'); + + if (genres.length) { + query.push('genre=' + genres.join(',')); + } + + if (cat == 'anime') type = 'anime'; + + if (languages.length) { + query.push('language=' + languages.join(',')); + } + + if (sort) query.push('sort=' + sort.sort); + if (quality) query.push('uhd=true'); + return '?cat=' + type + '&' + query.join('&'); + } + /** + * Запуск поиска + */ + + + function search$6() { + Controller.toggle('content'); + var source = Storage.field('source'); + var query = source == 'cub' ? queryForCUB() : queryForTMDB(); + var activity = { + url: query, + title: Lang.translate('title_filter'), + component: 'category_full', + source: source == 'cub' ? 'cub' : 'tmdb', + card_type: true, + page: 1 + }; + var object = Activity.active(); + if (object.component == 'category_full' && (object.url.indexOf('discover') == 0 || object.url.indexOf('?cat=') == 0)) Activity.replace(activity, true);else Activity.push(activity); + } + /** + * Выбор элемента + * @param {Array} where - массив элементов + * @param {Object} a - выбранный элемент + */ + + + function select$4(where, a) { + where.forEach(function (element) { + element.selected = false; + }); + a.selected = true; + } + /** + * Обновление подзаголовка + * @param {Object} where - объект с массивом items + */ + + + function selected$1(where) { + var title = []; + where.items.forEach(function (a) { + if (a.selected || a.checked) title.push(a.title); + }); + where.subtitle = title.length ? title.join(', ') : Lang.translate('nochoice'); + } + /** + * Подменю + * @param {Object} item - объект элемента + */ + + + function submenu$1(item) { + Select.show({ + title: item.title, + items: item.items, + onBack: main$3, + onSelect: function onSelect(a) { + select$4(item.items, a); + main$3(); + } + }); + } + /** + * Запуск фильтра + */ + + + function show$d() { + main$3(); + } + + var Filter$1 = { + show: show$d + }; + + var menu$4; + var timer$8; + + function init$1i(list) { + menu$4 = list; + observe$3(); + } + + function start$b() { + var list = $(''); + menu$4.find('.menu__item').each(function () { + var item_orig = $(this); + var item_clone = $(this).clone(); + var item_sort = $("
    \n
    \n
    ".concat(item_clone.find('.menu__text').text(), "
    \n
    \n \n \n \n
    \n
    \n \n \n \n
    \n
    \n \n \n \n \n
    \n
    ")); + item_sort.find('.menu-edit-list__icon').append(item_clone.find('.menu__ico').html()); + item_sort.find('.move-up').on('hover:enter', function () { + var prev = item_sort.prev(); + + if (prev.length) { + item_sort.insertBefore(prev); + item_orig.insertBefore(item_orig.prev()); + } + }); + item_sort.find('.move-down').on('hover:enter', function () { + var next = item_sort.next(); + + if (next.length) { + item_sort.insertAfter(next); + item_orig.insertAfter(item_orig.next()); + } + }); + item_sort.find('.toggle').on('hover:enter', function () { + item_orig.toggleClass('hidden'); + item_sort.find('.dot').attr('opacity', item_orig.hasClass('hidden') ? 0 : 1); + }).find('.dot').attr('opacity', item_orig.hasClass('hidden') ? 0 : 1); + list.append(item_sort); + }); + Modal.open({ + title: Lang.translate('extensions_edit'), + html: list, + size: 'small', + scroll_to_center: true, + onBack: function onBack() { + Modal.close(); + save$4(); + Controller.toggle('menu'); + } + }); + } + + function order() { + var items = Storage.get('menu_sort', '[]'); + + if (items.length) { + items.forEach(function (item) { + var el = $('.menu__item:contains("' + item + '")', menu$4); + if (el.length) el.appendTo(menu$4); + }); + } + } + + function hide$3() { + var items = Storage.get('menu_hide', '[]'); + $('.menu__item', menu$4).removeClass('hidden'); + + if (items.length) { + items.forEach(function (item) { + var el = $('.menu__item:contains("' + item + '")', menu$4); + if (el.length) el.addClass('hidden'); + }); + } + } + + function save$4() { + var sort = []; + var hide = []; + $('.menu__item', menu$4).each(function () { + var name = $(this).find('.menu__text').text().trim(); + sort.push(name); + + if ($(this).hasClass('hidden')) { + hide.push(name); + } + }); + Storage.set('menu_sort', sort); + Storage.set('menu_hide', hide); + } + + function update$g() { + order(); + hide$3(); + } + + function observe$3() { + clearTimeout(timer$8); + timer$8 = setTimeout(function () { + var memory = Storage.get('menu_sort', '[]'); + var anon = []; + $('.menu__item', menu$4).each(function () { + anon.push($(this).find('.menu__text').text().trim()); + }); + anon.forEach(function (item) { + if (memory.indexOf(item) == -1) memory.push(item); + }); + Storage.set('menu_sort', memory); + update$g(); + }, 500); + } + + var Editor = { + init: init$1i, + start: start$b, + update: update$g, + observe: observe$3 + }; + + var Router$1 = /*#__PURE__*/function () { + function Router() { + _classCallCheck(this, Router); + + this.routes = []; + } + + _createClass(Router, [{ + key: "add", + value: function add(name, callback) { + if (typeof name === 'string' && typeof callback === 'function') { + this.routes.push({ + name: name, + callback: callback + }); + } else { + console.error('Invalid route definition. Expected a string and a function.'); + } + } + }, { + key: "get", + value: function get(name) { + return this.routes.find(function (route) { + return route.name === name; + }); + } + }, { + key: "call", + value: function call(name, data) { + var route = this.get(name); + + if (route) { + var push = route.callback(data); + Arrays.extend(push, { + url: data.url || '', + component: route.name, + source: data.source || Storage.field('source'), + page: data.page || 1 + }); + Activity.push(push); + } else { + Arrays.extend(data, { + url: data.url || '', + component: name, + source: data.source || Storage.field('source'), + page: data.page || 1 + }); + Activity.push(data); + } + } + }]); + + return Router; + }(); + + var router = new Router$1(); + router.add('full', function (data) { + return { + id: data.id, + method: data.original_name ? 'tv' : 'movie', + card: data + }; + }); + router.add('category_full', function (data) { + return { + genres: data.genres || '', + keywords: data.keywords || '', + companies: data.companies || '', + query: data.query || '', + filter: data.filter || '', + title: data.title || Lang.translate('title_category') + }; + }); + router.add('category', function (data) { + return _objectSpread2(_objectSpread2({}, data), {}, { + title: data.title || Lang.translate('title_category') + }); + }); + router.add('favorite', function (data) { + return { + title: data.title || Lang.translate('title_' + data.type), + type: data.type, + filter: data.filter || '' + }; + }); + router.add('episodes', function (data) { + return { + title: Lang.translate('title_episodes'), + card: data + }; + }); + router.add('discuss', function (data) { + return { + card: data, + id: data.id, + method: data.name ? 'tv' : 'movie', + page: data.page || 2 + }; + }); + router.add('company', function (data) { + return { + url: data.url || (data.card.name ? 'tv' : 'movie'), + id: data.id, + source: data.card.source, + title: Lang.translate('title_company') + }; + }); + router.add('recomend', function (data) { + return { + title: Lang.translate('title_recomend_watch'), + page: data.page || 1, + media: data.media || 'movie' + }; + }); + router.add('actor', function (data) { + return { + id: data.id, + job: (data.known_for_department || 'actor').toLowerCase() + }; + }); + + var html$m; + var last$4; + var scroll$3; + var visible_timer; + + function menuAlwaysVisible() { + return Platform.screen('tv') && Storage.field('menu_always'); + } + + var menu_items = [{ + action: 'main', + title: 'menu_main', + sprite: 'home' + }, { + action: 'feed', + title: 'menu_feed', + sprite: 'feed' + }, { + action: 'movie', + title: 'menu_movies', + sprite: 'movie' + }, { + action: 'cartoon', + title: 'menu_multmovie', + sprite: 'cartoon' + }, { + action: 'tv', + title: 'menu_tv', + sprite: 'tv' + }, { + action: 'myperson', + title: 'title_persons', + sprite: 'person' + }, { + action: 'catalog', + title: 'menu_catalog', + sprite: 'catalog' + }, { + action: 'filter', + title: 'menu_filter', + sprite: 'filter' + }, { + action: 'relise', + title: 'menu_relises', + sprite: 'hd' + }, { + action: 'anime', + title: 'menu_anime', + sprite: 'anime' + }, { + action: 'favorite', + title: 'settings_input_links', + sprite: 'favorite' + }, { + action: 'history', + title: 'menu_history', + sprite: 'history' + }, { + action: 'subscribes', + title: 'title_subscribes', + sprite: 'subscribes' + }, { + action: 'timetable', + title: 'menu_timeline', + sprite: 'calendar' + }, { + action: 'mytorrents', + title: 'menu_torrents', + sprite: 'torrent' + }]; + /** + * Инициализация меню + * @returns {void} + */ + + function init$1h() { + html$m = Template.get('menu'); + scroll$3 = new Scroll({ + mask: true, + over: true + }); // Фильтрация пунктов меню в зависимости от настроек + + menu_items = menu_items.filter(function (item) { + if (!window.lampa_settings.torrents_use && item.action == 'mytorrents') return false; + if (window.lampa_settings.disable_features.persons && item.action == 'myperson') return false; + if (window.lampa_settings.disable_features.subscribe && item.action == 'subscribes') return false; + if (!window.lampa_settings.feed && item.action == 'feed') return false; + if (!Lang.selected(['ru', 'uk', 'be']) && (item.action == 'relise' || item.action == 'anime' || item.action == 'feed')) return false; + return true; + }); // Добавление кнопок меню + + menu_items.forEach(function (item) { + addButton(""), Lang.translate(item.title)).attr('data-action', item.action); + }); // Отправка события для плагинов + + Lampa.Listener.send('menu', { + type: 'start', + body: html$m + }); // Инициализация редактора меню + + Editor.init($('.menu__list:eq(0)', html$m)); // Наблюдатель за добавлением новых селекторов в меню + + observe$2(); // Инициализация контроллера меню + + Controller.add('menu', { + toggle: function toggle() { + Controller.collectionSet(html$m); + Controller.collectionFocus(last$4, html$m, true); + clearTimeout(visible_timer); + $('.wrap__left').removeClass('wrap__left--hidden'); + $('body').toggleClass('menu--open', true); + }, + right: function right() { + Controller.toggle('content'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down'); + }, + gone: function gone() { + $('body').toggleClass('menu--open', false); + + if (!menuAlwaysVisible()) { + visible_timer = setTimeout(function () { + $('.wrap__left').addClass('wrap__left--hidden'); + }, 300); + } + }, + back: function back() { + Activity.backward(); + } + }); // Закрытие меню по клику вне его области + + $('body').on('mousedown', function (e) { + if (DeviceInput.canClick(e.originalEvent) && opened$2()) { + if (e.originalEvent.clientX > html$m.outerWidth()) close$9(); + } + }); + scroll$3.minus(); + scroll$3.append(html$m); + + if (menuAlwaysVisible()) { + $('.wrap__left').removeClass('wrap__left--hidden'); + } // Отправка события для плагинов + + + Lampa.Listener.send('menu', { + type: 'end' + }); + Lampa.Listener.follow('app', function (e) { + if (e.type == 'ready') ready(); + }); + } + /** + * Следит за добавлением новых селекторов в меню + * @returns {void} + */ + + + function observe$2() { + if (typeof MutationObserver == 'undefined') return; + var observer = new MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { + var mutation = mutations[i]; + + if (mutation.type == 'childList' && !mutation.removedNodes.length) { + var selectors = Array.from(mutation.target.querySelectorAll('.selector')).filter(function (s) { + return !s.checked; + }); + if (selectors.length) Editor.observe(); + selectors.forEach(function (s) { + s.checked = true; + + if (!$(s).data('binded_events')) { + $(s).on('hover:focus', function (e) { + last$4 = e.target; + scroll$3.update($(e.target), true); + }).on('hover:hover hover:touch hover:enter', function (e) { + last$4 = e.target; + }); + } + }); + } + } + }); + observer.observe(html$m[0], { + childList: true, + subtree: true + }); + } + /** + * Проверяет, нужно ли открывать новый компонент или обновлять текущий + * @param {string} action Действие, которое нужно выполнить + * @param {Array} name Название компонента(ов), которые нужно проверить + * @returns {boolean|void} Нужно ли открывать новый компонент или обновлять текущий + */ + + + function prepared(action, name) { + if (name.indexOf(action) >= 0) { + var comp = Lampa.Activity.active().component; + if (name.indexOf(comp) >= 0) Activity.replace();else return true; + } + } + /** + * Готово к работе + * @returns {void} + */ + + + function ready() { + html$m.find('.selector').data('binded_events', true).on('hover:enter', function (e) { + var action = $(e.target).data('action'); + Lampa.Listener.send('menu', { + type: 'action', + action: action, + target: e.target, + abort: function abort() { + action = null; + } + }); + if (action == 'catalog') catalog(); + + if (action == 'movie' || action == 'tv' || action == 'anime') { + router.call('category', { + url: action, + title: (action == 'movie' ? Lang.translate('menu_movies') : action == 'anime' ? Lang.translate('menu_anime') : Lang.translate('menu_tv')) + ' - ' + Storage.field('source').toUpperCase(), + source: action == 'anime' ? 'cub' : Storage.field('source') + }); + } + + if (action == 'cartoon') { + router.call('category', { + url: 'movie', + title: Lang.translate('menu_multmovie') + ' - ' + Storage.field('source').toUpperCase(), + genres: 16 + }); + } + + if (prepared(action, ['main'])) { + router.call('main', { + title: Lang.translate('title_main') + ' - ' + Storage.field('source').toUpperCase() + }); + } + + if (prepared(action, ['myperson'])) { + router.call('myperson', { + title: Lang.translate('title_persons') + }); + } + + if (action == 'search') Controller.toggle('search'); + + if (action == 'settings') { + ParentalControl.personal('settings', function () { + Controller.toggle('settings'); + }, false, true); + } + + if (action == 'about') { + var about = Template.get('about'); + + if (window.lampa_settings.white_use) { + about.find('.about__contacts > div:eq(1)').remove(); + } + + if (Platform.is('android')) { + about.find('.platform_android').removeClass('hide'); + about.find('.version_android').text(Platform.version('android')); + } + + about.find('.version_app').text(Platform.version('app')); + Modal.open({ + about: true, + title: Lang.translate('title_about'), + html: about, + size: 'medium', + onBack: function onBack() { + Modal.close(); + Controller.toggle('content'); + } + }); + } + + if (action == 'favorite') { + ParentalControl.personal('bookmarks', function () { + if (prepared('bookmarks', ['bookmarks'])) { + router.call('bookmarks', { + title: Lang.translate('settings_input_links') + }); + } + }, false, true); + } + + if (action == 'history') { + ParentalControl.personal('bookmarks', function () { + if (prepared('favorite', ['favorite']) || prepared('bookmarks', ['bookmarks'])) { + router.call('favorite', { + title: Lang.translate('title_history'), + type: 'history' + }); + } + }, false, true); + } + + if (action == 'subscribes') { + router.call('subscribes', { + title: Lang.translate('title_subscribes') + }); + } + + if (prepared(action, ['timetable'])) { + router.call('timetable', { + title: Lang.translate('title_timetable') + }); + } + + if (prepared(action, ['feed'])) { + router.call('feed', { + title: Lang.translate('menu_feed') + }); + } + + if (prepared(action, ['mytorrents'])) { + router.call('mytorrents', { + title: Lang.translate('title_mytorrents') + }); + } + + if (prepared(action, ['relise'])) { + router.call('relise', { + title: Lang.translate('title_relises') + }); + } + + if (action == 'console') { + Controller.toggle('console'); + } + + if (action == 'filter') Filter$1.show(); + if (action == 'edit') Editor.start(); + }).on('hover:focus', function (e) { + last$4 = e.target; + scroll$3.update($(e.target), true); + }).on('hover:hover hover:touch hover:enter', function (e) { + last$4 = e.target; + }); + } + /** + * Открывает каталог + * @returns {void} + */ + + + function catalog() { + Api.menu({ + source: Storage.field('source') + }, function (menu) { + Select.show({ + title: Lang.translate('title_catalog'), + items: menu, + onSelect: function onSelect(a) { + var tmdb = Storage.field('source') == 'tmdb' || Storage.field('source') == 'cub'; + router.call(tmdb ? 'category' : 'category_full', { + url: 'movie', + title: (a.title || Lang.translate('title_catalog')) + ' - ' + Storage.field('source').toUpperCase(), + genres: a.id, + id: a.id + }); + }, + onBack: open$8 + }); + }); + } + /** + * Добавляет элемент в меню + * @param {JQuery} element Элемент меню + * @param {Function} action Действие при нажатии на элемент + * @returns {JQuery} Добавленный элемент меню + */ + + + function addElement$1(element, action) { + html$m.find('.menu__list:eq(0)').append(element); + if (action && typeof action == 'function') element.on('hover:enter', action); + return element; + } + /** + * Добавляет кнопку в меню + * @param {string} svg_icon SVG иконка кнопки + * @param {string} title Название кнопки + * @param {Function} action Действие при нажатии на кнопку + * @returns {JQuery} Добавленная кнопка меню + */ + + + function addButton(svg_icon, title, action) { + return addElement$1($("
  • ".concat(svg_icon, "
    ").concat(title, "
  • ")), action); + } + /** + * Переключает меню + * @returns {void} + */ + + + function toggle$b() { + if ($('body').hasClass('menu--open')) Controller.toggle('content');else Controller.toggle('menu'); + Lampa.Listener.send('menu', { + type: 'toggle' + }); + } + /** + * Проверяет, открыто ли меню + * @returns {boolean} Открыто ли меню + */ + + + function opened$2() { + return $('body').hasClass('menu--open'); + } + /** + * Открывает меню + * @returns {void} + */ + + + function open$8() { + if (!opened$2()) toggle$b(); + } + /** + * Закрывает меню + * @returns {void} + */ + + + function close$9() { + if (opened$2()) toggle$b(); + } + /** + * Рендерит меню + * @returns {JQuery} Меню + */ + + + function render$k() { + return scroll$3.render(); + } + + var Menu$1 = { + init: Utils$1.onceInit(init$1h), + render: render$k, + ready: ready, + toggle: toggle$b, + opened: opened$2, + addElement: addElement$1, + addButton: addButton, + open: open$8, + close: close$9 + }; + + var html$l; + var last$3; + /** + * Наблюдение за изменениями в DOM + * @returns {void} + */ + + function observe$1() { + if (typeof MutationObserver == 'undefined') return; + var observer = new MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { + var mutation = mutations[i]; + + if (mutation.type == 'childList' && !mutation.removedNodes.length) { + var selectors = Array.from(mutation.target.querySelectorAll('.selector')); + selectors.forEach(function (s) { + $(s).unbind('hover:focus hover:hover hover:touch').on('hover:focus hover:hover hover:touch', function (e) { + last$3 = e.target; + }); + }); + } + } + }); + observer.observe(html$l[0], { + childList: true, + subtree: true + }); + } + /** + * Инициализация шапки + * @returns {void} + */ + + + function init$1g() { + html$l = Template.get('head'); + if (window.local_lampa) html$l.find('.head__logo-icon').append('local'); + + if (Platform.mouse()) { + var back = Template.elem('div', { + "class": 'head__backward', + children: [Template.js('icon_back')] + }); + back.on('click', Controller.back.bind(Controller)); + html$l.find('.head__body').prepend(back); + } + + Utils$1.time(html$l); + html$l.find('.head__logo-icon, .head__menu-icon').on('mousedown', function (e) { + if (DeviceInput.canClick(e.originalEvent)) Menu$1.toggle(); + }); + html$l.find('.full--screen').on('hover:enter', function () { + Utils$1.toggleFullscreen(); + }).toggleClass('hide', Platform.tv() || Platform.is('android') || !Utils$1.canFullScreen()); + observe$1(); + Controller.add('head', { + toggle: function toggle() { + Controller.collectionSet(html$l, false, true); + Controller.collectionFocus(last$3, html$l, true); + }, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + down: function down() { + Controller.toggle('content'); + }, + back: function back() { + Activity.backward(); + } + }); + } + /** + * Установка заголовка + * @param {string} title Заголовок + * @returns {void} + */ + + + function title$1(title) { + html$l.find('.head__title').text(title || ''); + } + /** + * Добавление элемента в шапку + * @param {JQuery|HTMLElement|string} element - Элемент + * @param {function} action - Действие при нажатии + * @returns {JQuery|HTMLElement} - Добавленный элемент + */ + + + function addElement(element, action) { + html$l.find('.head__actions').prepend(element); + if (action && typeof action == 'function') element.on('hover:enter', action); + return element; + } + /** + * Добавление иконки в шапку + * @param {string} svg_icon - SVG иконка + * @param {function} action - Действие при нажатии + * @returns {JQuery|HTMLElement} - Добавленная иконка + */ + + + function addIcon(svg_icon, action) { + return addElement($("
    ".concat(svg_icon, "
    ")), action); + } + /** + * Получение HTML шапки + * @param {boolean} js - Вернуть DOM элемент вместо JQuery + * @returns {JQuery|HTMLElement} + */ + + + function render$j(js) { + return js ? html$l[0] : html$l; + } + + var Head = { + init: init$1g, + render: render$j, + title: title$1, + addElement: addElement, + addIcon: addIcon + }; + + var html$k; + var body$1; + var listener$i = Subscribe$2(); + var last$2 = ''; + + var _main; + /** + * Инициализация настроек + * @returns {void} + */ + + + function init$1f() { + html$k = Template.get('settings'); + body$1 = html$k.find('.settings__body'); + html$k.find('.settings__layer').on('click', function (e) { + if (DeviceInput.canClick(e.originalEvent)) Controller.back(); + }); + _main = new Main$2(); + _main.onCreate = create$b; + _main.swipeAction = swipeAction; + + _main.create(); + + Controller.add('settings', { + toggle: function toggle() { + _main.render().detach(); + + _main.update(); + + listener$i.send('open', { + name: 'main', + body: _main.render() + }); + body$1.empty().append(_main.render()); + + _main.active(); + + $('body').toggleClass('settings--open', true); + html$k.addClass('animate'); + Activity.mixState('settings=main'); + }, + up: function up() { + Navigator.move('up'); + }, + down: function down() { + Navigator.move('down'); + }, + left: function left() { + _main.render().detach(); + + Controller.toggle('content'); + }, + gone: function gone(to) { + if (to !== 'settings_component') { + $('body').toggleClass('settings--open', false); + html$k.removeClass('animate').removeClass('animate-down'); + } + }, + back: function back() { + _main.render().detach(); + + Controller.toggle('head'); + Activity.mixState(); + listener$i.send('close'); + } + }); + ParentalControl.add('settings', { + title: 'title_settings' + }); + Head.addIcon(Template.string('icon_settings'), function () { + ParentalControl.personal('settings', function () { + Controller.toggle('settings'); + }, false, true); + }).addClass('open--settings'); + } + + function swipeAction() { + html$k.addClass('animate-down'); + setTimeout(function () { + Controller.back(); + }, 200); + } + /** + * Создать компонент + * @param {string} name - имя компонента + * @returns {void} + */ + + + function create$b(name) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var comp = new Component$2(name, params); + body$1.empty().append(comp.render()); + listener$i.send('open', { + name: name, + body: comp.render(), + params: params + }); + last$2 = name; + Controller.toggle('settings_component'); + Activity.mixState('settings=' + name); + } + /** + * Обновить открытый компонент + * @returns {void} + */ + + + function update$f() { + var selects = body$1.find('.selector'); + var lastinx = selects.index(body$1.find('.selector.focus')); + create$b(last$2, { + last_index: lastinx + }); + } + /** + * Рендер + * @param {boolean} js - вернуть DOM-элемент или jQuery объект + * @returns {HTMLElement|jQuery} - DOM-элемент или jQuery объект + */ + + + function render$i(js) { + return js ? html$k[0] : html$k; + } + + var Settings = { + listener: listener$i, + init: init$1f, + render: render$i, + update: update$f, + create: create$b, + main: function main() { + return _main; + } + }; + + var already_requested = false; + var last_time_requested = 0; + var personal_codes = {}; + + function init$1e() { + Params.trigger('parental_control', false); + Params.select('parental_control_time', { + 'always': '#{settings_parental_control_param_time_always}', + 'once': '#{settings_parental_control_param_time_once}', + '10': '#{settings_parental_control_param_time_10}', + '20': '#{settings_parental_control_param_time_20}', + '30': '#{settings_parental_control_param_time_30}', + '60': '#{settings_parental_control_param_time_60}', + '120': '#{settings_parental_control_param_time_120}' + }, 'once'); + Template.add('settings_parental_control', "
    \n
    \n
    #{title_parental_control}
    \n
    \n
    \n
    \n
    \n
    #{settings_parental_control_change_pin}
    \n
    \n
    \n
    #{settings_parental_control_demand_title}
    \n
    \n
    #{settings_parental_control_demand_descr}
    \n
    \n
    \n
    #{settings_parental_control_where}
    \n
    \n
    \n
    \n
    "); + Settings.listener.follow('open', function (e) { + if (e.name == 'parental_control') { + var toggle = e.body.find('.parental-control-toggle'); + var change = e.body.find('.parental-control-change'); + var other = e.body.find('.parental-control-other'); + var active; // Нельзя изменить код если детский профиль + + if (permit.child) change.remove(); + + var updateStatus = function updateStatus() { + toggle.find('.settings-param__value').text(Lang.translate(enabled$1() ? 'settings_parental_control_enabled' : 'settings_parental_control_disabled')); + other.toggleClass('hide', !Boolean(enabled$1())); + }; + + var drawPersonalList = function drawPersonalList() { + var enabled = Storage.get('parental_control_personal', '[]'); + var list = e.body.find('.parental-control-personal-list'); + + var item = function item(name, data) { + var line = $("
    \n
    ".concat(Lang.translate(data.title), "
    \n
    \n
    ")); + if (enabled.indexOf(name) >= 0) line.addClass('selectbox-item--checked'); + line.on('hover:enter', function () { + active = Controller.enabled().name; + query(function () { + enabled = Storage.get('parental_control_personal', '[]'); + + if (enabled.indexOf(name) >= 0) { + Arrays.remove(enabled, name); + Storage.set('parental_control_personal', enabled); + line.removeClass('selectbox-item--checked'); + } else { + Storage.add('parental_control_personal', name); + line.addClass('selectbox-item--checked'); + } + + Controller.toggle(active); + }, function () { + Controller.toggle(active); + }); + }); + list.append(line); + }; + + for (var name in personal_codes) { + item(name, personal_codes[name]); + } + + Params.listener.send('update_scroll'); + }; + + toggle.on('hover:enter', function () { + active = Controller.enabled().name; + + if (enabled$1()) { + request$1(function () { + Storage.set('parental_control', false); + updateStatus(); + Controller.toggle(active); + }, function () { + Controller.toggle(active); + }); + } else if (!Storage.value('parental_control_pin')) { + set$4(function (code) { + if (code) { + Storage.set('parental_control_pin', code); + Storage.set('parental_control', true); + updateStatus(); + } + }); + } else { + Storage.set('parental_control', true); + updateStatus(); + } + }); + change.on('hover:enter', function () { + active = Controller.enabled().name; + + if (Storage.value('parental_control_pin')) { + request$1(function () { + set$4(function (code) { + if (code) { + Storage.set('parental_control_pin', code); + } + + Controller.toggle(active); + }); + }, function () { + Controller.toggle(active); + }); + } + }); + updateStatus(); + drawPersonalList(); + } + }); + add$d('bookmarks', { + title: 'settings_input_links' + }); + } + /** + * Запрос на установку PIN-кода + * @param {function} call - вызов + */ + + + function set$4(call) { + var active = Controller.enabled().name; + pin(Lang.translate('parental_control_input_new_code'), function (code_one) { + if (code_one) { + pin(Lang.translate('parental_control_confirm_new_code'), function (code_two) { + if (code_one == code_two) { + Controller.toggle(active); + call(code_two); + } else { + Controller.toggle(active); + Noty.show(Lang.translate('parental_control_no_match_code')); + call(); + } + }); + } else { + Controller.toggle(active); + call(); + } + }); + } + /** + * Показать экран ввода пина + * @param {string} title - заголовок + * @param {function} call - вызов + */ + + + function pin(title, call) { + var input = ''; + var html_layer = $("
    \n
    \n
    ".concat(title, "
    \n
    \n
    ")); + var html_code = $("
    \n
    \n
    \n
    \n
    \n
    "); + + var drawPin = function drawPin() { + var div = html_code.find('div').removeClass('fill'); + + for (var i = 0; i < 4; i++) { + if (input[i]) div.eq(i).addClass('fill'); + } + }; + + var removeNum = function removeNum() { + input = input.slice(0, Math.max(0, input.length - 1)); + drawPin(); + if (!input) callClose(); + }; + + var callClose = function callClose() { + html_layer.remove(); + call(input); + }; + + if (Platform.tv()) { + var html_body = $("
    \n
    \n
    \n ".concat(Lang.translate('pincode_use_remote'), "\n
    \n
    \n ").concat(Lang.translate('pincode_use_toggle'), "\n
    \n
    \n
    \n
    \n
    \n
    \n \n \n \n \n \n \n \n \n \n
    \n
    \n
    1
    \n
    \n
    4
    \n
    0
    \n
    2
    \n
    \n
    3
    \n
    \n
    \n\n
    \n
    \n \n \n \n \n \n
    \n
    ").concat(Lang.translate('settings_remove'), "
    \n
    \n
    \n
    \n
    ")); + html_body.find('.pincode__left').prepend(html_code); + html_layer.find('.pincode__container').append(html_body); + var layout_active = 0; + var layout_keys = [[1, 2, 3, 4, '0'], [5, 6, 7, 8, 9]]; + + var drawLayout = function drawLayout() { + var keys = layout_keys[layout_active]; + html_body.find('.pincode-remote__num-top span').text(keys[0]); + html_body.find('.pincode-remote__num-right span').text(keys[1]); + html_body.find('.pincode-remote__num-bottom span').text(keys[2]); + html_body.find('.pincode-remote__num-left span').text(keys[3]); + html_body.find('.pincode-remote__num-center span').text(keys[4]); + }; + + var animate = function animate() { + var elem = html_body.find('.pincode-remote').removeClass('push'); + setTimeout(function () { + elem.addClass('push'); + }, 60); + }; + + var writeNum = function writeNum(key) { + input = input + layout_keys[layout_active][key]; + drawPin(); + if (input.length == 4) callClose();else animate(); + }; + + drawLayout(); + Controller.add('parental_controll', { + toggle: function toggle() { + Controller.clear(); + }, + "long": function long() { + layout_active++; + if (layout_active >= layout_keys.length) layout_active = 0; + drawLayout(); + }, + enter: function enter() { + writeNum(4); + }, + left: function left() { + writeNum(3); + }, + up: function up() { + writeNum(0); + }, + down: function down() { + writeNum(2); + }, + right: function right() { + writeNum(1); + }, + back: function back() { + removeNum(); + } + }); + Lampa.Controller.toggle('parental_controll'); + } else { + html_layer.addClass('mobile'); + var html_keyboard = $("
    \n
    1
    \n
    2
    \n
    3
    \n
    4
    \n
    5
    \n
    6
    \n
    7
    \n
    8
    \n
    9
    \n
    0
    \n
    \n
    \n \n \n \n \n
    \n
    "); + html_keyboard.find('[data-key]').on('hover:enter', function () { + input = input + $(this).data('key'); + drawPin(); + if (input.length == 4) callClose(); + }); + html_keyboard.find('.remove').on('hover:enter', removeNum); + html_layer.find('.pincode__container').append(html_code).append(html_keyboard); + Controller.add('parental_controll', { + toggle: function toggle() { + Controller.collectionSet(html_keyboard); + Controller.collectionFocus(false, html_keyboard); + }, + back: function back() { + input = ''; + call(''); + callClose(); + }, + up: function up() { + Navigator.move('up'); + }, + down: function down() { + Navigator.move('down'); + }, + left: function left() { + Navigator.move('left'); + }, + right: function right() { + Navigator.move('right'); + } + }); + Lampa.Controller.toggle('parental_controll'); + } + + if (Platform.mouse()) { + html_layer.prepend(HeadBackward('')); + } + + $('body').append(html_layer); + setTimeout(function () { + html_layer.addClass('animate'); + }, 100); + } + /** + * Устаревший метод, но все еще используется, + * если пароль состоит не из 4 цифр + * @param {string} title + * @param {function} call + */ + + + function pinFree(title, call) { + Input.edit({ + free: true, + title: title, + nosave: true, + value: '', + layout: 'nums', + keyboard: 'lampa', + password: true + }, call); + } + /** + * Запросить PIN-код для настроек + * @param {string} title - заголовок + * @param {function} call - вызов + */ + + + function request$1(call, error) { + if (enabled$1()) { + var called = getPinCode().length == 4 ? pin : pinFree; + called(Lang.translate('parental_control_input_code'), function (code) { + if (code == getPinCode()) { + call(); + } else if (code) { + Noty.show(Lang.translate('parental_control_input_error')); + if (error) error(); + } else if (error) error(); + }); + } else { + call(); + } + } + /** + * Запросить PIN-код (Обший) + * @param {function} call - если pin верный + * @param {function} error - если нет + * @param {boolean} save_controller - переключить на прошлый контроллер + */ + + + function query(call, error, save_controller) { + if (enabled$1()) { + var type = Storage.field('parental_control_time'); + var active = Controller.enabled().name; + + if (type !== 'always') { + if (type == 'once') { + if (already_requested) return call(); + } else { + if (last_time_requested + 1000 * 60 * parseInt(type) > Date.now()) return call(); + } + } + + request$1(function () { + already_requested = true; + last_time_requested = Date.now(); + if (save_controller) Controller.toggle(active); + call(); + }, function () { + if (save_controller) Controller.toggle(active); + if (error) error(); + }); + } else { + call(); + } + } + /** + * Запросить PIN-код (Персональный) + * @param {string} name - название модуля + * @param {function} call - если pin верный + * @param {function} error - если нет + * @param {boolean} save_controller - переключить на прошлый контроллер + */ + + + function personal(name, call, error, save_controller) { + var enabled = Storage.get('parental_control_personal', '[]'); + if (enabled.indexOf(name) !== -1) query(call, error, save_controller);else call(); + } + /** + * Запрос на установку PIN-кода, перед этим нужно проверить через enabled() + * @param {function} call - callback + */ + + + function install$3(call) { + set$4(function (code) { + if (code) { + Storage.set('parental_control_pin', code); + Storage.set('parental_control', true); + } + + call(Boolean(code)); + }); + } + /** + * Добавить персональный PIN-код для запроса + * @param {string} name - название модуля + * @param {object} data - данные + */ + + + function add$d(name, data) { + Arrays.extend(data, { + title: Lang.translate('player_unknown'), + "default": false + }); + if (data["default"]) Storage.add('parental_control_personal', name); + personal_codes[name] = data; + } + /** + * Проверить, установлен ли контроль + * @returns bollean + */ + + + function enabled$1() { + return Storage.field('parental_control') || permit.child; + } + /** + * Получить PIN-код + * @returns string + */ + + + function getPinCode() { + return permit.child ? permit.profile.pincode || '0000' : Storage.value('parental_control_pin'); + } + + var ParentalControl = { + init: init$1e, + query: query, + personal: personal, + enabled: enabled$1, + install: install$3, + add: add$d + }; + + var listener$h = Subscribe$2(); + var status$2 = { + active: false, + channel: false, + select: false, + program: false + }; + var numpad = { + timer: false, + prev: '' + }; + + function init$1d() { + Keypad.listener.follow('keydown', function (e) { + if (!playning()) return; + PlayerPanel.rewind(); //PG- + + if (e.code === 428 || e.code === 34 || e.code === 4 || e.code === 65) { + prevChannel(); + playDelay(); + } //PG+ + + + if (e.code === 427 || e.code === 33 || e.code === 5 || e.code === 68) { + nextChannel(); + playDelay(); + } + + var digid = 0; + if (e.code >= 48 && e.code <= 57) digid = e.code - 48;else if (e.code >= 96 && e.code <= 105) digid = e.code - 96; + + if (digid) { + clearTimeout(numpad.timer); + numpad.prev += digid; + toChannel(parseInt(numpad.prev)); + numpad.timer = setTimeout(function () { + play$3(); + numpad.prev = ''; + }, 2000); + } + }); + Player.listener.follow('destroy', destroy$o); + } + + function start$a(object) { + status$2.position_view = object.position; + status$2.position_channel = object.position; + status$2.active = object; + status$2.channel = channel$1(); + listener$h.send('channel', { + channel: status$2.channel, + dir: 0, + position: status$2.position_view + }); + if (status$2.active.onPlay) status$2.active.onPlay(status$2.channel); + listener$h.send('play', { + channel: status$2.channel, + position: status$2.position_view + }); + } + + function playning() { + return status$2.active; + } + + function channel$1(position) { + status$2.select = status$2.active.onGetChannel(position || status$2.position_view); + return status$2.select; + } + + function play$3() { + if (status$2.select !== status$2.channel) { + status$2.channel = status$2.select; + status$2.position_channel = status$2.position_view; + if (status$2.active.onPlay) status$2.active.onPlay(status$2.channel); + listener$h.send('play', { + channel: status$2.channel, + position: status$2.position_view + }); + } + } + + function playDelay() { + clearTimeout(status$2.timer); + status$2.timer = setTimeout(play$3, 2000); + } + + function reset$1() { + status$2.position_view = status$2.position_channel; + moveChannel(0); + } + + function programReady(data) { + setTimeout(function () { + if (status$2.select == data.channel) { + status$2.program = data; + status$2.position_program = data.position; + listener$h.send('draw-program', { + dir: 0 + }); + } + }, 10); + } + + function select$3() { + return status$2.select; + } + + function moveChannel(dir) { + channel$1(status$2.position_view); + listener$h.send('channel', { + channel: status$2.select, + dir: dir, + position: status$2.position_view + }); + } + + function nextChannel() { + if (status$2.position_view + 1 < status$2.active.total) { + status$2.position_view++; + moveChannel(1); + } + } + + function prevChannel() { + if (status$2.position_view - 1 >= 0) { + status$2.position_view--; + moveChannel(-1); + } + } + + function toChannel(num) { + num = Math.max(1, num); + + if (num <= status$2.active.total) { + status$2.position_view = num - 1; + moveChannel(1); + } + } + + function redrawChannel() { + moveChannel(0); + } + + function moveProgram(dir) { + if (status$2.program) { + status$2.position_program += dir; + status$2.position_program = Math.max(0, Math.min(status$2.program.total, status$2.position_program)); + listener$h.send('draw-program', { + dir: dir + }); + } + } + + function nextProgram() { + moveProgram(1); + } + + function prevProgram() { + moveProgram(-1); + } + + function drawProgram(container) { + status$2.active.onGetProgram(status$2.select, status$2.position_program, container); + } + + function playlistProgram() { + if (status$2.active.onPlaylistProgram) status$2.active.onPlaylistProgram(status$2.select, status$2.position_program); + } + + function openMenu() { + if (status$2.active.onMenu) status$2.active.onMenu(status$2.select, status$2.position_program);else if (status$2.active.onPlaylistProgram) status$2.active.onPlaylistProgram(status$2.select, status$2.position_program); + } + + function destroy$o() { + clearTimeout(status$2.timer); + clearTimeout(numpad.timer); + status$2 = { + active: false, + channel: false, + select: false, + program: false + }; + } + + function locked(data, call) { + var name = Controller.enabled().name; + + if (data.locked) { + ParentalControl.query(call, function () { + Controller.toggle(name); + }); + } else call(); + } + + var PlayerIPTV = { + listener: listener$h, + init: init$1d, + start: start$a, + playning: playning, + channel: channel$1, + programReady: programReady, + reset: reset$1, + play: play$3, + select: select$3, + nextChannel: nextChannel, + prevChannel: prevChannel, + prevProgram: prevProgram, + nextProgram: nextProgram, + drawProgram: drawProgram, + playlistProgram: playlistProgram, + openMenu: openMenu, + redrawChannel: redrawChannel, + locked: locked, + destroy: destroy$o + }; + + /** + * События для компонентов + * Компоненты - классы с методами onEvent и onlyEvent + * onEvent - событие, которое вызывается у всех компонентов + * onlyEvent - событие, которое вызывается только у одного компонента + * Если несколько компонентов реализуют onlyEvent, то будет вызван только первый + */ + var Emit = /*#__PURE__*/function () { + function Emit() { + _classCallCheck(this, Emit); + + this.components = []; + } + /** + * Добавляет компонент + * @param {class|object} Module - класс или объект компонента + * @param {number|null} position - позиция в массиве компонентов, по умолчанию в конец + * @return {void} + */ + + + _createClass(Emit, [{ + key: "use", + value: function use(Module) { + var position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var instance = typeof Module === 'function' ? new Module(this) : Module; + if (this.components.includes(instance)) return; + + if (position === null) { + this.components.push(instance); + } else { + this.components.splice(position, 0, instance); + } + } + /** + * Удаляет компонент + * @param {class|object} Module - класс или объект компонента + * @return {void} + */ + + }, { + key: "unuse", + value: function unuse(Module) { + this.components = this.components.filter(function (c) { + return c !== Module; + }); + } + /** + * Проверяет наличие компонента + * @param {class|object} Module - класс или объект компонента + * @return {boolean} + */ + + }, { + key: "has", + value: function has(Module) { + return this.components.some(function (c) { + return c === Module || typeof Module === 'function' && c instanceof Module; + }); + } + /** + * Вызывает событие у компонентов + * @param {string} event - имя события + * @param {...any} args - аргументы события + * @return {void} + */ + + }, { + key: "emit", + value: function emit(event) { + var _this = this; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + var name = event.charAt(0).toUpperCase() + event.slice(1); + var only = false; + this.components.forEach(function (c) { + var handler = c["only".concat(name)]; + + if (typeof handler === 'function') { + only = handler; + } + }); + + if (only) { + var _only; + + return (_only = only).call.apply(_only, [this].concat(args)); + } + + this.components.forEach(function (c) { + var handler = c["on".concat(name)]; + + if (typeof handler === 'function') { + handler.call.apply(handler, [_this].concat(args)); + } + }); + } + }]); + + return Emit; + }(); + + /** + * Для работы с битовыми масками + * @example + * import Mask from '../utils/mask' + * import Arrays from '../utils/arrays' + * const Helper = new Mask(Arrays.getKeys(Map)) + * // где Map - объект с модулями + * // например: {Mark:..., Watchlist:..., Favorite:...} + * // теперь можно использовать Helper для работы с масками + * // например: + * // Helper.MASK.Mark - битовая маска для модуля Mark + * // Helper.MASK.Favorite - битовая маска для модуля Favorite + * // Helper.MASK.all - битовая маска для всех модулей + * // Helper.MASK.none - битовая маска для отсутствия модулей + * // Helper.only('Mark','Favorite') - битовая маска только для модулей Mark и Favorite + * // Helper.add(mask,'Watchlist') - добавляет модуль Watchlist к маске mask + * // Helper.remove(mask,'Mark') - удаляет модуль Mark из маски mask + * // Helper.toggle(mask,'Favorite') - переключает наличие модуля Favorite в маске mask + * // Helper.except('Mark') - битовая маска для всех модулей кроме Mark + * // Helper.has(mask,'Mark') - проверяет наличие модуля Mark в маске mask + * // Helper.getNames(mask) - возвращает массив названий модулей, присутствующих в маске mask + * // Helper.toObject(mask) - возвращает объект с названиями модулей и булевыми значениями их наличия в маске mask + * // Helper.describe(mask) - возвращает строковое описание модулей, присутствующих в маске mask + */ + var Mask = /*#__PURE__*/function () { + function Mask(moduleNames) { + var _this = this; + + _classCallCheck(this, Mask); + + this.moduleNames = moduleNames; + this.nameToBit = {}; + this.bitToName = {}; + this.MASK = {}; + moduleNames.forEach(function (name, index) { + var bit = 1 << index; + _this.nameToBit[name] = bit; + _this.bitToName[bit] = name; + _this.MASK[name] = bit; + }); + this.MASK.all = (1 << moduleNames.length) - 1; + this.MASK.none = 0; + } + + _createClass(Mask, [{ + key: "only", + value: function only() { + var _this2 = this; + + for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) { + names[_key] = arguments[_key]; + } + + return names.reduce(function (mask, name) { + return mask | _this2._bit(name); + }, 0); + } + }, { + key: "add", + value: function add(mask) { + for (var _len2 = arguments.length, names = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + names[_key2 - 1] = arguments[_key2]; + } + + return mask | this.only.apply(this, names); + } + }, { + key: "remove", + value: function remove(mask) { + var _this3 = this; + + for (var _len3 = arguments.length, names = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { + names[_key3 - 1] = arguments[_key3]; + } + + return names.reduce(function (acc, name) { + return acc & ~_this3._bit(name); + }, mask); + } + }, { + key: "toggle", + value: function toggle(mask) { + var _this4 = this; + + for (var _len4 = arguments.length, names = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { + names[_key4 - 1] = arguments[_key4]; + } + + return names.reduce(function (acc, name) { + return acc ^ _this4._bit(name); + }, mask); + } + }, { + key: "except", + value: function except() { + for (var _len5 = arguments.length, names = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { + names[_key5] = arguments[_key5]; + } + + return this.remove.apply(this, [this.MASK.all].concat(names)); + } + }, { + key: "has", + value: function has(mask, name) { + return (mask & this._bit(name)) !== 0; + } + }, { + key: "getNames", + value: function getNames(mask) { + var _this5 = this; + + return this.moduleNames.filter(function (name) { + return _this5.has(mask, name); + }); + } + }, { + key: "toObject", + value: function toObject(mask) { + var _this6 = this; + + var obj = {}; + this.moduleNames.forEach(function (name) { + obj[name] = _this6.has(mask, name); + }); + return obj; + } + }, { + key: "describe", + value: function describe(mask) { + var names = this.getNames(mask); + return names.length ? names.join(', ') : '(none)'; + } + }, { + key: "_bit", + value: function _bit(name) { + if (!(name in this.nameToBit)) throw new Error("Unknown module name: ".concat(name)); + return this.nameToBit[name]; + } + }]); + + return Mask; + }(); + + /** + * Конструктор модуля + * @param {*} Map - карта модулей + * @returns {Class} - класс модуля + */ + + function Constructor() { + var Map = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var Helper = new Mask(Arrays.getKeys(Map)); + return /*#__PURE__*/function (_Emit) { + _inherits(Contrucor, _Emit); + + var _super = _createSuper(Contrucor); + + function Contrucor(data) { + var _this; + + _classCallCheck(this, Contrucor); + + _this = _super.call(this, data); + Arrays.extend(data, { + params: {} + }); + _this.data = data; + _this.params = data.params; + var module = typeof _this.params.module !== 'undefined' ? _this.params.module : Helper.MASK.none; + Helper.getNames(module).map(function (name) { + return Map[name]; + }).forEach(function (mod) { + return _this.use(mod); + }); + + _this.emit('init'); + + return _this; + } + + _createClass(Contrucor, [{ + key: "toggle", + value: function toggle() { + this.emit('toggle'); + } + }, { + key: "create", + value: function create() { + this.html = document.createElement('div'); + this.emit('create'); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html : $(this.html); + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Contrucor; + }(Emit); + } + + var Row = /*#__PURE__*/function (_Constructor) { + _inherits(Row, _Constructor); + + var _super = _createSuper(Row); + + function Row() { + _classCallCheck(this, Row); + + return _super.apply(this, arguments); + } + + return Row; + }(Constructor({})); + + var html$j; + var scroll$2; + var active$7 = 0; + var items$2 = []; + var listener$g = Subscribe$2(); + + function init$1c() { + html$j = Template.js('player_footer'); + scroll$2 = new Scroll({ + nopadding: true, + over: true + }); + + scroll$2.onWheel = function (step) { + if (step > 0) down();else up(); + }; + + html$j.find('.player-footer__body').append(scroll$2.render(true)); + Controller.add('player_footer', { + toggle: function toggle() { + items$2[active$7].toggle(); + open$7(); + }, + up: close$8, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + Navigator.move('left'); + }, + back: close$8 + }); + Player.listener.follow('start', function (data) { + if (!data.iptv) { + if (data.card) appendAbout(data.card);else { + Activity.active().movie && appendAbout(Activity.active().movie); + } + } + }); + Player.listener.follow('destroy', destroy$n); + } + + function open$7() { + html$j.addClass('open'); + listener$g.send('open'); + } + + function close$8() { + html$j.removeClass('open'); + listener$g.send('close'); + } + + function appendRow(element) { + var row = new Row({}); + row.use({ + onCreate: function onCreate() { + this.html.append(element); + this.html.addClass('player-footer__row'); + }, + onToggle: function onToggle() { + var _this = this; + + Controller.add('player_footer_element', { + toggle: function toggle() { + Controller.collectionSet(_this.html); + Controller.collectionFocus(false, _this.html); + }, + up: this.emit.bind(this, 'up'), + down: this.emit.bind(this, 'down'), + right: function right() { + Navigator.move('right'); + }, + left: function left() { + Navigator.move('left'); + }, + back: this.emit.bind(this, 'back') + }); + Controller.toggle('player_footer_element'); + } + }); + appendClass(row); + return row; + } + + function removeRow(row) { + var index = items$2.indexOf(row); + + if (index !== -1) { + items$2.splice(index, 1); + row.destroy(); + } + } + + function up() { + active$7--; + + if (active$7 < 0) { + active$7 = 0; + close$8(); + } else { + items$2[active$7].toggle(); + scroll$2.update(items$2[active$7].render(true)); + } + } + + function down() { + active$7++; + active$7 = Math.min(active$7, items$2.length - 1); + scroll$2.update(items$2[active$7].render(true)); + items$2[active$7].toggle(); + } + + function appendClass(classElement) { + classElement.use({ + onUp: up, + onDown: down, + onToggle: function onToggle() { + scroll$2.render(true).style.height = this.render(true).offsetHeight; + scroll$2.update(items$2[active$7].render(true)); + }, + onEnter: function onEnter() { + close$8(); + if ($('.modal').length) Modal.close(); + Lampa.Player.close(); + }, + onBack: close$8 + }); + classElement.create(); + scroll$2.prepend(classElement.render(true)); + Arrays.insert(items$2, 0, classElement); + } + + function appendAbout(card) { + var card_html = Template.js('player_footer_card'); + var tags = []; + var relise = (card.release_date || card.first_air_date || '') + ''; + var year = relise ? relise.slice(0, 4) : ''; + if (year) tags.push(year); + + if (card.genres && Arrays.isArray(card.genres)) { + tags.push(card.genres.map(function (a) { + return Utils$1.capitalizeFirstLetter(a.name); + }).join(', ')); + } + + card_html.find('.player-footer-card__title').text(card.name || card.title); + card_html.find('.player-footer-card__tags').text(tags.length ? tags.join(' - ') : '---'); + var text = card_html.find('.player-footer-card__text'); + if (card.overview) text.text(card.overview);else { + card_html.addClass('notext'); + + for (var i = 0; i < 3; i++) { + text.append(document.createElement('div')); + } + } + Utils$1.imgLoad(card_html.find('img'), card.poster_path ? Api.img(card.poster_path, 'w200') : './img/img_broken.svg'); + appendRow(card_html); + } + + function available() { + return items$2.length; + } + + function destroy$n() { + Arrays.destroy(items$2); + active$7 = 0; + scroll$2.reset(); + items$2 = []; + } + + function render$h() { + return html$j; + } + + var PlayerFooter = { + init: init$1c, + listener: listener$g, + appendAbout: appendAbout, + appendRow: appendRow, + removeRow: removeRow, + render: render$h, + destroy: destroy$n, + available: available + }; + + var listener$f = Subscribe$2(); + var current = ''; + var playlist$1 = []; + var _position = 0; + + function init$1b() { + PlayerPanel.listener.follow('playlist', show$c); + PlayerPanel.listener.follow('prev', prev); + PlayerPanel.listener.follow('next', next); + Player.listener.follow('start', function (data) { + url$4(data.url); + if (data.playlist && data.playlist.length) set$3(data.playlist);else set$3(get$e()); + }); + Player.listener.follow('destroy', destroy$m); + PlayerVideo.listener.follow('ended', function (e) { + if (Storage.field('playlist_next') && !Select.opened()) next(); + }); + } + /** + * Показать плейлист + */ + + + function show$c() { + if (!playlist$1.length) return; + active$6(); + var enabled = Controller.enabled(); + Select.show({ + title: Lang.translate('player_playlist'), + items: playlist$1, + onSelect: function onSelect(a) { + Controller.toggle(enabled.name); + listener$f.send('select', { + playlist: playlist$1, + item: a, + position: _position + }); + }, + onBack: function onBack() { + Controller.toggle(enabled.name); + } + }); + } + /** + * Найти текущий элемент в плейлисте и установить его позицию + */ + + + function active$6() { + playlist$1.forEach(function (p) { + return p.selected = false; + }); + var find = playlist$1.find(function (l) { + return l.url == current; + }); + var data = Player.playdata(); // Если текущий урл не найден в плейлисте, то ищем по урлу из плеера + + if (!find) find = playlist$1.find(function (l) { + return l.url == data.url; + }); // Пробуем найти по эпизоду и сезону, если есть + + if (!find) find = playlist$1.find(function (l) { + return l.episode == data.episode && l.season == data.season; + }); + + if (find) { + _position = playlist$1.indexOf(find); + find.selected = true; + } + } + /** + * Назад + */ + + + function prev() { + active$6(); + + if (_position > 0) { + listener$f.send('select', { + playlist: playlist$1, + position: _position - 1, + item: playlist$1[_position - 1] + }); + } + } + /** + * Далее + */ + + + function next() { + if (canNext()) { + listener$f.send('select', { + playlist: playlist$1, + position: _position + 1, + item: playlist$1[_position + 1] + }); + } + } + /** + * Можно ли далее + * @returns {boolean} + */ + + + function canNext() { + active$6(); + return _position < playlist$1.length - 1; + } + /** + * Установить плейлист + * @param {[{title:string, url:string, thumbnail:string}]} p + */ + + + function set$3(p) { + playlist$1 = p; + active$6(); + listener$f.send('set', { + playlist: playlist$1, + position: _position + }); + } + /** + * Получить список + * @returns {[{title:string, url:string, thumbnail:string}]} + */ + + + function get$e() { + return playlist$1; + } + /** + * Установить текуший урл + * @param {string} u + */ + + + function url$4(u) { + current = u; + } + /** + * Очистить плейлист + */ + + + function destroy$m() { + current = ''; + playlist$1 = []; + _position = 0; + } + + var PlayerPlaylist = { + init: init$1b, + listener: listener$f, + active: active$6, + show: show$c, + url: url$4, + get: get$e, + set: set$3, + prev: prev, + next: next, + canNext: canNext, + position: function position() { + return _position; + }, + destroy: destroy$m + }; + + var listener$e = Subscribe$2(); + var segments = { + ad: [], + skip: [] + }; + var origin = { + ad: [], + skip: [] + }; + var ref_duration = 0; + var skip_preview_lead = 5; + + function init$1a() { + Player.listener.follow('start', function (data) { + if (data.segments) set$2(data.segments); + }); + Player.listener.follow('destroy', destroy$l); + } + + function update$e(time) { + var skip = get$d(time); + + if (skip && !skip.segment.viewed) { + skip.segment.viewed = true; + listener$e.send('skip', skip); + } + } + + function parseDurationMs(val) { + val = parseFloat(val); + if (isNaN(val) || val <= 0) return 0; + return val / 1000; + } + + function set$2(new_segments) { + origin = { + ad: [], + skip: [] + }; + ref_duration = 0; + + if (typeof new_segments === 'number') { + ref_duration = parseDurationMs(new_segments); + } else if (typeof new_segments === 'string' && new_segments && !isNaN(parseFloat(new_segments))) { + ref_duration = parseDurationMs(new_segments); + } else if (Arrays.isObject(new_segments)) { + for (var i in new_segments) { + if (i == 'duration_ms') { + ref_duration = parseDurationMs(new_segments[i]); + } else if (Arrays.isArray(new_segments[i])) { + origin[i] = new_segments[i].map(function (seg) { + return Object.assign({}, seg); + }); + } + } + } + + segments = clone$1(origin); + listener$e.send('set', segments); + } + + function clone$1(source) { + var result = {}; + + for (var i in source) { + result[i] = source[i].map(function (seg) { + return Object.assign({}, seg); + }); + } + + return result; + } + + function skipHeadSegment(source) { + if (!source.skip || !source.skip.length) return null; + var head = null; + + for (var j = 0; j < source.skip.length; j++) { + var seg = source.skip[j]; + if (!head || (seg.start || 0) < (head.start || 0)) head = seg; + } + + return head; + } + + function introSkipSegment(source) { + if (!source.skip || !source.skip.length) return null; + var head = null; + var limit = ref_duration > 0 ? ref_duration * 0.45 : Infinity; + + for (var j = 0; j < source.skip.length; j++) { + var seg = source.skip[j]; + var start = seg.start || 0; // Логотип/бампер в первые секунды — не заставка серии. + + if (start < 30) continue; + if (start > limit) continue; + if (!head || start > (head.start || 0)) head = seg; + } + + return head || skipHeadSegment(source); + } + + function tailSkipSegment(source) { + if (!source.skip || !source.skip.length) return null; + var tail = null; + var limit = ref_duration > 0 ? ref_duration * 0.55 : Infinity; + + for (var j = 0; j < source.skip.length; j++) { + var seg = source.skip[j]; + var start = seg.start || 0; // Титры у конца эталона — не бампер/промо с 0 с. + + if (start < 30) continue; + if (ref_duration > 0 && start < limit) continue; + if (!tail || (seg.end || 0) > (tail.end || 0)) tail = seg; + } + + return tail; + } + + function mapSegment(seg, duration, is_tail, credit_ref_len, tail_start) { + var start = seg.start || 0; + var end = seg.end || 0; + if (!ref_duration) return Object.assign({}, seg); // Почти эталон — метки. + + if (Math.abs(duration - ref_duration) <= 2) { + return Object.assign({}, seg); + } + + var slack = duration - ref_duration; // Короче эталона — в начале урезано, якорь с конца уводит заставку раньше. + + if (slack < 0) { + return Object.assign({}, seg); + } + + if (is_tail) { + var credit_len = Math.max(1, end - start); + var mapped_start = duration - credit_len; // Лишняя длина чаще в начале — титры фикс. длины у конца файла. + + if (credit_ref_len > 0 && slack < credit_ref_len) { + mapped_start -= Math.floor(slack * 0.3); + } + + return { + start: Math.max(0, Math.min(duration - 1, mapped_start)), + end: duration + }; + } // Бампер 0–30 с не сдвигаем. + + + if (start < 30) return Object.assign({}, seg); // Малый slack (+3…20 с) — часть offset в титрах, заставка ближе к title card. + + if (slack <= 20 && tail_start > start) { + var width = end - start || 1; + var base = duration - (ref_duration - start); + var booster = slack <= 10 ? Math.floor(slack * 2) : Math.floor(slack * 0.75); + var guide = start + Math.floor(start / 45) + booster; + var mapped = Math.max(base, guide); + var _copy = { + start: mapped, + end: mapped + width + }; + _copy.start = Math.max(0, Math.min(duration, _copy.start)); + _copy.end = Math.max(_copy.start + 1, Math.min(duration, _copy.end)); + return _copy; + } + + var copy = { + start: duration - (ref_duration - start), + end: duration - (ref_duration - end) + }; // Средний slack — часть offset в титрах, заставка ближе к контенту. + + if (credit_ref_len > 0 && slack < credit_ref_len) { + var _width = end - start || 1; + + var _base = duration - (ref_duration - start); + + var anchor = start + Math.floor(slack * 0.84); + var softened = start + Math.floor(start / 45) + Math.floor(slack * 0.52); + + if (_base > anchor) { + copy.start = anchor; + } else { + copy.start = _base + Math.floor(slack * 0.2); + } + + if (slack >= 100 && softened > start && softened < copy.start) { + copy.start = softened; + } + + copy.end = copy.start + _width; + } + + copy.start = Math.max(0, Math.min(duration, copy.start)); + copy.end = Math.max(copy.start + 1, Math.min(duration, copy.end)); + return copy; + } + + function keepEarlySkip(seg, list) { + var start = seg.start || 0; + var end = seg.end || 0; + if (start >= 30) return true; // Убираем только дубль заставки: пересечение или «хвост» в зону intro. + + for (var j = 0; j < list.length; j++) { + var other = list[j]; + var oStart = other.start || 0; + if (oStart < 30) continue; + var oEnd = other.end || 0; + if (end > oStart && start < oEnd) return false; + if (end > oStart + 15) return false; + } + + return true; + } + + function shouldKeepSkipSegment(seg, list, anchor) { + var start = seg.start || 0; + var end = seg.end || 0; + if (!keepEarlySkip(seg, list)) return false; + if (end >= ref_duration - 60) return true; + if (start >= anchor - 1) return true; // Бампер/лого до заставки — отдельная зона, не дубль intro. + + if (end <= anchor + 15) return true; + return false; + } + + function pruneSkipDuplicates() { + if (!segments.skip || !segments.skip.length) return; + var intro = introSkipSegment(segments); + if (!intro) return; + var anchor = intro.start || 0; + segments.skip = segments.skip.filter(function (seg) { + return shouldKeepSkipSegment(seg, segments.skip, anchor); + }); + } + + function skipSegmentsUi() { + var skips = [].concat(segments.skip || [], segments.ad || []); + if (!skips.length) return []; + var intro = introSkipSegment(segments); + if (!intro) return skips; + var anchor = intro.start || 0; + return skips.filter(function (seg) { + return shouldKeepSkipSegment(seg, skips, anchor); + }); + } + + function scanSkip(time, lead, preview) { + var list = skipSegmentsUi(); + if (!list.length) return preview ? false : null; + var nearest = false; + + for (var j = 0; j < list.length; j++) { + var seg = list[j]; + if (seg.skiped) continue; + + if (time >= seg.start && time <= seg.end) { + if (preview) return { + type: 'skip', + segment: seg, + phase: 'inside' + }; + return { + type: 'skip', + segment: seg + }; + } + + if (preview && time >= seg.start - lead && time < seg.start) { + var item = { + type: 'skip', + segment: seg, + phase: 'preview', + starts_in: Math.max(1, Math.ceil(seg.start - time)) + }; + if (!nearest || seg.start < nearest.segment.start) nearest = item; + } + } + + return nearest; + } + + function adjust(duration) { + duration = parseFloat(duration); + var valid = Boolean(duration) && !isNaN(duration); + + if (!valid || !ref_duration) { + segments = clone$1(origin); + listener$e.send('set', segments); + return; + } + + var tail = tailSkipSegment(origin); + var credit_ref_len = tail ? Math.max(0, (tail.end || 0) - (tail.start || 0)) : 0; + var tail_start = tail ? tail.start || 0 : 0; + var tail_at_ref = tail && Math.abs((tail.end || 0) - ref_duration) <= 15 && (tail.start || 0) >= ref_duration - Math.max(credit_ref_len, 60) - 15; + segments = {}; + + for (var i in origin) { + segments[i] = origin[i].map(function (seg) { + var is_tail = tail_at_ref && seg === tail; + return mapSegment(seg, duration, is_tail, credit_ref_len, tail_start); + }); + } + + pruneSkipDuplicates(); + listener$e.send('set', segments); + } + + function get$d(time) { + var skip = scanSkip(time, skip_preview_lead, false); + return skip || false; + } + + function getNear(time, lead) { + lead = parseFloat(lead); + if (!lead || isNaN(lead)) lead = skip_preview_lead; + time = parseFloat(time) || 0; + var skip = scanSkip(time, lead, true); + if (skip) return skip; + + for (var i in segments) { + if (i == 'skip') continue; + if (!segments[i]) continue; + + for (var j = 0; j < segments[i].length; j++) { + var seg = segments[i][j]; + if (seg.skiped) continue; + + if (time >= seg.start && time <= seg.end) { + return { + type: i, + segment: seg, + phase: 'inside' + }; + } + + if (time >= seg.start - lead && time < seg.start) { + return { + type: i, + segment: seg, + phase: 'preview', + starts_in: Math.max(1, Math.ceil(seg.start - time)) + }; + } + } + } + + return false; + } + + function all$4() { + return segments; + } + + function destroy$l() { + segments = { + ad: [], + skip: [] + }; + origin = { + ad: [], + skip: [] + }; + } + + var Segments$1 = { + init: init$1a, + listener: listener$e, + update: update$e, + set: set$2, + adjust: adjust, + get: get$d, + getNear: getNear, + all: all$4, + destroy: destroy$l + }; + + /** + * Отрисовка сегментов на таймлайне плеера + */ + + function init$19() { + PlayerVideo.listener.follow('loadeddata', draw$7); + Segments$1.listener.follow('set', draw$7); + } + + function draw$7() { + var segments = Segments$1.all(); + var timeline = Html.elem('segments').empty(); + var video = PlayerVideo.video(); + var duration = video && video.duration ? video.duration : 0; + + for (var name in segments) { + for (var a = 0; a < segments[name].length; a++) { + var seg = segments[name][a]; + var seg_elem = $("
    ")); + var r_start = Math.min(duration, seg.start); + var r_end = Math.min(duration, seg.end); + var start = duration ? r_start / duration * 100 : 0; + var length = duration ? (r_end - r_start) / duration * 100 : 0; + seg_elem.css({ + left: duration ? start + '%' : 0, + width: duration ? length + '%' : 0 + }); + timeline.append(seg_elem); + } + } + } + + function destroy$k() { + Html.elem('segments').empty(); + } + + var Segments = { + init: init$19, + destroy: destroy$k + }; + + var last_action; + /** + * Показать настройки плеера + */ + + function show$b() { + var speed = Storage.get('player_speed', 'default'); + var items = [{ + title: Lang.translate('player_video_size'), + subtitle: Lang.translate('player_size_' + Storage.get('player_size', 'default') + '_title'), + method: 'size' + }, { + title: Lang.translate('player_video_speed'), + subtitle: speed == 'default' ? Lang.translate('player_speed_default_title') : speed, + method: 'speed' + }, { + title: Lang.translate('player_share_title'), + subtitle: Lang.translate('player_share_descr'), + method: 'share' + }, { + title: Lang.translate('player_segments_title'), + subtitle: Lang.translate('player_segments_descr'), + method: 'segments' + }, { + title: Lang.translate('settings_player_subs'), + method: 'subs' + }]; + + if (Storage.field('player_normalization')) { + items.push({ + title: Lang.translate('player_normalization'), + separator: true + }); + items.push({ + title: Lang.translate('player_normalization_power_title'), + subtitle: Lang.translate('player_normalization_step_' + Storage.get('player_normalization_power', 'hight')), + method: 'normalization_power' + }); + items.push({ + title: Lang.translate('player_normalization_smooth_title'), + subtitle: Lang.translate('player_normalization_step_' + Storage.get('player_normalization_smooth', 'medium')), + method: 'normalization_smooth' + }); + items.push({ + title: Lang.translate('player_normalization_type_title'), + subtitle: Lang.translate('player_normalization_type_' + Storage.get('player_normalization_type', 'all')), + method: 'normalization_type' + }); + } + + if (last_action) { + items.find(function (a) { + return a.method == last_action; + }).selected = true; + } + + Select.show({ + title: Lang.translate('title_settings'), + items: items, + nomark: true, + onSelect: function onSelect(a) { + last_action = a.method; + if (a.method == 'size') selectSize(); + if (a.method == 'speed') selectSpeed(); + if (a.method == 'normalization_power') selectNormalizationStep('power', 'hight'); + if (a.method == 'normalization_smooth') selectNormalizationStep('smooth', 'medium'); + if (a.method == 'normalization_type') selectNormalizationType(); + if (a.method == 'segments') selectSegments(); + if (a.method == 'subs') selectSubs(); + + if (a.method == 'share') { + Controller.toggle(Platform.screen('mobile') ? 'player' : 'player_panel'); + listener$j.send('share', {}); + } + }, + onBack: function onBack() { + Controller.toggle(Platform.screen('mobile') ? 'player' : 'player_panel'); + } + }); + } + + function selectSubs() { + var items = [{ + title: Lang.translate('settings_player_subs_size'), + subtitle: Lang.translate('settings_player_subs_size_descr'), + name: 'subtitles_size' + }, { + title: Lang.translate('settings_player_subs_stroke_use'), + subtitle: Lang.translate('settings_player_subs_stroke_use_descr'), + name: 'subtitles_stroke' + }, { + title: Lang.translate('settings_player_subs_backdrop_use'), + subtitle: Lang.translate('settings_player_subs_backdrop_use_descr'), + name: 'subtitles_backdrop' + }, { + title: Lang.translate('settings_rest_time'), + name: 'player_subs_shift_time' + }]; + Select.show({ + title: Lang.translate('settings_player_subs'), + items: items, + nohide: true, + onBack: show$b, + onSelect: function onSelect(a) { + var subitems = []; + + if (a.name == 'subtitles_size') { + subitems = [{ + title: Lang.translate('settings_param_subtitles_size_small'), + value: 'small' + }, { + title: Lang.translate('settings_param_subtitles_size_normal'), + value: 'normal' + }, { + title: Lang.translate('settings_param_subtitles_size_bigger'), + value: 'large' + }]; + } + + if (a.name == 'subtitles_stroke' || a.name == 'subtitles_backdrop') { + subitems = [{ + title: Lang.translate('settings_param_yes'), + value: 'true' + }, { + title: Lang.translate('settings_param_no'), + value: 'false' + }]; + } + + if (a.name == 'player_subs_shift_time') { + subitems = [-120, -90, -60, -30, -10, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 10, 30, 60, 90, 120]; + subitems = subitems.map(function (i) { + return { + title: (i > 0 ? '+' : '') + i + ' sec.', + value: i, + selected: Storage.get('player_subs_shift_time', '0') == i + }; + }); + } else { + subitems.forEach(function (i) { + i.selected = Storage.field(a.name) + '' == i.value; + }); + } + + Select.show({ + title: a.title, + items: subitems, + nohide: true, + onBack: selectSubs, + onSelect: function onSelect(b) { + Storage.set(a.name, b.value); + listener$j.send('subs', { + type: a.name, + value: b.value + }); + selectSubs(); + } + }); + } + }); + } + + function selectSegments() { + var items = [{ + title: Lang.translate('player_segments_ad_title'), + name: 'ad', + subtitle: Lang.translate('player_segments_value_' + Storage.get('player_segments_ad', 'auto')) + }, { + title: Lang.translate('player_segments_skip_title'), + name: 'skip', + subtitle: Lang.translate('player_segments_value_' + Storage.get('player_segments_skip', 'auto')) + }]; + Select.show({ + title: Lang.translate('player_segments_title'), + items: items, + nohide: true, + onBack: show$b, + onSelect: function onSelect(a) { + Select.show({ + title: a.title, + items: [{ + title: Lang.translate('player_segments_value_auto'), + value: 'auto', + selected: Storage.get('player_segments_' + a.name, 'auto') == 'auto' + }, { + title: Lang.translate('player_segments_value_user'), + value: 'user', + selected: Storage.get('player_segments_' + a.name, 'auto') == 'user' + }, { + title: Lang.translate('player_segments_value_none'), + value: 'none', + selected: Storage.get('player_segments_' + a.name, 'auto') == 'none' + }], + nohide: true, + onBack: selectSegments, + onSelect: function onSelect(b) { + Storage.set('player_segments_' + a.name, b.value); + listener$j.send('segments', { + type: a.name, + value: b.value + }); + selectSegments(); + } + }); + } + }); + } + + function selectNormalizationType() { + var select = Storage.get('player_normalization_type', 'all'); + var items = [{ + title: Lang.translate('player_normalization_type_all'), + value: 'all', + selected: select == 'all' + }, { + title: Lang.translate('player_normalization_type_up'), + value: 'up', + selected: select == 'up' + }, { + title: Lang.translate('player_normalization_type_down'), + value: 'down', + selected: select == 'down' + }]; + Select.show({ + title: Lang.translate('player_normalization_type_title'), + items: items, + nohide: true, + onBack: show$b, + onSelect: function onSelect(a) { + Storage.set('player_normalization_type', a.value); + listener$j.send('normalization', { + type: 'type', + value: a.value + }); + show$b(); + } + }); + } + + function selectNormalizationStep(type, def) { + var select = Storage.get('player_normalization_' + type, def); + var items = [{ + title: Lang.translate('player_normalization_step_none'), + value: 'none', + selected: select == 'none' + }, { + title: Lang.translate('player_normalization_step_low'), + value: 'low', + selected: select == 'low' + }, { + title: Lang.translate('player_normalization_step_medium'), + value: 'medium', + selected: select == 'medium' + }, { + title: Lang.translate('player_normalization_step_hight'), + value: 'hight', + selected: select == 'hight' + }]; + Select.show({ + title: Lang.translate('player_normalization_' + type + '_title'), + items: items, + nohide: true, + onBack: show$b, + onSelect: function onSelect(a) { + Storage.set('player_normalization_' + type, a.value); + listener$j.send('normalization', { + type: type, + value: a.value + }); + show$b(); + } + }); + } + + function selectSize() { + var select = Storage.get('player_size', 'default'); + var items = [{ + title: Lang.translate('player_size_default_title'), + subtitle: Lang.translate('player_size_default_descr'), + value: 'default', + selected: select == 'default' + }, { + title: Lang.translate('player_size_cover_title'), + subtitle: Lang.translate('player_size_cover_descr'), + value: 'cover', + selected: select == 'cover' + }]; + + if (Platform.is('orsay') && Storage.field('player') == 'orsay') { + items.splice(1, 1); + } + + if (!(Platform.is('tizen') && Storage.field('player') == 'tizen')) { + items = items.concat([{ + title: Lang.translate('player_size_fill_title'), + subtitle: Lang.translate('player_size_fill_descr'), + value: 'fill', + selected: select == 'fill' + }, { + title: Lang.translate('player_size_s115_title'), + subtitle: Lang.translate('player_size_s115_descr'), + value: 's115', + selected: select == 's115' + }, { + title: Lang.translate('player_size_s130_title'), + subtitle: Lang.translate('player_size_s130_descr'), + value: 's130', + selected: select == 's130' + }, { + title: Lang.translate('player_size_v115_title'), + subtitle: Lang.translate('player_size_v115_descr'), + value: 'v115', + selected: select == 'v115' + }, { + title: Lang.translate('player_size_v130_title'), + subtitle: Lang.translate('player_size_v130_descr'), + value: 'v130', + selected: select == 'v130' + }]); + } else { + if (select == 's130' || select == 'fill') { + items[0].selected = true; + } + } + + Select.show({ + title: Lang.translate('player_video_size'), + items: items, + nohide: true, + onSelect: function onSelect(a) { + listener$j.send('size', { + size: a.value + }); + }, + onBack: show$b + }); + } + + function selectSpeed() { + var select = Storage.get('player_speed', 'default'); + var items = [{ + title: '0.25', + value: '0.25' + }, { + title: '0.50', + value: '0.50' + }, { + title: '0.75', + value: '0.75' + }, { + title: Lang.translate('player_speed_default_title'), + value: 'default' + }, { + title: '1.25', + value: '1.25' + }, { + title: '1.50', + value: '1.50' + }, { + title: '1.75', + value: '1.75' + }, { + title: '2', + value: '2' + }]; + + if (Platform.is('tizen') && Storage.field('player') == 'tizen' || Platform.is('orsay') && Storage.field('player') == 'orsay') { + items = [{ + title: Lang.translate('player_speed_default_title'), + value: 'default', + selected: select == 'default' + }, { + title: '2', + subtitle: Platform.is('orsay') && Storage.field('player') == 'orsay' ? Lang.translate('player_speed_two_descr') : '', + value: '2' + }]; + } + + var any; + items.forEach(function (e) { + if (e.value == select) { + any = true; + e.selected = true; + } + }); + + if (!any) { + Storage.set('player_speed', 'default'); + if (items.length == 3) items[0].selected = true;else items[3].selected = true; + } + + Select.show({ + title: Lang.translate('player_video_speed'), + items: items, + nohide: true, + onSelect: function onSelect(a) { + Storage.set('player_speed', a.value); + listener$j.send('speed', { + speed: a.value + }); + show$b(); + }, + onBack: show$b + }); + } + + var PanelSettings = { + listener: listener$j, + show: show$b + }; + + var channel_active; + + function playAnimation(elem, anim) { + elem.css('animation', 'none'); + elem[0].offsetHeight; + elem.css('animation', (anim || 'pulse') + ' 0.2s ease'); + } + + function program(data) { + if (channel_active) { + var prog = channel_active.find('.player-panel-iptv-item__prog'); + PlayerIPTV.drawProgram(prog); + playAnimation(prog, data.dir > 0 ? 'endless-left' : 'endless-right'); + } + } + + function channel(data) { + var select = PlayerIPTV.select(); + Html.elem('iptv_channel').removeClass('up down'); + var active = Html.elem('iptv_channel').find('.active'); + Html.elem('iptv_channel').find('> div:not(.active)').remove(); + var new_item = $("\n
    \n
    \n \n
    \n
    \n
    ".concat(select.group, "
    \n
    ").concat(select.name, "
    \n
    \n
    ").concat(Lang.translate('loading'), "...
    \n
    \n
    \n
    \n ")); + + if (select.icons) { + select.icons.forEach(function (ic) { + new_item.find('.player-panel-iptv-item__name').append($('
    ' + ic + '
    ')); + }); + } + + var ico = new_item.find('.player-panel-iptv-item__ico'); + var img = ico[0]; + + img.onload = function () { + ico.addClass('loaded'); + }; + + img.onerror = function () { + ico.remove(); + $('.player-panel-iptv-item__left', new_item).append("\n \n \n \n \n \n \n "); + }; + + if (select.logo) img.src = select.logo;else img.onerror(); + new_item.css({ + '-webkit-transform': 'translate3d(0,' + (data.dir > 0 ? '100%' : '-100%') + ',0)' + }); + Html.elem('iptv_channel').append(new_item); + channel_active = new_item; + playAnimation(Html.elem('iptv_position')); + playAnimation(data.dir > 0 ? Html.elem('iptv_arrow_down') : Html.elem('iptv_arrow_up')); + setTimeout(function () { + new_item.css({ + '-webkit-transform': 'translate3d(0,0,0)', + opacity: 1 + }); + if (active.length) active.removeClass('active').css({ + '-webkit-transform': 'translate3d(0,' + (data.dir > 0 ? '-100%' : '100%') + ',0)', + opacity: 0 + }); + Html.elem('iptv_position').text((data.position + 1).pad(3)); + }, 10); + } + + function settings$1() { + var enabled = Controller.enabled().name; + var items = []; + items.push({ + title: Lang.translate('player_tracks'), + trigger: Html.elem('tracks'), + ghost: Html.elem('tracks').hasClass('hide'), + noenter: Html.elem('tracks').hasClass('hide') + }); + items.push({ + title: Lang.translate('player_subs'), + trigger: Html.elem('subs'), + ghost: Html.elem('subs').hasClass('hide'), + noenter: Html.elem('subs').hasClass('hide') + }); + items.push({ + title: Lang.translate('player_quality'), + trigger: Html.elem('quality'), + ghost: !Option.hasQuality(), + noenter: !Option.hasQuality() + }); + items.push({ + title: Lang.translate('settings_main_rest'), + trigger: Html.elem('settings') + }); + Select.show({ + title: Lang.translate('title_settings'), + items: items, + onSelect: function onSelect(a) { + Controller.toggle(enabled); + a.trigger.trigger('hover:enter'); + }, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + } + + var IptvPanel = { + channel: channel, + program: program, + settings: settings$1 + }; + + var skip_button; + var skip_line; + var skip_current = null; + var skip_timer = null; + var skip_text_in = ''; + var skip_text_btn = ''; + var skip_is_end = false; + var skip_phase = ''; + + function init$18() { + skip_button = $("
    "); + skip_line = skip_button.find('.player-skip__progress-line'); + skip_button.on('hover:enter', skipDo); + PlayerVideo.listener.follow('timeupdate', function (e) { + var near = Segments$1.getNear(e.current || 0); + var user_seg = near && Storage.get('player_segments_' + near.type, 'auto') == 'user' && !near.segment.skiped; + + if (user_seg) { + if (near.phase === 'preview') { + if (!skip_current || skip_current.segment !== near.segment || skip_phase !== 'preview') preview(near);else previewUpdate(near.starts_in); + } else if (near.phase === 'inside') { + if (!skip_current || skip_current.segment !== near.segment || skip_phase !== 'active') active$5(near, e.current || 0);else progressUpdate(e.current || 0); + } + } else if (skip_current) hide$2(); + }); + Player.listener.follow('destroy', destroy$j); + addController$1(); + } + + function addController$1() { + Controller.add('player_skip', { + toggle: function toggle() { + var html = Player.render(); + Controller.collectionSet(html); + Controller.collectionFocus(skip_button[0], html); + }, + up: function up() { + if (PlayerPanel.visibleStatus()) PlayerPanel.hide();else PlayerPanel.reveal(); + }, + down: PlayerPanel.toggle, + left: Player.toggle, + right: Player.toggle, + gone: function gone() { + if (skip_button) skip_button.removeClass('focus'); + }, + back: Player.close + }); + } + + function toggle$a() { + if (!isActive$2()) return; + Controller.toggle('player_skip'); + } + + function isActive$2() { + return skip_phase === 'active' && Boolean(skip_button) && !skip_button.hasClass('hide'); + } + + function progressSet(value, instant) { + if (!skip_line || !skip_line.length) return; + var scale = Math.max(0, Math.min(1, value)); // reflow до и после установки, иначе браузер склеит смену класса и transform в один кадр и проиграет transition + + if (instant) { + skip_line.addClass('player-skip__progress-line--instant'); + skip_line[0].offsetWidth; + } + + skip_line.css({ + '-webkit-transform': 'scaleX(' + scale + ')', + 'transform': 'scaleX(' + scale + ')' + }); + + if (instant) { + skip_line[0].offsetWidth; + skip_line.removeClass('player-skip__progress-line--instant'); + } + } + + function progressUpdate(current, instant) { + if (skip_phase !== 'active' || !skip_current) return; + var seg = skip_current.segment; + var length = (seg.end || 0) - (seg.start || 0); + progressSet(length > 0 ? ((seg.end || 0) - current) / length : 0, instant); + } + + function draw$6(e) { + var v = PlayerVideo.video(); + var dur = v ? v.duration || 0 : 0; + var end = dur && e.type == 'skip' && (e.segment.start >= dur * 0.7 || e.segment.end >= dur - 15); + skip_is_end = Boolean(end); + + if (end) { + skip_text_in = Lang.translate('player_segments_next_in'); + skip_text_btn = Lang.translate('player_segments_next'); + } else { + skip_text_in = Lang.translate('player_segments_skip_in'); + skip_text_btn = Lang.translate('player_segments_skip_now'); + } + } + + function preview(e) { + if (!skip_button) return; + clearInterval(skip_timer); + skip_current = e; + skip_phase = 'preview'; + draw$6(e); + previewUpdate(e.starts_in); + progressSet(0, true); + skip_button.removeClass('hide focus').addClass('player-skip--preview'); + } + + function previewUpdate(seconds) { + if (!skip_button || skip_phase !== 'preview') return; + skip_button.find('.player-skip__text').text(skip_text_in + ' ' + seconds); + } + + function active$5(e, current) { + if (!skip_button) return; + clearInterval(skip_timer); + skip_current = e; + skip_phase = 'active'; + draw$6(e); + skip_button.removeClass('player-skip--preview'); + show$a(); + progressUpdate(typeof current == 'number' ? current : e.segment.start, true); + } + + function show$a() { + if (!skip_button) return; + clearInterval(skip_timer); + skip_button.find('.player-skip__text').text(skip_text_btn); + skip_button.removeClass('hide'); + if (Controller.enabled().name == 'player') toggle$a(); + } + + function hide$2() { + clearInterval(skip_timer); + if (skip_button) skip_button.addClass('hide').removeClass('focus player-skip--preview'); + progressSet(0, true); + var was = skip_current; + skip_current = null; + skip_phase = ''; + if (was && Controller.enabled().name == 'player_skip') Controller.toggle('player'); + } + + function skipDo() { + if (skip_phase !== 'active') return; + + if (skip_current) { + skip_current.segment.skiped = true; + + if (skip_is_end) { + hide$2(); + PlayerPlaylist.next(); + return; + } + + PlayerVideo.to(Math.min(PlayerVideo.video().duration || skip_current.segment.end, skip_current.segment.end)); + } + + hide$2(); + } + + function render$g() { + return skip_button; + } + + function destroy$j() { + hide$2(); + } + + var Skip = { + init: init$18, + render: render$g, + hide: hide$2, + preview: preview, + toggle: toggle$a, + previewUpdate: previewUpdate, + active: active$5, + "do": skipDo, + isActive: isActive$2, + phase: function phase() { + return skip_phase; + }, + current: function current() { + return skip_current; + }, + button: function button() { + return skip_button; + }, + destroy: destroy$j + }; + + /** + * Добавить HTML в панель плеера + * @param {string} side - Сторона панели ('left', 'right', 'top', 'bottom') + * @param {string} html - HTML-код для добавления + */ + + function push$9(side, html) { + Html.render().find('.player-panel__apex-' + side + '-side').prepend(html); + } + + function render$f(side) { + return Html.render().find('.player-panel__apex-' + side + '-side'); + } + + function clear$c(side) { + Html.render().find('.player-panel__apex-' + side + '-side').empty(); + } + + function destroy$i() { + clear$c('left'); + clear$c('right'); + clear$c('bottom'); + clear$c('top'); + } + + var Apex = { + push: push$9, + render: render$f, + clear: clear$c, + destroy: destroy$i + }; + + /** + * Отрисовка следующего эпизода в плеере + */ + + function init$17() { + PlayerPlaylist.listener.follow('set', function (e) { + clear$b(); + var next = e.playlist[e.position + 1]; + if (next) draw$5(next); + }); + } + /** + * Отрисовка следующего эпизода + * @param {Object} item - Данные следующего эпизода + * @param {string} item.title - Название эпизода + * @param {string} item.thumbnail - URL миниатюры эпизода + * @param {string} item.episode - Номер эпизода + */ + + + function draw$5(item) { + var content = []; + + if (item.thumbnail) { + var thumbnail = Template.elem('div', { + "class": 'player-next__thumbnail', + children: [Template.elem('img', { + "class": 'player-next__thumbnail-img' + })] + }); + Utils$1.imgLoad(thumbnail.find('img'), item.thumbnail, function () { + thumbnail.addClass('loaded'); + }); + content.push(thumbnail); + } + + var body = Template.elem('div', { + "class": 'player-next__body', + children: [Template.elem('div', { + "class": 'player-next__title', + text: Lang.translate('player_segments_next') + }), Template.elem('div', { + "class": 'player-next__episode-title', + text: item.title + })] + }); + content.push(body); + var box = Template.elem('div', { + "class": 'player-next', + children: [Template.elem('div', { + "class": 'player-next__episode', + children: content + })] + }); + Apex.push('left', box); + } + + function clear$b() { + Apex.render('left').find('.player-next').remove(); + } + + function destroy$h() { + clear$b(); + } + + var Next$2 = { + init: init$17, + destroy: destroy$h + }; + + var state; + var panel_visible = false; + var timeline_last = { + position: 0, + peding: 0 + }; + var condition = {}; + var timer$7 = {}; + + function init$16() { + Html.init(); + Option.init(); + Segments.init(); + Next$2.init(); + /** + * Отсеживаем состояние, + * когда надо показать панель, а когда нет + */ + + state = new StateMachine({ + state: 'start', + transitions: { + start: function start() { + clearTimeout(timer$7.hide); + clearTimeout(timer$7.rewind); + this.dispath('canplay'); + }, + canplay: function canplay() { + if (condition.canplay) this.dispath('visible');else _visible(true); + }, + visible: function visible() { + if (condition.visible) _visible(true);else this.dispath('rewind'); + }, + rewind: function rewind() { + var _this = this; + + clearTimeout(timer$7.rewind); + + if (condition.rewind) { + _visible(true); + + timer$7.rewind = setTimeout(function () { + condition.rewind = false; + + _this.dispath('mousemove'); + }, 1000); + } else { + this.dispath('mousemove'); + } + }, + mousemove: function mousemove() { + if (condition.mousemove) { + _visible(true); + } + + this.dispath('hide'); + }, + hide: function hide() { + clearTimeout(timer$7.hide); + timer$7.hide = setTimeout(function () { + if (PlayerIPTV.playning()) { + PlayerIPTV.reset(); + Controller.toggle('player'); + } else if (Html.render().hasClass('panel--footer-open')) ; else if (!PlayerVideo.video().paused) _visible(false); + }, PlayerIPTV.playning() || Platform.screen('mobile') ? 5000 : 3000); + } + } + }); + PlayerPlaylist.listener.follow('set', function (e) { + Html.elem('playlist_buttons').toggleClass('hide', Boolean(e.playlist.length == 0)); + Html.elem('next').toggleClass('hide', !PlayerPlaylist.canNext()); + }); + Html.elem('playpause').on('hover:enter', function (e) { + listener$j.send('playpause', {}); + }); + Html.elem('next').on('hover:enter', function (e) { + listener$j.send('next', {}); + }); + Html.elem('prev').on('hover:enter', function (e) { + listener$j.send('prev', {}); + }); + Html.elem('rprev').on('hover:enter', function (e) { + listener$j.send('rprev', {}); + }); + Html.elem('rnext').on('hover:enter', function (e) { + listener$j.send('rnext', {}); + }); + Html.elem('playlist').on('hover:enter', function (e) { + listener$j.send('playlist', {}); + }); + Html.elem('tstart').on('hover:enter', function (e) { + listener$j.send('to_start', {}); + }); + Html.elem('tend').on('hover:enter', function (e) { + listener$j.send('to_end', {}); + }); + Html.elem('fullscreen').on('hover:enter', function (e) { + listener$j.send('fullscreen', {}); + }); + Html.elem('settings').on('hover:enter', PanelSettings.show); + Html.render().find('.player-panel__pip,.player-panel__volume').toggleClass('hide', !Boolean(Platform.desktop() || Platform.is('browser') || Platform.is('apple') && !Utils$1.isPWA())); + Html.elem('pip').on('hover:enter', function () { + listener$j.send('pip', {}); + }); + Html.elem('rewind_touch').toggleClass('hide', !Platform.screen('mobile')); + Html.elem('timeline').on('mousemove', function (e) { + if (!Platform.screen('mobile')) listener$j.send('mouse_rewind', { + method: 'move', + time: Html.elem('time'), + percent: percent(e) + }); + }).on('mouseout', function () { + if (!Platform.screen('mobile')) Html.elem('time').addClass('hide'); + }).on('click', function (e) { + if (DeviceInput.canClick(e.originalEvent) && !Platform.screen('mobile')) listener$j.send('mouse_rewind', { + method: 'click', + time: Html.elem('time'), + percent: percent(e) + }); + }); + + if (!Html.elem('volume').hasClass('hide')) { + Html.elem('volume').find('.player-panel__volume-range').val(Storage.get('player_volume', '1')).on('input', function () { + listener$j.send('change_volume', { + volume: $(this).val() + }); + PlayerVideo.volume($(this).val()); + }); + } + + var touch; + + var touchEnd = function touchEnd(e) { + window.removeEventListener('touchend', touchEnd); + PlayerVideo.video().rewind = false; + listener$j.send('mouse_rewind', { + method: 'click', + time: Html.elem('time'), + percent: touch.to / 100 + }); + touch = false; + }; + + Html.elem('rewind_touch').on('touchstart', function (e) { + var point = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + touch = { + now: percent({ + clientX: Html.elem('position').width() + }) * 100, + from: percent(point) * 100 + }; + touch.move = touch.from; + touch.to = touch.from; + window.addEventListener('touchend', touchEnd); + }).on('touchmove', function (e) { + var point = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + + if (touch) { + touch.move = percent(point) * 100; + touch.to = Math.max(0, Math.min(100, touch.now + (touch.move - touch.from))); + timeline_last.position = touch.to + '%'; + Html.elem('timenow').text(Utils$1.secondsToTime(touch.to / 100 * (PlayerVideo.video().duration || 0))); + PlayerVideo.video().rewind = true; + rewind$1(); + } + }); + PlayerIPTV.listener.follow('channel', IptvPanel.channel); + PlayerIPTV.listener.follow('draw-program', IptvPanel.program); + Player.listener.follow('start', function (data) { + show$9(); + Option.setQualitys(data.quality, data.url); + Option.setTracks(data.voiceovers); + Option.setTranslates(data.translate); + }); + Player.listener.follow('destroy', destroy$g); + PlayerFooter.listener.follow('open', function () { + Html.render().addClass('panel--footer-open'); + }); + PlayerFooter.listener.follow('close', function () { + Html.render().removeClass('panel--footer-open'); + Controller.toggle('player_panel'); + }); + PlayerVideo.listener.follow('timeupdate', function (e) { + update$d('time', Utils$1.secondsToTime(e.current | 0, true)); + update$d('timenow', Utils$1.secondsToTime(e.current || 0)); + update$d('timeend', Utils$1.secondsToTime(e.duration || 0) + ' - ' + Lang.translate('title_left') + ' ' + Utils$1.secondsToTimeHuman(e.duration - e.current || 0)); + update$d('position', e.current / e.duration * 100 + '%'); + }); + PlayerVideo.listener.follow('progress', function (e) { + update$d('peding', e.down); + }); + PlayerVideo.listener.follow('canplay', function () { + canplay(); + }); + PlayerVideo.listener.follow('play', function () { + update$d('play'); + rewind$1(); + }); + PlayerVideo.listener.follow('pause', function () { + update$d('pause'); + }); + PlayerVideo.listener.follow('rewind', function () { + rewind$1(); + }); + PlayerVideo.listener.follow('subs', function (e) { + Option.setSubtitles(e.subs); + }); + PlayerVideo.listener.follow('levels', function (e) { + Option.setLevels(e.levels, e.current); + }); + PlayerVideo.listener.follow('translate', function (e) { + Option.updateTranslate(e.where, e.translate); + }); + listener$j.follow('mouse_rewind', function (e) { + var vid = PlayerVideo.video(); + + if (vid && vid.duration) { + if (!Platform.screen('mobile')) e.time.removeClass('hide').text(Utils$1.secondsToTime(vid.duration * e.percent)).css('left', e.percent * 100 + '%'); + + if (e.method == 'click') { + PlayerVideo.to(vid.duration * e.percent); + } + } + }); + listener$j.follow('playpause', function () { + PlayerVideo.playpause(); + if (Platform.screen('mobile')) rewind$1(); + }); + listener$j.follow('size', function (e) { + PlayerVideo.size(e.size); + Storage.set('player_size', e.size); + }); + listener$j.follow('speed', function (e) { + PlayerVideo.speed(e.speed); + Storage.set('player_speed', e.speed); + }); + listener$j.follow('rprev', function () { + PlayerVideo.rewind(false); + }); + listener$j.follow('rnext', function () { + PlayerVideo.rewind(true); + }); + listener$j.follow('subsview', function (e) { + PlayerVideo.subsview(e.status); + }); + listener$j.follow('to_start', function () { + PlayerVideo.to(0); + }); + listener$j.follow('fullscreen', function () { + Utils$1.toggleFullscreen(); + }); + listener$j.follow('pip', function () { + PlayerVideo.pip(); + }); + } + /** + * Cкрыть панель перемотки + */ + + + function hideRewind() { + Html.render().addClass('panel--norewind'); + } + /** + * Добавить контроллеры + */ + + + function addController() { + Controller.add('player_tv', { + invisible: true, + toggle: function toggle() { + Controller.clear(); + condition.visible = false; + state.start(); + }, + up: function up() { + PlayerIPTV.prevChannel(); + state.start(); + }, + down: function down() { + PlayerIPTV.nextChannel(); + state.start(); + }, + left: function left() { + condition.visible = true; + PlayerIPTV.openMenu(); + state.start(); + }, + right: function right() { + condition.visible = true; + IptvPanel.settings(); + state.start(); + }, + enter: function enter() { + PlayerIPTV.play(); + state.start(); + }, + back: function back() { + PlayerIPTV.reset(); + Controller.toggle('player'); + hide$1(); + } + }); + Controller.add('player_rewind', { + toggle: function toggle() { + Controller.collectionSet(render$e()); + Controller.collectionFocus(false, render$e()); + }, + up: function up() { + toggleUp(); + }, + down: function down() { + toggleButtons(); + }, + right: function right() { + listener$j.send('rnext', {}); + }, + left: function left() { + listener$j.send('rprev', {}); + }, + gone: function gone() { + Html.render().find('.selector').removeClass('focus'); + }, + back: toPlayer + }); + Controller.add('player_panel', { + toggle: function toggle() { + if (PlayerIPTV.playning()) Controller.toggle('player_tv');else { + Controller.collectionSet(render$e()); + Controller.collectionFocus($(Player.playdata().iptv ? '.player-panel__next' : '.player-panel__playpause', Html.render())[0], render$e()); + } + }, + up: function up() { + Player.playdata().iptv || Html.render().hasClass('panel--norewind') ? toggleUp() : toggleRewind(); + }, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + Navigator.move('left'); + }, + down: function down() { + PlayerFooter.available() ? Controller.toggle('player_footer') : listener$j.send('playlist', {}); + }, + gone: function gone() { + Html.render().find('.selector').removeClass('focus'); + }, + back: toPlayer + }); + } + /** + * Рассчитать проценты + * @param {object} e + * @returns {number} + */ + + + function percent(e) { + var offset = Html.elem('timeline').offset(); + var width = Html.elem('timeline').width(); + return (e.clientX - offset.left) / width; + } + /** + * Обновляем состояние панели + * @param {string} need - что нужно обновить + * @param {string|number} value - значение + */ + + + function update$d(need, value) { + if (need == 'position') { + timeline_last.position = value; + if (panel_visible) Html.elem('position').css({ + width: value + }); + } + + if (need == 'peding') { + timeline_last.peding = value; + if (panel_visible) Html.elem('peding').css({ + width: value + }); + } + + if (need == 'timeend') { + Html.elem('timeend').text(value); + } + + if (need == 'timenow') { + Html.elem('timenow').text(value); + } + + if (need == 'play') { + Html.render().toggleClass('panel--paused', false); + } + + if (need == 'pause') { + Html.render().toggleClass('panel--paused', true); + } + } + /** + * Показать или скрыть панель + * @param {boolean} status + */ + + + function _visible(status) { + panel_visible = status; + listener$j.send('visible', { + status: status + }); + Html.render().toggleClass('panel--visible', status); + Html.elem('position').css({ + width: timeline_last.position + }); + Html.elem('peding').css({ + width: timeline_last.peding + }); + } + /** + * Получили событие canplay, теперь можно скрывать панель и отслеживать статус + */ + + + function canplay() { + condition.canplay = true; + state.start(); + } + /** + * Запустили режим перемотки, показываем панель и через 3 секунды скрываем + */ + + + function rewind$1() { + condition.rewind = true; + state.start(); + } + /** + * Переключить на контроллер перемотки + */ + + + function toggleRewind() { + Controller.toggle(Player.playdata().iptv || Html.render().hasClass('panel--norewind') ? 'player_panel' : 'player_rewind'); + } + /** + * Уйти вверх с панели: на кнопку пропуска, если она показана, иначе на плеер + */ + + + function toggleUp() { + if (Skip.isActive()) Skip.toggle();else Controller.toggle('player'); + } + /** + * Уйти на плеер и скрыть панель + */ + + + function toPlayer() { + Controller.toggle('player'); + hide$1(); + } + /** + * Показать панель, не переключая контроллер + */ + + + function reveal() { + condition.visible = true; + state.start(); + } + /** + * Переключить на контроллер кнопки + */ + + + function toggleButtons() { + if (!Platform.screen('mobile')) Controller.toggle('player_panel'); + } + /** + * Переключить на контроллер панели + */ + + + function toggle$9() { + condition.visible = true; + state.start(); + if (PlayerIPTV.playning()) Controller.toggle('player_tv');else if (!Platform.screen('mobile')) toggleButtons(); + } + /** + * Запустили плеер и нужно запустить статус панели + */ + + + function show$9() { + state.start(); + Html.elem('fullscreen').toggleClass('hide', Platform.tv() || Platform.is('android') || !Utils$1.canFullScreen()); + addController(); + } + /** + * Если двигали мышку + */ + + + function mousemove() { + condition.mousemove = true; + state.start(); + } + /** + * Скрыть панель + */ + + + function hide$1() { + condition.visible = false; + condition.mousemove = false; + + _visible(false); + } + /** + * Состояние видимости панели + * @returns {boolean} + */ + + + function visibleStatus() { + return panel_visible; + } + /** + * Уничтожить + */ + + + function destroy$g() { + condition = {}; + timeline_last.position = 0; + timeline_last.peding = 0; + panel_visible = false; + Option.destroy(); + Apex.destroy(); + Segments.destroy(); + Next$2.destroy(); + Html.elem('peding').css({ + width: 0 + }); + Html.elem('position').css({ + width: 0 + }); + Html.elem('time').text('00:00'); + Html.elem('timenow').text('00:00'); + Html.elem('timeend').text('00:00'); + Html.elem('episode').toggleClass('hide', true); + Html.elem('playlist_buttons').toggleClass('hide', true); + Html.render().toggleClass('panel--paused', false); + Html.render().toggleClass('panel--norewind', false); + Html.render().toggleClass('panel--footer-open', false); + } + /** + * Получить html + * @returns {object} + */ + + + function render$e() { + return Html.render(); + } + + var PlayerPanel = { + init: init$16, + listener: listener$j, + render: render$e, + toggle: toggle$9, + show: show$9, + destroy: destroy$g, + hide: hide$1, + toPlayer: toPlayer, + reveal: reveal, + canplay: canplay, + update: update$d, + rewind: rewind$1, + mousemove: mousemove, + quality: Option.setQualitys, + updateTranslate: Option.updateTranslate, + visible: _visible, + visibleStatus: visibleStatus, + hideRewind: hideRewind, + setTranslate: Option.setTranslates, + setTracks: Option.setTracks, + setSubs: Option.setSubtitles, + setLevels: Option.setLevels, + setFlows: Option.setFlows + }; + + var html$i; + var listener$d = Subscribe$2(); + var network$a = new Request(); + var elems; + var error$2, stat_timer; + + function init$15() { + html$i = Template.get('player_info'); + html$i.find('.player-info__body').prepend(HeadBackward(Lang.translate('settings_main_player'))); + elems = { + name: $('.player-info__name,.head-backward__title', html$i), + title: $('.player-info__title', html$i), + size: $('.value--size span', html$i), + stat: $('.value--stat span', html$i), + speed: $('.value--speed span', html$i), + vname: $('.value--name', html$i), + error: $('.player-info__error', html$i), + timeend: $('.player-info__time-end span', html$i), + pieces: $('.value--pieces', html$i) + }; + Utils$1.time(html$i); + PlayerVideo.listener.follow('videosize', function (e) { + set$1('size', e); + }); + PlayerVideo.listener.follow('destroy', function (e) { + set$1('bitrate', ''); + }); + PlayerVideo.listener.follow('timeupdate', updateTimeEnd); + PlayerVideo.listener.follow('error', function (e) { + if (e.fatal) elems.size.text(Lang.translate('title_error'));else set$1('error', e.error); + }); + PlayerPanel.listener.follow('visible', function (e) { + toggle$8(e.status); + updateTimeEnd(); + }); + Player.listener.follow('start', function (data) { + set$1('name', data.title); + if (Torserver.ip() && data.url.indexOf(Torserver.ip()) > -1) set$1('stat', data); + }); + Player.listener.follow('destroy', destroy$f); + } + + function updateTimeEnd() { + var video = PlayerVideo.video(); + + if (PlayerPanel.visibleStatus() && video && video.duration) { + elems.timeend.text(Lang.translate('player_time_end') + ' ' + Utils$1.parseTime(new Date(Date.now() + (video.duration - video.currentTime) * 1000)).time); + } else { + elems.timeend.text(''); + } + } + /** + * Установить значение + * @param {string} need + * @param {string|{width,height}} value + */ + + + function set$1(need, value) { + if (need == 'name') { + var name = value; + var work = Player.playdata(); + var head = ''; + + if (!work.iptv) { + if (work.card) head = work.card.title || work.card.name;else if (Lampa.Activity.active().movie) { + head = Lampa.Activity.active().movie.title || Lampa.Activity.active().movie.name; + } + if (!head) head = name; + elems.title.text(head).toggleClass('hide', Boolean(work.iptv)); + elems.name.toggleClass('hide', Boolean(name == head)).toggleClass('hide', true); + elems.vname.toggleClass('hide', Boolean(name == head)).find('span').text(name); + } else elems.title.text(name); + } else if (need == 'size' && value.width && value.height) elems.size.text(value.width + 'x' + value.height);else if (need == 'error') { + clearTimeout(error$2); + elems.error.removeClass('hide').text(value); + error$2 = setTimeout(function () { + elems.error.addClass('hide'); + }, 10000); + } else if (need == 'stat') stat$3(value);else if (need == 'bitrate' && !stat_timer) elems.stat.html(value); + } + + function pieces(cache) { + elems.pieces.empty(); + + if (cache.Readers.length) { + var reader = cache.Readers[0].Reader; + var end = cache.Readers[0].End; + var start = reader; + var total = end - reader; + var dots = 5; + var loaded = 0; + + while (cache.Pieces[start] && cache.Pieces[start].Completed && start < end) { + start++; + loaded++; + } + + var percent = loaded / total * 100; + + for (var i = 0; i < dots; i++) { + var color = ''; + var filled = Math.round(dots * (loaded / total)) >= i; + + if (i == 0) { + if (percent > 80) color = 'green';else if (percent >= 40) color = 'yellow';else color = 'red'; + } else if (filled) color = 'active'; + + elems.pieces.append(''); + } + } + } + /** + * Показываем статистику по торренту + * @param {object} player_data + */ + + + function stat$3(player_data) { + var wait = 0; + elems.stat.text('- / - • - ' + Lang.translate('connected_seeds')); + elems.speed.text('--'); + + var update = function update() { + // если панель скрыта, то зачем каждую секунду чекать? хватит и 5 сек + // проверено, если ставить на паузу, разадача удаляется, но если чекать постоянно, то все норм + if (!html$i.hasClass('info--visible')) { + wait++; + if (wait <= 5) return;else wait = 0; + } + + network$a.timeout(2000); + var url = ''; + if (Torserver.gstWork()) url = Torserver.url() + '/gst/' + player_data.torrent_hash + '/heartbeat';else url = player_data.url.replace('&preload', '&stat').replace('&play', '&stat'); + network$a.silent(url, function (data) { + var torrent = data.Torrent || data; + elems.stat.text((torrent.active_peers || 0) + ' / ' + (torrent.total_peers || 0) + ' • ' + (torrent.connected_seeders || 0) + ' ' + Lang.translate('connected_seeds')); + elems.speed.text(Utils$1.bytesToSize(torrent.download_speed ? torrent.download_speed * 8 : 0, true)); + if (Torserver.gstWork()) return pieces(data); + var hash = url.match(/link=(.*?)\&/); + + if (hash) { + Torserver.cache(hash[1], function (cache) { + pieces(cache); + listener$d.send('stat', { + data: data, + cache: cache + }); + }, function () { + listener$d.send('stat', { + data: data + }); + }); + } else { + listener$d.send('stat', { + data: data + }); + } + }); + }; + + stat_timer = setInterval(update, 2000); + update(); + } + /** + * Показать скрыть инфо + * @param {boolean} status + */ + + + function toggle$8(status) { + html$i.toggleClass('info--visible', status); + } + + function loading$2() { + elems.size.text(Lang.translate('loading') + '...'); + } + /** + * Уничтожить + */ + + + function destroy$f() { + elems.size.text(Lang.translate('loading') + '...'); + elems.stat.text(''); + elems.speed.text(''); + elems.error.addClass('hide'); + elems.pieces.empty(); + elems.vname.toggleClass('hide', true); + elems.name.toggleClass('hide', true); + elems.title.toggleClass('hide', false); + clearTimeout(error$2); + clearInterval(stat_timer); + network$a.clear(); + } + + function render$d() { + return html$i; + } + + var PlayerInfo = { + init: init$15, + listener: listener$d, + render: render$d, + set: set$1, + toggle: toggle$8, + loading: loading$2, + destroy: destroy$f + }; + + var cues_timer; + /** + * Отрисовка субтитров в плеере + * @param {String} text - Текст субтитров + * @param {String} style - Стиль субтитров (например, 'bold', 'italic', 'underline') + */ + + function draw$4(text, style) { + var cues = render$c(); + var inner = $('> div', cues); + inner.removeClass('bold italic underline'); + if (style) inner.addClass(style); + inner.html(text ? text : ' ').css({ + display: text ? 'inline-block' : 'none' + }); + clearTimeout(cues_timer); + cues_timer = setTimeout(function () { + inner.html(' ').css({ + display: 'none' + }); + }, 10000); + } + + function render$c() { + return PlayerVideo.render().find('.player-video__subtitles'); + } + + var Cue = { + draw: draw$4, + render: render$c + }; + + var _hls = null; + var _hls_parser = null; + var _hls_subs_cues = {}; + + var _hls_subs_active_track = -1; + + function levelName(level) { + var level_width = level.width || 0; + var level_height = level.height || 0; + var levels = [240, 360, 480, 720, 1080, 1440, 2160]; + var name = levels.find(function (size) { + var quality_width = Math.round(size * 1.777); + var quality_height = size; + var w = level_width > quality_width - 50 && level_width < quality_width + 50; + var h = level_height > quality_height - 50 && level_height < quality_height + 50; + return w || h; + }); + return name ? name + 'p' : level.qu ? level.qu : level.width ? level.height + 'p' : 'AUTO'; + } + + function levelDefault(where) { + var start_level = where.levels.find(function (level) { + var level_width = level.width || 0; + var level_height = level.height || 0; + var quality_width = Math.round(Storage.field('video_quality_default') * 1.777); + var quality_height = Storage.field('video_quality_default'); + var w = level_width > quality_width - 50 && level_width < quality_width + 50; + var h = level_height > quality_height - 50 && level_height < quality_height + 50; + return w || h; + }); + return start_level ? where.levels.indexOf(start_level) : where.currentLevel; + } + + function bitrate(seconds) { + if (_hls && _hls.streamController && _hls.streamController.fragPlaying && _hls.streamController.fragPlaying.baseurl && _hls.streamController.fragPlaying.stats) { + var ch = Lang.translate('title_channel') + ' ' + parseFloat(_hls.streamController.fragLastKbps / 1000).toFixed(2) + ' ' + Lang.translate('speed_mb'); + var bt = '  •  ' + Lang.translate('torrent_item_bitrate') + ' ~' + parseFloat(_hls.streamController.fragPlaying.stats.total / 1000000 / 10 * 8).toFixed(2) + ' ' + Lang.translate('speed_mb'); + var bf = '  •  ' + Lang.translate('title_buffer') + ' ' + Utils$1.secondsToTimeHuman(seconds); + PlayerInfo.set('bitrate', ch + bt + bf); + } + } + + function update$c(seconds) { + if (!_hls || _hls_subs_active_track < 0) return; + var cues = _hls_subs_cues[_hls_subs_active_track]; + if (!cues) return; + var active = null; + + for (var i = 0; i < cues.length; i++) { + var c = cues[i]; + + if (c.startTime <= seconds && seconds < c.endTime) { + active = c; + break; + } + } + + Cue.draw(active ? active.text || '' : ''); + } + + function shouldUseProgram(videoEl, playdata) { + var use_program = Storage.field('player_hls_method') == 'hlsjs' || Platform.chromeVersion() > 120; + var hls_type = playdata.hls_type; + var hls_native = videoEl.canPlayType('application/vnd.apple.mpegurl'); + if (Platform.is('tizen') && Storage.field('player') == 'tizen') use_program = false;else if (Platform.is('orsay') && Storage.field('player') == 'orsay') use_program = false;else if (!use_program && !hls_native) use_program = true; + if (hls_type == 'hlsjs') use_program = true;else if (hls_type == 'native' && hls_native) use_program = false; + if (!Hls.isSupported()) use_program = false; + return { + use_program: use_program, + hls_native: hls_native + }; + } + + function createProgram(src, videoEl, playdata, callbacks) { + var timeout = playdata.hls_manifest_timeout || 10000; + console.log('Player', 'hls start program'); + _hls = new Hls({ + manifestLoadTimeout: timeout, + manifestLoadMaxRetryTimeout: playdata.hls_retry_timeout || 30000, + renderTextTracksNatively: false, + xhrSetup: function xhrSetup(xhr) { + xhr.timeout = timeout; + + xhr.ontimeout = function () { + console.log('Player', 'hls manifestLoadTimeout'); + }; + } + }); + + _hls.loadSource(src); + + _hls.attachMedia(videoEl); + + _hls.on(Hls.Events.ERROR, function (_, data) { + console.log('Player', 'hls error', data.reason, data.details, data.fatal); + + if (data.details === Hls.ErrorDetails.MANIFEST_PARSING_ERROR) { + if (data.reason === "no EXTM3U delimiter") { + callbacks.load(src); + } else { + callbacks.error('details [' + data.details + '] fatal [' + data.fatal + ']', data.fatal); + } + } else { + callbacks.error('details [' + data.details + '] fatal [' + data.fatal + ']', data.fatal); + } + }); + + _hls.on(Hls.Events.MANIFEST_LOADED, function () { + callbacks.play(); + }); + + _hls.on(Hls.Events.MANIFEST_PARSED, function () { + _hls.currentLevel = levelDefault(_hls); + }); + + _hls.on(Hls.Events.SUBTITLE_TRACKS_UPDATED, function (_event, data) { + if (!data.subtitleTracks || !data.subtitleTracks.length) return; + _hls_subs_cues = {}; + _hls_subs_active_track = -1; + var subs = data.subtitleTracks.map(function (track, i) { + var sub = { + index: i, + label: track.name || track.lang || 'Subtitle ' + (i + 1), + selected: false + }; + Object.defineProperty(sub, 'mode', { + set: function set(v) { + if (v == 'showing') { + _hls_subs_active_track = i; + _hls.subtitleTrack = i; + Cue.render().removeClass('hide'); + } else { + if (_hls_subs_active_track == i) { + _hls_subs_active_track = -1; + _hls.subtitleTrack = -1; + Cue.draw(''); + } + } + }, + get: function get() { + return _hls_subs_active_track == i ? 'showing' : 'disabled'; + } + }); + return sub; + }); + callbacks.subtitles(subs); + }); + + _hls.on(Hls.Events.CUES_PARSED, function (_event, data) { + var idx = _hls.subtitleTrack; + if (idx < 0) return; + if (!_hls_subs_cues[idx]) _hls_subs_cues[idx] = []; + data.cues.forEach(function (cue) { + _hls_subs_cues[idx].push(cue); + }); + }); + } + + function createParser(src, playdata, callbacks) { + var timeout = playdata.hls_manifest_timeout || 10000; + var send_load_ready = false; + console.log('Player', 'hls start parse'); + _hls_parser = new Hls({ + manifestLoadTimeout: timeout, + manifestLoadMaxRetryTimeout: playdata.hls_retry_timeout || 30000, + xhrSetup: function xhrSetup(xhr) { + xhr.timeout = timeout; + + xhr.ontimeout = function () { + console.log('Player', 'hls manifestLoadTimeout'); + }; + } + }); + + _hls_parser.loadSource(src); + + _hls_parser.on(Hls.Events.ERROR, function (_, data) { + console.log('Player', 'hls parse error', data.reason, data.details, data.fatal); + if (!send_load_ready) callbacks.load(src); + }); + + _hls_parser.on(Hls.Events.MANIFEST_LOADED, function () { + if (_hls_parser.audioTracks.length) callbacks.translate('tracks', _hls_parser.audioTracks.map(function (a) { + return { + name: a.name + }; + })); + if (_hls_parser.subtitleTracks.length) callbacks.translate('subs', _hls_parser.subtitleTracks.map(function (a) { + return { + label: a.name + }; + })); + console.log('Player', 'parse hls audio', _hls_parser.audioTracks.length, _hls_parser.audioTracks.map(function (a) { + return a.name; + })); + console.log('Player', 'parse hls subs', _hls_parser.subtitleTracks.length, _hls_parser.subtitleTracks.map(function (a) { + return a.name; + })); + + if (!_hls_parser.audioTracks.length) { + var start_level = levelDefault(_hls_parser); + var select_level = start_level >= 0 ? _hls_parser.levels[start_level] : _hls_parser.levels[_hls_parser.levels.length - 1]; + + var parsed_levels = _hls_parser.levels.map(function (level) { + return { + title: levelName(level), + change_quality: true, + url: level.url[0], + selected: level === select_level + }; + }); + + console.log('Player', 'set hls levels', parsed_levels); + callbacks.levels(parsed_levels, levelName(select_level)); + console.log('Player', 'hls select level url:', select_level.url[0]); + callbacks.load(select_level.url[0]); + } else callbacks.load(src); + + send_load_ready = true; + }); + } + + function setupAudioTracks$1() { + var tracks = audioTracks$1(); + if (!tracks) return null; + tracks.forEach(function (track) { + if (_hls.audioTrack == track.id) track.selected = true; + Object.defineProperty(track, "enabled", { + set: function set(v) { + if (v) _hls.audioTrack = track.id; + }, + get: function get() {} + }); + }); + return tracks; + } + + function audioTracks$1() { + return _hls && _hls.audioTracks && _hls.audioTracks.length ? _hls.audioTracks : null; + } + + function buildLevels$1(savedLevel) { + if (!_hls || !_hls.levels) return null; + var current_level = 'AUTO'; + + _hls.levels.forEach(function (level, i) { + level.title = levelName(level); + + if (_hls.currentLevel == i) { + current_level = level.title; + level.selected = true; + } + + Object.defineProperty(level, "enabled", { + set: function set(v) { + if (v) { + _hls.currentLevel = i; + + _hls.levels.map(function (e) { + return e.selected = false; + }); + + level.selected = true; + } + }, + get: function get() {} + }); + }); + + if (typeof savedLevel !== 'undefined' && _hls.levels[savedLevel]) { + _hls.levels.map(function (e) { + return e.selected = false; + }); + + _hls.levels[savedLevel].enabled = true; + _hls.levels[savedLevel].selected = true; + current_level = _hls.levels[savedLevel].title; + } else { + if (_hls.currentLevel >= 0) current_level = _hls.levels[_hls.currentLevel].title; + } + + return { + levels: _hls.levels, + current: current_level + }; + } + + function currentLevel$1() { + return _hls ? _hls.currentLevel : undefined; + } + + function isActive$1() { + return !!_hls; + } + + function destroyParser() { + if (_hls_parser) { + try { + _hls_parser.destroy(); + } catch (e) {} + + _hls_parser = null; + } + } + + function destroy$e() { + destroyParser(); + _hls_subs_cues = {}; + _hls_subs_active_track = -1; + + if (_hls) { + try { + _hls.destroy(); + } catch (e) {} + + _hls = null; + return true; + } + + return false; + } + + var HlsStream = { + bitrate: bitrate, + update: update$c, + shouldUseProgram: shouldUseProgram, + createProgram: createProgram, + createParser: createParser, + setupAudioTracks: setupAudioTracks$1, + audioTracks: audioTracks$1, + buildLevels: buildLevels$1, + currentLevel: currentLevel$1, + isActive: isActive$1, + destroy: destroy$e, + destroyParser: destroyParser + }; + + var _dash = null; + + function create$a(src, videoEl, callbacks) { + try { + if (Platform.is('orsay') && Storage.field('player') == 'orsay') { + callbacks.load(src); + } else { + _dash = dashjs.MediaPlayer().create(); + _dash.getSettings().streaming.abr.autoSwitchBitrate = false; + + _dash.initialize(videoEl, src, true); + } + } catch (e) { + console.log('Player', 'Dash error:', e.stack); + callbacks.load(src); + } + } + + function setupAudioTracks() { + if (!_dash) return null; + + var tracks = _dash.getTracksFor('audio'); + + if (!tracks || !tracks.length) return null; + tracks.forEach(function (track, i) { + if (i == 0) track.selected = true; + track.language = (track.lang + '').replace(/\d+/g, ''); + Object.defineProperty(track, "enabled", { + set: function set(v) { + if (v) _dash.setCurrentTrack(track); + }, + get: function get() {} + }); + }); + return tracks; + } + + function audioTracks() { + if (!_dash) return null; + + var tracks = _dash.getTracksFor('audio'); + + return tracks && tracks.length ? tracks : null; + } + + function buildLevels(savedLevel) { + if (!_dash) return null; + + var bitrates = _dash.getBitrateInfoListFor("video"); + + var current_level = 'AUTO'; + bitrates.forEach(function (level, i) { + level.title = level.width ? level.width + 'x' + level.height : 'AUTO'; + if (i == 0) current_level = level.title; + Object.defineProperty(level, "enabled", { + set: function set(v) { + if (v) { + _dash.getSettings().streaming.abr.autoSwitchBitrate = false; + + _dash.setQualityFor("video", level.qualityIndex); + } + }, + get: function get() {} + }); + }); + + if (typeof savedLevel !== 'undefined' && bitrates[savedLevel]) { + bitrates.map(function (e) { + return e.selected = false; + }); + _dash.getSettings().streaming.abr.autoSwitchBitrate = false; + bitrates[savedLevel].enabled = true; + bitrates[savedLevel].selected = true; + current_level = bitrates[savedLevel].title; + } + + return { + levels: bitrates, + current: current_level + }; + } + + function currentLevel() { + return _dash ? _dash.getQualityFor('video') : undefined; + } + + function isActive() { + return !!_dash; + } + + function destroy$d() { + if (_dash) { + try { + _dash.destroy(); + } catch (e) {} + + _dash = null; + return true; + } + + return false; + } + + var DashStream = { + create: create$a, + setupAudioTracks: setupAudioTracks, + audioTracks: audioTracks, + buildLevels: buildLevels, + currentLevel: currentLevel, + isActive: isActive, + destroy: destroy$d + }; + + var context; + + function smooth(a, b, s, c) { + return a + (b - a) * (s * 0.02); + } + + function toDb(_float) { + var db = 20 * (Math.log(_float) / Math.log(10)); + db = Math.max(-48, Math.min(db, 0)); + return db; + } + + function Source(video) { + var source = context.createMediaElementSource(video); + var analyser = context.createAnalyser(); + var volume = context.createGain(); + var destroy = false; + var display = true; + var draw_html = $('
    '); + var draw_canvas = draw_html.find('canvas')[0]; + var draw_context = draw_canvas.getContext("2d"); + draw_canvas.width = 5; + draw_canvas.height = Math.round(window.innerHeight * 0.26); + + try { + analyser.fftSize = 2048 * 4; + console.log('Player', 'normalization fftSize 2048 * 4'); + } catch (e) { + try { + analyser.fftSize = 2048 * 2; + console.log('Player', 'normalization fftSize 2048 * 2'); + } catch (e) { + analyser.fftSize = 2048; + console.log('Player', 'normalization fftSize 2048'); + } + } + + var frequencyData = new Uint8Array(analyser.frequencyBinCount); + var midFreqRange = { + start: 1300, + end: 4000 + }; // Средние частоты + + var highFreqRange = { + start: 4000, + end: 8000 + }; // Высокие частоты + + function calculateRMS(range) { + var startIndex = Math.floor(range.start * analyser.frequencyBinCount / (context.sampleRate / 2)); + var endIndex = Math.floor(range.end * analyser.frequencyBinCount / (context.sampleRate / 2)); + startIndex = Math.max(0, Math.min(startIndex, frequencyData.length - 1)); + endIndex = Math.max(0, Math.min(endIndex, frequencyData.length - 1)); + var total = 0; + var count = 0; + + for (var i = startIndex; i <= endIndex; i++) { + var value = frequencyData[i]; + total += value * value; + count++; + } + + return count > 0 ? Math.sqrt(total / count) : 0; + } + + analyser.gain_smooth = 1; //подключаем анализ + + source.connect(analyser); //подключаем регулятор звука + + analyser.connect(volume); //подключаем к выходу + + volume.connect(context.destination); + $('body').append(draw_html); + + function update() { + if (!destroy) requestAnimationFrame(update); + analyser.getByteFrequencyData(frequencyData); + var rms_mid = calculateRMS(midFreqRange); + var rms_high = calculateRMS(highFreqRange); + var db_mid = toDb(rms_mid / 255); + var db_high = toDb(rms_high / 255); + var sm_st = Storage.get('player_normalization_smooth', 'medium'); + var pw_st = Storage.get('player_normalization_power', 'hight'); + var tp_st = Storage.get('player_normalization_type', 'all'); + var pw_am = pw_st == 'hight' ? 1 : pw_st == 'medium' ? 0.7 : 0.35; + var gain = Math.max(0.0, Math.min(2, (db_mid + db_high) / 2 / -24)); + analyser.gain_smooth = sm_st == 'none' ? gain : smooth(analyser.gain_smooth, gain, sm_st == 'hight' ? 45 : sm_st == 'medium' ? 20 : 5); + var vol = pw_st == 'none' ? 1 : 1 + (analyser.gain_smooth - 1) * pw_am; + volume.gain.value = tp_st == 'all' ? vol : tp_st == 'up' ? Math.max(1, vol) : Math.min(1, vol); + + if (display) { + draw_context.clearRect(0, 0, draw_canvas.width, draw_canvas.height); + var down = Math.min(1, Math.max(0, 1 - volume.gain.value)); + var up = Math.min(1, Math.max(0, volume.gain.value - 1)); + var half = draw_canvas.height / 2; + draw_context.fillStyle = 'rgba(251,91,91,1)'; + draw_context.fillRect(0, half, draw_canvas.width, half * down); + draw_context.fillStyle = 'rgba(91,213,251,1)'; + draw_context.fillRect(0, half - half * up, draw_canvas.width, half * up); + } + } + + update(); + + this.visible = function (status) { + display = status; + draw_html.toggleClass('normalization--visible', status); + }; + + this.destroy = function () { + volume.disconnect(); + analyser.disconnect(); + source.disconnect(); + destroy = true; + draw_html.remove(); + }; + } + + function Normalization() { + + if (!context) { + var classContext = window.AudioContext || window.webkitAudioContext; + context = new classContext(); + } + + var source; + + this.attach = function (video) { + if (!source) source = new Source(video); + }; + + this.visible = function (status) { + if (source) source.visible(status); + }; + + this.destroy = function () { + if (source) source.destroy(); + source = null; + }; + } + + function AVPlay(call_video) { + var avplay, plugin, stream_url, loaded, current_time; + var object = $(''); + var video = object[0]; + var listener = Subscribe$2(); + var change_scale_later; + var change_speed_later; + var canGetVideoResolution = false; + /** + * Установить урл + */ + + Object.defineProperty(video, "src", { + set: function set(url) { + if (url) { + if (url.toLowerCase().indexOf(".m3u8") != -1 && url.toUpperCase().indexOf("|COMPONENT=HLS") == -1) { + url += "|COMPONENT=HLS"; + } else if (url.toLowerCase().indexOf(".mpd") != -1 && url.toUpperCase().indexOf("|COMPONENT=HAS") == -1) { + url += "|COMPONENT=HAS"; + } + + stream_url = url; + console.log(stream_url); + avplay.init(); + plugin = avplay.setPlayerPluginObject(); + avplay.onEvent = eventHandler; + } + }, + get: function get() {} + }); + /** + * Позиция + */ + + Object.defineProperty(video, "currentTime", { + set: function set(t) { + try { + seekTo(t); + } catch (e) { + listener.send('error', { + error: 'code [' + e.code + '] ' + e.message + }); + } + }, + get: function get() { + return current_time ? current_time / 1000 : 0; + } + }); + /** + * + */ + + function seekTo(time) { + var time_s; + var time_ms = Math.ceil(time) * 1000; + var duration_ms = avplay.getDuration(); + + if (time_ms >= 0 && current_time - time_ms >= 0) { + time_s = Math.ceil((current_time - time_ms) / 1000); + plugin.Execute("JumpBackward", time_s); + } else if (time_ms >= 0 && duration_ms - current_time + time_ms >= 0) { + time_s = Math.ceil((time_ms - current_time) / 1000); + plugin.Execute("JumpForward", time_s); + } + } + /** + * Длительность + */ + + + Object.defineProperty(video, "duration", { + set: function set() {}, + get: function get() { + var d = 0; + + try { + d = avplay.getDuration(); + } catch (e) {} + + return d ? d / 1000 : 0; + } + }); + /** + * Пауза + */ + + Object.defineProperty(video, "paused", { + set: function set() {}, + get: function get() { + try { + return avplay.status == '5'; + } catch (e) { + return false; + } + } + }); + /** + * Аудиодорожки + */ + + Object.defineProperty(video, "audioTracks", { + set: function set() {}, + get: function get() { + try { + var amount = avplay.getTotalNumOfStreamID(1); + var tracks = Array.apply(null, { + length: amount + }).map(Number.call, Number).map(function (i) { + var item = { + extra: JSON.parse(avplay.getStreamExtraData(1, i)), + index: parseInt(i), + language: languageNumToStr(avplay.getStreamLanguageInfo(1, i)) + }; + Object.defineProperty(item, "enabled", { + set: function set(v) { + if (v) { + try { + avplay.setStreamID(1, item.index); + } catch (e) { + console.log('Player', 'no change audio:', e.message); + } + } + }, + get: function get() {} + }); + return item; + }).sort(function (a, b) { + return a.index - b.index; + }); + return tracks; + } catch (e) { + return []; + } + } + }); + /** + * Субтитры + */ + + Object.defineProperty(video, "textTracks", { + set: function set() {}, + get: function get() { + try { + var amount = avplay.getTotalNumOfStreamID(4); + var tracks = Array.apply(null, { + length: amount + }).map(Number.call, Number).map(function (i) { + var item = { + extra: JSON.parse(avplay.getStreamExtraData(4, i)), + index: parseInt(i), + language: languageNumToStr(avplay.getStreamLanguageInfo(4, i)) + }; + Object.defineProperty(item, "mode", { + set: function set(v) { + if (v == 'showing') { + try { + avplay.setStreamID(4, item.index); + } catch (e) { + console.log('Player', 'no change text:', e.message); + } + } + }, + get: function get() {} + }); + return item; + }).sort(function (a, b) { + return a.index - b.index; + }); + return tracks; + } catch (e) { + return []; + } + } + }); + /** + * Получаем текст языка субтитров или аудио + */ + + function languageNumToStr(num) { + var str; //Словарь кодов озвучек + + var lang = { + 6384738: "Albanian", + 7565673: "Albanian", + 6647399: "English", + 6388325: "Azerbaijan", + 6386285: "Armenian", + 6448492: "Belarusian", + 6452588: "Bulgarian", + 6514793: "Chinese", + 6776178: "German", + 6911073: "Italian", + 7565409: "Spanish", + 7037306: "Kazakh", + 7040882: "Korean", + 7368562: "Portuguese", + 7501171: "Russian", + 7564399: "Slovak", + 7564406: "Slovenian", + 7565936: "Serbian", + 7632242: "Turkish", + 7699042: "Uzbek", + 7695218: "Ukrainian", + 8026747: "Ukrainian", + 6713957: "French", + 7567205: "Swedish", + 6975598: "Japanese" + }; + + if (lang[num] != undefined) { + str = lang[num]; + } else { + var nHex = num.toString(16); + var sHex1 = "0x" + nHex.substring(0, 2); + var sHex2 = "0x" + nHex.substring(2, 2); + var sHex3 = "0x" + nHex.substring(4, 2); + var str1 = String.fromCharCode(sHex1); + var str2 = String.fromCharCode(sHex2); + var str3 = String.fromCharCode(sHex3); + str = str1 + str2 + str3; + + if (str === "\0\0\0") { + str = "Неизвестный"; + } + } + + return str; + } + /** + * Ширина видео + */ + + + Object.defineProperty(video, "videoWidth", { + set: function set() {}, + get: function get() { + if (canGetVideoResolution) { + return avplay.getVideoResolution().split('|')[0]; + } else { + return 0; + } + } + }); + /** + * Высота видео + */ + + Object.defineProperty(video, "videoHeight", { + set: function set() {}, + get: function get() { + if (canGetVideoResolution) { + return avplay.getVideoResolution().split('|')[1]; + } else { + return 0; + } + } + }); + /** + * Меняем размер видео + * @param {string} scale - default|fill + */ + + function changeScale(scale) { + try { + var xV = curWidget.width, + yV = curWidget.height, + aX = 0, + aY = 0, + aW = curWidget.width, + aH = curWidget.height, + cX = 0, + cY = 0, + pH = 100, + pW = 100, + cW = video.videoWidth, + cH = video.videoHeight; + + if (cH == 0 || cW == 0) { + throw false; + } + + switch (scale) { + //original + case 'default': + if (cW / cH < 1.79) { + aW = yV * cW / cH; + aX = (xV - aW) / 2; + } else { + aH = xV * cH / cW; + aY = (yV - aH) / 2; + } + + ; + break; + //full + + case 'fill': + break; + + default: + //zoom + var type = scale[0]; + var zoom = parseInt(scale.replace(/\D+/g, "")); + + if (type == 's') { + pH = zoom; + pW = zoom; + } else if (type == 'v') { + pH = zoom; + pW = 100; + } + + if (zoom >= 80 && zoom <= 140) { + if (pW <= 100) { + aW = xV / 100 * pW; + aX = (xV - aW) / 2; + } else { + cX = cW * (pW / 200 - 0.5); + cW = cW * (2 - pW / 100); + } + + if (pH <= 100) { + aH = yV / 100 * pH; + aY = (yV - aH) / 2; + } else { + cY = cH * (pH / 200 - 0.5); + cH = cH * (2 - pH / 100); + } + } else { + changeScale('default'); + return; + } + + break; + } + + ; + avplay.setDisplayArea({ + left: aX, + top: aY, + width: aW, + height: aH + }); + + if (scale != 'fill') { + avplay.setCropArea(function () { + console.log('Player', 'change scale ' + scale); + }, function (e) { + listener.send('error', { + error: 'code [' + e.code + '] ' + e.message + }); + }, { + left: cX, + top: cY, + width: cW, + height: cH + }); + } else { + avplay.setCropArea(function () { + console.log('Player', 'change scale ' + scale); + }, function (e) { + listener.send('error', { + error: 'code [' + e.code + '] ' + e.message + }); + }, { + left: 0, + top: 0, + width: 0, + height: 0 + }); + } + } catch (e) { + change_scale_later = scale; + } + } + + function changeSpeed(speed) { + try { + avplay.setSpeed(speed); + } catch (e) { + change_speed_later = speed; + } + } + /** + * Всегда говорим да, мы можем играть + */ + + + video.canPlayType = function () { + return true; + }; + /** + * Вешаем кастомные события + */ + + + video.addEventListener = listener.follow.bind(listener); + /** + * Вешаем события от плеера orsay + */ + + var eventHandler = function eventHandler(type, data) { + switch (type) { + // 1 CONNECTION_FAILED; + case 1: + listener.send('error', { + error: '[orsay native player: CONNECTION_FAILED]' + }); + break; + // 2 AUTHENTICATION_FAILED + + case 2: + listener.send('error', { + error: '[orsay native player: AUTHENTICATION_FAILED]' + }); + break; + // 3 STREAM_NOT_FOUND + + case 3: + listener.send('error', { + error: '[orsay native player: STREAM_NOT_FOUND]' + }); + break; + // 4 NETWORK_DISCONNECTED + + case 4: + listener.send('error', { + error: '[orsay native player: NETWORK_DISCONNECTED]' + }); + break; + // 5 NETWORK_SLOW + + case 5: + listener.send('error', { + error: '[orsay native player: NETWORK_SLOW]' + }); + break; + // 6 RENDER_ERROR (a) + + case 6: + switch (data) { + case "0": + listener.send('error', { + error: '[orsay native player: UNKNOWN_ERROR]' + }); + break; + + case "1": + listener.send('error', { + error: '[orsay native player: UNSUPPORTED_CONTAINER]' + }); + break; + + case "2": + listener.send('error', { + error: '[orsay native player: UNSUPPORTED_VIDEO_CODEC]' + }); + break; + + case "3": + listener.send('error', { + error: '[orsay native player: UNSUPPORTED_AUDIO_CODEC]' + }); + break; + + case "4": + listener.send('error', { + error: '[orsay native player: UNSUPPORTED_VIDEO_RESOLUTION]' + }); + break; + + case "5": + listener.send('error', { + error: '[orsay native player: UNSUPPORTED_VIDEO_FRAMERATE]' + }); + break; + + case "6": + listener.send('error', { + error: '[orsay native player: CURRUPTED_STREAM]' + }); + break; + + case "100": + listener.send('error', { + error: '[orsay native player: CUSTOM_ERROR]' + }); + break; + } + + // 7 RENDERING_START + + case 7: + console.log('Player', 'RENDERING_START'); + break; + // 8 RENDERING_COMPLETE + + case 8: + console.log('Player', 'RENDERING_COMPLETE'); + avplay.stop(); + listener.send('ended'); + break; + // 9 STREAM_INFO_READY + + case 9: + canGetVideoResolution = true; + $('body').toggleClass('orsay-player--show', true); + console.log('Player', 'STREAM_INFO_READY'); + avplay.startSubtitle({ + path: "/dtv/temp/", + streamID: 999, + sync: 999, + callback: function callback() {} + }); + listener.send('loadeddata'); + break; + // 10 DECODING_COMPLETE + + case 10: + console.log('Player', 'DECODING_COMPLETE'); + break; + + case 11: + console.log('Player', 'buffering start'); + listener.send('waiting'); + break; + // 12 BUFFERING_COMPLETE + + case 12: + console.log('Player', 'BUFFERING_COMPLETE'); + listener.send('playing'); + break; + // 13 BUFFERING_PROGRESS + + case 13: + listener.send('progress', { + percent: data + }); + break; + // 14 CURRENT_PLAYBACK_TIME + + case 14: + current_time = data; + listener.send('timeupdate'); + + if (change_scale_later) { + changeScale(change_scale_later); + change_scale_later = false; + } + + if (change_speed_later) { + changeSpeed(change_speed_later); + change_speed_later = false; + } + + break; + // 15 AD_START + + case 15: + console.log('Player', 'AD_START'); + break; + // 16 AD_END + + case 16: + console.log('Player', 'AD_END'); + break; + // 17 RESOLUTION_CHANGED + + case 17: + console.log('Player', 'RESOLUTION_CHANGED ' + data); + break; + // 18 BITRATE_CHANGED + + case 18: + console.log('Player', 'BITRATE_CHANGED ' + data); + break; + // 19 SUBTITLE + + case 19: + listener.send('subtitle', { + text: data + }); + break; + } + }; + /** + * Загрузить + */ + + + video.load = function () { + if (stream_url) { + if (avplay.open(stream_url)) { + loaded = true; + listener.send('canplay'); + } + } + }; + /** + * Играть + */ + + + video.play = function () { + if (loaded) { + if (avplay.status == '5') { + avplay.resume(); + } else { + avplay.play(function () { + console.log('Player', 'play'); + }, function (e) { + listener.send('error', { + error: 'code [' + e.code + '] ' + e.message + }); + }); + } + } + }; + /** + * Пауза + */ + + + video.pause = function () { + if (loaded) avplay.pause(); + }; + /** + * Установить масштаб + */ + + + video.size = function (type) { + changeScale(type); + }; + /** + * Установить скорость + */ + + + video.speed = function (speed) { + changeSpeed(speed); + }; + /** + * Уничтожить + */ + + + video.destroy = function () { + try { + console.log('Player', 'destroy'); + avplay.destroy(); + } catch (e) {} + + $('body').toggleClass('orsay-player--show', false); + video.remove(); + listener.destroy(); + }; + + webapis.avplay.getAVPlay(function (av) { + avplay = av; + }, function (e) { + listener.send('error', { + error: 'code [' + e.code + '] ' + e.message + }); + }); + call_video(video); + return object; + } + + function YouTube$1(call_video) { + var stream_url; + var needclick = true; // Platform.screen('mobile') || navigator.userAgent.toLowerCase().indexOf('android') >= 0 + + var object = $("\n
    \n
    \n
    \n
    \n
    \n \n
    ".concat(Lang.translate('player_youtube_no_played'), "
    \n
    \n
    \n ")); + var video = object[0]; + var listener = Subscribe$2(); + var volume = 100; + var timeupdate; + var timetapplay; + var timer_waite; + var frame = null; + var frameWindow = null; + var frameReady = false; + var bridgeId = 'yt_' + Math.random().toString(36).slice(2); + + function getYouTubeId(url) { + if (!url) return ''; + + try { + url = String(url).trim(); + + if (url.includes('youtu.be/')) { + return url.split('youtu.be/')[1].split(/[?&#/]/)[0]; + } + + if (url.includes('youtube.com/embed/')) { + return url.split('youtube.com/embed/')[1].split(/[?&#/]/)[0]; + } + + if (url.includes('v=')) { + return url.split('v=')[1].split('&')[0]; + } + + return url; + } catch (e) { + return ''; + } + } + + function postToFrame(type) { + var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + try { + if (frameWindow) { + frameWindow.postMessage({ + bridgeId: bridgeId, + type: type, + data: data + }, '*'); + } + } catch (e) {} + } + + function videoSize() { + var size = { + width: 0, + height: 0 + }; + var str = video._playbackQuality || ''; + + if (str === 'highres' || str === 'hd2160') { + size.width = 3840; + size.height = 2160; + } else if (str === 'hd1440') { + size.width = 2560; + size.height = 1440; + } else if (str === 'hd1080') { + size.width = 1920; + size.height = 1080; + } else if (str === 'hd720') { + size.width = 1280; + size.height = 720; + } else { + size.width = 854; + size.height = 480; + } + + return size; + } + + function onMessage(event) { + if (!event.data || event.data.bridgeId !== bridgeId) return; + var _event$data = event.data, + type = _event$data.type, + data = _event$data.data; + + if (type === 'bridgeReady') { + frameReady = true; + return; + } + + if (type === 'ready') { + listener.send('canplay'); + listener.send('loadeddata'); + clearInterval(timeupdate); + timeupdate = setInterval(function () { + if (video._playerState !== 2) listener.send('timeupdate'); + }, 100); + if (needclick) listener.send('playing'); + return; + } + + if (type === 'stateChange') { + var state = data ? data.state : -1; + video._playerState = state; + object.removeClass('ended'); + + if (needclick) { + object.find('.player-video__youtube-needclick div').text(Lang.translate('loading') + '...'); + } + + if (state === 1) { + listener.send('playing'); + clearTimeout(timetapplay); + + if (needclick) { + needclick = false; + setTimeout(function () { + object.find('.player-video__youtube-needclick').remove(); + }, 500); + } + } + + if (state === 0) { + object.addClass('ended'); + listener.send('ended'); + } + + if (state === 3) { + listener.send('waiting'); + } + + return; + } + + if (type === 'time') { + video._currentTime = data.currentTime || 0; + video._duration = data.duration || 0; + video._playerState = typeof data.playerState === 'number' ? data.playerState : video._playerState; + video._playbackQuality = data.playbackQuality || ''; + return; + } + + if (type === 'qualityChange') { + video._playbackQuality = data.quality || ''; + console.log('YouTube', 'quality', video._playbackQuality); + return; + } + + if (type === 'error') { + console.log('YouTube', 'error', data ? data.error : ''); + object.find('.player-video__youtube-noplayed').removeClass('hide'); + object.addClass('ended'); + if (needclick) object.find('.player-video__youtube-needclick').remove(); + clearTimeout(timetapplay); + } + } + + function createFrame(videoId) { + if (frame) return; + var url = object$2.github_lampa + 'youtube.html?bridgeId=' + bridgeId + '&videoId=' + videoId + '&autoplay=1&controls=1&mute=0&start=0'; + frame = document.createElement('iframe'); + frame.className = 'player-video__youtube-bridge-frame'; + frame.src = url.toString(); + frame.setAttribute('frameborder', '0'); + frame.setAttribute('allowfullscreen', 'true'); + frame.setAttribute('allow', 'autoplay; encrypted-media; picture-in-picture'); + frame.style.border = '0'; + frame.style.display = 'block'; + + frame.onload = function () { + try { + frameWindow = frame.contentWindow; + } catch (e) {} + }; + + object.find('.player-video__youtube-player').empty().append(frame); + } + + Object.defineProperty(video, 'src', { + set: function set(url) { + if (url) stream_url = url; + }, + get: function get() {} + }); + Object.defineProperty(video, 'currentTime', { + set: function set(t) { + video._currentTime = t; + postToFrame('seekTo', { + time: t + }); + }, + get: function get() { + return video._currentTime || 0; + } + }); + Object.defineProperty(video, 'duration', { + set: function set() {}, + get: function get() { + return video._duration || 0; + } + }); + Object.defineProperty(video, 'paused', { + set: function set() {}, + get: function get() { + if (needclick) return true; + return video._playerState === 2 || video._playerState == null; + } + }); + Object.defineProperty(video, 'audioTracks', { + set: function set() {}, + get: function get() { + return []; + } + }); + Object.defineProperty(video, 'textTracks', { + set: function set() {}, + get: function get() { + return []; + } + }); + Object.defineProperty(video, 'videoWidth', { + set: function set() {}, + get: function get() { + return videoSize().width; + } + }); + Object.defineProperty(video, 'videoHeight', { + set: function set() {}, + get: function get() { + return videoSize().height; + } + }); + Object.defineProperty(video, 'volume', { + set: function set(num) { + volume = num * 100; + postToFrame('setVolume', { + volume: volume + }); + }, + get: function get() {} + }); + + video.canPlayType = function () { + return true; + }; + + video.resize = function () { + postToFrame('resize'); + }; + + video.addEventListener = listener.follow.bind(listener); + + video.load = function () { + if (stream_url && !frame) { + var id = getYouTubeId(stream_url); + + if (!id) { + object.find('.player-video__youtube-noplayed').removeClass('hide').find('div').text(Lang.translate('player_youtube_no_support')); + return; + } + + video._currentTime = 0; + video._duration = 0; + video._playerState = -1; + video._playbackQuality = ''; + video.resize(); + createFrame(id); + + if (needclick) { + object.append("\n
    \n \n
    ").concat(Lang.translate('loading'), "...
    \n
    \n ")); + timetapplay = setTimeout(function () { + object.find('.player-video__youtube-needclick div').text(Lang.translate('player_youtube_start_play')); + PlayerPanel.update('pause'); + }, 10000); + } + + var waitFrame = function waitFrame() { + if (!frameReady) { + timer_waite = setTimeout(waitFrame, 50); + return; + } + + postToFrame('init', { + volume: volume + }); + }; + + waitFrame(); + } + }; + + video.play = function () { + postToFrame('play'); + }; + + video.pause = function () { + postToFrame('pause'); + }; + + video.size = function (type) {}; + + video.speed = function (speed) { + postToFrame('setPlaybackRate', { + rate: speed + }); + }; + + video.destroy = function () { + clearInterval(timeupdate); + clearTimeout(timetapplay); + clearTimeout(timer_waite); + postToFrame('destroy'); + + if (frame) { + try { + frame.remove(); + } catch (e) {} + } + + frame = null; + frameWindow = null; + frameReady = false; + window.removeEventListener('message', onMessage); + object.remove(); + listener.destroy(); + }; + + window.addEventListener('message', onMessage); + call_video(video); + return object; + } + + var bell; + var items$1 = []; + + function Item$1(params) { + var _this = this; + + Arrays.extend(params, { + icon: "\n \n \n ", + type: 'info', + text: '', + from: '', + time: 5000 + }); + var element = $("
    \n
    ").concat(params.icon, "
    \n
    ").concat(params.text, "
    \n
    ")); + if (params.from) element.find('.bell__item-text').prepend("".concat(params.from, "
    ")); + setTimeout(function () { + element.removeClass('show'); + setTimeout(function () { + var slide = $("
    "); + slide.css('height', element.outerHeight() + 'px'); + element.after(slide); + element.remove(); + Arrays.remove(items$1, _this); + slide.animate({ + height: 0 + }, 300, function () { + slide.remove(); + }); + + if (items$1.length == 0) { + bell.removeClass('show'); + } + }, 300); + }, params.time); + bell.find('.bell__wrap').append(element); + setTimeout(function () { + element.addClass('show'); + }, 100); + items$1.push(this); + Sound$1.play('bell'); + } + + function init$14() { + bell = $("
    \n
    \n
    "); + $('body').append(bell); + } + + function push$8(params) { + new Item$1(params); + bell.addClass('show'); + } + + var Bell = { + init: init$14, + push: push$8 + }; + + var listener$c = Subscribe$2(); + var html$h; + var display; + var paused; + var backworkIcon; + var forwardIcon; + var timer$6 = {}; + var params$2 = {}; + var rewind_position = 0; + var rewind_force = 0; + + var _video; + + var retainedPipVideo = false; + var wait; + var need_scale; + var need_scale_last; + var need_speed; + + var _normalization; + var click_nums = 0; + var click_timer; + var pause_timer; + + function init$13() { + html$h = Template.get('player_video'); + display = html$h.find('.player-video__display'); + paused = html$h.find('.player-video__paused'); + backworkIcon = html$h.find('.player-video__backwork-icon'); + forwardIcon = html$h.find('.player-video__forward-icon'); + html$h.find('.player-video__backwork-icon,.player-video__forward-icon').on('animationend', function () { + $(this).removeClass('rewind'); + }); + html$h.on('click', function (e) { + if (DeviceInput.canClick(e.originalEvent)) { + clearTimeout(click_timer); + click_nums++; + if (PlayerIPTV.playning()) click_nums = 1; + + if (click_nums === 1) { + click_timer = setTimeout(function () { + click_nums = 0; + if (PlayerPanel.visibleStatus() && !PlayerIPTV.playning()) playpause();else PlayerPanel.mousemove(); + }, 300); + } else if (click_nums > 1) { + click_timer = setTimeout(function () { + var third = window.innerWidth / 3; + var pow = (click_nums - 1) * 10; + var dir; + + if (e.clientX > third * 2) { + dir = 1; + } else if (e.clientX < third) { + dir = -1; + } + + if (dir == 1) { + forwardIcon.addClass('rewind').find('span').text('+' + pow + ' sec'); + to(_video.currentTime + dir * pow); + } else if (dir == -1) { + backworkIcon.addClass('rewind').find('span').text('-' + pow + ' sec'); + to(_video.currentTime + dir * pow); + } else if (Utils$1.canFullScreen()) { + Utils$1.toggleFullscreen(); + } + + click_nums = 0; + }, 300); + } + } + }); + Lampa.Listener.follow('resize_end', function () { + if (_video) { + need_scale = need_scale_last; + scale(); + if (_video.resize) _video.resize(); + } + }); + Tube.register({ + name: 'YouTube', + verify: function verify(src) { + return src.indexOf('youtube.com') >= 0 || src.indexOf('youtu.be') >= 0; + }, + create: YouTube$1 + }); + Segments$1.listener.follow('skip', function (e) { + if (Storage.get('player_segments_' + e.type, 'auto') == 'auto') { + _video.currentTime = Math.min(_video.duration, e.segment.end); + Bell.push({ + text: Lang.translate('player_segments_skiped'), + icon: Template.string('icon_viewed') + }); + } + }); + PlayerPanel.listener.follow('visible', function (e) { + if (_normalization) _normalization.visible(e.status); + }); + } + /** + * Добовляем события к контейнеру + */ + + + function bind$3() { + // ждем загрузки + _video.addEventListener("waiting", function () { + loader$1(true); + }); // начали играть + + + _video.addEventListener("playing", function () { + loader$1(false); + }); // видео закончилось + + + _video.addEventListener('ended', function () { + listener$c.send('ended', {}); + }); + + if (Platform.is('apple') && Storage.field('player') == 'ios') { + _video.addEventListener('webkitendfullscreen', function (e) { + Controller.back(); + }); + } // что-то пошло не так + + + _video.addEventListener('error', function (e) { + var error = _video.error || {}; + var msg = (error.message || '').toUpperCase(); + + if (msg.indexOf('EMPTY SRC') == -1) { + if (error.code == 3) { + listener$c.send('error', { + error: Lang.translate('player_error_one'), + fatal: true + }); + } else if (error.code == 4) { + listener$c.send('error', { + error: Lang.translate('player_error_two'), + fatal: true + }); + } else if (typeof error.code !== 'undefined') { + listener$c.send('error', { + error: 'code [' + error.code + '] details [' + msg + ']', + fatal: true + }); + } + } + }); // прогресс буферизации + + + _video.addEventListener('progress', function (e) { + if (typeof e.percent !== 'undefined') { + listener$c.send('progress', { + down: e.percent + '%' + }); + } else { + var duration = _video.duration; + var seconds = 0; + + if (duration > 0) { + try { + for (var i = 0; i < _video.buffered.length; i++) { + if (_video.buffered.start && _video.buffered.start(_video.buffered.length - 1 - i) < _video.currentTime) { + var down = Math.max(0, Math.min(100, _video.buffered.end(_video.buffered.length - 1 - i) / duration * 100)) + "%"; + seconds = Math.max(0, _video.buffered.end(_video.buffered.length - 1 - i) - _video.currentTime); + listener$c.send('progress', { + down: down + }); + break; + } + } + } catch (e) {} + + HlsStream.bitrate(seconds); + } + } + }); // можно ли уже проигрывать? + + + _video.addEventListener('canplay', function () { + listener$c.send('canplay', {}); + }); // сколько прошло + + + _video.addEventListener('timeupdate', function () { + if (rewind_position == 0 && !_video.rewind) listener$c.send('timeupdate', { + duration: _video.duration, + current: _video.currentTime + }); + listener$c.send('videosize', { + width: _video.videoWidth, + height: _video.videoHeight + }); + scale(); + HlsStream.update(_video.currentTime); + Segments$1.update(_video.currentTime); + }); //получены первые данные + + + _video.addEventListener('loadeddata', function (e) { + Segments$1.adjust(_video.duration); + listener$c.send('videosize', { + width: _video.videoWidth, + height: _video.videoHeight + }); + listener$c.send('loadeddata', { + duration: _video.duration, + current: _video.currentTime + }); + scale(); + if (need_speed) speed(need_speed); + loaded$2(); + }); + + var pc = Boolean(Platform.desktop() || Platform.is('browser') || Platform.is('apple') && !Utils$1.isPWA()); // для страховки + + _video.volume = pc ? parseFloat(Storage.get('player_volume', '1')) : 1; + _video.muted = false; + } + /** + * Конвертировать object to array, + * в некоторых случаях video возвращает object вместо array + * @param {object[]} arr + * @returns {array} + */ + + + function convertToArray(arr) { + if (!Arrays.isArray(arr)) { + var new_arr = []; + + for (var index = 0; index < arr.length; index++) { + new_arr.push(arr[index]); + } + + arr = new_arr; + } + + return arr; + } + /** + * Масштаб видео + */ + + + function scale() { + if (!need_scale) return; + var vw = _video.videoWidth, + vh = _video.videoHeight, + rt = 1, + sx = 1.00, + sy = 1.00; + if (vw == 0 || vh == 0 || typeof vw == 'undefined') return; + + var increase = function increase(sfx, sfy) { + rt = Math.min(window.innerWidth / vw, window.innerHeight / vh); + sx = sfx; + sy = sfy; + }; + + if (need_scale == 'default') { + rt = Math.min(window.innerWidth / vw, window.innerHeight / vh); + } else if (need_scale == 'fill') { + rt = Math.min(window.innerWidth / vw, window.innerHeight / vh); + sx = window.innerWidth / (vw * rt); + sy = window.innerHeight / (vh * rt); + } else if (need_scale == 's115') { + increase(1.15, 1.15); + } else if (need_scale == 's130') { + increase(1.34, 1.34); + } else if (need_scale == 'v115') { + increase(1.01, 1.15); + } else if (need_scale == 'v130') { + increase(1.01, 1.34); + } else { + rt = Math.min(window.innerWidth / vw, window.innerHeight / vh); + vw = vw * rt; + vh = vh * rt; + rt = Math.max(window.innerWidth / vw, window.innerHeight / vh); + sx = rt; + sy = rt; + } + + sx = sx.toFixed(2); + sy = sy.toFixed(2); // Для некоторых платформ, где видео не масштабируется, а растягивается + + if (Platform.is('orsay') && Storage.field('player') == 'inner' || Storage.field('player_scale_method') == 'calculate') { + var nw = vw * rt, + nh = vh * rt; + var sz = { + width: Math.round(nw * sx) + 'px', + height: Math.round(nh * sy) + 'px', + marginLeft: Math.round(window.innerWidth / 2 - nw * sx / 2) + 'px', + marginTop: Math.round(window.innerHeight / 2 - nh * sy / 2) + 'px' + }; + } else { + var sz = { + width: Math.round(window.innerWidth) + 'px', + height: Math.round(window.innerHeight) + 'px', + transform: sx == 1.00 && sy == 1.00 || need_scale == 'fill' ? 'unset' : 'scaleX(' + sx + ') scaleY(' + sy + ')', + objectFit: need_scale == 'fill' ? 'fill' : 'contain' + }; + } + + $(_video).css(sz); + need_scale = false; + } + /** + * Сохранить текущие состояние дорожек и сабов + * @returns {{sub:integer, track:integer, level:integer}} + */ + + + function saveParams() { + var subs = _video.customSubs || _video.webos_subs || _video.textTracks || []; + var tracks = []; + var hlsTracks = HlsStream.audioTracks(); + var dashTracks = DashStream.audioTracks(); + var webosTracks = WebOSManager.audioTracks(); + if (hlsTracks) tracks = hlsTracks;else if (dashTracks) tracks = dashTracks;else if (_video.audioTracks && _video.audioTracks.length) tracks = _video.audioTracks; + if (webosTracks !== null) tracks = webosTracks; + + if (tracks.length) { + for (var i = 0; i < tracks.length; i++) { + if (tracks[i].enabled == true || tracks[i].selected == true) params$2.track = i; + } + } + + if (subs.length) { + for (var _i = 0; _i < subs.length; _i++) { + if (subs[_i].enabled == true || subs[_i].selected == true) { + params$2.sub = subs[_i].index; + } + } + } + + var hlsLevel = HlsStream.currentLevel(); + var dashLevel = DashStream.currentLevel(); + if (hlsLevel !== undefined) params$2.level = hlsLevel; + if (dashLevel !== undefined) params$2.level = dashLevel; + console.log('Player', 'saved params', params$2); + return params$2; + } + /** + * Очисить состояние + */ + + + function clearParamas() { + params$2 = {}; + } + /** + * Загрузитьновое состояние из прошлого + * @param {{sub:integer, track:integer, level:integer}} saved_params + */ + + + function setParams(saved_params) { + params$2 = saved_params; + } + /** + * Смотрим есть ли дорожки и сабы + */ + + + function loaded$2() { + var tracks = []; + var subs = _video.customSubs || _video.textTracks || []; + console.log('Player', 'video full loaded'); + var hlsTracks = HlsStream.setupAudioTracks(); + var dashTracks = DashStream.setupAudioTracks(); + if (hlsTracks) tracks = hlsTracks;else if (dashTracks) tracks = dashTracks;else if (_video.audioTracks && _video.audioTracks.length) tracks = _video.audioTracks; + console.log('Player', 'tracks', _video.audioTracks); + if (WebOSManager.handleLoaded(params$2, subsview)) tracks = []; + + if (tracks.length) { + tracks = convertToArray(tracks); + + if (typeof params$2.track !== 'undefined' && tracks[params$2.track]) { + tracks.forEach(function (e) { + e.selected = false; + }); + tracks[params$2.track].enabled = true; + tracks[params$2.track].selected = true; + console.log('Player', 'enable track by default'); + } + + listener$c.send('tracks', { + tracks: tracks + }); + } + + if (subs.length) { + subs = convertToArray(subs); + + if (typeof params$2.sub !== 'undefined' && subs[params$2.sub]) { + subs.forEach(function (e) { + e.mode = 'disabled'; + e.selected = false; + }); + subs[params$2.sub].mode = 'showing'; + subs[params$2.sub].selected = true; + subsview(true); + } else if (Storage.field('subtitles_start')) { + var code = Storage.field('subtitles_lang'); + var pick = preferredSubtitle(subs, code == 'auto' ? Storage.get('language', 'ru') : code); + + if (pick) { + pick.mode = 'showing'; + pick.selected = true; + } + + subsview(true); + } + + listener$c.send('subs', { + subs: subs + }); + } + + var hlsLevels = HlsStream.buildLevels(params$2.level); + var dashLevels = DashStream.buildLevels(params$2.level); + if (hlsLevels || dashLevels) listener$c.send('levels', hlsLevels || dashLevels); + } + /** + * Включить или выключить субтитры + * @param {boolean} status + */ + + + function subsview(status) { + html$h.find('.player-video__subtitles').toggleClass('hide', !Boolean(status)); + } + /** + * Создать контейнер для видео + */ + + + function create$9() { + if (retainedPipVideo) { + retainedPipVideo = false; + WebOSManager.setup(); + return; + } + + var videobox; + + if (Platform.is('tizen') && Storage.field('player') == 'tizen') { + videobox = AVPlay$1(function (object) { + _video = object; + }); + } else if (Platform.is('orsay') && Storage.field('player') == 'orsay') { + videobox = AVPlay(function (object) { + _video = object; + }); + } else { + videobox = $(''); + if (Platform.is('apple') && Storage.field('player') !== 'ios') videobox.attr('playsinline', 'true'); + _video = videobox[0]; + if (typeof _video.canPlayType !== 'function') _video.canPlayType = function () {}; + + if (Storage.field('player_normalization')) { + try { + console.log('Player', 'normalization enabled'); + _normalization = new Normalization(); + + _normalization.attach(_video); + } catch (e) { + console.log('Player', 'normalization error:', e.stack); + } + } + } + + display.append(videobox); + WebOSManager.setup(); + bind$3(); + } + /** + * Показать згразку или нет + * @param {boolean} status + */ + + + function loader$1(status) { + wait = status; + html$h.toggleClass('video--load', status); + } + /** + * Устанавливаем ссылку на видео + * @param {string} src - ссылка на видео + * @param {boolean} change_quality - указывает что меняем качество, нужно для hlsjs, чтобы не создавать парсер заново + */ + + + function url$3(src, change_quality) { + loader$1(true); + var verify = Tube.verify(src); + + if (verify) { + var videobox = verify.create(function (object) { + _video = object; + }); + !!videobox && display.append(videobox); + bind$3(); + setTimeout(function () { + load$3(src); + }, 100); + return; + } + + create$9(); + + if (/\.mpd/.test(src) && typeof dashjs !== 'undefined') { + DashStream.create(src, _video, { + load: load$3 + }); + } else if (/\.m3u8/.test(src)) { + if (navigator.userAgent.toLowerCase().indexOf('maple') > -1) src += '|COMPONENT=HLS'; + + if (typeof Hls !== 'undefined') { + var _HlsStream$shouldUseP = HlsStream.shouldUseProgram(_video, Player.playdata()), + use_program = _HlsStream$shouldUseP.use_program, + hls_native = _HlsStream$shouldUseP.hls_native; + + console.log('Player', 'use program hls:', use_program, 'hlsjs support:', Hls.isSupported()); + if (!Platform.is('tizen')) console.log('Player', 'can play native hls:', hls_native ? true : false); + + if (use_program) { + HlsStream.createProgram(src, _video, Player.playdata(), { + play: play$2, + load: load$3, + error: function error(msg, fatal) { + return listener$c.send('error', { + error: msg, + fatal: fatal + }); + }, + subtitles: function subtitles(subs) { + return listener$c.send('subs', { + subs: subs + }); + } + }); + } else if (!change_quality && !PlayerIPTV.playning()) { + HlsStream.createParser(src, Player.playdata(), { + load: load$3, + levels: function levels(_levels, current) { + return listener$c.send('levels', { + levels: _levels, + current: current + }); + }, + translate: function translate(where, _translate) { + return listener$c.send('translate', { + where: where, + translate: _translate + }); + } + }); + } else load$3(src); + } else load$3(src); + } else load$3(src); + } + /** + * Начать загрузку + * @param {string} src + */ + + + function load$3(src) { + HlsStream.destroyParser(); + DashStream.destroy(); + _video.src = src; + console.log('Player', 'video load url:', src); + + _video.load(); + + play$2(); + } + /** + * Играем + */ + + + function play$2() { + try { + var promise = _video.play(); + + var call = function call() { + paused.addClass('hide'); + listener$c.send('play', {}); + console.log('Player', 'start playing'); + }; + + if (promise && typeof promise.then === 'function') { + promise.then(call)["catch"](function (e) { + console.log('Player', 'play promise error:', e.message); + }); + } else { + // Старые браузеры + call(); + } + } catch (e) { + console.log('Player', 'play error:', e.message); + } + } + /** + * Пауза + */ + + + function pause() { + try { + var promise = _video.pause(); + + var call = function call() { + paused.removeClass('hide'); + listener$c.send('pause', {}); + console.log('Player', 'pause'); + clearTimeout(pause_timer); + pause_timer = setTimeout(function () { + paused.addClass('hide'); + }, 4000); + }; + + if (promise && typeof promise.then === 'function') { + promise.then(call)["catch"](function (e) { + console.log('Player', 'pause promise error:', e.message); + }); + } else { + // Старые браузеры + call(); + } + } catch (e) { + console.log('Player', 'pause error:', e.message); + } + } + /** + * Играем или пауза + */ + + + function playpause() { + if (wait || rewind_position) return; + if (_video.paused) play$2();else pause(); + } + /** + * Завершаем перемотку + * @param {boolean} immediately - завершить немедленно + */ + + + function rewindEnd(immediately) { + clearTimeout(timer$6.rewind_call); + timer$6.rewind_call = setTimeout(function () { + _video.currentTime = rewind_position; + rewind_position = 0; + rewind_force = 0; + play$2(); + WebOSManager.rewinded(); + }, immediately ? 0 : 1000); + } + /** + * Подготовка к перемотке + * @param {number} position_time - новое время + * @param {boolean} immediately - завершить немедленно + */ + + + function rewindStart(position_time, immediately) { + if (!_video.duration) return; + rewind_position = Math.max(0, Math.min(position_time, _video.duration)); + pause(); + if (rewind_position == 0) _video.currentTime = 0;else if (rewind_position == _video.duration) _video.currentTime = _video.duration; + timer$6.rewind = Date.now(); + listener$c.send('timeupdate', { + duration: _video.duration, + current: rewind_position + }); + listener$c.send('rewind', {}); + rewindEnd(immediately); + } + /** + * Начать перематывать + * @param {boolean} forward - направление, true - вперед + * @param {number} custom_step - свое значение в секундах + */ + + + function rewind(forward, custom_step) { + if (_video.duration) { + var step = Storage.field('player_rewind'); + + if (rewind_position == 0) { + rewind_force = Math.max(5, custom_step || step); + rewind_position = _video.currentTime; + } + + rewind_force *= 1.03; + + if (forward) { + rewind_position += rewind_force; + } else { + rewind_position -= rewind_force; + } + + var skip = Segments$1.get(_video.currentTime); + + if (forward && skip && !skip.segment.skiped && Storage.get('player_segments_' + skip.type) == 'user') { + rewind_position = Math.min(_video.duration, skip.segment.end); + skip.segment.skiped = true; + } + + rewindStart(rewind_position); + } + } + /** + * Размер видео, масштаб + * @param {string} type + */ + + + function size$1(type) { + need_scale = type; + need_scale_last = type; + scale(); + if (_video.size) _video.size(type); + } + + function speed(value) { + need_speed = value; + var fv = value == 'default' ? 1 : parseFloat(value); + if (_video.speed) _video.speed(fv);else if (WebOSManager.isActive()) WebOSManager.speed(fv);else _video.playbackRate = fv; + } + /** + * Перемотка на позицию + * @param {number} type + */ + + + function to(seconds) { + pause(); + + try { + if (seconds == -1) _video.currentTime = Math.max(0, _video.duration - 3);else _video.currentTime = Math.max(0, Math.min(seconds, _video.duration)); + } catch (e) {} + + play$2(); + } + /** + * Включить режим PIP + */ + + + function enterToPIP() { + if (!document.pictureInPictureElement && document.pictureInPictureEnabled && _video.requestPictureInPicture) { + _video.requestPictureInPicture(); + } + } + /** + * Выключить режим PIP + */ + + + function exitFromPIP() { + if (document.pictureInPictureElement) { + document.exitPictureInPicture(); + } + } + /** + * Переключить режим PIP + */ + + + function pip() { + if (document.pictureInPictureElement) exitFromPIP();else enterToPIP(); + } + /** + * Установить громкость + * @param {number} vol 0-1 + */ + + + function volume(vol) { + vol = Math.max(0, Math.min(vol, 1)); + _video.volume = vol; + Storage.set('player_volume', vol); + } + /** + * Уничтожить + * @param {boolean} savemeta - сохранить с параметрами + * @param {boolean} keepPip - сохранить видеоэлемент при смене серии в PiP + */ + + + function destroy$c(savemeta, keepPip) { + subsview(false); + need_scale = false; + paused.addClass('hide'); + WebOSManager.destroy(); + clearTimeout(click_timer); + var hls_destoyed = HlsStream.destroy(); + var dash_destoyed = DashStream.destroy(); + if (!keepPip) exitFromPIP(); + + if (_video && !keepPip && !(hls_destoyed || dash_destoyed)) { + if (_video.destroy) _video.destroy();else { + _video.removeAttribute('src'); + + _video.load(); + } + } + + if (_normalization && !keepPip) { + _normalization.destroy(); + + _normalization = false; + } + + if (!keepPip) display.empty(); + retainedPipVideo = Boolean(keepPip); + loader$1(false); + listener$c.send('destroy', { + savemeta: savemeta + }); + } + + function render$b() { + return html$h; + } + + var PlayerVideo = { + init: init$13, + listener: listener$c, + url: url$3, + render: render$b, + destroy: destroy$c, + playpause: playpause, + rewind: rewind, + play: play$2, + pause: pause, + size: size$1, + speed: speed, + subsview: subsview, + to: to, + video: function video() { + return _video; + }, + normalization: function normalization() { + return _normalization; + }, + saveParams: saveParams, + clearParamas: clearParamas, + setParams: setParams, + pip: pip, + volume: volume, + registerTube: Tube.register, + removeTube: Tube.remove, + verifyTube: Tube.verify + }; + + var Nature = /*#__PURE__*/function () { + function Nature() { + _classCallCheck(this, Nature); + + this.slide = 'one'; + this.direct = ['lt', 'rt', 'br', 'lb', 'ct']; + } + + _createClass(Nature, [{ + key: "create", + value: function create() { + var _this = this; + + this.html = Template.get('screensaver'); + + this.timer = function () { + _this.next(); + }; + + Timer.add(30000, this.timer); + this.time = Utils$1.time(this.html); + this.next(); + } + }, { + key: "next", + value: function next() { + var _this2 = this; + + var image = 'https://picsum.photos/1600/900?v=' + Math.random(); + var to_img = $('.screensaver__slides-' + (this.slide == 'one' ? 'two' : 'one'), this.html)[0]; + + to_img.onload = function () { + $(to_img).removeClass(_this2.direct.join(' ') + ' animate').addClass(_this2.direct[Math.floor(Math.random() * _this2.direct.length)]); + setTimeout(function () { + $('.screensaver__slides-' + _this2.slide, _this2.html).removeClass('visible'); + _this2.slide = _this2.slide == 'one' ? 'two' : 'one'; + $(to_img).addClass('visible').addClass('animate'); + }, 100); + }; + + to_img.onerror = this.next.bind(this); + to_img.src = image; + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "destroy", + value: function destroy() { + Timer.remove(this.timer); + this.time.destroy(); + this.html.remove(); + } + }]); + + return Nature; + }(); + + var Chrome = /*#__PURE__*/function () { + function Chrome() { + _classCallCheck(this, Chrome); + } + + _createClass(Chrome, [{ + key: "create", + value: function create() { + this.html = $('
    '); + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + } + }]); + + return Chrome; + }(); + + var IndexedDB = /*#__PURE__*/function () { + function IndexedDB(database_name) { + var tables = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var version = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3; + + _classCallCheck(this, IndexedDB); + + this.listener = Subscribe$2(); + this.database_name = 'lampa_' + database_name; + this.tables = tables; + this.version = version; + this.db = null; + this.logs = true; + } + + _createClass(IndexedDB, [{ + key: "log", + value: function log(err, store_name, key) { + if (this.logs) console.log('DB', this.database_name + (store_name ? '_' + store_name : '') + (key ? ' -> [' + key + ']' : ''), err); + } + /** + * Открытие базы данных + * @returns {Promise} + */ + + }, { + key: "openDatabase", + value: function openDatabase() { + var _this = this; + + return new Promise(function (resolve, reject) { + var Base = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB; + if (!Base) return _this.log('Not supported'), reject('Not supported'); + if (!_this.tables.length) return _this.log('No tables'), reject('No tables'); + var request = Base.open(_this.database_name, _this.version); + + request.onerror = function (event) { + _this.log(request.error || 'An error occurred while opening the database'); + + reject(request.error || 'An error occurred while opening the database'); + }; + + request.onsuccess = function (event) { + _this.db = event.target.result; + resolve(); + }; + + request.onupgradeneeded = function (event) { + var db = event.target.result; + + _this.log('OnUpgradeNeeded'); + + _this.tables.forEach(function (name) { + if (!db.objectStoreNames.contains(name)) { + _this.log('Create table - ' + name); + + db.createObjectStore(name, { + keyPath: 'key' + }); + } + }); + }; + }); + } + /** + * Добавление данных в таблицу + * @param {string} store_name - Название таблицы + * @param {string} key - Ключ записи + * @param {any} value - Значение записи + * @returns {Promise} + */ + + }, { + key: "addData", + value: function addData(store_name, key, value) { + var _this2 = this; + + return new Promise(function (resolve, reject) { + if (!_this2.db) { + return _this2.log('Database not open', store_name, key), reject('Database not open'); + } + + var transaction = _this2.db.transaction([store_name], 'readwrite'); + + var objectStore = transaction.objectStore(store_name); + var addRequest = objectStore.add({ + key: key, + value: value, + time: Date.now() + }); + + addRequest.onerror = function (event) { + _this2.log(addRequest.error || 'An error occurred while adding data', store_name, key); + + reject(addRequest.error || 'An error occurred while adding data'); + }; + + addRequest.onsuccess = resolve; + }); + } + /** + * Получение данных из таблицы + * @param {string} store_name - Название таблицы + * @param {string} key - Ключ записи, если не указан, вернет все записи + * @param {number} life_time - Время жизни записи в минутах. -1 - без ограничений + * @param {boolean} return_meta - Возвращать мета данные (ключ, время) вместе со значением + * @returns {Promise} + */ + + }, { + key: "getData", + value: function getData(store_name, key) { + var _this3 = this; + + var life_time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : -1; + var return_meta = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + return new Promise(function (resolve, reject) { + if (!_this3.db) { + return _this3.log('Database not open', store_name, key), reject('Database not open'); + } + + var transaction = _this3.db.transaction([store_name], 'readonly'); + + var objectStore = transaction.objectStore(store_name); + var getRequest = key ? objectStore.get(key) : objectStore.getAll(); + + getRequest.onerror = function (event) { + _this3.log(getRequest.error || 'An error occurred while retrieving data', store_name, key); + + reject(getRequest.error || 'An error occurred while retrieving data'); + }; + + getRequest.onsuccess = function (event) { + var result = event.target.result; + + if (result) { + if (key) { + if (life_time == -1) resolve(return_meta ? result : result.value);else { + if (Date.now() < result.time + life_time * 1000 * 60) resolve(return_meta ? result : result.value);else resolve(null); + } + } else resolve(return_meta ? result : result.map(function (r) { + return r.value; + })); + } else { + resolve(null); + } + }; + }); + } + /** + * Получение данных из таблицы без ошибки + * @param {string} store_name - Название таблицы + * @param {string} key - Ключ записи + * @param {number} life_time - Время жизни записи в минутах. -1 - без ограничений + * @param {boolean} return_meta - Возвращать мета данные (ключ, время) вместе со значением + * @returns {Promise} + */ + + }, { + key: "getDataAnyCase", + value: function getDataAnyCase(store_name, key, life_time) { + var _this4 = this; + + var return_meta = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + return new Promise(function (resolve, reject) { + _this4.getData(store_name, key, life_time, return_meta).then(resolve)["catch"](function () { + resolve(null); + }); + }); + } + /** + * Обновление данных в таблице + * @param {string} store_name - Название таблицы + * @param {string} key - Ключ записи + * @param {any} value - Новое значение записи + * @returns {Promise} + */ + + }, { + key: "updateData", + value: function updateData(store_name, key, value) { + var _this5 = this; + + return new Promise(function (resolve, reject) { + if (!_this5.db) { + return _this5.log('Database not open', store_name, key), reject('Database not open'); + } + + var transaction = _this5.db.transaction([store_name], 'readwrite'); + + var objectStore = transaction.objectStore(store_name); + var getRequest = objectStore.get(key); + + getRequest.onerror = function (event) { + _this5.log(getRequest.error || 'An error occurred while updating data', store_name, key); + + reject(getRequest.error || 'An error occurred while updating data'); + }; + + getRequest.onsuccess = function (event) { + var result = event.target.result; + + if (result) { + result.value = value; + result.time = Date.now(); + var updateRequest = objectStore.put(result); + + updateRequest.onerror = function (event) { + _this5.log(updateRequest.error || 'An error occurred while updating data', store_name, key); + + reject(updateRequest.error || 'An error occurred while updating data'); + }; + + updateRequest.onsuccess = resolve; + } else { + _this5.log('No data found with the given key', store_name, key); + + reject('No data found with the given key'); + } + }; + }); + } + /** + * Перезапись данных в таблице (если нет, то создаст новую запись) + * @param {string} store_name - Название таблицы + * @param {string} key - Ключ записи + * @param {any} value - Новое значение записи + * @returns {Promise} + */ + + }, { + key: "rewriteData", + value: function rewriteData(store_name, key, value) { + var _this6 = this; + + return new Promise(function (resolve, reject) { + if (!_this6.db) { + return _this6.log('Database not open', store_name, key), reject('Database not open'); + } + + var transaction = _this6.db.transaction([store_name], 'readwrite'); + + var objectStore = transaction.objectStore(store_name); + var addRequest = objectStore.put({ + key: key, + value: value, + time: Date.now() + }); + + addRequest.onerror = function (event) { + _this6.log(addRequest.error || 'An error occurred while rewrite data', store_name, key); + + reject(addRequest.error || 'An error occurred while rewrite data'); + }; + + addRequest.onsuccess = resolve; + }); + } + /** + * Удаление данных из таблицы + * @param {string} store_name - Название таблицы + * @param {string} key - Ключ записи + * @returns {Promise} + */ + + }, { + key: "deleteData", + value: function deleteData(store_name, key) { + var _this7 = this; + + return new Promise(function (resolve, reject) { + if (!_this7.db) { + return _this7.log('Database not open', store_name, key), reject('Database not open'); + } + + var transaction = _this7.db.transaction([store_name], 'readwrite'); + + var objectStore = transaction.objectStore(store_name); + var deleteRequest = objectStore["delete"](key); + + deleteRequest.onerror = function (event) { + _this7.log(deleteRequest.error || 'An error occurred while deleting data', store_name, key); + + reject(deleteRequest.error || 'An error occurred while deleting data'); + }; + + deleteRequest.onsuccess = resolve; + }); + } + /** + * Очистка таблицы + * @param {string} store_name - Название таблицы + * @returns {Promise} + */ + + }, { + key: "clearTable", + value: function clearTable(store_name) { + var _this8 = this; + + return new Promise(function (resolve, reject) { + if (!_this8.db) { + return _this8.log('Database not open', store_name), reject('Database not open'); + } + + var transaction = _this8.db.transaction([store_name], 'readwrite'); + + var objectStore = transaction.objectStore(store_name); + var clearRequest = objectStore.clear(); + + clearRequest.onerror = function (event) { + _this8.log(clearRequest.error || 'An error occurred while clearing the table', store_name); + + reject(clearRequest.error || 'An error occurred while clearing the table'); + }; + + clearRequest.onsuccess = function () { + resolve(); + }; + }); + } + /** + * Очистка всех таблиц + * @returns {Promise} + */ + + }, { + key: "clearAll", + value: function clearAll() { + var _this9 = this; + + return new Promise(function (resolve, reject) { + if (!_this9.db) { + return _this9.log('Database not open'), reject('Database not open'); + } + + var objectStoreNames = _this9.db.objectStoreNames; + var tableNames = Array.from(objectStoreNames); + tableNames.forEach(function (n) { + _this9.clearTable(n); + }); + resolve(); + }); + } + }]); + + return IndexedDB; + }(); + + var Cache = new IndexedDB('cache', ['screensavers', 'plugins', 'backgrounds', 'images', 'themes', 'other', 'timetable', 'cards', 'storage'], 7); + + var Cub = /*#__PURE__*/function () { + function Cub(params) { + _classCallCheck(this, Cub); + + this.params = params; + this["default"] = Utils$1.protocol() + object$2.cub_domain + '/img/background/default.mp4'; + } + + _createClass(Cub, [{ + key: "create", + value: function create() { + this.html = Template.get('screensaver'); + var source = this.params && this.params.url ? this.params.url : Storage.get('cub_screensaver', ''); + if (!source) source = this["default"]; + this.url = Utils$1.fixMirrorLink(Utils$1.addUrlComponent(source, 'token=' + encodeURIComponent(Storage.get('account', '{}').token))); + this.preload = $('
    '); + this.html.prepend(this.preload); + this.html.find('.screensaver__slides').remove(); + this.time = Utils$1.time(this.html); + this.time.tik(); + if (Platform.is('webos')) this.video(this.url);else this.cache(this.url); + } + }, { + key: "load", + value: function load(video, er) { + var _this = this; + + video.load(); + var playPromise; + + try { + playPromise = video.play(); + } catch (e) {} + + var startPlay = function startPlay() { + console.log('Screesaver', 'playing'); + + _this.preload.remove(); + }; + + if (playPromise !== undefined) { + playPromise.then(function () { + return startPlay(); + })["catch"](function (e) { + console.log('Screesaver', 'play promise error:', e.message); + }); + } else startPlay(); + } + }, { + key: "video", + value: function video(src) { + var video = $(''); + this.html.prepend(video); + video[0].src = src; + this.load(video[0]); + } + }, { + key: "cache", + value: function cache(url) { + var _this3 = this; + + var getblob = function getblob(result) { + return new Promise(function (resolve, reject) { + console.log('Screesaver', 'db find:', result ? 'true' : 'false'); + if (result) resolve(result);else { + console.log('Screesaver', 'start download video'); + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'blob'; + + xhr.onload = function (e) { + var _this2 = this; + + if (this.status == 200) { + Cache.addData('screensavers', url, this.response).then(function () { + console.log('Screesaver', 'push blob to db'); + resolve(_this2.response); + })["catch"](resolve.bind(this.response)); + } else reject(); + }; + + xhr.onerror = reject; + xhr.send(); + } + }); + }; + + Cache.getData('screensavers', url).then(getblob).then(function (blob) { + console.log('Screesaver', 'set video blob'); + _this3.create_url_blob = URL.createObjectURL(new Blob([blob], { + type: "video/mp4" + })); + + _this3.video(_this3.create_url_blob); + })["catch"](function (e) { + console.log('Screesaver', 'error:', typeof e == 'string' ? e : e.message); + + _this3.video(url); + }); + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + + this.video = function () {}; + + if (this.create_url_blob) URL.revokeObjectURL(this.create_url_blob); + } + }]); + + return Cub; + }(); + + var Aerial = /*#__PURE__*/function () { + function Aerial(params) { + _classCallCheck(this, Aerial); + + this.params = params; + this.net = new Request(); + this.visible = false; + this.items = []; + this.opacity = 0; + this.transition_time = 4000; + this.transition_timeout; + } + + _createClass(Aerial, [{ + key: "create", + value: function create() { + var _this = this; + + this.html = Template.get('screensaver'); + this.preload = $('
    '); + this.video = $('')[0]; + this.overlay = $('
    '); + this.video.addEventListener('timeupdate', function () { + if (_this.video.duration) { + var visible = _this.video.currentTime > 0 && _this.video.currentTime < _this.video.duration - 5; + var points = _this.object.pointsOfInterest; + + if (visible !== _this.visible) { + _this.visible = visible; + + _this.info.toggleClass('visible', visible); + + if (_this.visible) _this.fadeVideoOut(_this.transition_time);else _this.fadeVideoIn(_this.transition_time); + } + + if (_this.video.currentTime == _this.video.duration && !_this.wait_load) { + _this.wait_load = true; + + _this.select(); + + _this.play(); + } + + if (points) { + for (var time in points) { + var text = points[time]; + + if (parseInt(time) <= _this.video.currentTime && _this.tagline.text_ready !== text) { + _this.tagline.text_ready = text; + + _this.tagline.text(text); + } + } + } + } + }); + this.info = $("
    \n
    \n
    \n
    "); + this.title = this.info.find('.screensaver__title-name'); + this.tagline = this.info.find('.screensaver__title-tagline'); + this.html.prepend(this.preload); + this.html.prepend(this.overlay); + this.html.prepend(this.video); + this.html.find('.screensaver__slides').remove(); + this.html.find('.screensaver__gradient').after(this.info); + this.time = Utils$1.time(this.html); + this.time.tik(); + this.cache(function () { + _this.select(); + + _this.play(); + }); + } + }, { + key: "select", + value: function select() { + this.object = this.items[Math.floor(Math.random() * this.items.length)]; + this.title.text(this.object.name.replace(/\s\d$/, '')); + this.tagline.text(Utils$1.capitalizeFirstLetter(this.object.type)); + } + }, { + key: "fadeVideoIn", + value: function fadeVideoIn(time) { + if (time > 0) { + this.transition_timeout = setTimeout(this.fadeVideoIn.bind(this), 16, time - 16); + } + + this.opacity = 1 - time / this.transition_time; + this.overlay[0].style.opacity = this.opacity; + } + }, { + key: "fadeVideoOut", + value: function fadeVideoOut(time) { + if (time > 0) { + this.transition_timeout = setTimeout(this.fadeVideoOut.bind(this), 16, time - 16); + } + + this.opacity = time / this.transition_time; + this.overlay[0].style.opacity = this.opacity; + } + }, { + key: "play", + value: function play() { + var _this2 = this; + + this.video.src = this.object.src.H2641080p.replace('https:', 'http:'); + this.video.load(); + var playPromise; + + try { + playPromise = this.video.play(); + } catch (e) {} + + var startPlay = function startPlay() { + console.log('Screesaver', 'playing'); + + _this2.preload.remove(); + + _this2.wait_load = false; + }; + + if (playPromise !== undefined) { + playPromise.then(function () { + return startPlay(); + })["catch"](function (e) { + console.log('Player', 'play promise error:', e.message); + }); + } else startPlay(); + } + }, { + key: "cache", + value: function cache(call) { + var _this3 = this; + + this.items = Storage.get('screensaver_aerial_items', '[]'); + if (this.items.length) call();else { + this.net.silent('https://raw.githubusercontent.com/OrangeJedi/Aerial/master/videos.json', function (json) { + _this3.items = json.filter(function (a) { + return a.src.H2641080p; + }); + Storage.set('screensaver_aerial_items', _this3.items); + call(); + }); + } + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + this.net.clear(); + clearTimeout(this.transition_timeout); + } + }]); + + return Aerial; + }(); + + /** + * Скринсейвер + * @class + * @returns {Screensaver} + */ + + var Screensaver$1 = /*#__PURE__*/function () { + function Screensaver() { + _classCallCheck(this, Screensaver); + + this.listener = Subscribe$2(); + this.enabled = false; + this.worked = false; + this.screensaver; + this.timer; + this.time_reset = 0; + this.time_start = 0; + this.class_list = { + nature: Nature, + chrome: Chrome, + cub: Cub, + aerial: Aerial + }; + } + + _createClass(Screensaver, [{ + key: "init", + value: function init() { + var _this = this; + + this.html = $('
    '); + this.html.on('click', this.stop.bind(this)); + $('body').append(this.html); + this.resetTimer(); + Keypad.listener.follow('keydown', function (e) { + _this.resetTimer(); + + if (_this.worked) { + _this.stopSlideshow(); + + e.event.preventDefault(); + } + }); + Keypad.listener.follow('keyup', function (e) { + if (_this.worked) e.event.preventDefault(); + }); + $(window).on('mousedown', function (e) { + _this.resetTimer(); + }); + $(window).on('focus', this.resetTimer.bind(this)); + } + }, { + key: "toggle", + value: function toggle(enabled) { + this.enabled = enabled; + this.resetTimer(); + this.listener.send('toggle', { + status: this.enabled + }); + } + }, { + key: "enable", + value: function enable() { + this.toggle(true); + } + }, { + key: "disable", + value: function disable() { + this.toggle(false); + } + }, { + key: "isWorked", + value: function isWorked() { + return this.enabled ? this.worked : this.enabled; + } + }, { + key: "stop", + value: function stop() { + if (this.isWorked()) this.stopSlideshow(); + } + }, { + key: "show", + value: function show(type, params) { + clearTimeout(this.timer); + this.listener.send('start', {}); + var select = Storage.field('screensaver_type'); + if (typeof type == 'string') select = type; + var Class = Chrome; + if (this.class_list[select]) Class = this.class_list[select]; + this.screensaver = new Class(params); + this.screensaver.create(); + this.html.append(this.screensaver.render()); + this.html.fadeIn(300); + this.worked = true; + } + }, { + key: "resetTimer", + value: function resetTimer() { + var _this2 = this; + + clearTimeout(this.timer); + this.time_reset = Date.now(); + if (!Storage.field('screensaver') || !this.enabled || this.worked) return; + var timeout = 1000 * 60 * Storage.field('screensaver_time'); + this.timer = setTimeout(function () { + //для ведра, когда в лампе появляетя фокус срабатывает таймер + if (Date.now() - _this2.time_reset <= timeout + 100) _this2.show();else _this2.resetTimer(); + }, timeout); + } + }, { + key: "stopSlideshow", + value: function stopSlideshow() { + var _this3 = this; + + this.worked = false; + this.html.fadeOut(300, function () { + _this3.html.removeClass('visible'); + + if (_this3.screensaver) { + _this3.screensaver.destroy(); + + _this3.screensaver = false; + } + }); + this.resetTimer(); + this.listener.send('stop', {}); + } + }]); + + return Screensaver; + }(); + + var Screensaver$2 = new Screensaver$1(); + + function languageCode(value) { + return String(value || '').toLowerCase().split(/[-_]/)[0]; + } + + function selectLogo(logos, language) { + if (!Array.isArray(logos) || !logos.length) return false; + var preferred = languageCode(language); + var ordered = [preferred, 'en', null].filter(function (code, index, list) { + return code !== '' && list.indexOf(code) === index; + }); + + var _loop = function _loop(i) { + var code = ordered[i]; + var logo = logos.find(function (item) { + return code === null ? !item.iso_639_1 : languageCode(item.iso_639_1) === code; + }); + if (logo && logo.file_path) return { + v: logo + }; + }; + + for (var i = 0; i < ordered.length; i++) { + var _ret = _loop(i); + + if (_typeof(_ret) === "object") return _ret.v; + } + + return logos.find(function (item) { + return item.file_path; + }) || false; + } + + function imageUrl(path, size) { + if (!path) return ''; + if (/^(https?:)?\/\//i.test(path) || /^(data|blob):/i.test(path)) return path; + return Api.img(path, size); + } + + function mediaData() { + var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var card = data.card || data.movie || data; + var logo = selectLogo(card.images && card.images.logos, Storage.field('tmdb_lang')); + return { + title: data.first_title || card.title || card.name || data.title || '', + background: imageUrl(card.backdrop_path, 'original') || card.background_image || card.background || data.background || data.img || data.thumbnail || '', + logo: logo ? imageUrl(logo.file_path, 'w500') : card.logo || data.logo || '' + }; + } + + function createMark(media, class_name) { + var mark = $('
    '); + + if (media.logo) { + mark.append($('').attr('src', media.logo)); + } else { + mark.append($('
    ').text(media.title)); + } + + return mark; + } + + function create$8() { + var html = $("
    \n \"\"\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n \n \n \n \n \n \n \n \n 0%\n
    \n
    \n
    "); + var media = {}; + var hide_timer; + + function set(data) { + media = mediaData(data); + var backdrop = html.find('.media-loading__backdrop'); + var background = html.find('.media-loading__mark-background'); + var fill = html.find('.media-loading__mark-fill'); + if (media.background) backdrop.attr('src', media.background).removeClass('hide');else backdrop.attr('src', '').addClass('hide'); + background.empty().append(createMark(media, 'media-loading__mark-content--background')); + fill.empty().append(createMark(media, 'media-loading__mark-content--foreground')); + html.toggleClass('media-loading--text', !media.logo); + } + + function update(value, detail) { + var progress = Math.max(0, Math.min(100, parseFloat(value) || 0)); + var stats = _typeof(detail) == 'object' && detail ? detail : { + speed: detail + }; + var speed = stats.speed || ''; + var active = parseInt(stats.active_peers); + var total = parseInt(stats.total_peers); + var show_peers = !isNaN(active); + html.find('.media-loading__mark-fill').css('width', progress + '%'); + html.find('.media-loading__percent').text(Math.round(progress) + '%'); + html.find('.media-loading__speed').text(speed).toggleClass('hide', !speed); + html.find('.media-loading__peers-separator').toggleClass('hide', !show_peers); + html.find('.media-loading__speed-separator').toggleClass('hide', !speed); + html.find('.media-loading__peers').toggleClass('hide', !show_peers); + html.find('.media-loading__peers-value').text(show_peers ? active + ' / ' + (isNaN(total) ? '—' : total) : ''); + } + + function show(data) { + clearTimeout(hide_timer); + if (data) set(data); + html.removeClass('hide media-loading--leaving'); + } + + function hide(immediate) { + clearTimeout(hide_timer); + + if (immediate) { + html.addClass('hide').removeClass('media-loading--leaving'); + } else { + html.addClass('media-loading--leaving'); + hide_timer = setTimeout(function () { + html.addClass('hide').removeClass('media-loading--leaving'); + }, 300); + } + } + + function destroy() { + clearTimeout(hide_timer); + html.remove(); + } + + return { + render: function render() { + return html; + }, + set: set, + update: update, + show: show, + hide: hide, + destroy: destroy + }; + } + + var MediaLoading = { + create: create$8 + }; + + var callback_cancel, controller_enabled, loader, media_loader, timer$5; + /** + * Отображает слой загрузки с возможностью отмены + * @param {function} on_cancel - вызывается при отмене загрузки + * @param {string} text - текст загрузки + * @returns {void} + */ + + function start$9(on_cancel, text) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + callback_cancel = on_cancel; + controller_enabled = Controller.enabled().name; + + if (media_loader) { + media_loader.destroy(); + media_loader = false; + } + + if (options.media) { + media_loader = MediaLoading.create(); + loader = media_loader.render().addClass('media-loading--standalone'); + media_loader.set(options.media); + media_loader.update(options.progress || 0, text); + media_loader.show(); + } else { + loader = $("
    \n
    \n
    ".concat(Lang.translate('loading'), "
    \n
    \n
    \n
    ")); + if (text) loader.find('.loading-layer__text').text(text); + } + + loader.on('click', function (e) { + if (DeviceInput.canClick(e.originalEvent)) cancel(); + }); + clearTimeout(timer$5); + + if (options.media) { + $('body').append(loader); + } else { + timer$5 = setTimeout(function () { + $('body').append(loader); + }, 500); + } + + toggle$7(); + } + /** + * Переключает контроллер на слой загрузки + * @returns {void} + */ + + + function toggle$7() { + Controller.add('loading', { + invisible: true, + toggle: function toggle() { + Controller.clear(); + }, + back: cancel, + up: cancel, + down: cancel, + left: cancel, + right: cancel + }); + Controller.toggle('loading'); + } + /** + * Вызывает колбэк отмены загрузки + * @returns {void} + */ + + + function cancel() { + if (callback_cancel) callback_cancel(); + } + /** + * Удаляет слой загрузки и восстанавливает контроллер + * @returns {void} + */ + + + function stop$1() { + if (media_loader) { + media_loader.destroy(); + media_loader = false; + } else if (loader) loader.remove(); + + loader = false; + clearTimeout(timer$5); + if (controller_enabled) Controller.toggle(controller_enabled); + } + /** + * Обновляет текст загрузки + * @param {string} text - текст загрузки + * @returns {void} + */ + + + function setText(text) { + if (media_loader) media_loader.update(0, text);else if (loader) loader.find('.loading-layer__text').text(text); + } + + function setProgress(progress, detail) { + if (media_loader) media_loader.update(progress, detail);else setText(Math.round(progress) + '%' + (detail ? ' - ' + detail : '')); + } + + var Loading$1 = { + start: start$9, + stop: stop$1, + setText: setText, + setProgress: setProgress + }; + + function init$12() { + Settings.listener.follow('open', function (e) { + if (e.name == 'account') e.body.find('.settings--account-device-add').on('hover:enter', function () { + login(function () { + Controller.toggle('settings_component'); + }); + }); + }); + } + + function add$c(value) { + var code = parseInt(value); + + if (!isNaN(code)) { + var _login = function _login(error) { + network.silent(Api$1.url() + 'device/add', function (result) { + Loading$1.stop(); + Storage.set('account', result, true); + Storage.set('account_email', result.email, true); + window.location.reload(); + }, error, { + code: code + }); + }; + + var network = new Request(); + Loading$1.start(function () { + network.clear(); + Loading$1.stop(); + }); + + _login(function (e) { + if (network.errorCode(e) == 200) { + Loading$1.stop(); + Noty.show(Lang.translate('account_code_error')); + } else { + localStorage.setItem('protocol', window.location.protocol == 'https:' ? 'https' : 'http'); + + _login(function (e) { + Loading$1.stop(); + Noty.show(Lang.translate(network.errorCode(e) == 200 ? 'account_code_error' : 'network_noconnect')); + }); + } + }); + } else { + Noty.show(Lang.translate('account_code_wrong')); + } + } + + function login(callback) { + var html = Template.get('account_add_device_new'); + var nums = html.find('.account-modal-split__code-num'); + var keyboard; + + if (Platform.tv()) { + var code = html.find('.account-modal-split__qr-code'); + var img = html.find('.account-modal-split__qr-img'); + html.addClass('layer--' + (Platform.mouse() ? 'wheight' : 'height')); + Utils$1.qrcode('https://' + object$2.cub_site + '/add', code, function () { + code.remove(); + img.removeClass('hide'); + Utils$1.imgLoad(img, Utils$1.protocol() + object$2.qr_device_add, function () { + img.addClass('loaded'); + }); + }); + } else html.addClass('account-modal-split--mobile'); + + function drawCode(value) { + nums.find('span').text('-'); + value.split('').forEach(function (v, i) { + if (nums[i]) nums[i].find('span').text(v); + }); + } + + drawCode(''); + Modal.open({ + title: '', + html: html, + size: Platform.tv() ? 'full' : 'medium', + scroll: { + nopadding: true + }, + onBack: function onBack() { + keyboard.destroy(); + Modal.close(); + callback && callback(); + } + }); + keyboard = new window.SimpleKeyboard["default"]({ + display: { + '{BKSP}': ' ', + '{ENTER}': ' ' + }, + layout: { + 'default': ['0 1 2 3 4 {BKSP}', '5 6 7 8 9 {ENTER}'] + }, + onChange: function onChange(value) { + drawCode(value); + if (value.length == 6) add$c(value); + }, + onKeyPress: function onKeyPress(button) { + if (button === '{BKSP}') { + keyboard.setInput(keyboard.getInput().slice(0, -1)); + drawCode(keyboard.getInput()); + } else if (button === '{ENTER}') { + if (keyboard.getInput().length == 6) add$c(keyboard.getInput()); + } + } + }); + var keys = $('.simple-keyboard .hg-button').addClass('selector'); + Controller.collectionSet($('.simple-keyboard')); + Controller.collectionFocus(keys[0], $('.simple-keyboard')); + $('.simple-keyboard .hg-button').on('hover:enter', function (e) { + Controller.collectionFocus($(this)[0]); + keyboard.handleButtonClicked($(this).attr('data-skbtn'), e); + }); + } + + var Device = { + init: Utils$1.onceInit(init$12), + login: login + }; + + function show$8(template_name) { + var enabled = Controller.enabled().name; + Modal.open({ + title: '', + html: Template.get(template_name), + onBack: function onBack() { + Modal.close(); + Controller.toggle(enabled); + } + }); + } + + function account() { + var enabled = Controller.enabled().name; + var html = Template.js('account_none'); + + if (Platform.tv()) { + var code = html.find('.account-modal-split__qr-code'); + var img = html.find('.account-modal-split__qr-img'); + html.addClass('layer--' + (Platform.mouse() ? 'wheight' : 'height')); + Utils$1.qrcode('https://' + object$2.cub_site + '/#signup', code, function () { + code.remove(); + img.removeClass('hide'); + Utils$1.imgLoad(img, Utils$1.protocol() + object$2.qr_site, function () { + img.addClass('loaded'); + }); + }); + } else html.addClass('account-modal-split--mobile'); + + Modal.open({ + title: '', + html: $(html), + size: Platform.tv() ? 'full' : 'medium', + scroll: { + nopadding: true + }, + onSelect: function onSelect() { + Modal.close(); + Device.login(function () { + Controller.toggle(enabled); + }); + }, + onBack: function onBack() { + Modal.close(); + Controller.toggle(enabled); + } + }); + } + + function limited() { + show$8('account_limited'); + } + + function premium() { + var enabled = Controller.enabled().name; + var html = Template.js('account_premium'); + + if (Platform.tv()) { + html.addClass('layer--' + (Platform.mouse() ? 'wheight' : 'height')); + Utils$1.qrcode('https://' + object$2.cub_site + '/premium', html.find('.account-modal-split__qr-code'), function () { + html.find('.account-modal-split__qr').remove(); + }); + } else html.addClass('account-modal-split--mobile'); + + if (!permit.token) { + var button = Template.elem('div', { + "class": 'simple-button simple-button--inline selector', + text: Lang.translate('settings_cub_signin_button') + }); + button.on('hover:enter', function () { + Modal.close(); + Controller.toggle(enabled); + account(); + }); + html.find('.account-modal-split__info').append(button); + } + + Modal.open({ + title: '', + html: $(html), + size: Platform.tv() ? 'full' : 'medium', + scroll: { + nopadding: true + }, + onBack: function onBack() { + Modal.close(); + Controller.toggle(enabled); + } + }); + } + + var Modal$1 = { + account: account, + limited: limited, + premium: premium + }; + + var network$9 = new Request(); + + function url$2() { + return Utils$1.protocol() + object$2.cub_domain + '/api/'; + } + + function load$2(path) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var post = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + return new Promise(function (resolve, reject) { + if (permit.token) { + var account = permit.account; + Arrays.extend(params, { + headers: { + token: account.token, + profile: account.profile.id + }, + timeout: 8000 + }); + var u = params.url ? params.url : url$2() + path; + network$9.silent(u, resolve, reject, post, params); + } else { + reject({ + decode_code: 403 + }); + } + }); + } + + function persons(secuses, error) { + if (permit.access && !window.lampa_settings.disable_features.persons) { + load$2('person/list').then(function (data) { + Storage.set('person_subscribes_id', data.results.map(function (a) { + return a.person_id; + })); + if (secuses) secuses(data.results); + })["catch"](error ? error : function () {}); + } else if (error) error({ + decode_code: 403 + }); + } + + function user(secuses, error) { + if (permit.access) { + load$2('users/get?device_name=' + decodeURIComponent(Storage.get('device_name'))).then(function (data) { + Storage.set('account_user', JSON.stringify(data.user)); + if (secuses) secuses(data.user); + })["catch"](error ? error : function () {}); + } else if (error) error({ + decode_code: 403 + }); + } + + function plugins(call) { + if (permit.access) { + load$2('plugins/all', { + timeout: 3000 + }).then(function (result) { + if (result.secuses) { + Storage.set('account_plugins', result.plugins); + call(result.plugins); + } else { + call(Storage.get('account_plugins', '[]')); + } + })["catch"](function () { + call(Storage.get('account_plugins', '[]')); + }); + } else call([]); + } + + function pluginToggle(plugin, status) { + if (permit.access) { + load$2((plugin.author ? 'extensions' : 'plugins') + '/status', {}, { + id: plugin.id, + status: status + })["catch"](function () {}); + } + } + + function notices(call) { + if (permit.access) { + load$2('notice/all', { + cache: 1000 * 60 * 10 + }).then(function (result) { + if (result.secuses) { + Storage.set('account_notice', result.notice.map(function (n) { + return n; + })); + call(result.notice); + } else call([]); + })["catch"](function () { + call([]); + }); + } else call([]); + } + + function subscribes() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var secuses = arguments.length > 1 ? arguments[1] : undefined; + var error = arguments.length > 2 ? arguments[2] : undefined; + + if (permit.access) { + load$2('notifications/all').then(function (result) { + if (params.to_card_subscribe) { + var cards = []; + result.notifications.forEach(function (n) { + var card = Arrays.decodeJson(n.card, {}); + card.subscribe = n; + delete card.subscribe.card; + cards.push(card); + }); + secuses({ + results: cards + }); + } else { + secuses({ + results: result.notifications.map(function (r) { + return Arrays.decodeJson(r.card, {}); + }) + }); + } + })["catch"](error ? error : function () {}); + } else if (error) error({ + decode_code: 403 + }); + } + + function subscribeToTranslation() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var call = arguments.length > 1 ? arguments[1] : undefined; + var error = arguments.length > 2 ? arguments[2] : undefined; + + if (permit.access && params.voice) { + load$2('notifications/add', {}, { + voice: params.voice, + data: JSON.stringify(Utils$1.clearCard(params.card)), + episode: params.episode, + season: params.season + }).then(function (result) { + if (result.limited) Modal$1.limited();else if (call) call(); + })["catch"](error ? error : function () {}); + } else if (error) error({ + decode_code: 403 + }); + } + + var Api$1 = { + url: url$2, + load: load$2, + user: user, + persons: persons, + plugins: plugins, + pluginToggle: pluginToggle, + subscribes: subscribes, + notices: notices, + subscribeToTranslation: subscribeToTranslation, + clear: network$9.clear + }; + + /** + * Трекер синхронизации + * @class + * @param {string} name - имя трекера + * @returns {Tracker} + */ + + var Tracker = /*#__PURE__*/function () { + function Tracker(name) { + _classCallCheck(this, Tracker); + + this.name = name; + } + /** + * Получить трекеры синхронизации + * @return {object} - {time, version} + */ + + + _createClass(Tracker, [{ + key: "get", + value: function get() { + return Storage.get(this.name + '_' + this.profile(), JSON.stringify({ + time: 0, + version: 0 + })); + } + /** + * Сохранить трекеры синхронизации + * @param {object} data - {time, version} + * @return {void} + */ + + }, { + key: "set", + value: function set(data) { + Storage.set(this.name + '_' + this.profile(), data); + } + /** + * Обновить трекеры синхронизации + * @param {object} data - {time, version} + * @return {void} + */ + + }, { + key: "update", + value: function update(data) { + var traker = this.get(); + traker.time = data.time; + traker.version = data.version; + this.set(traker); + } + /** + * Получить ID профиля + * @returns {number} + */ + + }, { + key: "profile", + value: function profile() { + return permit.token ? permit.account.profile.id : 0; + } + /** + * Получить версию последней синхронизации + * @returns {number} + */ + + }, { + key: "version", + value: function version() { + return this.get().version || 0; + } + /** + * Получить время последней синхронизации + * @returns {number} + */ + + }, { + key: "time", + value: function time() { + return this.get().time || 0; + } + }]); + + return Tracker; + }(); + + var tracker = new Tracker('account_timeline_sync'); + + function init$11() { + Storage.listener.follow('change', function (e) { + if (e.name == 'account_use' || e.name == 'account') refrash(); + }); + Socket.listener.follow('open', function () { + if (Date.now() - window.app_time_end > 1000 * 60 * 5) update$b(); + }); + Socket.listener.follow('send', function (e) { + if (e.method == 'timeline') send$1(e.data); + }); + Storage.listener.follow('clear', function () { + refrash(); + }); + } + /** + * Отправить прогресс просмотра на сервер + * @param {object} data - данные для отправки + * @param {object} data.params - параметры прогресса + * @returns {void} + */ + + + function send$1(data) { + if (!permit.sync) return; // Отправляем только данные. Сюда часто приходит объект из Timeline.view() вместе с функцией + // handler, а jQuery.param при сборке запроса вызывает найденные функции: handler() без + // аргументов перезаписывает прогресс с percent: undefined, и отметка тут же слетает. + + var params = JSON.parse(JSON.stringify(data.params)); + Api$1.load('timeline/update', {}, params).then(function (result) {})["catch"](function (e) { + console.log('Account', 'timeline send error', e); + }); + } + /** + * Обновить трекер и таймлайн, если сменился профиль или вошли в аккаунт + * @returns {void} + */ + + + function refrash() { + tracker.update({ + version: 0, + time: 0 + }); + update$b(); + } + /** + * Обновить таймлайн + * @returns {void} + */ + + + function update$b() { + if (permit.sync) { + // Если с момента последнего обновления прошло больше 10 дней, то загружаем дамп + if (tracker.time() < Date.now() - 1000 * 60 * 60 * 24 * 10) { + console.log('Account', 'timeline start full update', tracker.version()); + Api$1.load('timeline/dump', { + dataType: 'text' + }).then(function (result) { + // Парсим текст в массив + AppWorker.json({ + type: 'parse', + data: result + }, function (e) { + var data = e.data; + var name = 'file_view_' + permit.account.profile.id; + + if (!data.timelines) { + return console.error('Account', 'timeline wrong dump format, no timelines:', result); + } + + console.log('Account', 'timeline dump loaded, items:', Object.keys(data.timelines).length, 'profile id:', permit.account.profile.id); // Если нет файла в localStorage, то создаем его из кеша + + if (window.localStorage.getItem(name) === null) { + Storage.set(name, JSON.stringify(Storage.cache('file_view', 10000, {}))); + } + + var viewed = Storage.cache(name, 10000, {}); + + for (var i in data.timelines) { + var time = data.timelines[i]; + viewed[i] = time; + Arrays.extend(viewed[i], { + duration: 0, + time: 0, + percent: 0, + updated: 0 + }); + delete viewed[i].hash; + } + + Storage.set(name, viewed, false, function () { + // Наверно закончилось место в localStorage, тогда сбрасываем версию на следующее обновление + tracker.update({ + version: 0, + time: 0 + }); + console.warn('Account', 'timeline dump error, not saved to storage, try again next update'); + }); + tracker.update({ + version: data.version, + time: Date.now() + }); + Timeline$1.read(); // Нужно прочитать прогресс просмотра из localStorage + + console.log('Account', 'timeline dump update complete to version', data.version); + }); + })["catch"](function () { + console.error('Account', 'timeline dump error, not loaded'); + }); + } // Иначе получаем только изменения с последней версии + else { + console.log('Account', 'timeline start update since', tracker.version()); + Api$1.load('timeline/changelog?since=' + tracker.version()).then(function (result) { + console.log('Account', 'timeline changelog loaded, items:', Object.keys(result.timelines || {}).length, 'profile id:', permit.account.profile.id); + + for (var i in result.timelines) { + var time = result.timelines[i]; + time.received = true; // Чтоб снова не отправлять и не зациклить + + Timeline$1.update(time); + } + + tracker.update({ + version: result.version || tracker.version(), + time: Date.now() + }); + console.log('Account', 'timeline update since complete to version', tracker.version()); + })["catch"](function (e) { + console.warn('Account', 'timeline update changelog error, no response', e); + }); + } + } // Если вышли из аккаунта, то повторно прочитываем прогресс просмотра из localStorage + else Timeline$1.read(); + } + + var Timeline$2 = { + init: Utils$1.onceInit(init$11), + update: update$b + }; + + var rows = []; + var component$o = 'content_rows'; + + function init$10() { + SettingsApi.addComponent({ + component: component$o, + after: 'interface', + icon: "\n \n \n \n ", + name: Lang.translate('title_channels') + }); + Lampa.Settings.listener.follow('open', function (e) { + if (e.name == 'main') settings(); + }); + } + + function settings() { + SettingsApi.removeParams(component$o); + rows.filter(function (r) { + return r.name; + }).forEach(function (row) { + var name = component$o + '_' + (row.name || 'unknown'); + SettingsApi.addParam({ + component: component$o, + param: { + name: name, + type: 'trigger', + "default": true + }, + field: { + name: row.title || Lang.translate('extensions_no_name') + } + }); + }); + } + + function add$b(row) { + if (_typeof(row) == 'object' && typeof row.call == 'function') { + if (rows.indexOf(row) == -1) { + rows.push(row); + + if (!row.name || !row.title) { + console.warn('Content row must have name and title', row); + } + } + } else { + console.warn('Content row must be an object with a call function', row); + } + } + + function remove$3(row) { + var index = rows.indexOf(row); + + if (index > -1) { + rows.splice(index, 1); + } + } + + function call$1(screen, params, calls) { + var stop = ['genres', 'keywords']; + if (stop.find(function (a) { + return params[a]; + })) return; + rows.filter(function (row) { + return row.screen ? Arrays.isArray(row.screen) ? row.screen.indexOf(screen) >= 0 : row.screen == screen : false; + }).filter(function (row) { + return Storage.get(component$o + '_' + (row.name || 'unknown'), 'true'); + }).forEach(function (row) { + var result = row.call(params, screen); + + if (Arrays.isArray(result)) { + result.forEach(function (callback, i) { + if (typeof callback == 'function') { + Arrays.insert(calls, (row.index || 0) + i, callback); + } else if (Arrays.isObject(callback)) { + Arrays.insert(calls, (row.index || 0) + i, callback); + } + }); + } else if (Arrays.isObject(result)) { + Arrays.insert(calls, row.index || 0, result); + } else if (typeof result == 'function') { + Arrays.insert(calls, row.index || 0, result); + } + }); + } + + var ContentRows = { + init: init$10, + add: add$b, + remove: remove$3, + call: call$1 + }; + + var broken_images = 0; + + function proxy(name) { + var proxy = Storage.field(name); + + if (proxy.length > 0 && proxy.charAt(proxy.length - 1) == '/') { + proxy = proxy.substring(0, proxy.length - 1); + } + + return Utils$1.checkHttp(proxy); + } + /** + * Проксировать API запрос + * @param {string} url URL запроса + * @return {string} Проксированный URL запроса + */ + + + function api$2(url) { + var base = Utils$1.protocol() + 'api.themoviedb.org/3/' + url; + return Storage.field('proxy_tmdb') && Storage.field('tmdb_proxy_api') ? proxy('tmdb_proxy_api') + '/' + base : base; + } + /** + * Проксировать изображение + * @param {string} url URL изображения + * @return {string} Проксированный URL изображения + */ + + + function image(url) { + var base = Utils$1.protocol() + 'image.tmdb.org/' + url; + return Storage.field('proxy_tmdb') && Storage.field('tmdb_proxy_image') ? proxy('tmdb_proxy_image') + '/' + base : base; + } + /** + * Сообщить о сломанных изображениях + */ + + + function broken() { + broken_images++; + + if (broken_images > 50) { + broken_images = 0; + if (Storage.field('tmdb_proxy_image') && Storage.field('proxy_tmdb_auto')) Storage.set('proxy_tmdb', true); + } + } + /** + * Получить ключ TMDB + * @return {string} Ключ TMDB + */ + + + function key() { + return '4ef0d7355d9ffb5151e987764708ce96'; + } + + var TMDB$1 = { + api: api$2, + key: key, + image: image, + broken: broken + }; + + var NoticeClass = /*#__PURE__*/function () { + function NoticeClass() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, NoticeClass); + + this.params = params; + this.name = 'Noname'; + } + + _createClass(NoticeClass, [{ + key: "active", + value: function active() { + return true; + } + }, { + key: "push", + value: function push(element, resolve, reject) { + resolve(); + } + }, { + key: "empty", + value: function empty(title, descr) { + var item = Template.get('notice_card', { + title: title || '', + descr: descr || Lang.translate('notice_none_system'), + time: '' + }); + item.addClass('image--icon image--loaded'); + item.find('.notice__img').html(Template.string('icon_bell_plus')); + return item; + } + }, { + key: "viewed", + value: function viewed() {} + }, { + key: "items", + value: function items() { + return []; + } + }, { + key: "count", + value: function count() { + return 0; + } + }]); + + return NoticeClass; + }(); + + var NoticeAll = /*#__PURE__*/function (_NoticeClass) { + _inherits(NoticeAll, _NoticeClass); + + var _super = _createSuper(NoticeAll); + + function NoticeAll() { + var _this; + + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, NoticeAll); + + _this = _super.call(this, params); + _this.name = Lang.translate('settings_param_jackett_interview_all'); + return _this; + } + + _createClass(NoticeAll, [{ + key: "active", + value: function active() { + return false; + } + }, { + key: "count", + value: function count() { + return Notice$1.count(); + } + }, { + key: "viewed", + value: function viewed() { + for (var name in Notice$1.classes) { + if (Notice$1.classes[name] !== this) { + Notice$1.classes[name].viewed(); + } + } + } + }, { + key: "items", + value: function items() { + var _this2 = this; + + var items = []; + + var _loop = function _loop(name) { + if (Notice$1.classes[name] !== _this2) { + items = items.concat(Notice$1.classes[name].items().map(function (item) { + var new_item = Arrays.clone(item); + new_item.display = name; + return new_item; + })); + } + }; + + for (var name in Notice$1.classes) { + _loop(name); + } + + items.sort(function (a, b) { + return a.time > b.time ? -1 : a.time < b.time ? 1 : 0; + }); + return items; + } + }]); + + return NoticeAll; + }(NoticeClass); + + var NoticeLampa = /*#__PURE__*/function (_NoticeClass) { + _inherits(NoticeLampa, _NoticeClass); + + var _super = _createSuper(NoticeLampa); + + function NoticeLampa() { + var _this; + + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, NoticeLampa); + + _this = _super.call(this, params); + _this.name = params.name || 'Lampa'; + _this.time = 0; + _this.view = 0; + _this.db_name = params.db_name || 'notice'; + _this.notices = []; + + _this.connect(); + + return _this; + } + + _createClass(NoticeLampa, [{ + key: "connect", + value: function connect() { + this.db = new IndexedDB(this.db_name, ['all', 'readed'], 2); + this.db.openDatabase().then(this.update.bind(this))["catch"](function () { + return console.log('Notice', 'error', 'no open database'); + }); + } + }, { + key: "update", + value: function update() { + var _this2 = this; + + this.db.getData('readed', 'time').then(function (time) { + _this2.time = time || 0; + return _this2.db.getData('all'); + }).then(function (result) { + result.sort(function (a, b) { + return a.time > b.time ? -1 : a.time < b.time ? 1 : 0; + }); + _this2.notices = result; + _this2.view = result.filter(function (n) { + return n.time > _this2.time; + }).length; + Notice$1.drawCount(); + })["catch"](function (e) {}); + } + }, { + key: "count", + value: function count() { + return this.view; + } + }, { + key: "push", + value: function push(element, resolve, reject) { + if (!(element.id && element.from)) { + if (reject) reject('No (id) or (from)'); + return; + } + + if (!this.notices.find(function (n) { + return n.id == element.id; + })) { + this.db.addData('all', element.id, element).then(this.update.bind(this)).then(function (e) { + if (resolve) resolve(e); + })["catch"](function (e) { + if (reject) reject(e); + }); + } else if (reject) reject('Already added'); + } + }, { + key: "viewed", + value: function viewed() { + this.db.rewriteData('readed', 'time', Date.now()); + this.view = 0; + this.time = Date.now(); + Notice$1.drawCount(); + } + }, { + key: "items", + value: function items() { + return this.notices; + } + }]); + + return NoticeLampa; + }(NoticeClass); + + function enrichTmdbNotice(element, oncomplite) { + var card = element.card || {}; + if (!card.imdb_id) return oncomplite(element); + var method = 'find/' + card.imdb_id + '?external_source=imdb_id'; + Api.sources.tmdb.get(method, {}, function (data) { + var movie = data.movie_results && data.movie_results[0]; + var tv = data.tv_results && data.tv_results[0]; + var tmdb = card.seasons ? tv || movie : movie || tv; + + if (tmdb) { + tmdb.source = 'tmdb'; + tmdb.imdb_id = card.imdb_id; + tmdb.imdb_rating = card.imdb_rating; + tmdb.kp_rating = card.kp_rating; + tmdb.release_quality = card.release_quality; + tmdb.countries = card.countries; + tmdb.seasons = card.seasons; + tmdb.episode = card.episode; + element.card = tmdb; + element.title = tmdb.title || tmdb.name || element.title; + element.poster = tmdb.poster_path || element.poster; + } + + oncomplite(element); + }, function () { + oncomplite(element); + }, { + life: 60 * 24 * 7 + }); + } + + function enrichTmdbNotices(items, oncomplite) { + var result = []; + var index = 0; + var active = 0; + var limit = 4; + + function next() { + if (index >= items.length && active == 0) return oncomplite(result); + + var _loop = function _loop() { + var position = index; + var element = items[index]; + index++; + active++; + enrichTmdbNotice(element, function (updated) { + result[position] = updated; + active--; + next(); + }); + }; + + while (active < limit && index < items.length) { + _loop(); + } + } + + next(); + } + + var NoticeCub = /*#__PURE__*/function (_NoticeClass) { + _inherits(NoticeCub, _NoticeClass); + + var _super = _createSuper(NoticeCub); + + function NoticeCub() { + var _this; + + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, NoticeCub); + + _this = _super.call(this, params); + _this.name = 'CUB'; + _this.time = Storage.get('cub_notice_time', '0'); + _this.notices = []; + Cache.getData('other', 'cub_notice').then(function (data) { + if (data && permit.sync) _this.notices = data; + })["catch"](function (e) {}); + Storage.listener.follow('change', function (e) { + if (e.name == 'account' || e.name == 'account_use') { + if (!permit.sync) _this.notices = [];else _this.update(); + } + }); + Timer.add(1000 * 60 * 5, _this.update.bind(_assertThisInitialized(_this))); + + _this.update(); + + return _this; + } + + _createClass(NoticeCub, [{ + key: "update", + value: function update() { + var _this2 = this; + + Account$1.Api.notices(function (result) { + var notices = result.map(function (item) { + var data = JSON.parse(item.data); + var text = Lang.translate('notice_new_quality'); + var labels = []; + + if (data.card.seasons) { + var k = []; + + for (var i in data.card.seasons) { + k.push(i); + } + + var s = k.pop(); + labels.push('S - ' + s + ''); + labels.push('E - ' + data.card.seasons[s] + ''); + if (data.voice) labels.push(data.voice); + text = Lang.translate('notice_new_episode'); + } else { + labels.push(Lang.translate('notice_quality') + ' - ' + data.card.quality + ''); + } + + return { + time: item.time || Utils$1.parseToDate(item.date).getTime(), + title: !Lang.selected(['ru', 'uk', 'be']) ? data.card.original_title || data.card.original_name : data.card.title || data.card.name, + text: text, + poster: data.card.poster ? data.card.poster : data.card.img ? data.card.img : data.card.poster_path, + card: data.card, + labels: labels, + data: data, + item: item + }; + }); + notices.sort(function (a, b) { + return a.time > b.time ? -1 : a.time < b.time ? 1 : 0; + }); + enrichTmdbNotices(notices, function (items) { + _this2.notices = items; + Cache.rewriteData('other', 'cub_notice', _this2.notices); + Notice$1.drawCount(); + }); + }); + } + }, { + key: "viewed", + value: function viewed() { + Storage.set('cub_notice_time', Date.now()); + this.time = Date.now(); + Notice$1.drawCount(); + } + }, { + key: "empty", + value: function empty() { + var item = _get(_getPrototypeOf(NoticeCub.prototype), "empty", this).call(this, Lang.translate('empty_title_two'), Lang.translate('notice_none_account')); + + if (!Account$1.Permit.access) { + item = _get(_getPrototypeOf(NoticeCub.prototype), "empty", this).call(this, Lang.translate('account_none_title'), Lang.translate('notice_none')); + if (Platform.screen('tv')) Utils$1.qrcode('https://' + object$2.cub_site, item.find('.notice__img')); + return item; + } + + return item; + } + }, { + key: "count", + value: function count() { + var _this3 = this; + + return this.notices.filter(function (n) { + return n.time > _this3.time; + }).length; + } + }, { + key: "items", + value: function items() { + return this.notices; + } + }]); + + return NoticeCub; + }(NoticeClass); + + function translate$1(str) { + if (Arrays.isObject(str)) { + var code = Lampa.Storage.get('language', 'ru'); + if (str[code]) return str[code];else if (str.ru) return str.ru;else return str[Arrays.getKeys(str)[0]]; + } + + return str; + } + + var Notice = /*#__PURE__*/function () { + function Notice() { + _classCallCheck(this, Notice); + + this.listener = Subscribe$2(); + this.display = 'all'; + this.classes = {}; + } + + _createClass(Notice, [{ + key: "init", + value: function init() { + var _this = this; + + this.icon = Head.addIcon(Template.string('icon_bell'), this.open.bind(this)); + this.icon.addClass('notice--icon'); + this.classes.all = new NoticeAll(); + this.classes.lampa = new NoticeLampa(); + this.classes.cub = new NoticeCub(); + Lampa.Listener.follow('app', function (e) { + if (e.type == 'ready') _this.drawCount(); + }); + } + }, { + key: "get", + value: function get(name) { + if (!this.classes[name]) throw new Error('No find class: ' + name); + return this.classes[name]; + } + }, { + key: "open", + value: function open() { + var _this2 = this; + + if (Lampa.Controller.enabled().name == 'modal') Modal.close(); + var html = $('
    '); + var tabs = []; + var viever = this.classes[this.display]; + var items = viever.items(); + var navigation = $(''); + + for (var name in this.classes) { + var count = this.classes[name].count(); + var tab = { + name: name, + count: count + }; + tabs.push(tab); + } + + tabs.forEach(function (tab, i) { + var button = $(''); + if (tab.count) button.append('' + tab.count + ''); + button.on('hover:enter', function () { + _this2.display = tab.name; + + _this2.open(); + }); + if (tab.name == _this2.display) button.addClass('active'); + if (i > 0) navigation.append(''); + navigation.append(button); + }); + html.append(navigation); + items.forEach(function (element) { + try { + var _element$card; + + var item = Template.get('notice_card', {}); + var icon = element.poster || ((_element$card = element.card) === null || _element$card === void 0 ? void 0 : _element$card.poster_path) || element.icon || element.img; + var author_data = {}; + var author_html; + item.addClass('image--' + (element.poster ? 'poster' : element.icon ? 'icon' : element.img ? 'img' : 'none')); + item.find('.notice__title').html(translate$1(element.title)); + item.find('.notice__descr').html(translate$1(element.text)); + item.find('.notice__time').html(Utils$1.parseTime(element.time)["short"]); + if (element.labels) item.find('.notice__descr').append($('')); + + if (element.author) { + author_data = translate$1(element.author); + author_html = $("
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    "); + author_html.find('.notice__author-name').html(author_data.name); + author_html.find('.notice__author-text').html(author_data.text); + item.find('.notice__body').append(author_html); + } + + item.on('hover:enter', function () { + if (element.card) { + _this2.close(); + + Activity.push({ + url: '', + component: 'full', + id: element.card.id, + method: element.card.number_of_seasons || element.card.seasons ? 'tv' : 'movie', + card: element.card, + source: element.card.source || (Lang.selected(['ru', 'uk', 'be']) ? 'cub' : '') + }); + } else _this2.listener.send('select', { + display: element.display || _this2.display, + element: element + }); + }).on('visible', function () { + if (icon) { + var _element$card2; + + if (Arrays.isObject(icon)) icon = icon[Lampa.Storage.get('tmdb_lang')] || ((_element$card2 = element.card) === null || _element$card2 === void 0 ? void 0 : _element$card2.poster_path); + if (icon && icon.indexOf('http') == -1) icon = TMDB$1.image('t/p/w300/' + icon); + var img_icon = item.find('.notice__left img')[0] || {}; + var img_author = item.find('.notice__author img')[0] || {}; + + img_icon.onload = function () { + item.addClass('image--loaded'); + }; + + img_icon.onerror = function () { + img_icon.src = './img/img_broken.svg'; + }; + + img_author.onload = function () { + item.addClass('image-author--loaded'); + }; + + img_author.onerror = function () { + img_author.src = './img/img_broken.svg'; + }; + + img_icon.src = icon ? Utils$1.fixProtocolLink(icon) : './img/img_broken.svg'; + if (element.author) img_author.src = author_data.img ? Utils$1.fixProtocolLink(author_data.img.indexOf('http') >= 0 ? author_data.img : TMDB$1.image('t/p/w200/' + author_data.img)) : './img/img_broken.svg'; + } + }); + html.append(item); + } catch (e) { + console.error('Notice', 'render error', e, element); + } + }); + + if (!items.length) { + var empty = viever.empty(); + + if (typeof empty == 'string') { + var wrap = $('
    '); + wrap.append(empty); + html.append(wrap); + } else html.append(empty); + } + + viever.viewed(); + this.listener.send('viewed', { + display: this.display + }); + Modal.open({ + title: Lang.translate('title_notice'), + select: html.find('.navigation-tabs .active')[0], + size: 'medium', + html: html, + onBack: this.close.bind(this) + }); + } + }, { + key: "count", + value: function count() { + var all = 0; + + for (var name in this.classes) { + if (this.classes[name].active()) all += this.classes[name].count(); + } + + return all; + } + }, { + key: "close", + value: function close() { + Modal.close(); + Controller.toggle('head'); + } + }, { + key: "drawCount", + value: function drawCount() { + var _this3 = this; + + var status = Boolean(this.count()); + this.icon.toggleClass('active', status); + clearInterval(this.blick_timer); + + if (status) { + this.blick_timer = setInterval(function () { + _this3.icon.addClass('animate'); + + setTimeout(function () { + _this3.icon.removeClass('animate'); + }, 1000); + }, 1000 * 15); + } + } + }, { + key: "addClass", + value: function addClass(class_name, noticeClass) { + this.classes[class_name] = noticeClass; + } + }, { + key: "pushNotice", + value: function pushNotice(class_name, data, resolve, reject) { + if (this.classes[class_name] && this.classes[class_name].push) { + this.classes[class_name].push(data, resolve, reject); + } else if (reject) reject('No find class'); + } + }]); + + return Notice; + }(); + + var Notice$1 = new Notice(); + + /** + * Утилита для отслеживания статуса + * Нужно для того, чтобы дождаться завершения нескольких асинхронных процессов + * @constructor + * @param {number} need - количество процессов, которые нужно дождаться + * @property {function} onComplite - функция, которая будет вызвана по завершении всех процессов + * @property {function} stop - остановить проверку (например, если пользователь ушёл со страницы) + * @property {function(string, object)} append - добавить успешный процесс + * @property {function()} error - отметить ошибку в процессе + * @example + let status = new Status(3) + status.onComplite = (result)=>{ + //все процессы завершены + } + + asyncProcess1((data)=>{ + status.append('process1', data) + }, ()=>{ + status.error() + }) + + asyncProcess2((data)=>{ + status.append('process2', data) + }, ()=>{ + status.error() + }) + + asyncProcess3((data)=>{ + status.append('process3', data) + }, ()=>{ + status.error() + }) + */ + function Status(need) { + this.data = {}; + this.work = 0; + this.need = need; + this.complited = false; + + this.check = function () { + if (this.stopped) return; + + if (this.work >= this.need && !this.complited) { + this.complited = true; + this.onComplite(this.data); + } + }; + + this.append = function (name, json) { + this.work++; + this.data[name] = json; + this.check(); + }; + + this.error = function () { + this.work++; + this.check(); + }; + + this.stop = function () { + this.stopped = true; + }; + } + + function hasOpaqueBackground(el) { + var bg = getComputedStyle(el).backgroundColor; // Если background-color: transparent + + if (bg === 'transparent') return false; // Если rgba(0, 0, 0, 0) или любая с alpha = 0 + + var match = bg.match(/rgba?\(([^)]+)\)/); + + if (match) { + var parts = match[1].split(',').map(function (p) { + return p.trim(); + }); + var alpha = parts[3] !== undefined ? parseFloat(parts[3]) : 1; + return alpha > 0; + } // Если это rgb(...) или hex — значит непрозрачный + + + return true; + } + /** + * Плашка для отображения дополнительной информации или действий. + * @extends Emit + * @param {object} params - параметры плашки + * @param {string} [params.text] - текст плашки + * @param {string} [params.style=default] - стиль плашки (default, accent, warning, danger) + * @returns {More} - экземпляр класса More + */ + + + var More$1 = /*#__PURE__*/function (_Emit) { + _inherits(More, _Emit); + + var _super = _createSuper(More); + + function More() { + var _this; + + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, More); + + _this = _super.call(this); + _this.params = params; + return _this; + } + + _createClass(More, [{ + key: "create", + value: function create() { + this.html = Template.js('more'); + this.html.find('.card-more__title').html(this.params.text || Lang.translate('more')); + this.params.style && this.html.addClass('card-more--' + (this.params.style || 'default')); + this.emit('create'); + } + }, { + key: "size", + value: function size(target) { + if (!target) return this.html.find('.card-more__box').style.height = '10em'; + var elements = [target].concat(Array.from(target.querySelectorAll('*'))); + var max_area = 0; + var biggest_element = null; + elements.forEach(function (el) { + var rect = el.getBoundingClientRect(); + var area = rect.width * rect.height; + + if (area > max_area && hasOpaqueBackground(el)) { + max_area = area; + biggest_element = el; + } + }); + + if (biggest_element) { + var rect = biggest_element.getBoundingClientRect(); + this.html.style.width = (rect.width > rect.height ? rect.height : rect.width) + 'px'; + this.html.find('.card-more__box').style.height = rect.height + 'px'; + this.html.addClass('card-more--fixed-size'); + } + } + }, { + key: "render", + value: function render(js) { + return js ? this.html : $(this.html); + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + this.emit('destroy'); + } + }]); + + return More; + }(Emit); + + var MoreFirst = { + onCreate: function onCreate() { + var _this = this; + + this.more = new More$1(this.params.more); + this.more.create(); + this.more.html.addClass('card-more--first'); + this.more.html.on('hover:focus hover:touch', function () { + _this.last = _this.more.render(true); + _this.active = _this.items.indexOf(_this.more); + + _this.scroll.update(_this.more.render(true), _this.params.items.align_left ? false : true); + }); + this.more.html.on('hover:enter', this.emit.bind(this, 'more', this.data)); + this.scroll.append(this.more.render(true)); + this.items.push(this.more); + }, + onAppend: function onAppend(item, elem) { + if (this.data.results.indexOf(elem) == 0) this.more_set_size = item; + }, + onVisible: function onVisible() { + var _this$more_set_size; + + this.more.size((_this$more_set_size = this.more_set_size) === null || _this$more_set_size === void 0 ? void 0 : _this$more_set_size.render(true)); + this.more_set_size = null; + } + }; + + var Items$2 = { + onInit: function onInit() { + this.tv = Platform.screen('tv'); + this.items = []; + this.active = 0; + this.view = this.params.items.view; + }, + onAppend: function onAppend(item, element) { + var _this = this; + + var render = item.render(true); + render.on('hover:focus', function () { + _this.last = render; + var prev_active = _this.active; + _this.active = _this.items.indexOf(item); + if (_this.active > 0 || prev_active > _this.active) _this.scroll.update(_this.items[_this.active].render(true), _this.params.items.align_left ? false : true); + + _this.emit('active', item, element); + }); + render.on('hover:touch', function () { + _this.last = render; + _this.active = _this.items.indexOf(item); + + _this.emit('active', item, element); + }); + render.on('hover:enter', function () { + _this.last = render; + }); + render.on('visible', function () { + if (Controller.own(_this)) Controller.collectionAppend(render); + }); + + if (element.params.on && _typeof(element.params.on) == 'object') { + var _loop = function _loop(e) { + render.on(e, function () { + element.params.on[e].call(_this, item, element); + }); + }; + + for (var e in element.params.on) { + _loop(e); + } + } + + this.scroll.append(render); + this.items.push(item); + this.emit('push', item, element); + }, + onCreate: function onCreate() { + this.scroll.body(true).addClass('mapping--' + this.params.items.mapping); + this.scroll.onScroll = this.emit.bind(this, 'scroll'); + this.data.results.slice(0, this.view).forEach(this.emit.bind(this, 'createAndAppend')); + }, + onScroll: function onScroll() { + var size = this.tv ? (Math.round(this.active / this.view) + 1) * this.view + 1 : this.data.results.length; + var start = this.items.length; + if (this.has(MoreFirst)) start -= 1; + this.data.results.slice(start, size).forEach(this.emit.bind(this, 'createAndAppend')); + Layer.visible(this.scroll.render(true)); + }, + onDestroy: function onDestroy() { + Arrays.destroy(this.items); + } + }; + + var Base$2 = /*#__PURE__*/function (_Emit) { + _inherits(Base, _Emit); + + var _super = _createSuper(Base); + + function Base(data) { + var _this; + + _classCallCheck(this, Base); + + _this = _super.call(this); + Arrays.extend(data, { + title: data.name, + original_title: data.original_name, + release_date: data.first_air_date, + params: {} + }); + Arrays.extend(data.params, { + style: { + name: 'default' + } + }); + _this.data = data; + _this.params = data.params; + return _this; + } + + _createClass(Base, [{ + key: "create", + value: function create() { + this.html = document.createElement('div'); + this.emit('create'); + } + }, { + key: "visible", + value: function visible() { + this.emit('visible'); + } + }, { + key: "update", + value: function update() { + this.emit('update'); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html : $(this.html); + } + }, { + key: "disable", + value: function disable() { + var status = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + this.disabled = status; + this.html.toggleClass('card--disabled', status); + this.emit('disable', status); + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Base; + }(Emit); + + var Card$3 = /*#__PURE__*/function (_Base) { + _inherits(Card, _Base); + + var _super = _createSuper(Card); + + function Card(data) { + var _this; + + _classCallCheck(this, Card); + + _this = _super.call(this, data); + var module = _this.params.module || Helper$9.MASK.base; + Helper$9.getNames(module).map(function (name) { + return CardMap[name]; + }).forEach(function (mod) { + return _this.use(mod); + }); + + _this.emit('init'); + + return _this; + } + + return Card; + }(Base$2); + + var Create$2 = { + onCreateAndAppend: function onCreateAndAppend(element) { + try { + var item = Utils$1.createInstance(Card$3, element); + this.emit('instance', item, element); + item.create(); + this.emit('append', item, element); + } catch (e) { + console.warn('Warning', 'onCreateAndAppend error:', e.message, e.stack); + } + } + }; + + var More = { + onVisible: function onVisible() { + var pages = this.data.total_pages || 1; + if (pages <= 1) return; + var button = document.createElement('div'); + button.classList.add('items-line__more'); + button.classList.add('selector'); + button.text(Lang.translate('more')); + button.on('hover:enter', this.emit.bind(this, 'more', this.data)); + this.html.find('.items-line__head').append(button); + }, + onScroll: function onScroll() { + var _this = this; + + if (!this.more && this.data.results.length == this.items.length && this.data.total_pages > 1) { + this.more = new More$1(this.params.more); + this.more.create(); + this.more.size(this.items[this.items.length - 1].render(true)); + this.more.html.on('hover:focus hover:touch', function () { + _this.last = _this.more.render(true); + _this.active = _this.items.indexOf(_this.more); + + _this.scroll.update(_this.more.render(true), _this.params.items.align_left ? false : true); + }); + this.more.html.on('hover:enter', this.emit.bind(this, 'more', this.data)); + this.scroll.append(this.more.render(true)); + this.items.push(this.more); + if (Controller.own(this)) Controller.collectionAppend(this.more.render(true)); + } + } + }; + + var Event$1 = { + onEvent: function onEvent(type) { + Lampa.Listener.send('line', { + line: this, + type: type, + params: this.params, + data: this.data, + scroll: this.scroll, + body: this.body, + items: this.items, + active: this.active + }); + }, + onCreate: function onCreate() { + this.emit('event', 'create'); + }, + onCreateAndAppend: function onCreateAndAppend() { + this.emit('event', 'append'); + }, + onVisible: function onVisible() { + this.emit('event', 'visible'); + }, + onToggle: function onToggle() { + this.emit('event', 'toggle'); + }, + onDestroy: function onDestroy() { + this.emit('event', 'destroy'); + } + }; + + var Icon$1 = { + onCreate: function onCreate() { + var _this = this; + + var icon = $("
    \n
    \n \n
    \n \n
    \n
    ".concat(this.data.title, "
    \n
    \n
    "))[0]; + icon.on('visible', function () { + if (_this.data.icon_svg) { + icon.find('.full-person__photo').html(_this.data.icon_svg); + if (_this.data.icon_bgcolor) icon.find('.full-person__photo').style.backgroundColor = _this.data.icon_bgcolor; + if (_this.data.icon_color) icon.find('.full-person__photo').style.color = _this.data.icon_color; + icon.addClass('full-person--loaded'); + icon.addClass('full-person--svg'); + } else { + Utils$1.imgLoad(icon.find('img'), _this.data.icon_img || './img/actor.svg', function (img) { + icon.addClass('full-person--loaded'); + }, function (img) { + img.src = './img/actor.svg'; + }); + } + }); + this.html.find('.items-line__title').html(icon); + } + }; + + var LineMap = { + MoreFirst: MoreFirst, + Items: Items$2, + Create: Create$2, + More: More, + Icon: Icon$1, + Event: Event$1 + }; + + var Helper$b = new Mask(Arrays.getKeys(LineMap)); + Helper$b.MASK.base = Helper$b.except('Icon', 'MoreFirst'); + + function ImageMirror() { + var stat = []; + var mirrors = ['imagetmdb.com/', 'nl.imagetmdb.com/', 'de.imagetmdb.com/', 'pl.imagetmdb.com/', 'lampa.byskaz.ru/tmdb/img/']; + if (Account$1.hasPremium()) Arrays.insert(mirrors, 0, 'imagetmdb.' + object$2.cub_domain + '/'); + mirrors.forEach(function (mirror) { + stat[mirror] = { + errors: [], + banned: false + }; + }); + + this.current = function () { + var free = mirrors.filter(function (mirror) { + return !stat[mirror].banned; + }); + var last = Storage.get('tmdb_img_mirror', ''); + + if (free.indexOf(last) > -1) { + return last; + } else if (free.length) { + Storage.set('tmdb_img_mirror', free[0]); + return free[0]; + } + + return free.length ? free[0] : mirrors[0]; + }; + + this.broken = function (url) { + mirrors.forEach(function (mirror) { + if (url && url.indexOf('://' + mirror) !== -1) { + var now = Date.now(); + var s = stat[mirror]; + s.errors.push(now); + s.errors = s.errors.filter(function (t) { + return now - t < 10000; + }); + console.log('TMDB-Proxy', 'mirror', mirror, 'errors', s.errors.length); + + if (s.errors.length >= 20) { + s.banned = true; + s.errors = []; + console.warn('TMDB-Proxy', 'mirror', mirror, 'banned'); + } + } + }); + }; + } + + function init$$() { + var tmdb_proxy = { + name: 'TMDB Proxy', + version: '1.0.6', + description: 'Проксирование постеров и API сайта TMDB', + path_api: 'apitmdb.' + object$2.cub_domain + '/3/', + path_api_backup: 'lampa.byskaz.ru/tmdb/api/3/' + }; + var IMG = new ImageMirror(); + + function filter(u) { + var s = u.slice(0, 8); + var e = u.slice(8).replace(/\/+/g, '/'); + return s + e; + } + + function email() { + return Storage.get('account', '{}').email || ''; + } + + TMDB$1.image = function (url) { + var base = Utils$1.protocol() + 'image.tmdb.org/' + url; + return Utils$1.addUrlComponent(filter(Storage.field('proxy_tmdb') ? Utils$1.protocol() + IMG.current() + url : base), 'email=' + encodeURIComponent(email())); + }; + + TMDB$1.api = function (url) { + var base = Utils$1.protocol() + 'api.themoviedb.org/3/' + url; + return Utils$1.addUrlComponent(filter(Storage.field('proxy_tmdb') ? Utils$1.protocol() + tmdb_proxy.path_api + url : base), 'email=' + encodeURIComponent(email())); + }; + + TMDB$1.broken = function (url) { + IMG.broken(url); + }; + + Settings.listener.follow('open', function (e) { + if (e.name == 'tmdb') { + e.body.find('[data-parent="proxy"]').remove(); + } + }); + console.log('TMDB-Proxy', 'init'); + console.log('TMDB-Proxy', Storage.field('proxy_tmdb') ? 'enabled' : 'disabled'); + } + + var TMDBProxy = { + init: init$$ + }; + + /** + * Короче, постоянно пишут (почему нет картинок?) + * Решил сделать автоматическую установку TMDB Proxy если регион RU + */ + + var network$8 = new Request(); + var responce_code = 'ru'; + + function region(call) { + if (!window.lampa_settings.geo) return call && call(responce_code); + var reg = Storage.get('region', '{}'); + Arrays.extend({ + time: 0 + }); + + if (!reg.code || reg.time + 1000 * 60 * 60 * 24 < Date.now()) { + var extracted = function extracted(code) { + code = code.trim().toLowerCase(); + code = code.length <= 2 ? code || 'ru' : 'ru'; + Storage.set('region', { + code: code, + time: Date.now() + }); + call(code); + }; + + extract$1(extracted, function (e, x) { + console.warn('VPN', 'geo.' + object$2.cub_domain + ' domain not responding', network$8.errorDecode(e, x)); + Storage.set('region', { + code: Storage.field('language'), + time: Date.now() + }); + call(Storage.field('language')); + }); + } else call(reg.code); + } + + var extract$1 = function extract(call, error) { + $.ajax({ + url: Utils$1.protocol() + 'geo.' + object$2.cub_domain, + type: 'GET', + dataType: 'text', + timeout: 8000, + success: call, + error: error + }); + }; + + function task$4(call) { + if (!window.lampa_settings.geo) return call && call(); + extract$1(function (country) { + console.log('VPN', 'geo.' + object$2.cub_domain + ' domain responding ', country); + country = country.trim().toLowerCase(); + + if (country.length > 10) { + country = 'ru'; + console.warn('VPN', 'wrong responce, use default ru'); + } + + if ((country == 'ru' || country == 'by' || country == '' || country.length > 10) && !window.lampa_settings.disable_features.install_proxy) { + console.log('VPN', 'launch TMDB Proxy'); + TMDBProxy.init(); + } + + responce_code = country || 'ru'; // Для совместимости с Manifest.cub_domain + + window.vpn_region = responce_code; + call(); + }, function (e, x) { + console.warn('VPN', 'geo.' + object$2.cub_domain + ' domain not responding:', network$8.errorDecode(e, x)); + + if (!window.lampa_settings.disable_features.install_proxy) { + console.log('VPN', 'launch TMDB Proxy'); + TMDBProxy.init(); //будем считать что если не ответил, то все равно запускаем + } + + call(); + }); + } + + function is$1() { + var need_array = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return need_array.indexOf(responce_code) >= 0; + } + + var vpn = { + task: task$4, + is: is$1 + }; + Object.defineProperty(vpn, 'region', { + value: function value(call) { + region(call); + }, + writable: false + }); + Object.defineProperty(vpn, 'code', { + value: function value() { + return responce_code; + }, + writable: false + }); + + var lgbt = ["bisexual man", "bisexuality", "black lgbt", "closeted homosexual", "drag queen", "female homosexuality", "gay hardcore", "gay adoption", "gay artist", "gay bar", "gay club", "gay couple", "gay erotica", "gay for pay", "gay friend", "gay history", "gay interest", "gay kiss", "gay love", "gay love story", "gay man", "gay marriage", "gay men", "gay muslim", "gay parent", "gay pornography", "gay pride", "gay priest", "gay relationship", "gay rights", "gay romance", "gay sauna", "gay sex", "gay son", "gay teenager", "gay theme", "gay youth", "gender transition", "homoerotic", "homoeroticism", "homoerotism", "homofobia", "homophobia", "homophobic", "homophobic attack", "homosexual", "homosexual father", "homosexuality", "indigenous lgbt", "intersex", "intersexuality", "lesbian", "lesbian couple", "lesbian love", "lesbian maid", "lesbian nun", "lesbian relationship", "lesbian sex", "lgbt", "lgbt activist", "lgbt athlete", "lgbt history", "lgbt in africa", "lgbt in the military", "lgbt parenting", "lgbt rights", "lgbt teen", "male homosexuality", "queer", "queer cinema", "queer history", "queer loneliness", "queer love", "queer romance", "queer sexuality", "repressed gay", "teenage lesbian romance", "trans man", "trans woman", "transgender", "transgender rights", "transition", "transsexual", "transsexuality", "transvestism", "transvestite", "boys' love", "boys love"]; + var adult = ['porn', 'sex', 'xxx', 'erotic', 'fetish', 'bdsm', 'bondage', 'sado', 'masochism', 'voyeurism', 'exhibitionism', 'incest', 'softcore', 'eroticism', 'erotica', 'nude', 'nudity', 'nudism', 'naked', 'pink film']; + var filter$2 = ['путин', 'россия', 'putin', 'russia', 'лукашенко', 'lukashenko', 'навальный', 'navalny', '^буча', 'мариуполь', 'гомосекс', 'homosex', 'кремль']; + var Keys = { + lgbt: lgbt, + adult: adult, + filter: filter$2 + }; + + var network$7 = new Request(); + var menu_list = []; + var day$1 = 60 * 24; + var source$2 = 'tmdb'; + var genres$1 = { + movie: [{ + "id": 28, + "title": "#{filter_genre_ac}" + }, { + "id": 12, + "title": "#{filter_genre_ad}" + }, { + "id": 16, + "title": "#{filter_genre_mv}" + }, { + "id": 35, + "title": "#{filter_genre_cm}" + }, { + "id": 80, + "title": "#{filter_genre_cr}" + }, { + "id": 99, + "title": "#{filter_genre_dc}" + }, { + "id": 18, + "title": "#{filter_genre_dr}" + }, { + "id": 10751, + "title": "#{filter_genre_fm}" + }, { + "id": 14, + "title": "#{filter_genre_fe}" + }, { + "id": 36, + "title": "#{filter_genre_hi}" + }, { + "id": 27, + "title": "#{filter_genre_ho}" + }, { + "id": 10402, + "title": "#{filter_genre_mu}" + }, { + "id": 9648, + "title": "#{filter_genre_de}" + }, { + "id": 10749, + "title": "#{filter_genre_md}" + }, { + "id": 878, + "title": "#{filter_genre_fa}" + }, { + "id": 10770, + "title": "#{filter_genre_tv}" + }, { + "id": 53, + "title": "#{filter_genre_tr}" + }, { + "id": 10752, + "title": "#{filter_genre_mi}" + }, { + "id": 37, + "title": "#{filter_genre_ve}" + }], + tv: [{ + "id": 10759, + "title": "#{filter_genre_aa}" + }, { + "id": 16, + "title": "#{filter_genre_mv}" + }, { + "id": 35, + "title": "#{filter_genre_cm}" + }, { + "id": 80, + "title": "#{filter_genre_cr}" + }, { + "id": 99, + "title": "#{filter_genre_dc}" + }, { + "id": 18, + "title": "#{filter_genre_dr}" + }, { + "id": 10751, + "title": "#{filter_genre_fm}" + }, { + "id": 10762, + "title": "#{filter_genre_ch}" + }, { + "id": 9648, + "title": "#{filter_genre_de}" + }, { + "id": 10763, + "title": "#{filter_genre_nw}" + }, { + "id": 10764, + "title": "#{filter_genre_rs}" + }, { + "id": 10765, + "title": "#{filter_genre_hf}" + }, { + "id": 10766, + "title": "#{filter_genre_op}" + }, { + "id": 10767, + "title": "#{filter_genre_tc}" + }, { + "id": 10768, + "title": "#{filter_genre_mp}" + }, { + "id": 37, + "title": "#{filter_genre_ve}" + }] + }; + var keywords = { + movie: [{ + id: 9663, + title: '#{filter_keyword_sequel}' + }, { + id: 9717, + title: '#{filter_keyword_based_comic}' + }, { + id: 9882, + title: '#{filter_keyword_space}' + }, { + id: 10349, + title: '#{filter_keyword_survival}' + }, { + id: 12377, + title: '#{filter_keyword_zombie}' + }, { + id: 10873, + title: '#{filter_keyword_school}' + }, { + id: 9748, + title: '#{filter_keyword_revenge}' + }, { + id: 703, + title: '#{filter_keyword_detective}' + }, { + id: 14544, + title: '#{filter_keyword_robots}' + }, { + id: 3133, + title: '#{filter_keyword_vampires}' + }, { + id: 9951, + title: '#{filter_keyword_aliens}' + }, { + id: 6149, + title: '#{filter_keyword_police}' + }, { + id: 5484, + title: '#{filter_keyword_reincarnation}' + }, { + id: 470, + title: '#{filter_keyword_spy}' + }, { + id: 10617, + title: '#{filter_keyword_disaster}' + }], + tv: [{ + id: 9882, + title: '#{filter_keyword_space}' + }, { + id: 10349, + title: '#{filter_keyword_survival}' + }, { + id: 12377, + title: '#{filter_keyword_zombie}' + }, { + id: 10873, + title: '#{filter_keyword_school}' + }, { + id: 9748, + title: '#{filter_keyword_revenge}' + }, { + id: 703, + title: '#{filter_keyword_detective}' + }, { + id: 14544, + title: '#{filter_keyword_robots}' + }, { + id: 3133, + title: '#{filter_keyword_vampires}' + }, { + id: 9951, + title: '#{filter_keyword_aliens}' + }, { + id: 6149, + title: '#{filter_keyword_police}' + }, { + id: 5484, + title: '#{filter_keyword_reincarnation}' + }, { + id: 470, + title: '#{filter_keyword_spy}' + }, { + id: 10617, + title: '#{filter_keyword_disaster}' + }] + }; + + function url$1(u) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var ln = [Storage.field('tmdb_lang')]; + var genre = params.genres; + if (permit.child_small) genre = genre ? genre + (genre == '16' ? '' : ',16') : '16'; + if (params.langs) ln = typeof params.langs == 'string' ? [params.langs] : ln.concat(params.langs.filter(function (n) { + return n !== ln[0]; + })); + u = add$a(u, 'api_key=' + TMDB$1.key()); + u = add$a(u, 'language=' + ln.join(',')); + if (genre && u.indexOf('with_genres') == -1) u = add$a(u, 'with_genres=' + genre); + if (params.page) u = add$a(u, 'page=' + params.page); + if (params.query) u = add$a(u, 'query=' + params.query); + if (params.keywords) u = add$a(u, 'with_keywords=' + params.keywords); + if (params.watch_region) u = add$a(u, 'watch_region=' + params.watch_region); + if (params.watch_providers) u = add$a(u, 'with_watch_providers=' + params.watch_providers); + if (params.companies) u = add$a(u, 'with_companies=' + params.companies); + if (params.networks) u = add$a(u, 'with_networks=' + params.networks); + if (params.sort_by) u = add$a(u, 'sort_by=' + params.sort_by); + if (params.orig_lang) u = add$a(u, 'with_original_language=' + params.orig_lang); + + if (params.filter) { + for (var i in params.filter) { + u = add$a(u, i + '=' + params.filter[i]); + } + } // Добавляем проверку для запросов по жанрам + + + if (params.genres && u.indexOf('discover/') !== 0) { + u = 'discover/' + u; + } + + return TMDB$1.api(u); + } + + function add$a(u, params) { + return u + (/\?/.test(u) ? '&' : '?') + params; + } + + function get$c(method) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var oncomplite = arguments.length > 2 ? arguments[2] : undefined; + var onerror = arguments.length > 3 ? arguments[3] : undefined; + var cache = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + var u = url$1(method, params); + var s = method.match(/tv\/(\d+)\/season\/(\d+)/); + network$7.timeout(1000 * 10); + network$7.silent(u, function (json) { + json.url = method; + json.source = source$2; // Исправляем сезоны для сериалов + + if (s && s[2] == 1) { + var _seasons = Utils$1.splitEpisodesIntoSeasons(json.episodes); // Считаем количество реальных сезонов и отмечаем в объекте + + + json.seasons_count = Arrays.getKeys(_seasons).length; // Если есть 1й сезон, то заменяем эпизоды на него + + if (_seasons[1]) { + // Оставляем оригинальные эпизоды на случай, если понадобятся все эпизоды + json.episodes_original = json.episodes; // Заменяем данные на 1й сезон + + json.episodes = _seasons[1]; + } + } // Фильтруем результаты по ключевым словам, чтобы не показывать фильмы с неуместными словами в названии + + + if (json.results && Arrays.isArray(json.results)) { + json.results = json.results.filter(function (item) { + var title = (item.title || item.name || '').toLowerCase(); + return !Keys.filter.find(function (word) { + var reg = new RegExp(word, 'i'); + return reg.test(title); + }); + }); + } + + oncomplite(Utils$1.addSource(json, source$2)); + }, function () { + // Если сезон не найден, то пробуем найти правильный сезон из 1го сезона + if (s) seasonFix(parseInt(s[2]), method, params = {}, oncomplite, onerror, cache);else if (onerror) onerror(); + }, false, { + cache: cache + }); + } + + function img$1(src, size) { + var poster_size = Storage.field('poster_size'); + var baseimg = 't/p/' + poster_size + '/'; + var path = baseimg; + if (size) path = path.replace(new RegExp(poster_size, 'g'), size); + return src ? TMDB$1.image(path + src) : ''; + } + + function seasonFix(season_need, method) { + var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var oncomplite = arguments.length > 3 ? arguments[3] : undefined; + var onerror = arguments.length > 4 ? arguments[4] : undefined; + var cache = arguments.length > 5 ? arguments[5] : undefined; + method = method.replace(/\/season\/(\d+)/, '/season/1'); + network$7.timeout(1000 * 10); + network$7.silent(url$1(method, params), function (new_json) { + new_json.url = method; + new_json.source = source$2; + var seasons = Utils$1.splitEpisodesIntoSeasons(new_json.episodes); // Считаем количество реальных сезонов и отмечаем в объекте + + new_json.seasons_count = Arrays.getKeys(seasons).length; // Если нужный сезон есть, то отдаем его + + if (seasons[season_need]) { + // Заменяем данные на нужный сезон + new_json.episodes = seasons[season_need]; + new_json.season_number = season_need; + new_json.name = Lang.translate('torrent_serial_season') + ' ' + season_need; + oncomplite(Utils$1.addSource(new_json, source$2)); + } else if (onerror) onerror(); + }, onerror, false, { + cache: cache + }); + } + + function find$2(find) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var finded; + + var filtred = function filtred(items) { + for (var i = 0; i < items.length; i++) { + var item = items[i]; + + if (params.original_title == item.original_title || params.title == item.title) { + finded = item; + break; + } + } + }; + + if (find.movie && find.movie.results.length) filtred(find.movie.results); + if (find.tv && find.tv.results.length && !finded) filtred(find.tv.results); + return finded; + } + + function main$2() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var parts_limit = 6; + var parts_data = [function (call) { + get$c('movie/now_playing', params, function (json) { + json.title = Lang.translate('title_now_watch'); + call(json); + }, call, { + life: day$1 * 2 + }); + }, function (call) { + get$c('trending/movie/day', params, function (json) { + json.title = Lang.translate('title_trend_day'); + call(json); + }, call, { + life: day$1 * 2 + }); + }, function (call) { + get$c('trending/movie/week', params, function (json) { + json.title = Lang.translate('title_trend_week'); + call(json); + }, call, { + life: day$1 * 3 + }); + }, function (call) { + get$c('movie/upcoming', params, function (json) { + json.title = Lang.translate('title_upcoming'); + call(json); + }, call, { + life: day$1 * 7 + }); + }, function (call) { + get$c('movie/popular', params, function (json) { + json.title = Lang.translate('title_popular_movie'); + json.icon_svg = Template.string('icon_fire'); + json.icon_bgcolor = '#fff'; + json.icon_color = '#fd4518'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day$1 * 3 + }); + }, function (call) { + get$c('trending/tv/week', params, function (json) { + json.title = Lang.translate('title_popular_tv'); + json.icon_svg = Template.string('icon_fire'); + json.icon_bgcolor = '#fff'; + json.icon_color = '#fd4518'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day$1 * 3 + }); + }, function (call) { + get$c('movie/top_rated', params, function (json) { + json.title = Lang.translate('title_top_movie'); + json.icon_svg = Template.string('icon_top'); + json.icon_bgcolor = '#e02129'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day$1 * 7 + }); + }, function (call) { + get$c('tv/top_rated', params, function (json) { + json.title = Lang.translate('title_top_tv'); + json.icon_svg = Template.string('icon_top'); + json.icon_bgcolor = '#e02129'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day$1 * 7 + }); + }]; + ContentRows.call('main', params, parts_data); + var start_shuffle = parts_data.length + 2; + Arrays.insert(parts_data, 0, Api.partKeywords(parts_data, 'movie', start_shuffle)); + Arrays.insert(parts_data, 0, Api.partPersons(parts_data, parts_limit, 'movie', start_shuffle)); + genres$1.movie.forEach(function (genre) { + var event = function event(call) { + get$c('discover/movie?with_genres=' + genre.id, params, function (json) { + json.title = Lang.translate(genre.title.replace(/[^a-z_]/g, '')); + call(json); + }, call, { + life: day$1 * 7 + }); + }; + + parts_data.push(event); + }); + + function loadPart(partLoaded, partEmpty) { + Api.partNext(parts_data, parts_limit, partLoaded, partEmpty); + } + + loadPart(oncomplite, onerror); + return loadPart; + } + + function category$3() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var fullcat = !(params.genres || params.keywords); + var years = [2000, 2010, 2015]; + var parts_limit = 6; + var parts_data = [function (call) { + if (params.url == 'movie') { + get$c('discover/' + params.url + '?with_release_type=1', params, function (json) { + json.title = Lang.translate('title_now_watch'); + call(json); + }, call, { + life: day$1 * 2 + }); + } else call(); + }, function (call) { + get$c(params.url == 'movie' ? 'trending/movie/week' : 'trending/tv/week', params, function (json) { + json.title = Lang.translate('title_popular'); + json.icon_svg = Template.string('icon_fire'); + json.icon_bgcolor = '#fff'; + json.icon_color = '#fd4518'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day$1 * 3 + }); + }, function (call) { + get$c('discover/' + params.url + '?' + (params.url == 'movie' ? 'primary_release_year' : 'first_air_date_year') + '=' + (new Date().getFullYear() - 1), params, function (json) { + json.title = Lang.translate('title_last_year'); + call(json); + }, call, { + life: day$1 * 7 + }); + }, function (call) { + var lte = new Date().getFullYear() - 2 + '-12-31'; + var gte = new Date().getFullYear() - 7 + '-01-01'; + var reg = params.url == 'movie' ? 'primary_release_date' : 'first_air_date'; + lte = reg + '.lte=' + lte; + gte = reg + '.gte=' + gte; + get$c('discover/' + params.url + '?' + lte + '&' + gte, params, function (json) { + json.title = Lang.translate('title_worth_rewatch'); + call(json); + }, call, { + life: day$1 * 7 + }); + }, function (call) { + var lte = new Date().getFullYear() - 2 + '-12-31'; + var gte = new Date().getFullYear() - 7 + '-01-01'; + var reg = params.url == 'movie' ? 'primary_release_date' : 'first_air_date'; + lte = reg + '.lte=' + lte; + gte = reg + '.gte=' + gte; + get$c('discover/' + params.url + '?' + lte + '&' + gte + '&vote_average.gte=8&vote_average.lte=9', params, function (json) { + json.title = Lang.translate('title_hight_voite'); + json.icon_svg = Template.string('icon_star'); + json.icon_bgcolor = '#fff'; + json.icon_color = '#212121'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day$1 * 7 + }); + }, function (call) { + if (params.genres) return call(); + + if (params.url == 'tv') { + get$c('trending/tv/week', params, function (json) { + json.title = Lang.translate('title_this_week'); + call(json); + }, call, { + life: day$1 * 3 + }); + } else { + get$c('movie/upcoming', params, function (json) { + json.title = Lang.translate('title_upcoming'); + json.results.forEach(function (card) { + card.params = { + style: { + name: 'wide' + } + }; + }); + json.params = { + items: { + view: 3 + } + }; + call(json); + }, call, { + life: day$1 * 7 + }); + } + }]; // Дух Рождества + //Arrays.insert(parts_data, 1, Api.partKeyword({id: 207317, title: '#{filter_keyword_christmas}'}, params.url, params)) + + ContentRows.call('category', params, parts_data); + var start_shuffle = parts_data.length + 2; + Arrays.insert(parts_data, 0, Api.partKeywords(parts_data, params.url, start_shuffle, [], params)); + if (fullcat) Arrays.insert(parts_data, 0, Api.partPersons(parts_data, parts_limit, params.url, start_shuffle)); + + if (fullcat) { + genres$1[params.url].forEach(function (genre) { + var event = function event(call) { + get$c('discover/' + params.url + '?with_genres=' + genre.id, params, function (json) { + json.title = Lang.translate(genre.title.replace(/[^a-z_]/g, '')); + call(json); + }, call, { + life: day$1 * 7 + }); + }; + + parts_data.push(event); + }); + } + + years.forEach(function (year) { + var lte = year + 5 + '-12-31'; + var gte = year + '-01-01'; + var reg = params.url == 'movie' ? 'primary_release_date' : 'first_air_date'; + lte = reg + '.lte=' + lte; + gte = reg + '.gte=' + gte; + + var eventYear = function eventYear(call) { + get$c('discover/' + params.url + '?' + gte + '&' + lte, params, function (json) { + json.title = Lang.translate('title_best_of_' + year); + call(json); + }, call, { + life: day$1 * 7 + }); + }; + + parts_data.push(eventYear); + + var eventComedy = function eventComedy(call) { + get$c('discover/' + params.url + '?' + gte + '&' + lte + '&with_genres=35', params, function (json) { + json.title = Lang.translate('title_comedy_of_' + year); + call(json); + }, call, { + life: day$1 * 7 + }); + }; + + if (fullcat) parts_data.push(eventComedy); + }); + Arrays.shuffleArrayFromIndex(parts_data, start_shuffle); + + function loadPart(partLoaded, partEmpty) { + Api.partNext(parts_data, parts_limit, partLoaded, partEmpty); + } + + loadPart(oncomplite, onerror); + return loadPart; + } + + function full$3() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var status = new Status(9); + status.onComplite = oncomplite; + var image_language = (Storage.field('tmdb_lang') || 'en').split(/[-_]/)[0]; + var image_languages = [image_language, 'en', 'null'].filter(function (language, index, list) { + return list.indexOf(language) == index; + }).join(','); + if (Utils$1.dcma(params.method, params.id)) return onerror(); + get$c(params.method + '/' + params.id + '?append_to_response=content_ratings,release_dates,external_ids,keywords,alternative_titles,images&include_image_language=' + image_languages, params, function (json) { + var _json$overview; + + json.source = 'tmdb'; + + if (json.external_ids) { + json.imdb_id = json.external_ids.imdb_id; + } + + if (!((_json$overview = json.overview) !== null && _json$overview !== void 0 && _json$overview.trim()) && Storage.field('tmdb_lang') !== 'en') { + get$c(params.method + '/' + params.id, { + langs: 'en' + }, function (enjson) { + var _enjson$overview; + + if ((_enjson$overview = enjson.overview) !== null && _enjson$overview !== void 0 && _enjson$overview.trim()) json.overview = enjson.overview; + status.need--; + status.check(); + }, status.error.bind(status), { + life: day$1 * 7 + }); + } else status.need--; + + if (params.method == 'tv') { + var season = Utils$1.countSeasons(json); + get$c('tv/' + json.id + '/season/' + season, {}, function (ep) { + status.append('episodes', ep); + }, status.error.bind(status), { + life: day$1 * 3 + }); + } else status.need--; + + if (json.belongs_to_collection) { + get$c('collection/' + json.belongs_to_collection.id, {}, function (collection) { + collection.results = collection.parts.slice(0, 19); + status.append('collection', collection); + }, status.error.bind(status), { + life: day$1 * 7 + }); + } else status.need--; + + status.append('movie', json); + }, function () { + status.need -= 2; + status.error(); + }, { + life: day$1 * 7 + }); + + if (!permit.child_small) { + get$c(params.method + '/' + params.id + '/credits', params, function (json) { + status.append('persons', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + get$c(params.method + '/' + params.id + '/recommendations', params, function (json) { + status.append('recomend', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + get$c(params.method + '/' + params.id + '/similar', params, function (json) { + status.append('simular', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + + if (!permit.child) { + videos(params, function (json) { + status.append('videos', json); + }, status.error.bind(status)); + } else { + status.need--; + } + } else { + status.need -= 4; + } + + Api.sources.cub.reactionsGet(params, function (json) { + status.append('reactions', json); + }); + + if (Lang.selected(['ru', 'uk', 'be']) && window.lampa_settings.account_use && !permit.child) { + status.need++; + Api.sources.cub.discussGet(params, function (json) { + status.append('discuss', json); + }, status.error.bind(status)); + } + + if (params.method == 'movie') { + status.need++; + Api.sources.cub.metadataGet(params, function (json) { + status.append('metadata', json); + }, status.error.bind(status)); + } + } + + function videos() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var lg = Storage.field('tmdb_lang'); + var status = new Status(lg == 'en' ? 1 : 2); + + status.onComplite = function (res) { + var data = []; + if (res.one && res.one.results && res.one.results.length) data = data.concat(res.one.results); + if (res.two && res.two.results && res.two.results.length) data = data.concat(res.two.results); + oncomplite({ + results: data + }); + }; + + get$c(params.method + '/' + params.id + '/videos', { + langs: Storage.field('tmdb_lang') + }, function (json) { + status.append('one', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + + if (lg !== 'en') { + get$c(params.method + '/' + params.id + '/videos', { + langs: 'en' + }, function (json) { + status.append('two', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + } + } + + function list$5() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var u = url$1(params.url, params); + network$7.silent(u, function (data) { + oncomplite(Utils$1.addSource(data, source$2)); + }, onerror, false, { + cache: { + life: day$1 * 2 + } + }); + } + + function search$5() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var status = new Status(3); + + status.onComplite = function (data) { + var items = []; + if (data.movie && data.movie.results.length) items.push(data.movie); + if (data.tv && data.tv.results.length) items.push(data.tv); + if (data.person && data.person.results.length) items.push(data.person); + oncomplite(items); + }; + + get$c('search/movie', params, function (json) { + json.title = Lang.translate('menu_movies'); + json.type = 'movie'; + status.append('movie', json); + }, status.error.bind(status)); + get$c('search/tv', params, function (json) { + json.title = Lang.translate('menu_tv'); + json.type = 'tv'; + status.append('tv', json); + }, status.error.bind(status)); + get$c('search/person', params, function (json) { + json.title = Lang.translate('title_actors'); + json.type = 'person'; + json.results.forEach(function (person) { + person.params = { + module: Helper$9.only('Card', 'Release', 'Callback') + }; + }); + status.append('person', json); + }, status.error.bind(status)); + } + + function discovery$2() { + return { + title: 'TMDB', + search: search$5, + params: { + save: true + }, + onRecall: function onRecall(rows, last_query) { + rows.forEach(function (row) { + if (row.type == 'person') { + row.results.forEach(function (element) { + element.params = { + module: Helper$9.only('Card', 'Release', 'Callback') + }; + }); + } + }); + }, + onSelect: function onSelect(params, close) { + close(); + router.call(params.element.gender ? 'actor' : 'full', params.element); + }, + onMore: function onMore(params, close) { + close(); + Activity.push({ + url: 'search/' + params.data.type, + title: Lang.translate('search') + ' - ' + params.query, + component: 'category_full', + page: 2, + query: encodeURIComponent(params.query), + source: source$2 + }); + }, + onCancel: network$7.clear.bind(network$7) + }; + } + + function person$2() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + + var sortCredits = function sortCredits(credits) { + return Utils$1.addSource(credits.map(function (a) { + a.year = parseInt(((a.release_date || a.first_air_date || '0000') + '').slice(0, 4)); + return a; + }).sort(function (a, b) { + return b.vote_average - a.vote_average && b.vote_count - a.vote_count; + }) //сортируем по оценке и кол-ву голосов (чтобы отсечь мусор с 1-2 оценками) + , source$2); + }; + + var convert = function convert(credits, person_data) { + if (params.only_credits) { + var cast = sortCredits(credits.cast); + var result = {}; + result[params.only_credits] = sortCredits(cast.filter(function (media) { + return media.media_type === params.only_credits; + })); + return result; + } else { + var department = ['directing', 'writing', 'editing', 'creator']; + credits.crew.forEach(function (a) { + a.department = Lang.translate(department.indexOf(a.department.toLowerCase()) == -1 ? 'settings_main_rest' : 'full_' + a.department.toLowerCase()); + }); + + var _cast = sortCredits(credits.cast), + crew = sortCredits(credits.crew), + tv = sortCredits(_cast.filter(function (media) { + return media.media_type === 'tv'; + })), + movie = sortCredits(_cast.filter(function (media) { + return media.media_type === 'movie'; + })), + knownFor; //Наиболее известные работы человека + //1. Группируем все работы по департаментам (Актер, Режиссер, Сценарист и т.д.) + + + knownFor = Arrays.groupBy(crew, 'department'); + if (movie.length > 0) knownFor[Lang.translate('menu_movies')] = movie; + if (tv.length > 0) knownFor[Lang.translate('menu_tv')] = tv; //2. Для каждого департамента суммируем кол-ва голосов (вроде бы сам TMDB таким образом определяет knownFor для людей) + + knownFor = Object.entries(knownFor).map(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + depIdx = _ref2[0], + dep = _ref2[1]; + + //убираем дубликаты (человек может быть указан в одном департаменте несколько раз на разных должностях (job)) + var set = {}, + credits = dep.filter(function (credit) { + return set.hasOwnProperty(credit.original_title || credit.original_name) ? false : credit.original_title ? set[credit.original_title] = true : set[credit.original_name] = true; + }); + return { + name: depIdx, + credits: credits, + vote_count: dep.reduce(function (a, b) { + return a + b.vote_count; + }, 0) + }; //3. Сортируем департаменты по кол-ву голосов + }).sort(function (a, b) { + return b.credits.length - a.credits.length; + }); + return { + raw: credits, + cast: _cast, + crew: crew, + tv: tv, + movie: movie, + knownFor: knownFor + }; + } + }; + + var status = new Status(params.only_credits ? 1 : 2); + + status.onComplite = function () { + var fulldata = {}; + if (status.data.person) fulldata.person = status.data.person; + if (status.data.credits) fulldata.credits = convert(status.data.credits, status.data.person || {}); + oncomplite(fulldata); + }; + + if (!params.only_credits) { + get$c('person/' + params.id, params, function (json) { + status.append('person', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + } + + get$c('person/' + params.id + '/combined_credits', params, function (json) { + status.append('credits', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + } + + function menu$3() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + if (menu_list.length) oncomplite(menu_list);else { + var u = url$1('genre/movie/list', params); + network$7.silent(u, function (j) { + j.genres.forEach(function (g) { + menu_list.push({ + title: g.name, + id: g.id + }); + }); + oncomplite(menu_list); + }); + } + } + + function menuCategory$2(params, oncomplite) { + var menu = []; + + if (params.action !== 'tv') { + menu.push({ + title: Lang.translate('title_now_watch'), + url: params.action + '/now_playing' + }); + } + + menu.push({ + title: Lang.translate('title_popular'), + url: params.action + '/popular' + }); + var date = new Date(); + var query = []; + query.push('sort_by=release_date.desc'); + query.push('year=' + date.getFullYear()); + query.push('first_air_date_year=' + date.getFullYear()); + query.push('vote_average.gte=7'); + menu.push({ + title: Lang.translate('title_new'), + url: 'discover/' + params.action + '?' + query.join('&') + }); + + if (params.action == 'tv') { + menu.push({ + title: Lang.translate('title_tv_today'), + url: params.action + '/airing_today' + }); + menu.push({ + title: Lang.translate('title_this_week'), + url: params.action + '/on_the_air' + }); + } + + menu.push({ + title: Lang.translate('title_in_top'), + url: params.action + '/top_rated' + }); + oncomplite(menu); + } + + function external_ids() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + get$c((params.type || 'tv') + '/' + params.id + '/external_ids', params, oncomplite, onerror, { + life: day$1 * 7 + }); + } + + function external_imdb_id() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + get$c(params.type + '/' + params.id + '/external_ids', params, function (ids) { + oncomplite(ids.imdb_id || ''); + }, function () { + oncomplite(''); + }, { + life: day$1 * 7 + }); + } + + function company$1() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var status = new Status(3); + + status.onComplite = function () { + function sortResultsByVoteAverage(results) { + return results.sort(function (a, b) { + return b.vote_average - a.vote_average; + }); + } + + if (status.data.company) { + var fulldata = { + company: status.data.company, + lines: [] + }; + if (status.data.movie && status.data.movie.results.length) fulldata.lines.push({ + total_pages: status.data.movie.total_pages, + url: 'discover/movie', + title: Lang.translate('menu_movies') + ' (' + status.data.movie.total_results + ')', + results: sortResultsByVoteAverage(status.data.movie.results), + total_results: status.data.movie.total_results + }); + if (status.data.tv && status.data.tv.results.length) fulldata.lines.push({ + total_pages: status.data.tv.total_pages, + url: 'discover/tv', + title: Lang.translate('menu_tv') + ' (' + status.data.tv.total_results + ')', + results: sortResultsByVoteAverage(status.data.tv.results), + total_results: status.data.tv.total_results + }); + oncomplite(fulldata); + } else onerror(); + }; + + get$c('company/' + params.id, params, function (json) { + status.append('company', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + get$c('discover/movie?sort_by=vote_count.desc&with_companies=' + params.id, params, function (json) { + status.append('movie', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + get$c('discover/tv?sort_by=vote_count.desc&with_companies=' + params.id, params, function (json) { + status.append('tv', json); + }, status.error.bind(status), { + life: day$1 * 7 + }); + } + + function seasons$2(tv, from, oncomplite) { + var status = new Status(from.length); + status.onComplite = oncomplite; + from.forEach(function (season) { + get$c('tv/' + tv.id + '/season/' + season, {}, function (json) { + status.append('' + season, json); + }, status.error.bind(status), { + life: day$1 * 3 + }); + }); + } + + function parsePG(movie) { + var pg; + var cd = Storage.field('language'); + + if (movie.content_ratings) { + try { + var _find = movie.content_ratings.results.find(function (a) { + return a.iso_3166_1 == cd.toUpperCase(); + }); + + if (!_find) _find = movie.content_ratings.results.find(function (a) { + return a.iso_3166_1 == 'US'; + }); + if (_find) pg = Utils$1.decodePG(_find.rating); + } catch (e) {} + } + + if (movie.release_dates && movie.release_dates.results && !pg) { + try { + var _find2 = movie.release_dates.results.find(function (a) { + return a.iso_3166_1 == cd.toUpperCase(); + }); + + if (!_find2) _find2 = movie.release_dates.results.find(function (a) { + return a.iso_3166_1 == 'US'; + }); + + if (_find2 && _find2.release_dates.length) { + pg = Utils$1.decodePG(_find2.release_dates[0].certification); + } + } catch (e) {} + } + + if (movie.restrict) pg = movie.restrict + '+'; + return pg; + } + + function parseCountries(movie) { + var iso_countries = { + 'AD': Lang.translate('country_ad'), + 'AE': Lang.translate('country_ae'), + 'AF': Lang.translate('country_af'), + //'AG' : 'Antigua And Barbuda', + //'AI' : 'Anguilla', + 'AL': Lang.translate('country_al'), + 'AM': Lang.translate('country_am'), + //'AN' : 'Netherlands Antilles', + 'AO': Lang.translate('country_ao'), + //'AQ' : 'Antarctica', + 'AR': Lang.translate('country_ar'), + //'AS' : 'American Samoa', + 'AT': Lang.translate('country_at'), + 'AU': Lang.translate('country_au'), + 'AW': Lang.translate('country_aw'), + 'AZ': Lang.translate('country_az'), + 'BA': Lang.translate('country_ba'), + //'BB' : 'Barbados', + 'BD': Lang.translate('country_bd'), + 'BE': Lang.translate('country_be'), + //'BF' : 'Burkina Faso', + 'BG': Lang.translate('country_bg'), + 'BH': Lang.translate('country_bh'), + 'BI': Lang.translate('country_bi'), + 'BJ': Lang.translate('country_bj'), + //'BL' : 'Saint Barthelemy', + //'BM' : 'Bermuda', + //'BN' : 'Brunei Darussalam', + 'BO': Lang.translate('country_bo'), + 'BR': Lang.translate('country_br'), + 'BS': Lang.translate('country_bs'), + 'BT': Lang.translate('country_bt'), + //'BV' : 'Bouvet Island', + 'BW': Lang.translate('country_bw'), + 'BY': Lang.translate('country_by'), + //'BZ' : 'Belize', + 'CA': Lang.translate('country_ca'), + //'CC' : 'Cocos (Keeling) Islands', + //'CD' : 'Congo, Democratic Republic', + //'CF' : 'Central African Republic', + //'CG' : 'Congo', + 'CH': Lang.translate('country_ch'), + //'CI' : 'Cote D\'Ivoire', + //'CK' : 'Cook Islands', + 'CL': Lang.translate('country_cl'), + 'CM': Lang.translate('country_cm'), + 'CN': Lang.translate('country_cn'), + 'CO': Lang.translate('country_co'), + 'CR': Lang.translate('country_cr'), + 'CU': Lang.translate('country_cu'), + 'CV': Lang.translate('country_cv'), + //'CX' : 'Christmas Island', + 'CY': Lang.translate('country_cy'), + 'CZ': Lang.translate('country_cz'), + 'DE': Lang.translate('country_de'), + 'DJ': Lang.translate('country_dj'), + 'DK': Lang.translate('country_dk'), + //'DM' : 'Dominica', + 'DO': Lang.translate('country_do'), + 'DZ': Lang.translate('country_dz'), + 'EC': Lang.translate('country_ec'), + 'EE': Lang.translate('country_ee'), + 'EG': Lang.translate('country_eg'), + //'EH' : 'Western Sahara', + //'ER' : 'Eritrea', + 'ES': Lang.translate('country_es'), + 'ET': Lang.translate('country_et'), + 'FI': Lang.translate('country_fi'), + //'FJ' : 'Fiji', + //'FK' : 'Falkland Islands (Malvinas)', + //'FM' : 'Micronesia, Federated States Of', + 'FO': Lang.translate('country_fo'), + 'FR': Lang.translate('country_fr'), + 'GA': Lang.translate('country_ga'), + 'GB': Lang.translate('country_gb'), + //'GD' : 'Grenada', + 'GE': Lang.translate('country_ge'), + //'GF' : 'French Guiana', + //'GG' : 'Guernsey', + 'GH': Lang.translate('country_gh'), + //'GI' : 'Gibraltar', + 'GL': Lang.translate('country_gl'), + //'GM' : 'Gambia', + //'GN' : 'Guinea', + 'GP': Lang.translate('country_gp'), + //'GQ' : 'Equatorial Guinea', + 'GR': Lang.translate('country_gr'), + //'GS' : 'South Georgia And Sandwich Isl.', + 'GT': Lang.translate('country_gt'), + //'GU' : 'Guam', + //'GW' : 'Guinea-Bissau', + //'GY' : 'Guyana', + 'HK': Lang.translate('country_hk'), + //'HM' : 'Heard Island & Mcdonald Islands', + //'HN' : 'Honduras', + 'HR': Lang.translate('country_hr'), + 'HT': Lang.translate('country_ht'), + 'HU': Lang.translate('country_hu'), + 'ID': Lang.translate('country_id'), + 'IE': Lang.translate('country_ie'), + 'IL': Lang.translate('country_il'), + //'IM' : 'Isle Of Man', + 'IN': Lang.translate('country_in'), + //'IO' : 'British Indian Ocean Territory', + 'IQ': Lang.translate('country_iq'), + 'IR': Lang.translate('country_ir'), + 'IS': Lang.translate('country_is'), + 'IT': Lang.translate('country_it'), + //'JE' : 'Jersey', + 'JM': Lang.translate('country_jm'), + 'JO': Lang.translate('country_jo'), + 'JP': Lang.translate('country_jp'), + 'KE': Lang.translate('country_ke'), + 'KG': Lang.translate('country_kg'), + 'KH': Lang.translate('country_kh'), + //'KI' : 'Kiribati', + //'KM' : 'Comoros', + //'KN' : 'Saint Kitts And Nevis', + 'KP': Lang.translate('country_kp'), + 'KR': Lang.translate('country_kr'), + 'KW': Lang.translate('country_kw'), + //'KY' : 'Cayman Islands', + 'KZ': Lang.translate('country_kz'), + 'LA': Lang.translate('country_la'), + 'LB': Lang.translate('country_lb'), + //'LC' : 'Saint Lucia', + 'LI': Lang.translate('country_li'), + 'LK': Lang.translate('country_lk'), + 'LR': Lang.translate('country_lr'), + //'LS' : 'Lesotho', + 'LT': Lang.translate('country_lt'), + 'LU': Lang.translate('country_lu'), + 'LV': Lang.translate('country_lv'), + 'LY': Lang.translate('country_ly'), + 'MA': Lang.translate('country_ma'), + 'MC': Lang.translate('country_mc'), + 'MD': Lang.translate('country_md'), + 'ME': Lang.translate('country_me'), + //'MF' : 'Saint Martin', + //'MG' : 'Madagascar', + //'MH' : 'Marshall Islands', + 'MK': Lang.translate('country_mk'), + //'ML' : 'Mali', + 'MM': Lang.translate('country_mm'), + 'MN': Lang.translate('country_mn'), + 'MO': Lang.translate('country_mo'), + //'MP' : 'Northern Mariana Islands', + //'MQ' : 'Martinique', + //'MR' : 'Mauritania', + //'MS' : 'Montserrat', + 'MT': Lang.translate('country_mt'), + 'MU': Lang.translate('country_mu'), + 'MV': Lang.translate('country_mv'), + 'MW': Lang.translate('country_mw'), + 'MX': Lang.translate('country_mx'), + 'MY': Lang.translate('country_my'), + 'MZ': Lang.translate('country_mz'), + 'NA': Lang.translate('country_na'), + //'NC' : 'New Caledonia', + 'NE': Lang.translate('country_ne'), + //'NF' : 'Norfolk Island', + 'NG': Lang.translate('country_ng'), + 'NI': Lang.translate('country_ni'), + 'NL': Lang.translate('country_nl'), + 'NO': Lang.translate('country_no'), + 'NP': Lang.translate('country_np'), + //'NR' : 'Nauru', + //'NU' : 'Niue', + 'NZ': Lang.translate('country_nz'), + 'OM': Lang.translate('country_om'), + 'PA': Lang.translate('country_pa'), + 'PE': Lang.translate('country_pe'), + //'PF' : 'French Polynesia', + 'PG': Lang.translate('country_pg'), + 'PH': Lang.translate('country_ph'), + 'PK': Lang.translate('country_pk'), + 'PL': Lang.translate('country_pl'), + //'PM' : 'Saint Pierre And Miquelon', + //'PN' : 'Pitcairn', + 'PR': Lang.translate('country_pr'), + 'PS': Lang.translate('country_ps'), + 'PT': Lang.translate('country_pt'), + //'PW' : 'Palau', + 'PY': Lang.translate('country_py'), + 'QA': Lang.translate('country_qa'), + //'RE' : 'Reunion', + 'RO': Lang.translate('country_ro'), + 'RS': Lang.translate('country_rs'), + 'RU': Lang.translate('country_ru'), + 'RW': Lang.translate('country_rw'), + 'SA': Lang.translate('country_sa'), + //'SB' : 'Solomon Islands', + //'SC' : 'Seychelles', + 'SD': Lang.translate('country_sd'), + 'SE': Lang.translate('country_se'), + 'SG': Lang.translate('country_sg'), + //'SH' : 'Saint Helena', + 'SI': Lang.translate('country_si'), + //'SJ' : 'Svalbard And Jan Mayen', + 'SK': Lang.translate('country_sk'), + //'SL' : 'Sierra Leone', + //'SM' : 'San Marino', + 'SN': Lang.translate('country_sn'), + //'SO' : 'Somalia', + //'SR' : 'Suriname', + //'ST' : 'Sao Tome And Principe', + 'SU': Lang.translate('country_su'), + 'SV': Lang.translate('country_sv'), + 'SY': Lang.translate('country_sy'), + //'SZ' : 'Swaziland', + //'TC' : 'Turks And Caicos Islands', + //'TD' : 'Chad', + //'TF' : 'French Southern Territories', + //'TG' : 'Togo', + 'TH': Lang.translate('country_th'), + 'TJ': Lang.translate('country_tj'), + //'TK' : 'Tokelau', + //'TL' : 'Timor-Leste', + 'TM': Lang.translate('country_tm'), + 'TN': Lang.translate('country_tn'), + //'TO' : 'Tonga', + 'TR': Lang.translate('country_tr'), + //'TT' : 'Trinidad And Tobago', + //'TV' : 'Tuvalu', + 'TW': Lang.translate('country_tw'), + 'TZ': Lang.translate('country_tz'), + 'UA': Lang.translate('country_ua'), + 'UG': Lang.translate('country_ug'), + //'UM' : 'United States Outlying Islands', + 'US': Lang.translate('country_us'), + 'UY': Lang.translate('country_uy'), + 'UZ': Lang.translate('country_uz'), + //'VA' : 'Holy See (Vatican City State)', + //'VC' : 'Saint Vincent And Grenadines', + 'VE': Lang.translate('country_ve'), + //'VG' : 'Virgin Islands, British', + //'VI' : 'Virgin Islands, U.S.', + 'VN': Lang.translate('country_vn'), + //'VU' : 'Vanuatu', + //'WF' : 'Wallis And Futuna', + 'WS': Lang.translate('country_ws'), + 'YE': Lang.translate('country_ye'), + //'YT' : 'Mayotte', + 'YU': Lang.translate('country_yu'), + 'ZA': Lang.translate('country_za'), + 'ZM': Lang.translate('country_zm'), + 'ZW': Lang.translate('country_zw') + }; + return movie.production_countries ? movie.production_countries.map(function (a) { + //let cc = 'country_' + a.iso_3166_1.toLowerCase() + //return Lang.translate(cc) // FIXME! return a.name as fallback + if (iso_countries.hasOwnProperty(a.iso_3166_1)) { + return iso_countries[a.iso_3166_1]; + } else { + return a.name; + } + }) : ''; + } + + function getGenresNameFromIds(card_type, ids) { + var finded = []; + var where = genres$1[card_type]; + ids.forEach(function (a) { + var find = where.find(function (i) { + return i.id == a; + }); + if (find) finded.push(Utils$1.capitalizeFirstLetter(Lang.translate(find.title))); + }); + return finded; + } + + function clear$a() { + network$7.clear(); + } + + var TMDB = { + main: main$2, + menu: menu$3, + img: img$1, + full: full$3, + list: list$5, + category: category$3, + search: search$5, + clear: clear$a, + company: company$1, + person: person$2, + seasons: seasons$2, + find: find$2, + external_ids: external_ids, + get: get$c, + menuCategory: menuCategory$2, + discovery: discovery$2, + parsePG: parsePG, + parseCountries: parseCountries, + genres: genres$1, + keywords: keywords, + external_imdb_id: external_imdb_id, + getGenresNameFromIds: getGenresNameFromIds, + videos: videos + }; + + var Card$2 = { + onInit: function onInit() { + var _this = this; + + this.getPosterPath = function () { + var src = ''; + if (_this.params.style.name == 'wide' && _this.data.backdrop_path) src = TMDB.img(_this.data.backdrop_path, 'w780');else if (_this.params.style.name == 'collection' && _this.data.backdrop_path) src = TMDB.img(_this.data.backdrop_path, 'w500');else if (_this.data.poster_path) src = TMDB.img(_this.data.poster_path);else if (_this.data.profile_path) src = TMDB.img(_this.data.profile_path);else if (_this.data.poster) src = _this.data.poster;else if (_this.data.img) src = _this.data.img;else src = './img/img_broken.svg'; + return src; + }; + }, + onCreate: function onCreate() { + var _this2 = this, + _this$html$find; + + this.html = Template.js('card'); + this.img = this.html.find('.card__img') || {}; + this.img_errors = 0; + this.html.addClass('card--loaded'); + + this.img.onerror = function () { + var load_src = _this2.img.src; + console.log('Img', 'noload', load_src); + TMDB$1.broken(load_src); + _this2.img_errors++; + clearTimeout(_this2.img_timer); + + if (_this2.img_errors > 3) { + _this2.img.src = './img/img_broken.svg'; + $(_this2.img).after(Template.elem('div', { + "class": 'card__img-broken', + children: [Template.elem('div', { + children: [Template.elem('div', { + text: vpn.code().toUpperCase() + }), Template.elem('br'), Template.elem('div', { + text: load_src.split('?')[0] + })] + })] + })); + + _this2.img.onerror = function () {}; + } else { + _this2.img_timer_next = setTimeout(function () { + var next_src = _this2.getPosterPath(); + + if (next_src == load_src) _this2.img.onerror();else _this2.img.src = next_src; + }, 2000); + } + }; + + this.html.card_data = this.data; + (_this$html$find = this.html.find('.card__title')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.text(this.data.title || ''); + this.html.on('visible', this.emit.bind(this, 'visible')); + }, + onVisible: function onVisible() { + var _this3 = this; + + var src = this.getPosterPath(); + this.img_timer = setTimeout(function () { + _this3.img.onerror(); + }, 1000 * 15); + + this.img.onload = function () { + clearTimeout(_this3.img_timer); + clearTimeout(_this3.img_timer_next); + }; + + this.img.src = src; + this.emit('update'); + }, + onDestroy: function onDestroy() { + this.img.onerror = function () {}; + + this.img.onload = function () {}; + + clearTimeout(this.img_timer); + clearTimeout(this.img_timer_next); + this.img.src = ''; + } + }; + + var Folder = { + onCreate: function onCreate() { + this.html = Template.js('bookmarks_folder'); + this.html.find('.bookmarks-folder__title').text(Lang.translate('menu_' + this.data.media)); + this.html.find('.bookmarks-folder__num').text(this.data.results.length); + this.html.on('visible', this.emit.bind(this, 'visible')); + }, + onImage: function onImage(src, i) { + var _this = this; + + var img = Template.elem('img', { + "class": 'card__img i-' + i + }); + this.html.find('.bookmarks-folder__body').append(img); + Utils$1.imgLoad(img, src, function () { + _this.html.addClass('card--loaded'); + }, function () { + img.src = './img/img_broken.svg'; + }); + }, + onVisible: function onVisible() { + var _this2 = this; + + var filtred = this.data.results.filter(function (a) { + return a.poster_path; + }).slice(0, 3); + filtred.forEach(function (a, i) { + _this2.emit('image', TMDB.img(a.poster_path), i); + }); + if (filtred.length == 0) this.emit('image', './img/img_load.svg'); + } + }; + + var Icons = { + onCreate: function onCreate() { + var data = this.data; + + if (data.original_name) { + var _this$html$find; + + (_this$html$find = this.html.find('.card__view')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.append(Template.elem('div', { + "class": 'card__type', + text: data.original_name ? 'TV' : 'MOV' + })); + this.html.addClass(data.original_name ? 'card--tv' : 'card--movie'); + } + + var qu = data.quality || data.release_quality; + + if (qu && Storage.field('card_quality') && !data.original_name) { + var _this$html$find2; + + (_this$html$find2 = this.html.find('.card__view')) === null || _this$html$find2 === void 0 ? void 0 : _this$html$find2.append(Template.elem('div', { + "class": 'card__quality', + children: [Template.elem('div', { + text: qu + })] + })); + } + } + }; + + var Ratting = { + onCreate: function onCreate() { + var vote = parseFloat((this.data.cub_hundred_rating || this.data.vote_average || 0) + '').toFixed(1); + + if (vote > 0) { + this.html.find('.card__view').append(Template.elem('div', { + "class": 'card__vote', + text: this.data.cub_hundred_fire ? Utils$1.bigNumberToShort(this.data.cub_hundred_fire) : vote >= 10 ? 10 : vote + })); + } + } + }; + + var Release = { + onCreate: function onCreate() { + var release_year = ((this.data.release_date || this.data.birthday || '0000') + '').slice(0, 4); + + if (release_year == '0000') { + var _this$html$find; + + (_this$html$find = this.html.find('.card__age')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.remove(); + } else { + var _this$html$find2; + + (_this$html$find2 = this.html.find('.card__age')) === null || _this$html$find2 === void 0 ? void 0 : _this$html$find2.text(release_year); + } + } + }; + + var Favorite$1 = { + onCreate: function onCreate() { + var _this = this; + + var onCheck = function onCheck(a) { + Favorite.toggle(a.where, _this.data); + }; + + var onSelect = function onSelect(a) { + onCheck(a); + + _this.emit('menuSelect', a, _this.html, _this.data); + }; + + var onDraw = function onDraw(item) { + if (!Account$1.hasPremium()) { + var wrap = $('
    '); + wrap.append(Template.js('icon_lock')); + item.find('.selectbox-item__checkbox').remove(); + item.append(wrap); + item.on('hover:enter', function () { + Select.close(); + Account$1.showCubPremium(); + }); + } + }; + + function drawMenu() { + var status = Favorite.check(this.data); + var menu = []; + var items_check = ['book', 'like', 'wath', 'history']; + var items_mark = ['look', 'viewed', 'scheduled', 'continued', 'thrown']; + items_check.forEach(function (c) { + menu.push({ + title: Lang.translate('title_' + c), + where: c, + checkbox: true, + checked: status[c], + onCheck: onCheck + }); + }); + + if (window.lampa_settings.account_use) { + menu.push({ + title: Lang.translate('settings_cub_status'), + separator: true + }); + items_mark.forEach(function (m) { + menu.push({ + title: Lang.translate('title_' + m), + where: m, + picked: Account$1.hasPremium() ? status[m] : false, + collect: true, + noenter: !Account$1.hasPremium(), + onSelect: onSelect, + onDraw: onDraw + }); + }); + } + + return menu; + } + + this.menu_list.push({ + title: Lang.translate('settings_input_links'), + menu: drawMenu.bind(this) + }); + + this.listenerFavorite = function (e) { + if (e.target == 'favorite') { + if (e.card) { + if (e.card.id == _this.data.id) _this.emit('favorite'); + } else _this.emit('favorite'); + } + }; + + Lampa.Listener.follow('state:changed', this.listenerFavorite); + }, + onUpdate: function onUpdate() { + this.emit('favorite'); + }, + onAddicon: function onAddicon(name) { + this.html.find('.card__icons-inner').append(Template.elem('div', { + "class": 'card__icon icon--' + name + })); + }, + onFavorite: function onFavorite() { + var status = Favorite.check(this.data); + var marker = this.html.find('.card__marker'); + var marks = ['look', 'viewed', 'scheduled', 'continued', 'thrown']; + this.html.find('.card__icons-inner').innerHTML = ''; + if (status.book) this.emit('addicon', 'book'); + if (status.like) this.emit('addicon', 'like'); + if (status.wath) this.emit('addicon', 'wath'); + if (status.history || Timeline$1.watched(this.data)) this.emit('addicon', 'history'); + var any_marker = marks.find(function (m) { + return status[m]; + }); + + if (any_marker) { + if (!marker) { + marker = Template.elem('div', { + "class": 'card__marker', + children: [Template.elem('span')] + }); + this.html.find('.card__view').append(marker); + } + + marker.find('span').text(Lang.translate('title_' + any_marker)); + marker.removeClass(marks.map(function (m) { + return 'card__marker--' + m; + }).join(' ')).addClass('card__marker--' + any_marker); + } else if (marker) marker.remove(); + }, + onDestroy: function onDestroy() { + Lampa.Listener.remove('state:changed', this.listenerFavorite); + } + }; + + var Callback$1 = { + onCreate: function onCreate() { + this.html.on('hover:focus', this.emit.bind(this, 'focus', this.html, this.data)); + this.html.on('hover:touch', this.emit.bind(this, 'touch', this.html, this.data)); + this.html.on('hover:hover', this.emit.bind(this, 'hover', this.html, this.data)); + this.html.on('hover:enter', this.emit.bind(this, 'enter', this.html, this.data)); + this.html.on('hover:long', this.emit.bind(this, 'long', this.html, this.data)); + } + }; + + var Line$6 = { + onCreate: function onCreate() { + var _this = this; + + this.html = Template.js('season_episode', this.data); + this.prefix = Template.prefix(this.html, 'season-episode'); + + if (this.data.vote_average) { + this.prefix.info.append(Template.js('season_episode_rate', { + rate: parseFloat(this.data.vote_average + '').toFixed(1) + })); + } + + if (this.data.air_date) { + this.data.vote_average && this.prefix.info.append(Template.elem('span', { + "class": 'season-episode-split', + text: '●' + })); + this.prefix.info.append(Template.elem('span', { + text: Utils$1.parseTime(this.data.air_date).full + })); + } + + if (this.data.left_days) { + this.prefix.quality.text(this.data.left_text); + this.html.style.opacity = 0.5; + } + + var visible = function visible() { + _this.prefix.loader.remove(); + + _this.prefix.img.append(Template.elem('div', { + "class": 'season-episode__episode-number', + text: ('0' + _this.data.episode_number).slice(-2) + })); + }; + + this.prefix.timeline.append(Timeline$1.render(this.data.timeline)); + this.html.on('visible', function () { + var img = _this.html.find('img'); + + img.onerror = function () { + img.src = './img/img_broken.svg'; + }; + + img.onload = function () { + _this.prefix.img.addClass('season-episode__img--loaded'); + + visible(); + }; + + if (_this.data.still_path) img.src = TMDB.img('t/p/w300' + _this.data.still_path);else if (_this.data.img) img.src = _this.data.img;else visible(); + }); + }, + onViewed: function onViewed() { + var _this$html$find; + + (_this$html$find = this.html.find('.season-episode__viewed')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.remove(); + var mark = Template.elem('div', { + "class": 'season-episode__viewed', + children: [Template.js('icon_viewed')] + }); + if (Boolean(this.data.timeline.percent)) this.html.find('.season-episode__img').append(mark); + } + }; + + var Small = { + onCreate: function onCreate() { + var _this = this; + + this.html = Template.js('full_episode', this.data); + this.prefix = Template.prefix(this.html, 'full-episode'); + this.html.addClass('full-episode--small'); + this.html.append(Template.elem('div', { + "class": 'full-episode__viewed', + children: [Template.js('icon_viewed')] + })); + this.html.on('visible', function () { + var src = './img/img_broken.svg'; + if (_this.data.still_path) src = TMDB.img(_this.data.still_path, 'w300');else if (_this.data.img) src = _this.data.img; + Utils$1.imgLoad(_this.html.find('img'), src, function () { + _this.html.addClass('full-episode--loaded'); + }); + }); + }, + onViewed: function onViewed() { + this.html.toggleClass('full-episode--viewed', Boolean(this.data.timeline.percent)); + } + }; + + var SmallNext = { + onCreate: function onCreate() { + this.html = Template.js('full_episode', this.data); + this.html.addClass('full-episode--small full-episode--next'); + } + }; + + var Mark = { + onCreate: function onCreate() { + var _this = this; + + this.html.on('hover:enter', function () { + if (Boolean(_this.data.timeline.percent)) { + _this.data.timeline.time = 0; + _this.data.timeline.percent = 0; + } else { + _this.data.timeline.time = typeof _this.data.timeline.duration == 'number' ? _this.data.timeline.duration * 0.95 : 0; + _this.data.timeline.percent = 95; + } + + Timeline$1.update(_this.data.timeline); + + _this.emit('viewed'); + }); + this.emit('viewed'); + + this.listenerTimeline = function (e) { + if (e.target == 'timeline' && e.reason == 'update' && e.data.hash == _this.data.timeline.hash) { + for (var i in e.data.road) { + _this.data.timeline[i] = e.data.road[i]; + } + + _this.emit('viewed'); + } + }; + + Lampa.Listener.follow('state:changed', this.listenerTimeline); + }, + onDestroy: function onDestroy() { + Lampa.Listener.remove('state:changed', this.listenerTimeline); + } + }; + + var Card$1 = { + onInit: function onInit() { + this.card = this.data.card || {}; + }, + onCreate: function onCreate() { + var _this = this; + + this.html = Template.js('card_episode'); + this.img_poster = this.html.find('.card__img') || {}; + this.img_episode = this.html.find('.full-episode__img img') || {}; + + this.img_poster.onerror = function () { + _this.img_poster.src = './img/img_broken.svg'; + }; + + this.img_episode.onload = function () { + _this.html.find('.full-episode__img').addClass('full-episode__img--loaded'); + }; + + this.img_episode.onerror = function () { + _this.img_episode.src = './img/img_broken.svg'; + }; + + this.html.find('.card__title').text(this.card.title || this.card.name); + this.html.find('.full-episode__name').text(this.data.name || Lang.translate('noname')); + this.html.find('.full-episode__num').text(this.data.episode_number || ''); + this.html.find('.full-episode__date').text(this.data.air_date ? Utils$1.parseTime(this.data.air_date).full : '----'); + var release_year = ((this.card.release_date || this.card.first_air_date || '0000') + '').slice(0, 4); + + if (release_year == '0000') { + var _this$html$find; + + (_this$html$find = this.html.find('.card__age')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.remove(); + } else { + this.html.find('.card__age').text(release_year); + } + + this.html.on('visible', this.emit.bind(this, 'visible')); + }, + onVisible: function onVisible() { + if (this.card.poster_path) this.img_poster.src = TMDB.img(this.card.poster_path);else if (this.card.profile_path) this.img_poster.src = TMDB.img(this.card.profile_path);else if (this.card.poster) this.img_poster.src = this.card.poster;else if (this.card.img) this.img_poster.src = this.card.img;else this.img_poster.src = './img/img_broken.svg'; + if (this.data.still_path) this.img_episode.src = TMDB.img(this.data.still_path, 'w300');else if (this.card.backdrop_path) this.img_episode.src = TMDB.img(this.card.backdrop_path, 'w300');else if (this.data.img) this.img_episode.src = this.data.img;else this.img_episode.src = './img/img_broken.svg'; + }, + onDestroy: function onDestroy() { + this.img_poster.onerror = function () {}; + + this.img_poster.onload = function () {}; + + this.img_episode.onerror = function () {}; + + this.img_episode.onload = function () {}; + + this.img_poster.src = ''; + this.img_episode.src = ''; + } + }; + + var EpisodeMap = { + Line: Line$6, + Card: Card$1, + Small: Small, + SmallNext: SmallNext, + Mark: Mark, + Callback: Callback$1 + }; + + var Episode = /*#__PURE__*/function (_Constructor) { + _inherits(Episode, _Constructor); + + var _super = _createSuper(Episode); + + function Episode(data) { + var _this; + + _classCallCheck(this, Episode); + + _this = _super.call(this, data); + data.hash = Utils$1.hash([data.season_number, data.season_number > 10 ? ':' : '', data.episode_number, data.card ? data.card.original_name : data.original_name].join('')); + var out_air = new Date((data.air_date + '').replace(/-/g, '/')); + var out_now = Date.now(); + var out_day = data.air_date ? Math.round((out_air.getTime() - out_now) / (24 * 60 * 60 * 1000)) : 1; + data.left_days = out_day > 0 ? out_day : 0; + data.left_text = Lang.translate('full_episode_days_left') + ': ' + (data.air_date ? out_day : '- -'); + data.timeline = Timeline$1.view(data.hash); + data.time = Utils$1.secondsToTime(data.runtime * 60, true); + data.title = data.name || Lang.translate('torrent_serial_episode') + ' ' + data.episode_number; + data.date = data.air_date ? Utils$1.parseTime(data.air_date).full : '----'; + data.num = data.episode_number; + return _this; + } + + return Episode; + }(Constructor(EpisodeMap)); + + var Helper$a = new Mask(Arrays.getKeys(EpisodeMap)); + Helper$a.MASK.base = Helper$a.only('Mark'); + + var data$2 = []; + var object$1 = false; + var limit$3 = 300; + var time_recent = 1000 * 60 * 60 * 24 * 14; // 14 дней + + var time_favorites = 1000 * 60 * 10; + var time_extract = 1000 * 30; + var time_season = 1000 * 60 * 60 * 24 * 7; // 7 дней + + /** + * Запуск + */ + + function init$_() { + data$2 = Storage.cache('timetable', limit$3, []); + Timer.add(time_favorites, favorites); + Timer.add(time_extract, extract); // Добавляем поле ssn для хранения времени обновления сезонов + + data$2.forEach(function (a) { + a.ssn = a.ssn || 0; + }); // Обнуляем эпизоды, будем подгружать из db + + data$2.forEach(function (a) { + a.episodes = []; + }); + Lampa.Listener.follow('state:changed', function (e) { + if (e.target == 'favorite' && e.reason == 'update' && (e.method == 'add' || e.method == 'added') && e.type !== 'history') { + console.log('Timetable', 'favorite changed:', e.reason, e.type, e.card.id); + if (e.card.original_name && (e.card.source == 'tmdb' || e.card.source == 'cub')) update$a(e.card); + } + }); + Favorite.listener.follow('remove', function (e) { + if (e.card.original_name && e.method == 'id') { + var find = data$2.find(function (a) { + return a.id == e.card.id; + }); + + if (find) { + Arrays.remove(data$2, find); + saveData(); + Storage.remove('timetable', find.id); + } + } + }); + Lampa.Listener.follow('worker_storage', function (e) { + if (e.type == 'insert' && e.name == 'timetable') { + data$2 = Storage.get('timetable', '[]'); + } + }); // Начальный импорт из закладок + + favorites(); + loadEpisodes(); + ContentRows.add({ + name: 'timetable_lately', + title: Lang.translate('title_upcoming_episodes'), + index: 1, + screen: ['main', 'category'], + call: function call(params, screen) { + if (screen == 'category' && params.url == 'movie') return; + var results = lately().slice(0, 20); + if (!results.length) return; + return function (call) { + results.forEach(function (item) { + item.params = { + createInstance: function createInstance(item) { + return new Episode(item); + }, + module: Helper$a.only('Card', 'Callback'), + emit: { + onlyEnter: router.call.bind(router, 'full', item.card), + onlyFocus: function onlyFocus() { + Background.change(Utils$1.cardImgBackgroundBlur(item.card)); + } + } + }; + Arrays.extend(item, item.episode); + }); + call({ + results: results, + title: Lang.translate('title_upcoming_episodes') + }); + }; + } + }); + ContentRows.add({ + name: 'timetable_recently', + title: Lang.translate('title_recent_episodes'), + index: 1, + screen: ['main', 'category'], + call: function call(params, screen) { + if (screen == 'category' && params.url == 'movie') return; + var results = recently().slice(0, 20); + if (!results.length) return; + return function (call) { + results.forEach(function (item) { + item.params = { + createInstance: function createInstance(item) { + return new Episode(item); + }, + module: Helper$a.only('Card', 'Callback'), + emit: { + onlyEnter: router.call.bind(router, 'full', item.card), + onlyFocus: function onlyFocus() { + Background.change(Utils$1.cardImgBackgroundBlur(item.card)); + } + } + }; + Arrays.extend(item, item.episode); + }); + call({ + results: results, + title: Lang.translate('title_recent_episodes') + }); + }; + } + }); + } + /** + * Загрузить эпизоды из кеша + * @returns {void} + */ + + + function loadEpisodes() { + Cache.getData('timetable').then(function (all_data) { + if (all_data) { + all_data.forEach(function (obj) { + var find = data$2.find(function (d) { + return d.id == obj.id; + }); + if (find) find.episodes = obj.episodes || []; + }); + console.log('Timetable', 'load episodes from cache:', all_data.length); + } + })["catch"](function (e) { + console.log('Timetable', 'load episodes from cache error:', e.message); + }); + } + /** + * Добавить карточки к парсингу + * @param {[{id:integer,number_of_seasons:integer}]} elems - карточки + */ + + + function add$9(elems, log_type) { + var filtred = elems.filter(function (elem) { + return elem.original_name && typeof elem.id == 'number' && (elem.source == 'tmdb' || elem.source == 'cub'); + }); + console.log('Timetable', 'add:', elems.length, 'filtred:', filtred.length, 'type:', log_type || 'unknown'); + filtred.forEach(function (elem) { + var find = data$2.find(function (a) { + return a.id == elem.id; + }); + + if (!find) { + data$2.push({ + id: elem.id, + season: elem.number_of_seasons || 0, + episodes: [], + ssn: 0 + }); + } + }); + saveData(); + } + /** + * Сохранить данные без эпизодов + * @returns {void} + */ + + + function saveData() { + var clear_data = Arrays.clone(data$2); + clear_data.forEach(function (a) { + a.episodes = []; + }); + Storage.set('timetable', clear_data); + } + /** + * Добавить из закладок + */ + + + function favorites() { + var category = ['like', 'wath', 'book', 'look', 'viewed', 'scheduled', 'continued']; + category.forEach(function (a) { + add$9(Favorite.get({ + type: a + }), a); + }); + } + + function filter$1(episodes) { + var filtred = []; + var fileds = ['air_date', 'season_number', 'episode_number', 'name', 'still_path']; + episodes.forEach(function (episode) { + var item = {}; + fileds.forEach(function (field) { + if (typeof episode[field] !== 'undefined') item[field] = episode[field]; + }); + filtred.push(item); + }); + return filtred; + } + /** + * Парсим карточку + */ + + + function parse$a(to_database) { + var check = Favorite.check(object$1); + var any = Favorite.checkAnyNotHistory(check); + + if (any || to_database) { + // Если нет сезонов или давно не обновляли количество сезонов + if (!object$1.season || Date.now() - object$1.ssn > time_season) { + console.log('Timetable', 'parse:', object$1.id, 'old season:', object$1.season); + TMDB.get('tv/' + object$1.id, {}, function (json) { + object$1.season = Utils$1.countSeasons(json) || 1; + object$1.ssn = Date.now(); + parse$a(to_database); + }, save$3, { + life: 60 * 24 * 3 + }); + } else { + console.log('Timetable', 'parse:', object$1.id, 'new season:', object$1.season); + TMDB.get('tv/' + object$1.id + '/season/' + object$1.season, {}, function (ep) { + if (!ep.episodes) return save$3(); + object$1.episodes = filter$1(ep.episodes_original || ep.episodes); + object$1.next = getNextEpisode(object$1.episodes); + Cache.getData('timetable', object$1.id).then(function (obj) { + if (obj) obj.episodes = object$1.episodes;else obj = Arrays.clone(object$1); + Cache.rewriteData('timetable', object$1.id, obj).then(function () {})["catch"](function () {}); + Lampa.Listener.send('state:changed', { + target: 'timetable', + reason: 'parse', + id: object$1.id + }); + })["catch"](function (e) {}); + save$3(); + }, save$3, { + life: 60 * 24 * 3 + }); + } + } else { + console.log('Timetable', 'remove:', object$1.id, 'not in favorites anymore'); + Arrays.remove(data$2, object$1); + Storage.remove('timetable', object$1.id); + save$3(); + } + } + /** + * Получить следующий эпизод из списка + * @param {[{air_date:string}]} episodes - эпизоды + * @returns {object|boolean} + */ + + + function getNextEpisode(episodes) { + var now_date = new Date(); + now_date.setHours(0, 0, 0); + var now_time = now_date.getTime(); + var now_year = now_date.getFullYear(); + var nxt_year = now_year + 1; + var any = episodes.filter(function (ep) { + if (ep.air_date) { + if (ep.air_date.indexOf(now_year) === 0 || ep.air_date.indexOf(nxt_year) === 0) { + return Lampa.Utils.parseToDate(ep.air_date).getTime() >= now_time; + } + } + }); + return any.length ? any[0] : false; + } + /** + * Получить карточку для парсинга + */ + + + function extract() { + var ids = data$2.filter(function (e) { + return !e.scaned; + }); + console.log('Timetable', 'extract:', ids.length, 'total:', data$2.length); + + if (ids.length) { + object$1 = ids[0]; + parse$a(); + } else { + data$2.forEach(function (a) { + return a.scaned = 0; + }); + } + + saveData(); + } + /** + * Сохранить состояние + */ + + + function save$3() { + if (object$1) { + object$1.scaned = 1; + object$1.scaned_time = Date.now(); + saveData(); + } + } + /** + * Получить эпизоды для карточки если есть + * @param {{id:integer}} elem - карточка + * @returns {array} + */ + + + function get$b(elem, callback) { + var fid = data$2.filter(function (e) { + return e.id == elem.id; + }); + var res = (fid.length ? fid[0] : {}).episodes || []; + + if (typeof callback == 'function') { + if (res.length) return callback(res); + Cache.getData('timetable', elem.id).then(function (obj) { + callback(obj ? obj.episodes || [] : [], true); + })["catch"](function (e) { + callback(res, true); + }); + } else { + return res; + } + } + /** + * Добавить карточку в парсинг самостоятельно + * @param {{id:integer,number_of_seasons:integer}} elem - карточка + */ + + + function update$a(elem) { + if (elem.original_name && typeof elem.id == 'number' && (elem.source == 'tmdb' || elem.source == 'cub')) { + var check = Favorite.check(elem); + var any = Favorite.checkAnyNotHistory(check); + var id = data$2.filter(function (a) { + return a.id == elem.id; + }); + var item = { + id: elem.id, + season: elem.number_of_seasons ? Utils$1.countSeasons(elem) : 0, + episodes: [], + ssn: Date.now() + }; + + if (any) { + if (!id.length) { + console.log('Timetable', 'push:', elem.id); + data$2.push(item); + saveData(); + object$1 = item; + } else { + object$1 = id[0]; + object$1.season = elem.number_of_seasons ? Utils$1.countSeasons(elem) : object$1.season || 0; + } + + parse$a(); + } else { + object$1 = item; + parse$a(true); + } + } + } + /** + * Получить все данные + * @returns {[{id:integer,season:integer,episodes:[]}]} + */ + + + function all$3() { + return data$2; + } + + function lately() { + var fav = favoriteCards(); + var cards = []; + data$2.filter(function (d) { + return fav.find(function (c) { + return c.id == d.id; + }); + }).forEach(function (season) { + var episode = season.episodes.length ? getNextEpisode(season.episodes) : season.next; + + if (episode) { + // Проверка season.next на актуальность + if (Lampa.Utils.parseToDate(episode.air_date).getTime() >= Date.now()) { + cards.push({ + card: Arrays.clone(fav.find(function (c) { + return c.id == season.id; + })), + episode: episode, + time: Lampa.Utils.parseToDate(episode.air_date).getTime(), + season: season + }); + } + } + }); + cards = cards.sort(function (a, b) { + if (a.time > b.time) return 1;else if (a.time < b.time) return -1;else return 0; + }); + return cards; + } + + function recently() { + var fav = favoriteCards(); + var now = new Date(); + now.setHours(0, 0, 0, 0); + var now_time = now.getTime(); + var start_time = now_time - time_recent; + var cards = []; + data$2.filter(function (d) { + return fav.find(function (c) { + return c.id == d.id; + }); + }).forEach(function (season) { + if (!season.episodes || !season.episodes.length) return; + var card = Arrays.clone(fav.find(function (c) { + return c.id == season.id; + })); + season.episodes.forEach(function (episode) { + if (!episode.air_date) return; + var air_time = Utils$1.parseToDate(episode.air_date).getTime(); + + if (air_time >= start_time && air_time <= now_time) { + var viewed = Timeline$1.watchedEpisode(card, episode.season_number, episode.episode_number); + + if (viewed < 60) { + cards.push({ + card: card, + episode: episode, + viewed: viewed, + time: air_time, + season: season + }); + } + } + }); + }); + cards = cards.sort(function (a, b) { + if (a.time > b.time) return -1;else if (a.time < b.time) return 1;else return 0; + }); + return cards; + } + + function favoriteCards() { + var fav = Favorite.full().card; + if (Account$1.Permit.sync) fav = Account$1.Bookmarks.all(); + fav = fav.filter(function (f) { + return f.original_name && (f.source == 'tmdb' || f.source == 'cub'); + }); + return fav; + } + + var TimeTable = { + init: init$_, + get: get$b, + add: add$9, + all: all$3, + update: update$a, + lately: lately, + recently: recently + }; + + var Watched = { + onCreate: function onCreate() { + var _this = this; + + var timer; + this.html.on('hover:focus hover:touch hover:hover', function () { + clearTimeout(timer); + timer = setTimeout(function () { + _this.html.classList.contains('focus') && _this.emit('watched'); + }, 500); + }); + + this.listenerWatched = function (e) { + if (e.target == 'timeline' && e.reason == 'read' || e.target == 'timetable' && e.id == _this.data.id) _this.emit('update'); + }; + + Lampa.Listener.follow('state:changed', this.listenerWatched); + }, + onUpdate: function onUpdate() { + var _this$watched_wrap; + + this.watched_checked = false; + (_this$watched_wrap = this.watched_wrap) === null || _this$watched_wrap === void 0 ? void 0 : _this$watched_wrap.remove(); + this.html.classList.contains('focus') && this.emit('watched'); + }, + onWatched: function onWatched() { + var _this2 = this; + + if (!Storage.field('card_episodes')) return; + + if (!this.watched_checked) { + var get = function get(callback) { + if (data.original_name) TimeTable.get(data, callback);else callback([]); + }; + + var data = this.data; + get(function (episodes, from_db) { + var viewed; // Нужно разбить 1й сезон на сезоны и взять последний сезон + + if (episodes[0] && episodes[0].season_number == 1) { + var seasons = Utils$1.splitEpisodesIntoSeasons(episodes); + episodes = seasons[Object.keys(seasons).pop()]; + } + + var Draw = function Draw() { + episodes.forEach(function (ep) { + var hash = Utils$1.hash([ep.season_number, ep.season_number > 10 ? ':' : '', ep.episode_number, data.original_title].join('')); + var view = Timeline$1.view(hash); + if (view.percent) viewed = { + ep: ep, + view: view + }; + }); // Пытаемся найти последний просмотренный из истории последнего просмотра + + if (!viewed && data.original_name) { + var last = Storage.get('online_watched_last', '{}'); + var filed = last[Utils$1.hash(data.original_title)]; + + if (filed && filed.episode) { + viewed = { + ep: { + episode_number: filed.episode, + name: Lang.translate('full_episode') + ' ' + filed.episode + }, + view: Timeline$1.view(Utils$1.hash([filed.season, filed.season > 10 ? ':' : '', filed.episode, data.original_title].join(''))) + }; + } + } // Если это фильм и не нашли просмотренное, то проверим по прогрессу просмотра из таймлайна + + + if (!viewed && !data.original_name) { + var time = Timeline$1.watched(data, true); + + if (time.percent) { + viewed = { + ep: { + name: Lang.translate('title_viewed') + ' ' + (time.time ? Utils$1.secondsToTimeHuman(time.time) : time.percent + '%') + }, + view: time + }; + } + } // Если это сериал и не нашли просмотренное, то проверим по прогрессу просмотра из таймлайна + + + if (!viewed && data.original_name) { + var any = Timeline$1.watched(data, true).pop(); + if (any) viewed = { + ep: { + name: Lang.translate('full_episode') + ' ' + any.ep + }, + view: any.view + }; + } + + if (viewed) { + var soon = []; + var start = episodes.indexOf(viewed.ep); // Эпизод из истории или из таймлайна не входит в список последнего сезона + + var next = (start >= 0 ? episodes.slice(start) : []).filter(function (ep) { + return ep.air_date; + }).filter(function (ep) { + var date = Utils$1.parseToDate(ep.air_date).getTime(); + if (date > Date.now()) soon.push(ep); + return date < Date.now(); + }).slice(0, 5); + if (next.length == 0) next = [viewed.ep]; + if (soon.length && next.length < 5 && !next.find(function (n) { + return n.episode_number == soon[0].episode_number; + })) next.push(soon[0]); + var wrap = Template.js('card_watched', {}); + next.forEach(function (ep) { + var div = document.createElement('div'); + var span = document.createElement('span'); + var date = Utils$1.parseToDate(ep.air_date); + var now = Date.now(); + var days = Math.ceil((date.getTime() - now) / (24 * 60 * 60 * 1000)); + div.addClass('card-watched__item'); + div.append(span); + span.innerText = (ep.episode_number ? ep.episode_number + ' - ' : '') + (days > 0 ? Lang.translate('full_episode_days_left') + ': ' + days : ep.name || Lang.translate('noname')); + if (ep == viewed.ep) div.append(Timeline$1.render(viewed.view)[0]); + wrap.find('.card-watched__body').append(div); + }); + _this2.watched_wrap = wrap; + + var view = _this2.html.find('.card__view'); + + view.insertBefore(wrap, view.firstChild); + } + }; + + Draw(); + }); + this.watched_checked = true; + } + }, + onDestroy: function onDestroy() { + Lampa.Listener.remove('state:changed', this.listenerWatched); + } + }; + + var Style = { + onCreate: function onCreate() { + if (this.params.style.name == 'collection') { + var _this$html$find; + + this.html.addClass('card--collection'); + (_this$html$find = this.html.find('.card__age')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.remove(); + } + + if (this.params.style.name == 'wide') { + var _this$html$find2, _this$html$find3; + + (_this$html$find2 = this.html.find('.card__title')) === null || _this$html$find2 === void 0 ? void 0 : _this$html$find2.remove(); + (_this$html$find3 = this.html.find('.card__age')) === null || _this$html$find3 === void 0 ? void 0 : _this$html$find3.remove(); + this.html.addClass('card--wide'); + this.data.poster = this.data.cover; + var promo_wrap = Template.elem('div', { + "class": 'card__promo' + }); + + if (this.data.title || this.data.name) { + promo_wrap.append(Template.elem('div', { + "class": 'card__promo-title', + text: this.data.title || this.data.name + })); + } + + if (this.data.overview) { + promo_wrap.append(Template.elem('div', { + "class": 'card__promo-text', + text: this.data.overview.slice(0, 110) + (this.data.overview.length > 110 ? '...' : '') + })); + } + + this.html.find('.card__view').append(promo_wrap); + } + } + }; + + var html$g = null; + /** + * Показать подсказку по управлению + * @param {Object} params - Параметры + * @param {string} params.name - Имя для кеша + * @param {string} params.text - Текст подсказки + * @param {string} params.button - Кнопка для подсветки (ok, up, down, left, right) + * @param {number} params.interval - Интервал показа в минутах (по умолчанию 7 дней) + * @return {void} + */ + + function show$7() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + if (html$g || !Platform.tv()) return; + Arrays.extend(params, { + name: 'none', + text: Lang.translate('remote_helper_long'), + button: 'ok', + interval: 60 * 24 * 7 // week + + }); + var cached_time = Storage.get('remote_helper', '{}'); + if (cached_time[params.name] && cached_time[params.name] + 1000 * 60 * params.interval > Date.now()) return; + html$g = Template.js('remote_helper', params); + html$g.addClass('highlight--' + params.button); + document.body.appendChild(html$g); + setTimeout(function () { + html$g.addClass('active'); + setTimeout(function () { + html$g.removeClass('active'); + setTimeout(function () { + html$g.remove(); + html$g = null; + }, 500); + }, 10000); + }, 10); + Storage.set('remote_helper', _objectSpread2(_objectSpread2({}, cached_time), {}, _defineProperty({}, params.name, Date.now()))); + } + + var RemoteHelper = { + show: show$7 + }; + + var Menu = { + onInit: function onInit() { + this.menu_list = []; + }, + onCreate: function onCreate() { + var _this = this; + + this.html.on('hover:long', function () { + var enabled = Controller.enabled().name; + var menu = []; + + _this.menu_list.forEach(function (item, i) { + i !== 0 && menu.push({ + title: item.title, + separator: true + }); + menu = menu.concat(item.menu()); + }); + + if (!menu.length) return; + + _this.emit('menu', menu, _this.html, _this.data); + + Select.show({ + title: Lang.translate('title_action'), + items: menu, + onBack: function onBack() { + Controller.toggle(enabled); + }, + onBeforeClose: function onBeforeClose() { + Controller.toggle(enabled); + return true; + } + }); + }); + this.html.on('hover:focus', function () { + if (window.app_time_end < Date.now() - 20000) RemoteHelper.show({ + name: 'card_menu' + }); + }); + } + }; + + var Plugins$1 = { + onCreate: function onCreate() { + function drawMenu() { + var _this = this; + + var menu = []; + object$2.plugins.forEach(function (plugin) { + if (plugin.type == 'video' && plugin.onContextMenu && plugin.onContextLauch) { + menu.push({ + title: plugin.name, + subtitle: plugin.subtitle || plugin.description, + onSelect: function onSelect() { + if (!_this.data.imdb_id && _this.data.source == 'tmdb') { + Loading$1.start(function () { + Loading$1.stop(); + Controller.toContent(); + }); + TMDB.external_imdb_id({ + type: _this.data.name ? 'tv' : 'movie', + id: _this.data.id + }, function (imdb_id) { + Loading$1.stop(); + _this.data.imdb_id = imdb_id; + plugin.onContextLauch(_this.data); + }); + } else plugin.onContextLauch(_this.data); + } + }); + } + }); + return menu; + } + + this.menu_list.push({ + title: Lang.translate('settings_main_plugins'), + menu: drawMenu.bind(this) + }); + } + }; + + var Subscribe = { + onCreate: function onCreate() { + if (this.data.subscribe) { + var data = this.data.subscribe; + var sube = Template.elem('div', { + "class": 'card__subscribe', + children: [Template.elem('div', { + "class": 'card__subscribe-status ' + (data.status ? 'on' : 'off') + }), Template.elem('div', { + "class": 'card__subscribe-position', + text: 'S' + data.season + ' E' + data.episode + }), Template.elem('div', { + "class": 'card__subscribe-voice', + text: data.voice + })] + }); + this.html.find('.card__view').after(sube); + } + } + }; + + var Lgbt = { + onVisible: function onVisible() { + var lgbt_block = Storage.field('lgbt_content_block') || vpn.is(['ru', 'by']); + var lgbt_key = this.data.id + '_' + (this.data.first_air_date ? 'tv' : 'movie'); + var img = this.html.find('.card__img'); + + if (img && lgbt_block && window.lampa_settings.lgbt && window.lampa_settings.lgbt[lgbt_key]) { + var pattern = Color.circlePattern(20); + var layer = Template.elem('div', { + "class": 'card__filter' + }); + layer.style.backgroundImage = 'url(' + pattern + ')'; + img.after(layer); + } + } + }; + + var CardMap = { + Card: Card$2, + Folder: Folder, + Icons: Icons, + Ratting: Ratting, + Release: Release, + Plugins: Plugins$1, + Favorite: Favorite$1, + Watched: Watched, + Lgbt: Lgbt, + Subscribe: Subscribe, + Style: Style, + Menu: Menu, + Callback: Callback$1 + }; + + var Helper$9 = new Mask(Arrays.getKeys(CardMap)); + Helper$9.MASK.base = Helper$9.toggle(Helper$9.MASK.all, 'Folder', 'Subscribe'); + + var data$1 = {}; + var listener$b = Subscribe$2(); + var category$2 = ['like', 'wath', 'book', 'history', 'look', 'viewed', 'scheduled', 'continued', 'thrown']; + var marks = ['look', 'viewed', 'scheduled', 'continued', 'thrown']; + /** + * Запуск + */ + + function init$Z() { + read$1(); + ContentRows.add({ + name: 'continue_watch', + title: Lang.translate('title_continue'), + index: 1, + screen: ['main', 'category'], + call: function call(params, screen) { + var media = screen == 'main' ? 'tv' : params.url; + var results = continues(media); + if (!results.length) return; + return function (call) { + // Смотрим есть ли новые серии с переводом + if (media == 'tv' || media == 'anime') { + var cub_notices = Notice$1.get('cub').items(); + cub_notices = cub_notices.filter(function (n) { + return n.item.method == 'tv-voice'; + }); // Получаем из истории только те карточки которые есть в уведомлениях + + var history = get$a({ + type: 'history' + }).filter(function (h) { + return cub_notices.find(function (n) { + return n.item.card_id == h.id; + }); + }); // Фильтруем только те карточки у которых есть новые серии + + var new_episode = history.map(function (h) { + var noty = cub_notices.find(function (n) { + return n.item.card_id == h.id; + }); + var card = Arrays.clone(h); + card.params = { + module: Helper$9.toggle(Helper$9.MASK.base, 'Subscribe') + }; + card.subscribe = { + status: 1, + season: noty.item.season, + episode: noty.item.episode, + voice: noty.data.voice + }; + card.viewed = Timeline$1.watchedEpisode(h, noty.item.season, noty.item.episode); + return card; + }); // Оставляем только те у которых просмотр меньше 10% + + new_episode = new_episode.filter(function (n) { + return n.viewed < 10; + }); + new_episode = new_episode.filter(function (e) { + var jpan = Utils$1.containsJapanese(e.original_name || e.name || '') || e.original_language == 'ja'; + return media == 'anime' ? jpan : !jpan; + }); + + if (new_episode.length) { + // Убираем из основного списка карточки у которых есть новые серии + results = results.filter(function (r) { + return !new_episode.find(function (h) { + return h.id == r.id; + }); + }); + results = [].concat(new_episode, results); // Оставляем не более 20 карточек + + results = results.slice(0, 19); + } + } + + call({ + results: results, + title: media == 'tv' || media == 'anime' ? Lang.translate('title_continue') : Lang.translate('title_watched') + }); + }; + } + }); + } + /** + * Сохранить + */ + + + function save$2() { + Storage.set('favorite', data$1); + } + /** + * Добавить + * @param {String} where + * @param {Object} card + */ + + + function add$8(where, card, limit) { + if (Account$1.Permit.sync) { + listener$b.send('add', { + where: where, + card: card + }); + } else { + var find = data$1[where].find(function (id) { + return id == card.id; + }); + + if (!find) { + Arrays.insert(data$1[where], 0, card.id); + listener$b.send('add', { + where: where, + card: card + }); + if (!search$4(card.id)) data$1.card.push(Utils$1.clearCard(Arrays.clone(card))); + + if (limit) { + var excess = data$1[where].slice(limit); + + for (var i = excess.length - 1; i >= 0; i--) { + remove$2(where, { + id: excess[i] + }); + } + } + + save$2(); + } else { + Arrays.remove(data$1[where], card.id); + Arrays.insert(data$1[where], 0, card.id); + save$2(); + listener$b.send('added', { + where: where, + card: card + }); + } + + Lampa.Listener.send('state:changed', { + target: 'favorite', + reason: 'update', + method: !find ? 'add' : 'added', + type: where, + card: card + }); + } + } + /** + * Удалить + * @param {String} where + * @param {Object} card + */ + + + function remove$2(where, card) { + if (Account$1.Permit.sync) { + listener$b.send('remove', { + where: where, + card: card, + method: 'id' + }); + } else { + Arrays.remove(data$1[where], card.id); + listener$b.send('remove', { + where: where, + card: card, + method: 'id' + }); + + for (var i = data$1.card.length - 1; i >= 0; i--) { + var element = data$1.card[i]; + + if (!check$3(element).any) { + Arrays.remove(data$1.card, element); + listener$b.send('remove', { + where: where, + card: element, + method: 'card' + }); + } + } + + save$2(); + Lampa.Listener.send('state:changed', { + target: 'favorite', + reason: 'update', + method: 'remove', + type: where, + card: card + }); + } + } + /** + * Найти + * @param {integer} id + * @returns Object + */ + + + function search$4(id) { + var found; + + for (var index = 0; index < data$1.card.length; index++) { + var element = data$1.card[index]; + + if (element.id == id) { + found = element; + break; + } + } + + return found; + } + /** + * Переключить + * @param {String} where + * @param {Object} card + */ + + + function toggle$6(where, card) { + var find = cloud(card); + + if (marks.find(function (a) { + return a == where; + })) { + var added = marks.find(function (a) { + return find[a]; + }); + if (added && added !== where) remove$2(added, card); + } + + if (find[where]) remove$2(where, card);else add$8(where, card); + return find[where] ? false : true; + } + /** + * Проверить + * @param {Object} card + * @returns Object + */ + + + function check$3(card) { + var result = { + any: false + }; + category$2.forEach(function (a) { + result[a] = data$1[a].find(function (id) { + return id == card.id; + }); + if (result[a]) result.any = true; + }); + return result; + } + /** + * Проверить есть ли карточка где либо кроме истории + * @param {Object} status + * @returns {Boolean} + */ + + + function checkAnyNotHistory(status) { + var any = false; + category$2.filter(function (a) { + return a !== 'history'; + }).forEach(function (a) { + if (status[a]) any = true; + }); + return any; + } + /** + * Облако, закладки из cub + * @param {Object} card + * @returns {Object} + */ + + + function cloud(card) { + if (Account$1.Permit.sync) { + var result = { + any: false + }; + category$2.forEach(function (a) { + result[a] = Boolean(Account$1.Bookmarks.find({ + type: a, + id: card.id + })); + if (result[a]) result.any = true; + }); + return result; + } else return check$3(card); + } + /** + * Получить списаок по типу + * @param {String} params.type - тип + * @returns Object + */ + + + function get$a(params) { + if (Account$1.Permit.sync) { + return Account$1.Bookmarks.get(params); + } else { + var result = []; + var ids = data$1[params.type]; + ids.forEach(function (id) { + for (var i = 0; i < data$1.card.length; i++) { + var card = data$1.card[i]; + if (card.id == id) result.push(card); + } + }); + return result; + } + } + /** + * Очистить + * @param {String} where + * @param {Object} card + */ + + + function clear$9(where, card) { + if (Account$1.Permit.sync) { + Account$1.Bookmarks.clear(where); + } else { + if (card) remove$2(where, card);else { + for (var i = data$1[where].length - 1; i >= 0; i--) { + var _card = search$4(data$1[where][i]); + + if (_card) remove$2(where, _card); + } + } + } + } + /** + * Считать последние данные + * @param {Boolean} nolisten - не посылать событие изменения состояния + */ + + + function read$1() { + var nolisten = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + data$1 = Storage.get('favorite', '{}'); + var empty = { + card: [] + }; + category$2.forEach(function (a) { + empty[a] = []; + }); + Arrays.extend(data$1, empty); + if (nolisten) return; + Lampa.Listener.send('state:changed', { + target: 'favorite', + reason: 'read' + }); + } + /** + * Получить весь список что есть + */ + + + function full$2() { + var empty = { + card: [] + }; + category$2.forEach(function (a) { + empty[a] = []; + }); + Arrays.extend(data$1, empty); + return data$1; + } + + function all$2() { + var result = {}; + category$2.forEach(function (a) { + result[a] = get$a({ + type: a + }); + }); + return result; + } + + function continues(type) { + var result = get$a({ + type: 'history' + }); + var viewed = get$a({ + type: 'viewed' + }); + var thrown = get$a({ + type: 'thrown' + }); // Убираем из продолжить то что уже полностью просмотрено + + result = result.filter(function (e) { + return !viewed.find(function (v) { + return v.id == e.id; + }) && !thrown.find(function (t) { + return t.id == e.id; + }); + }); + result = result.filter(function (e) { + var is_tv = e.number_of_seasons || e.first_air_date; + var jpan = e.original_language == 'ja'; + if (type == 'anime') return is_tv && (Utils$1.containsJapanese(e.original_name || e.name || '') || jpan);else if (type == 'tv') return is_tv && !(Utils$1.containsJapanese(e.original_name || e.name || '') || jpan);else return !is_tv; + }); + return Arrays.clone(result.slice(0, 19)); + } + + var Favorite = { + listener: listener$b, + init: Utils$1.onceInit(init$Z), + check: cloud, + add: add$8, + remove: remove$2, + toggle: toggle$6, + get: get$a, + clear: clear$9, + continues: continues, + full: full$2, + checkAnyNotHistory: checkAnyNotHistory, + all: all$2, + read: read$1 + }; + + var Listener$1 = Subscribe$2(); + + var html$f; + var destroyed = false; + /** + * Отображает прогресс загрузки приложения + * @returns {void} + */ + + function init$Y() { + html$f = $("
    \n
    \n
    \n
    "); + $('body').append(html$f); + step(0); + } + /** + * Обновляет шаг загрузки + * @param {number} position - номер шага + */ + + + function step(position) { + if (destroyed) return; + html$f.find('.lp-step').text(Lang.translate('loading_progress_step_' + position)); + console.log('LoadingProgress', 'step:', position, Lang.translate('loading_progress_step_' + position)); + } + /** + * Обновляет статус загрузки + * @param {string} text - текст статуса + */ + + + function status$1(text) { + if (destroyed) return; + html$f.find('.lp-status').text(text); + console.log('LoadingProgress', 'status:', text); + } + /** + * Удаляет прогресс загрузки + * @returns {void} + */ + + + function destroy$b() { + destroyed = true; + html$f.remove(); + } + + var LoadingProgress = { + init: init$Y, + step: step, + status: status$1, + destroy: destroy$b + }; + + var bookmarks = []; // имеет вид [{id, cid, card_id, type, data, profile, time},...] + + var bookmarks_map = {}; // имеет вид {type: {card_id: bookmark, ...}, ...} + + var tracker_name = 'account_bookmarks_sync'; + var tracker_data = { + version: 0, + time: 0 + }; + var update_timer; + var push_queue = []; + var push_running = false; + + function processQueue() { + if (push_running || push_queue.length === 0) return; + push_running = true; + + var _push_queue$shift = push_queue.shift(), + method = _push_queue$shift.method, + type = _push_queue$shift.type, + card = _push_queue$shift.card; + + var find = bookmarks.find(function (elem) { + return elem.card_id == card.id && elem.type == type; + }); + Api$1.load('bookmarks/' + method, {}, { + type: type, + data: JSON.stringify(Utils$1.clearCard(Arrays.clone(card))), + card_id: card.id, + id: find ? find.id : 0 + }).then(function () { + clearTimeout(update_timer); + update_timer = setTimeout(function () { + update$9(function () { + Socket.send('bookmarks', {}); + Lampa.Listener.send('state:changed', { + target: 'favorite', + reason: 'update', + method: method, + card: card, + type: type + }); + }); + }, 500); + })["catch"](function () { + console.warn('Account', 'bookmarks ' + method + ' fail'); + })["finally"](function () { + push_running = false; + processQueue(); + }); + } + /** + * Запуск + * @return {void} + */ + + + function init$X() { + Favorite.listener.follow('add,added', function (e) { + push$7('add', e.where, e.card); + }); + Favorite.listener.follow('remove', function (e) { + if (e.method == 'id') push$7('remove', e.where, e.card); + }); + Storage.listener.follow('change', function (e) { + if (e.name == 'protocol' || e.name == 'account_use' && e.value == 'true') update$9(function () { + Lampa.Listener.send('state:changed', { + target: 'favorite', + reason: 'read' + }); + }); + }); + Listener$1.follow('profile_select', function () { + bookmarks = []; + bookmarks_map = {}; // Сбрасываем трекер чтобы при смене профиля сразу получить дамп закладок + + tracker_data.time = 0; + tracker_data.version = 0; + Cache.rewriteData('other', tracker_name, tracker_data)["catch"](function (e) { + console.log('Account', 'bookmarks tracker cache not reset', e.message); + })["finally"](function () { + update$9(function () { + Lampa.Listener.send('state:changed', { + target: 'favorite', + reason: 'profile' + }); + }); + }); + }); + Timer.add(1000 * 60 * 5, function () { + update$9(); + }); + } + /** + * Добавить/Удалить закладку + * @param {String} method - add/remove + * @param {String} type - тип закладки + * @param {Object} card - карточка + * @return {void} + */ + + + function push$7(method, type, card) { + if (permit.sync) { + push_queue.push({ + method: method, + type: type, + card: card + }); + processQueue(); + } + } + /** + * Сохранение закладок в кэш + * @param {number} version - версия закладок на сервере + * @return {void} + */ + + + function saveToCache(version) { + Cache.rewriteData('other', 'account_bookmarks_' + permit.account.profile.id, bookmarks).then(function () { + tracker_data.version = version; + tracker_data.time = Date.now(); + Cache.rewriteData('other', tracker_name, tracker_data)["catch"](function (e) {}); + })["catch"](function (e) { + console.log('Account', 'bookmarks cache not saved', e.message); + }); + } + /** + * Загрузка закладок из кэша + * @param {function} call - вызов по окончании + * @return {void} + */ + + + function loadFromCache(call) { + if (bookmarks.length) return call && call(); + Cache.getData('other', 'account_bookmarks_' + permit.account.profile.id).then(function (data) { + bookmarks = data && data.length ? data : []; + console.log('Account', 'bookmarks cache load:', bookmarks.length, 'data:', data ? 'yes' : 'no'); + createMap(); + if (call) call(); + })["catch"](function () { + console.log('Account', 'bookmarks cache not load'); + if (call) call(); + }); + } + + function loadTrackerData(call) { + Cache.getDataAnyCase('other', tracker_name).then(function (data) { + if (data) { + tracker_data.version = data.version || 0; + tracker_data.time = data.time || 0; + } + + if (call) call(); + })["catch"](function () { + if (call) call(); + }); + } + /** + * Загрузка и обновление закладок + * @param {function} call - вызов по окончании + * @return {void} + */ + + + function update$9(call) { + if (permit.sync) { + console.log('Account', 'sync enabled, updating bookmarks'); + LoadingProgress.status('Bookmarks start sync'); + loadTrackerData(function () { + // Если с момента последнего обновления прошло больше 15 дней, то загружаем дамп + if (tracker_data.time < Date.now() - 1000 * 60 * 60 * 24 * 15) { + console.log('Account', 'bookmarks start full update', tracker_data.version); + LoadingProgress.status('Bookmarks loading full dump'); + Api$1.load('bookmarks/dump', { + dataType: 'text' + }).then(function (result) { + LoadingProgress.status('Bookmarks parsing dump'); // !!! WebWorker почему-то зависает на телевизорах и вылетает, пока без него + // Парсим текст в массив закладок + // WebWorker.json({ + // type: 'parse', + // data: result + // },(e)=>{ + + console.log('Account', 'bookmarks dump load complete, size:', result.length); + var e = { + data: Arrays.decodeJson(result, {}) + }; + + if (!e.data.bookmarks) { + console.error('Account', 'bookmarks wrong dump format', Utils$1.shortText(result, 300)); + if (call && typeof call == 'function') call(); + return; + } + + console.log('Account', 'bookmarks full update complete, total:', e.data.bookmarks.length); // Переводим строки с .data в объект, обновляем локальный кэш и карту + + rawToCard(e.data.bookmarks, function () { + saveToCache(e.data.version); + if (call && typeof call == 'function') call(); + }); //}) + })["catch"](function (e) { + LoadingProgress.status('Bookmarks no dump load, trying cache'); + console.error('Account', 'bookmarks full update fail, trying load from cache:', 'message', e.message); + loadFromCache(function () { + if (call && typeof call == 'function') call(); + }); + }); + } // Иначе получаем только изменения с последней версии + else { + console.log('Account', 'bookmarks start update since', tracker_data.version); + LoadingProgress.status('Bookmarks load from cache'); + loadFromCache(function () { + LoadingProgress.status('Bookmarks loading changelog'); + Api$1.load('bookmarks/changelog?since=' + tracker_data.version).then(function (result) { + LoadingProgress.status('Bookmarks applying changelog'); + result.changelog.forEach(function (change) { + if (change.action == 'remove') { + var _find = bookmarks.find(function (book) { + return book.id == change.entity_id; + }); + + if (_find) Arrays.remove(bookmarks, _find); + } else if (change.action == 'update') { + var _find2 = bookmarks.find(function (book) { + return book.id == change.entity_id; + }); + + if (_find2) { + _find2.time = change.updated_at; + Arrays.remove(bookmarks, _find2); + Arrays.insert(bookmarks, 0, _find2); + } + } else if (change.action == 'add') { + if (change.data) { + change.data = Utils$1.clearCard(Arrays.decodeJson(change.data, {})); // Если закладка уже есть, то обновляем время и двигаем ее в начало, иначе просто добавляем + // !!! Надеюсь это избавит от бага с дублированием закладок при обновлении + + var _find3 = bookmarks.find(function (book) { + return book.id == change.entity_id; + }); + + if (_find3) { + _find3.time = change.updated_at; + Arrays.remove(bookmarks, _find3); + Arrays.insert(bookmarks, 0, _find3); + } else { + Arrays.insert(bookmarks, 0, change); + } + } + } else if (change.action == 'clear') { + var filter = bookmarks.filter(function (book) { + return book.type == change.entity_id; + }); + filter.forEach(function (book) { + return Arrays.remove(bookmarks, book); + }); + } + }); // Сохраняем обновленные закладки в кэш + + saveToCache(result.version); // Обновляем карту + + createMap(); // Обновляем каналы на андроид тв + + updateChannels(); + console.log('Account', 'bookmarks update complete to version', result.version, 'changes:', result.changelog.length, 'total:', bookmarks.length); + if (call && typeof call == 'function') call(); + })["catch"](function () { + console.warn('Account', 'bookmarks update since fail'); + if (call && typeof call == 'function') call(); + }); + }); + } + }); + } else { + console.log('Account', 'sync disabled'); + rawToCard([], function () { + if (call && typeof call == 'function') call(); + }); + } + } + /** + * Очистка закладок + * @param {string} where - группа закладок для очистки + * @return {void} + */ + + + function clear$8(where) { + if (permit.sync) { + Api$1.load('bookmarks/clear', {}, { + type: 'group', + group: where + }).then(function () { + update$9(function () { + // Оповещаем другие устройства о изменении закладок + Socket.send('bookmarks', {}); // Глобальное оповещение об изменении закладок для обновления карточек + + Lampa.Listener.send('state:changed', { + target: 'favorite', + reason: 'clear', + type: where + }); + }); + })["catch"](function () { + console.warn('Account', 'bookmarks clear fail'); + }); + } + } + /** + * Получить закладки по типу + * @param {object} params - {type} + * @return {array} - [card, ...] + */ + + + function get$9(params) { + return bookmarks.filter(function (elem) { + return elem.type == params.type; + }).map(function (elem) { + return elem.data; + }); + } + /** + * Найти закладку по типу и id + * @param {object} params - {type, id} + * @return {object|null} - card или null + */ + + + function find$1(params) { + var _bookmarks_map$params; + + return bookmarks_map[params.type] ? (_bookmarks_map$params = bookmarks_map[params.type][params.id]) === null || _bookmarks_map$params === void 0 ? void 0 : _bookmarks_map$params.data : null; + } + /** + * Получить все закладки + * @return {array} - [card, ...] + */ + + + function all$1() { + return bookmarks.map(function (elem) { + return elem.data; + }); + } + /** + * Обновление каналов на андроид тв + * @return {void} + */ + + + function updateChannels() { + if (Platform.is('android') && typeof AndroidJS.saveBookmarks !== 'undefined' && bookmarks.length) { + AppWorker.json({ + type: 'stringify', + data: bookmarks + }, function (j) { + AndroidJS.saveBookmarks(j.data); + }); + } + } + /** + * Преобразует row.data из строки в объект + * @param {array} rows - массив закладок из БД + * @param {function} call - вызов по окончании + * @return {void} + */ + + + function rawToCard(rows, call) { + AppWorker.utils({ + type: 'account_bookmarks_parse', + data: rows + }, function (e) { + bookmarks = Arrays.isArray(e.data) ? e.data : []; + console.log('Account', 'bookmarks rawToCard complete, total:', bookmarks.length); + createMap(); + updateChannels(); + if (call) call(); + }); + } + /** + * Создаем карту закладок для быстрого поиска + * @return {void} + */ + + + function createMap() { + bookmarks_map = {}; + bookmarks.forEach(function (elem) { + elem.data = Utils$1.clearCard(elem.data); + if (!bookmarks_map[elem.type]) bookmarks_map[elem.type] = {}; + bookmarks_map[elem.type][elem.card_id] = elem; + }); + } + /** + * Синхронизация закладок из локальных на сервер + * @param {function} callback - вызов по окончании + * @return {void} + */ + + + function sync$1(callback) { + var file; + + try { + file = new File([localStorage.getItem('favorite') || '{}'], "bookmarks.json", { + type: "text/plain" + }); + } catch (e) { + console.warn('Account', 'bookmarks file create error', e.message); + } + + if (!file) { + try { + file = new Blob([localStorage.getItem('favorite') || '{}'], { + type: 'text/plain' + }); + file.lastModifiedDate = new Date(); + } catch (e) { + Noty.show(Lang.translate('account_export_fail')); + console.warn('Account', 'bookmarks blob create error', e.message); + } + } + + if (file) { + var formData = new FormData($('
    ')[0]); + formData.append("file", file, "bookmarks.json"); + $.ajax({ + url: Api$1.url() + 'bookmarks/sync', + type: 'POST', + data: formData, + async: true, + cache: false, + contentType: false, + enctype: 'multipart/form-data', + processData: false, + headers: { + token: permit.token, + profile: permit.account.profile.id + }, + success: function success(j) { + if (j.secuses) { + Noty.show(Lang.translate('account_sync_secuses')); + update$9(); + } else { + console.error('Account', 'bookmarks sync fail response'); + } + + callback && callback(); + }, + error: function error() { + console.error('Account', 'bookmarks sync fail'); + Noty.show(Lang.translate('account_export_fail')); + callback && callback(); + } + }); + } else { + callback && callback(); + console.error('Account', 'bookmarks no create file for sync'); + } + } + + var Bookmarks$1 = { + init: Utils$1.onceInit(init$X), + push: push$7, + update: update$9, + clear: clear$8, + get: get$9, + all: all$1, + sync: sync$1, + find: find$1 + }; + + var profile_icon; + + function init$W() { + profile_icon = Template.elem('div', { + "class": 'head__action selector open--profile' + }); + profile_icon.on('hover:enter', select$2.bind(null, Controller.toggle.bind(Controller, 'head'))); + Head.render().find('.full--screen').before(profile_icon); + Storage.listener.follow('change', function (e) { + if (e.name == 'account' || e.name == 'protocol') update$8(); + }); + ParentalControl.add('account_profiles', { + title: 'account_profiles' + }); + if (!permit.token) update$8(); + } + /** + * Обновляет иконку профиля + * @returns {void} + */ + + + function update$8() { + profile_icon.empty(); + + if (permit.token) { + profile_icon.append(Template.elem('img')); + Utils$1.imgLoad(profile_icon.find('img'), Utils$1.protocol() + object$2.cub_domain + '/img/profiles/' + (permit.account.profile.icon || 'l_1') + '.png', function () {}, function (img) { + img.src = './img/img_load.svg'; + }); + } else { + profile_icon.append(Template.js('icon_profile')); + } + } + /** + * Возвращает иконку профиля + * @returns {string} + */ + + + function icon$2() { + return permit.token ? Utils$1.protocol() + object$2.cub_domain + '/img/profiles/' + (permit.account.profile.icon || 'l_1') + '.png' : ''; + } + /** + * Проверяет наличие профиля, если его нет - загружает + * @param {function} call - вызывается если профиль есть + * @returns {void} + */ + + + function check$2(call) { + if (permit.access) { + Api$1.load('profiles/all', { + attempts: 3 + }).then(function (result) { + var account = permit.account; + + if (account.profile.id) { + var active = result.profiles.find(function (p) { + return p.id == account.profile.id; + }); + if (active) account.profile = active; + } else { + var main = result.profiles.find(function (p) { + return p.main; + }); + if (main) account.profile = main; + } + + Storage.set('account', account, true); // Переключение на детский источник + + Listener$1.send('profile_check', { + profile: account.profile + }); + call(); + })["catch"](call); + } else { + Storage.set('account_user', '', true); + } + } + /** + * Выбор профиля + * @param {string} callback - вызывается после выбора + * @returns {void} + */ + + + function select$2(callback) { + ParentalControl.personal('account_profiles', function () { + if (!permit.token) return Modal$1.account(); + var account = permit.account; + Loading$1.start(function () { + Api$1.clear(); + Loading$1.stop(); + }); + Api$1.load('profiles/all').then(function (result) { + Loading$1.stop(); + + if (result.secuses) { + var items = Arrays.clone(result.profiles); + var clone = Arrays.clone(result.profiles); + items.reverse(); + clone.reverse(); + var _select = []; + var maximum = Lampa.Account.hasPremium() ? 8 : 3; + var list = items.map(function (elem, index) { + elem.title = elem.name; + elem.template = 'selectbox_icon'; + elem.icon = ''; + elem.clone = clone[index]; + elem.subtitle = elem.main ? Lang.translate('account_profile_main') : elem.child ? Lang.translate('account_profile_child') + ' ' + '(' + Lang.translate('filter_rating_to') + ' ' + (elem.age || 12) + ')' : ''; + elem.selected = account.profile.id == elem.id; + return elem; + }); + var additional = { + title: Lang.translate('account_profile_add'), + template: 'selectbox_icon', + icon: '', + ghost: list.length >= maximum, + onSelect: function onSelect(a) { + callback && callback(); + + if (a.ghost) { + Noty.show(Lang.translate('account_profile_limited').replace('{count}', maximum)); + } else { + var contrioller = Controller.enabled().name; + Input.edit({ + title: Lampa.Lang.translate('account_profile_name'), + value: '', + free: true, + nosave: true, + nomic: true + }, function (name) { + Controller.toggle(contrioller); + + if (name) { + name = Utils$1.capitalizeFirstLetter(name); + Api$1.load('profiles/create', {}, { + name: name + }).then(function (result) { + Bell.push({ + text: Lang.translate('account_profile_created') + }); + })["catch"](function (e) { + Noty.show(Lang.translate(e.decode_code == 200 ? 'account_profile_limited' : 'network_error').replace('{count}', maximum)); + }); + } + }); + } + } + }; + _select = [additional].concat(list); + Select.show({ + title: Lang.translate('account_profiles'), + items: _select, + onSelect: function onSelect(a) { + account.profile = a.clone; + Storage.set('account', account); + callback && callback(); + Listener$1.send('profile_select', { + profile: account.profile + }); + }, + onBack: callback, + onFullDraw: function onFullDraw(container) { + container.append($('
    ' + Lang.translate('account_profile_info') + '
    ')); + } + }); + } else { + Noty.show(result.text); + callback && callback(); + } + })["catch"](function () { + Loading$1.stop(); + Noty.show(Lang.translate('account_profiles_empty')); + }); + }, false, true); + } + + var Profile = { + init: Utils$1.onceInit(init$W), + update: update$8, + check: check$2, + select: select$2, + icon: icon$2 + }; + + function inject(callback) { + if (!permit.access) return console.warn('Backup', 'no access'), callback && callback(); + confirm$1('', function () { + Api$1.load('users/backup/import').then(function (data) { + callback && callback(data); + + if (data.data) { + var imp = 0; + var ers = 0; + + for (var i in data.data) { + try { + localStorage.setItem(i, data.data[i]); + imp++; + } catch (e) { + ers++; + } + } + + Noty.show(Lang.translate('account_import_secuses') + ' - ' + Lang.translate('account_imported') + ' (' + imp + '/' + ers + ') - ' + Lang.translate('account_reload_after')); + setTimeout(function () { + window.location.reload(); + }, 5000); + } else Noty.show(Lang.translate('nodata')); + })["catch"](function () { + Noty.show(Lang.translate('account_import_fail')); + }); + }, callback); + } + + function publish(callback) { + if (!permit.access) return console.warn('Backup', 'no access'), callback && callback(); + confirm$1('', function () { + var file; // Удаляем из бэкапа app.js + + var serialized = JSON.stringify(localStorage, function (key, value) { + return key === 'app.js' ? undefined : value; + }); + + try { + file = new File([serialized], "backup.json", { + type: "text/plain" + }); + } catch (e) { + console.log('Backup', 'file create error', e.message); + } + + if (!file) { + try { + file = new Blob([serialized], { + type: 'text/plain' + }); + file.lastModifiedDate = new Date(); + } catch (e) { + console.log('Backup', 'file create error', e.message); + Noty.show(Lang.translate('account_export_fail')); + } + } + + if (file) { + var formData = new FormData($('
    ')[0]); + formData.append("file", file, "backup.json"); + $.ajax({ + url: Api$1.url() + 'users/backup/export', + type: 'POST', + data: formData, + async: true, + cache: false, + contentType: false, + enctype: 'multipart/form-data', + processData: false, + headers: { + token: permit.token + }, + success: function success(j) { + callback && callback(); + + if (j.secuses) { + if (j.limited) Modal$1.limited();else Noty.show(Lang.translate('account_export_secuses')); + } else Noty.show(Lang.translate('account_export_fail')); + }, + error: function error(e, x) { + callback && callback(); + console.log('Backup', 'network error', Lampa.Network.errorDecode(e, x)); + Noty.show(Lang.translate('account_export_fail_' + (Lampa.Network.errorJSON(e).code || 500))); + } + }); + } else { + console.log('Backup', 'file not created'); + callback && callback(); + } + }, callback); + } + + function confirm$1(title, onconfirm, oncancel) { + Select.show({ + title: Lang.translate(title || 'sure'), + nomark: true, + items: [{ + title: Lang.translate('confirm'), + confirm: true, + selected: true + }, { + title: Lang.translate('cancel') + }], + onSelect: function onSelect(a) { + if (a.confirm) { + onconfirm && onconfirm(); + } else { + oncancel && oncancel(); + } + }, + onBack: function onBack() { + oncancel && oncancel(); + } + }); + } + + function select$1(callback) { + if (permit.access) { + Select.show({ + title: Lang.translate('settings_cub_backup'), + nomark: true, + items: [{ + title: Lang.translate('settings_cub_backup_export'), + subtitle: Lang.translate('settings_cub_backup_export_descr'), + "export": true, + selected: true + }, { + title: Lang.translate('settings_cub_backup_import'), + subtitle: Lang.translate('settings_cub_backup_import_descr'), + "import": true + }, { + title: Lang.translate('cancel') + }], + onSelect: function onSelect(a) { + if (a["export"]) { + publish(callback); + } else if (a["import"]) { + inject(callback); + } else { + callback && callback(); + } + }, + onBack: function onBack() { + callback && callback(); + } + }); + } else console.warn('Backup', 'no access'); + } + + var Backup = { + select: select$1, + publish: publish, + inject: inject + }; + + function init$V() { + Settings.listener.follow('open', function (e) { + if (e.name == 'account') render$a(e.body); + }); + } + + function render$a(body) { + var account = permit.account; + var signed = Boolean(permit.token); + var premium = Utils$1.countDays(Date.now(), permit.user.premium); + + if (!window.lampa_settings.account_sync) { + body.find('[data-name="account_use"]').remove(); + } + + Utils$1.qrcode('https://' + object$2.cub_site, body.find('.ad-server__qr')); + body.find('.settings--account-signin').toggleClass('hide', signed); + body.find('.settings--account-user').toggleClass('hide', !signed); + body.find('.settings-param__label').toggleClass('hide', !Boolean(premium)); + + if (signed) { + body.find('.settings--account-user-info .settings-param__value').text(account.email); + body.find('.settings--account-user-profile .settings-param__value').text(account.profile.name); + body.find('.settings--account-user-out').on('hover:enter', function () { + Storage.set('account', ''); + Storage.set('account_user', ''); + Storage.set('account_email', ''); + Settings.update(); + Bookmarks$1.update(); + }); + body.find('.settings--account-user-sync').on('hover:enter', function (e) { + account = permit.account; + Select.show({ + title: Lang.translate('settings_cub_sync'), + items: [{ + title: Lang.translate('confirm'), + subtitle: Lang.translate('account_sync_to_profile') + ' (' + account.profile.name + ')', + confirm: true + }, { + title: Lang.translate('cancel') + }], + onSelect: function onSelect(a) { + if (a.confirm) { + var loader = $('
    '); + $(e.target).append(loader); + Bookmarks$1.sync(function () { + loader.remove(); + }); + } + + Controller.toggle('settings_component'); + }, + onBack: function onBack() { + Controller.toggle('settings_component'); + } + }); + }); + body.find('.settings--account-user-backup').on('hover:enter', function (e) { + var loader = $('
    '); + $(e.target).append(loader); + Backup.select(function () { + loader.remove(); + Controller.toggle('settings_component'); + }); + }); + body.find('.settings--account-user-profile .settings-param__value').text(account.profile.name); + body.find('.settings--account-user-profile').on('hover:enter', function () { + Profile.select(function () { + Controller.toggle('settings_component'); + }); + }); + } + } + + var Panel = { + init: Utils$1.onceInit(init$V), + render: render$a + }; + + var network$6 = new Request(); + var user_data; + /** + * Запуск + */ + + function init$U() { + if (!window.lampa_settings.account_use) return; + console.log('Account', 'use', permit.token ? permit.account.email : 'no account'); + Timeline$2.init(); + Bookmarks$1.init(); + Profile.init(); + Panel.init(); + Device.init(); + Socket.listener.follow('open', checkAccountValidity); + Timer.add(1000 * 60 * 10, checkAccountValidity); + Profile.check(function () { + Api$1.user(function (user) { + return user_data = user; + }); + Timeline$2.update(); + Profile.update(); + Api$1.persons(); + }); + delete Account.init; + } + /** + * Задача загрузки приложения + * @param {Function} call - функция обратного вызова + * @return {void} + */ + + + function task$3(call) { + if (!window.lampa_settings.account_use) return call(); + Bookmarks$1.update(call); + } + /** + * Проверить валидность аккаунта + * @return {void} + */ + + + function checkAccountValidity() { + permit.token && Socket.send('check_token', {}); + } + /** + * Выход из аккаунта + * @param {Object} data - данные аккаунта + * @return {void} + */ + + + function logoff(data) { + var account = permit.account; + + if (account.token && account.email == data.email) { + Storage.set('account', '', true); + Storage.set('account_use', false, true); + Storage.set('account_user', '', true); + Storage.set('account_email', '', true); + Storage.set('account_notice', '', true); + Storage.set('account_bookmarks', '', true); + $('.head .open--profile').addClass('hide'); + window.location.reload(); + } + } + + var Account = { + Api: Api$1, + Bookmarks: Bookmarks$1, + Profile: Profile, + Timeline: Timeline$2, + Permit: permit, + Modal: Modal$1, + listener: Listener$1, + network: network$6, + init: init$U, + task: task$3, + working: function working() { + console.warn('Account.working() is deprecated, use Account.Permit.sync'); + return permit.sync; + }, + canSync: function canSync() { + console.warn('Account.canSync() is deprecated, use Account.Permit.sync ? Account.Permit.account : false'); + return permit.sync ? permit.account : false; + }, + workingAccount: function workingAccount() { + console.warn('Account.workingAccount() is deprecated, use Account.Permit.sync ? Account.Permit.account : false'); + return permit.sync ? permit.account : false; + }, + logged: function logged() { + console.warn('Account.logged() is deprecated, use Permit.access'); + return permit.access; + }, + get: function get(params) { + console.warn('Account.get() is deprecated, use Account.Bookmarks.get()'); + return Bookmarks$1.get(params); + }, + all: function all() { + console.warn('Account.all() is deprecated, use Account.Bookmarks.all()'); + return Bookmarks$1.all(); + }, + plugins: function plugins(call) { + console.warn('Account.plugins() is deprecated, use Account.Api.plugins()'); + Api$1.plugins(call); + }, + notice: function notice(call) { + console.warn('Account.notice() is deprecated, use Account.Api.notices()'); + Api$1.notices(call); + }, + pluginsStatus: function pluginsStatus(plugin, status) { + console.warn('Account.pluginsStatus() is deprecated, use Account.Api.pluginToggle()'); + Api$1.pluginToggle(plugin, status); + }, + showProfiles: function showProfiles(callback) { + console.warn('Account.showProfiles() is deprecated, use Account.Profile.select()'); + Profile.select(callback); + }, + clear: function clear(where) { + console.warn('Account.clear() is deprecated, use Account.Bookmarks.clear()'); + Bookmarks$1.clear(where); + }, + update: function update(call) { + console.warn('Account.update() is deprecated, use Account.Bookmarks.update()'); + Bookmarks$1.update(call); + }, + backup: function backup() { + console.warn('Account.backup() is deprecated'); + }, + subscribeToTranslation: function subscribeToTranslation(params, call, error) { + console.warn('Account.subscribeToTranslation() is deprecated, use Account.Api.subscribeToTranslation()'); + Api$1.subscribeToTranslation(params, call, error); + }, + subscribes: function subscribes(params, secuses, error) { + console.warn('Account.subscribes() is deprecated, use Account.Api.subscribes()'); + Api$1.subscribes(params, secuses, error); + }, + showNoAccount: function showNoAccount() { + console.warn('Account.showNoAccount() is deprecated, use Account.Modal.account()'); + Modal$1.account(); + }, + showCubPremium: function showCubPremium() { + console.warn('Account.showCubPremium() is deprecated, use Account.Modal.premium()'); + Modal$1.premium(); + }, + showLimitedAccount: function showLimitedAccount() { + console.warn('Account.showLimitedAccount() is deprecated, use Account.Modal.limited()'); + Modal$1.limited(); + }, + logoff: logoff, + persons: function persons() { + console.warn('Account.persons() is deprecated, use Account.Api.persons()'); + Api$1.persons(); + }, + updateUser: function updateUser() { + Api$1.user(function (user) { + return user_data = user; + }); + } + }; + Object.defineProperty(Account, 'hasPremium', { + value: function value() { + var user = user_data || Storage.get('account_user', '{}'); + if (Storage.get('developer_nopremium', 'false')) return 0; + return user.id ? Utils$1.countDays(Date.now(), user.premium) : 0; + }, + writable: false + }); + var Account$1 = Account; + + var listener$a = Subscribe$2(), + viewed$1; + /** + * Инициализация + * @returns {void} + */ + + function init$T() { + read(); + } + /** + * Прочитать прогресс просмотра из localStorage + * @returns {void} + */ + + + function read() { + var no_nolisten = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + viewed$1 = Storage.get(filename(), {}); + listener$a.send('read', { + data: viewed$1 + }); + if (no_nolisten) return; + Lampa.Listener.send('state:changed', { + target: 'timeline', + reason: 'read', + viewed: viewed$1 + }); + } + /** + * Имя файла для хранения прогресса просмотра в localStorage + * @returns {string} - имя файла + */ + + + function filename() { + return 'file_view' + (Account$1.Permit.sync ? '_' + Account$1.Permit.account.profile.id : ''); + } + /** + * Обновить прогресс просмотра + * @param {object} params - параметры прогресса + * @param {number} params.hash - хеш файла + * @param {number} params.percent - процент просмотра (0-100) + * @param {number} [params.time] - текущее время просмотра в секундах + * @param {number} [params.duration] - общая длительность файла в секундах + * @param {number} [params.profile] - ID профиля + * @param {number} [params.updated] - когда отметка изменилась, в миллисекундах. Для локальных изменений ставится сам + * @param {boolean} [params.received] - флаг, что данные получены с сервера + * @returns {void} + */ + + + function update$7(params) { + if (params.hash == 0) return; // Штампуем только свои изменения: у полученных с сервера или с другого устройства + // уже есть штамп автора, и перезаписывать его локальным временем нельзя. + // Пишем в params, а не только в road, потому что ниже в сокет уходит именно params. + + if (!params.received) params.updated = Date.now(); + var road = viewed$1[params.hash]; + + if (typeof road == 'undefined' || typeof road == 'number') { + road = { + duration: 0, + time: 0, + percent: 0, + profile: 0, + updated: 0 + }; + viewed$1[params.hash] = road; + } + + road.percent = params.percent; + if (typeof params.time !== 'undefined') road.time = params.time; + if (typeof params.duration !== 'undefined') road.duration = params.duration; + if (typeof params.profile !== 'undefined') road.profile = params.profile; + if (typeof params.updated !== 'undefined') road.updated = params.updated; // округляем время и длительность до целых секунд + + road.time = Math.round(road.time); + road.duration = Math.round(road.duration); + Storage.set(filename(), viewed$1); + var layers = [].concat(Activity.renderLayers()); + layers.push($(document)); + layers.forEach(function (layer) { + var line = $('.time-line[data-hash="' + params.hash + '"]', layer).toggleClass('hide', params.percent ? false : true); + $('> div', line).css({ + width: params.percent + '%' + }); + $('.time-line-details[data-hash="' + params.hash + '"]', layer).each(function () { + var f = format(road); + $(this).find('[a="t"]').text(f.time); + $(this).find('[a="p"]').text(f.percent); + $(this).find('[a="d"]').text(f.duration); + $(this).toggleClass('hide', road.duration ? false : true); + }); + }); + listener$a.send('update', { + data: { + hash: params.hash, + road: road + } + }); + Lampa.Listener.send('state:changed', { + target: 'timeline', + reason: 'update', + data: { + hash: params.hash, + road: road + } + }); + if (!params.received && Account$1.hasPremium()) Socket.send('timeline', { + params: params + }); + } + /** + * Получить прогресс просмотра + * @param {string} hash - хеш файла + * @return {object} - объект с прогрессом просмотра {hash, percent, time, duration, profile, updated, handler} + */ + + + function view$1(hash) { + var curent = typeof viewed$1[hash] !== 'undefined' ? viewed$1[hash] : 0, + profile = Account$1.Permit.sync ? Account$1.Permit.account.profile.id : 0; + var road = { + percent: 0, + time: 0, + duration: 0, + profile: 0, + updated: 0 + }; + + if (_typeof(curent) == 'object') { + road.percent = curent.percent; + road.time = curent.time; + road.duration = curent.duration; + road.profile = curent.profile || profile; + road.updated = curent.updated || 0; + } else { + road.percent = curent || 0; + road.profile = profile; + } + + listener$a.send('view', { + data: { + hash: hash, + road: road + } + }); + return { + hash: hash, + percent: road.percent, + time: road.time, + duration: road.duration, + profile: road.profile, + updated: road.updated, + handler: function handler(percent, time, duration) { + return update$7({ + hash: hash, + percent: percent, + time: time, + duration: duration, + profile: road.profile + }); + } + }; + } + /** + * Создать прогресс просмотра + * @param {object} params - параметры прогресса от функции view + * @return {jQuery} - jQuery объект с прогрессом просмотра + */ + + + function render$9(params) { + var line = Template.get('timeline', params); + line.toggleClass('hide', params.percent ? false : true); + return line; + } + /** + * Создать детальную информацию о прогрессе просмотра + * @param {object} params - параметры прогресса от функции view + * @param {string} [str] - строка для добавления перед прогрессом + * @return {jQuery} - jQuery объект с детальной информацией о прогрессе просмотра + */ + + + function details(params) { + var str = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var line = Template.get('timeline_details', format(params)); + if (str) line.prepend(str); + line.attr('data-hash', params.hash); + line.toggleClass('hide', params.duration ? false : true); + return line; + } + /** + * Проверить, смотрел ли файл + * @param {object} card - карточка файла + * @return {number} - процент просмотра (0-100) + */ + + + function watched(card) { + var return_time = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (card.original_name) { + var max = 24; + var list = []; + + for (var i = 1; i <= max; i++) { + var time = view$1(Utils$1.hash([1, i, card.original_name].join(''))); + + if (time.percent) { + list.push({ + ep: i, + view: time + }); + } + } + + return return_time ? list : list.length; + } else { + var _time = view$1(Utils$1.hash(card.original_title)); + + return return_time ? _time : _time.percent; + } + } + + function watchedEpisode(card, season, episode) { + var return_time = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var time = view$1(Utils$1.hash([season, season > 10 ? ':' : '', episode, card.original_name || card.original_title].join(''))); + return return_time ? time : time.percent; + } + /** + * Форматировать прогресс в понятный человекy вид + * @param {object} params - параметры прогресса от функции view + * @return {object} - объект с отформатированными параметрами {percent, time, duration} + */ + + + function format(params) { + var road = { + percent: params.percent + '%', + time: Utils$1.secondsToTimeHuman(params.time), + duration: Utils$1.secondsToTimeHuman(params.duration) + }; + return road; + } + + var Timeline$1 = { + init: Utils$1.onceInit(init$T), + read: read, + listener: listener$a, + render: render$9, + update: update$7, + view: view$1, + details: details, + format: format, + watched: watched, + watchedEpisode: watchedEpisode, + filename: filename + }; + + var markers = ['socket', 'mirrors', 'request']; + var markers_object = {}; + var update_started = false; + markers.forEach(function (marker) { + markers_object[marker] = { + error: false, + live: false, + pass_count: 0, + pass_time: 0, + status_now: '', + status_prev: '' + }; + }); + + function init$S() { + markers.forEach(function (marker) { + markers_object[marker].element = Head.render()[0].querySelector('.head__markers .item--' + marker); + }); + + if (typeof requestAnimationFrame !== 'undefined') { + Lampa.Listener.follow('request_error', function (e) { + if (e.params.url.indexOf(object$2.cub_domain) > -1 && e.error.status == 0 && e.exception !== 'timeout') { + error$1('request'); + } + }); + Lampa.Listener.follow('request_secuses', function (e) { + if (e.params.url.indexOf(object$2.cub_domain) > -1) { + pass('request'); + normal('request'); + } + }); + } + } + + function update$6() { + if (update_started) return; + + if (typeof requestAnimationFrame !== 'undefined') { + update_started = true; + requestAnimationFrame(function updateMarkers() { + var any = false; + markers.forEach(function (marker) { + var marker_data = markers_object[marker]; + var status = marker_data.pass_count > 0 ? 'status--pass' : marker_data.live ? 'status--live' : marker_data.bad ? 'status--bad' : marker_data.error ? 'status--error' : ''; + + if (status !== marker_data.status_now) { + marker_data.status_prev = marker_data.status_now; + marker_data.status_now = status; + updateStatus(marker); + } + + if (status == 'status--pass' && marker_data.pass_time < Date.now() - 100) { + marker_data.pass_count--; + marker_data.pass_time = Date.now(); + } + + if (marker_data.pass_count >= 0) any = true; + if (marker_data.pass_count == 0) marker_data.pass_count = -1; + }); + if (any) requestAnimationFrame(updateMarkers);else update_started = false; + }); + } + } + + function updateStatus(marker) { + var marker_data = markers_object[marker]; + if (!marker_data.element) return; + var status = marker_data.pass_count > 0 ? 'status--pass' : marker_data.live ? 'status--live' : marker_data.bad ? 'status--bad' : marker_data.error ? 'status--error' : ''; + marker_data.element.classList.remove('status--error', 'status--live', 'status--pass', 'status--bad'); + if (status) marker_data.element.classList.add(status); + } + + function bad(who) { + markers_object[who].error = false; + markers_object[who].live = false; + markers_object[who].bad = true; + update$6(); + } + + function error$1(who) { + markers_object[who].error = true; + markers_object[who].live = false; + markers_object[who].bad = false; + update$6(); + } + + function pass(who) { + var add = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + markers_object[who].pass_count = Math.min(markers_object[who].pass_count + add, 20); + update$6(); + } + + function live(who) { + markers_object[who].error = false; + markers_object[who].live = true; + markers_object[who].bad = false; + update$6(); + } + + function normal(who) { + markers_object[who].error = false; + markers_object[who].live = false; + markers_object[who].bad = false; + update$6(); + } + + var Markers = { + init: init$S, + bad: bad, + error: error$1, + pass: pass, + live: live, + normal: normal + }; + + var socket; + var ping; + + var _uid = Utils$1.uid(); + + var _devices = []; + var listener$9 = Subscribe$2(); + var expects = []; + var timeping = 5000; + var timeout$1; + var used_mirrors = -1; + var terminal_access = false; + + function connect$1() { + if (!window.lampa_settings.socket_use) return; + var ws = Platform.is('orsay') || Platform.is('netcast') ? 'ws://' : 'wss://'; + var pt = Platform.is('orsay') || Platform.is('netcast') ? ':8080' : ':8443'; + var mirrors = object$2.soc_mirrors; + var mirror = mirrors[used_mirrors + 1] || mirrors[0]; + used_mirrors = (used_mirrors + 1) % mirrors.length; + var socket_url = ws + mirror + pt; + if (window.lampa_settings.socket_url) socket_url = window.lampa_settings.socket_url; + clearTimeout(ping); + clearTimeout(timeout$1); + timeout$1 = setTimeout(function () { + console.log('Socket', 'timeout close'); + if (socket) socket.close(); + }, 1000 * 60); + + try { + socket = new WebSocket(socket_url); + } catch (e) { + console.log('Socket', 'not work'); + } + + if (!socket) return; + socket.addEventListener('open', function (event) { + console.log('Socket', 'open on ' + socket_url); + timeping = 5000; + clearTimeout(timeout$1); + send('start', {}); + listener$9.send('open', {}); + Markers.live('socket'); + }); + socket.addEventListener('close', function (event) { + console.log('Socket', 'close', event.code); + clearTimeout(timeout$1); + listener$9.send('close', {}); + timeping = Math.min(1000 * 60 * 5, timeping); + console.log('Socket', 'try connect to ' + socket_url + ' after', Math.round(timeping) / 1000, 'sec.'); + setTimeout(connect$1, Math.round(timeping)); + timeping *= 2; + Markers.error('socket'); + }); + socket.addEventListener('error', function (event) { + console.log('Socket', 'error:', 'maybe there is no connection to the server'); + }, false); + socket.addEventListener('message', function (event) { + if (event.data == 'pong') { + socket.alive = true; + Markers.live('socket'); + return; + } + + var result = JSON.parse(event.data); + + if (window.lampa_settings.socket_methods) { + if (result.method == 'devices') { + _devices = result.data; + } else if (result.method == 'open') { + Controller.toContent(); + Activity.push(result.data); + } else if (result.method == 'timeline') { + //чтоб снова не остправлять и не зациклить + result.data.received = true; + var account = Account$1.Permit.account; + + if (Account$1.Permit.sync && account.profile && account.profile.id == result.data.profile) { + Timeline$1.update(result.data); + } + } else if (result.method == 'bookmarks') { + Account$1.Bookmarks.update(); + } else if (result.method == 'terminal_activate') { + if (Storage.get('terminal_access', '') == result.data.code) { + terminal_access = true; + send('terminal_result', { + result: 'Terminal access activated' + }); + } + } else if (result.method == 'terminal_eval') { + if (Storage.get('terminal_access', '') == result.data.code) { + var stroke = ''; + var tojson = {}; + console.log('Socket', 'terminal eval', result.data.eval); + + try { + stroke = eval(result.data.eval); + } catch (e) { + stroke = e.message + ' ' + e.stack; + } + + try { + if (Arrays.isObject(stroke) || Arrays.isArray(stroke)) tojson = JSON.stringify(stroke); + } catch (e) { + tojson = stroke; + } + + if (typeof stroke == 'function') { + tojson = 'Function cannot be converted to JSON'; + } + + if (typeof stroke == 'string' || typeof stroke == 'number' || typeof stroke == 'boolean') { + tojson = stroke; + } else if (stroke === undefined) { + tojson = 'undefined'; + } else if (stroke === null) { + tojson = 'null'; + } else tojson = 'unknown type'; + + console.log('Socket', 'terminal eval result', tojson); + send('terminal_result', { + result: tojson + }); + } + } else if (result.method == 'logoff') { + Account$1.logoff(result.data); + } else if (result.method == 'info') { + console.log('Socket', 'info', result.data); + } else if (result.method == 'token_status') { + console.log('Socket', 'token status', result.data); + } else if (result.method == 'buy_premium') { + Account$1.updateUser(); + } else if (result.method == 'other' && result.data.submethod == 'play') { + Controller.toContent(); + Modal.open({ + title: '', + align: 'center', + html: $('
    ' + Lang.translate('confirm_open_player') + '
    '), + buttons: [{ + name: Lampa.Lang.translate('settings_param_no'), + onSelect: function onSelect() { + Modal.close(); + Controller.toggle('content'); + } + }, { + name: Lampa.Lang.translate('settings_param_yes'), + onSelect: function onSelect() { + Modal.close(); + Controller.toggle('content'); + Player.play(result.data.object.player); + Player.playlist(result.data.object.playlist); + } + }], + onBack: function onBack() { + Modal.close(); + Controller.toggle('content'); + } + }); + } + } + + Markers.pass('socket', 5); + listener$9.send('message', result); + }); + Timer.add(1000, function () { + if (expects.length > 50) expects = expects.slice(-50); + + if (socket && socket.readyState == 1 && expects.length) { + var msg = expects.shift(); + console.log('Socket', 'sent with a delay:', msg.method); + send(msg.method, msg); + } + }, false, true); + Timer.add(1000 * 30, function () { + if (socket && socket.readyState == 1) { + clearTimeout(ping); + socket.alive = false; + socket.send('ping'); + ping = setTimeout(function () { + if (!socket.alive && socket.readyState == 1) { + console.log('Socket', 'ping timeout, maybe connection lost'); + Markers.bad('socket'); + } + }, 15000); + } + }, false, true); + } + + function send(method, data) { + var name_devise = Platform.get() ? Platform.get() : navigator.userAgent.toLowerCase().indexOf('mobile') > -1 ? 'mobile' : navigator.userAgent.toLowerCase().indexOf('x11') > -1 ? 'chrome' : 'other'; + listener$9.send('send', { + method: method, + data: data + }); + data.device_id = _uid; + data.name = Utils$1.capitalizeFirstLetter(name_devise) + ' - ' + Storage.field('device_name'); + data.method = method; + data.version = 2; + data.account = Storage.get('account', '{}'); + data.premium = Account$1.hasPremium(); + data.terminal = Storage.get('terminal_access', ''); + if (socket && socket.readyState == 1) socket.send(JSON.stringify(data));else expects.push(data); + Markers.pass('socket'); + } + + function restart() { + if (socket) socket.close(); + connect$1(); + } + + var Socket = { + listener: listener$9, + init: connect$1, + send: send, + uid: function uid() { + return _uid; + }, + devices: function devices() { + return _devices; + }, + restart: restart, + terminalAccess: function terminalAccess() { + return terminal_access; + } + }; + + var timer$4; + var listener$8; + + function init$R() { + var timer, activity; + var broadcast = Head.addIcon(Template.string('icon_broadcast'), function () { + open$6({ + type: 'card', + object: Activity.extractObject(activity) + }); + }); + broadcast.addClass('open--broadcast'); + broadcast.hide(); + Lampa.Listener.follow('activity', function (e) { + if (e.type == 'start') activity = e.object; + clearTimeout(timer); + timer = setTimeout(function () { + if (activity) { + if (activity.component !== 'full') { + broadcast.hide(); + activity = false; + } + } + }, 1000); + + if (e.type == 'start' && e.component == 'full' && !permit.child) { + broadcast.show(); + activity = e.object; + } + }); + } + /** + * Открыть окно + * @params {Object} params - параметры + * @params {String} params.type - тип (card, play) + * @params {Object} params.object - объект + * @returns {void} + */ + + + function open$6(params) { + var enabled = Controller.enabled().name; + var text = params.type == 'card' ? Lang.translate('broadcast_open') : params.type == 'play' ? Lang.translate('broadcast_play') : ''; + var temp = Template.get('broadcast', { + text: text + }); + var list = temp.find('.broadcast__devices'); + var last = ''; + if (!text) temp.find('.about').remove(); + Socket.send('devices', {}); + timer$4 = setInterval(function () { + Socket.send('devices', {}); + }, 3000); + + listener$8 = function listener(e) { + if (e.method == 'devices') { + var devices = e.data.filter(function (d) { + return !(d.name == 'CUB' || d.device_id == Socket.uid()); + }); + var select; + list.empty(); + devices.forEach(function (device) { + var item = $('
    ' + device.name + '
    '); + item.on('hover:enter', function () { + close$7(); + Controller.toggle(enabled); + + if (params.type == 'card') { + var object = Arrays.clone(params.object); + var card = { + id: object.card.id, + source: object.card.source || 'tmdb' + }; + object.card = card; + Socket.send('open', { + params: object, + uid: device.uid + }); + } + + if (params.type == 'play') { + var player = Arrays.clone(params.object.player); + delete player.playlist; + Socket.send('other', { + params: { + submethod: 'play', + object: { + player: player, + playlist: [] + } + }, + uid: device.uid + }); + } + }).on('hover:focus', function () { + last = device.uid; + }); + list.append(item); + if (last == device.uid) select = item[0]; + }); + Modal.toggle(select); + } + }; + + Modal.open({ + title: '', + html: temp, + size: 'small', + mask: true, + onBack: function onBack() { + close$7(); + Controller.toggle(enabled); + } + }); + listener$8({ + method: 'devices', + data: Socket.devices() + }); + Socket.listener.follow('message', listener$8); + } + /** + * Закрыть окно + */ + + + function close$7() { + Socket.listener.remove('message', listener$8); + clearInterval(timer$4); + Modal.close(); + listener$8 = null; + } + + var Broadcast = { + init: init$R, + open: open$6 + }; + + var wait_for_disclaimer = false; + var show_disclaimer = false; + + function init$Q() { + Player.listener.follow('destroy', reset); + } + + function needs(player_need, launch_player) { + return (Storage.field(player_need) == 'inner' || launch_player == 'inner') && Platform.is('apple_tv') && !show_disclaimer; + } + + function show$6(call) { + wait_for_disclaimer = true; + show_disclaimer = true; + + function openPlayerSettingSidebar() { + var openPlayer = function openPlayer(event) { + if (event.name !== 'player') return; + Settings.listener.remove('open', openPlayer); + + if (!Controller.enabled() || Controller.enabled().name !== 'settings_component') { + Controller.toggle('settings_component'); + } + + var player_field = event.body.find('[data-name="player"]'); + if (player_field.length) player_field.trigger('hover:enter'); + }; + + Settings.listener.follow('open', openPlayer); + Controller.toggle('settings'); + Settings.create('player'); + } + + Modal.open({ + title: Lang.translate('inner_player_disclaimer_title'), + size: 'small', + scroll: { + nopadding: true + }, + html: $('
    ' + Lang.translate('inner_player_disclaimer_text') + '
    '), + buttons: [{ + name: Lang.translate('confirm'), + onSelect: function onSelect() { + wait_for_disclaimer = false; + Modal.close(); + call(); + } + }, { + name: Lang.translate('inner_player_disclaimer_change_player'), + onSelect: function onSelect() { + wait_for_disclaimer = false; + Modal.close(); + openPlayerSettingSidebar(); + } + }], + onBack: function onBack() { + wait_for_disclaimer = false; + Modal.close(); + } + }); + } + + function reset() { + wait_for_disclaimer = false; + } + + function isWaiting() { + return wait_for_disclaimer; + } + + var Disclaimer = { + init: init$Q, + needs: needs, + show: show$6, + reset: reset, + isWaiting: isWaiting + }; + + var status = false; + + function init$P() { + $.ajax({ + url: "./personal.lampa", + dataType: 'text', + success: function success() { + status = true; + } + }); + } + + function confirm() { + return status; + } + + var Personal = { + init: init$P, + confirm: confirm + }; + + function init$O() { + var today = new Date(); + var date = today.toISOString().split('T')[0]; + + if (Storage.get('metric_date') !== date) { + if (Storage.get('metric_adview', 0) > 0) histogram('adview', Storage.get('metric_adview', 0)); + Storage.set('metric_date', date); + Storage.set('metric_adview', 0); + } + + if (!Storage.get('metric_uid', '')) Storage.set('metric_uid', Utils$1.uid()); + $.ajax({ + dataType: 'json', + url: Utils$1.protocol() + object$2.cub_domain + '/api/metric/unic?platform=' + Platform.get() + '&uid=' + Storage.get('metric_uid', '') + '&premium=' + (Account$1.hasPremium() ? 1 : 0) + '&geo=' + vpn.code() + }); + counter('screen', Platform.get(), Platform.screen('tv') ? 'tv' : 'mobile'); + counter('client_region', vpn.code()); + + function playerStat(data) { + if (!data.iptv) { + counter('player_start', Platform.get(), data.stat_from, data.torrent_hash ? 'torrent' : data.youtube ? 'youtube' : data.continue_play ? 'continue' : 'online'); + + if (data.vast_url) { + counter('player_vast_url', Storage.get('activity', '{}').component || 'none', data.continue_play ? 'continue' : 'start'); + } + } + } + + Lampa.Player.listener.follow('start', function (data) { + playerStat(_objectSpread2(_objectSpread2({}, data), {}, { + stat_from: 'inner' + })); + }); + Lampa.Player.listener.follow('external', function (data) { + playerStat(_objectSpread2(_objectSpread2({}, data), {}, { + stat_from: 'external' + })); + }); + } + + function counter(method, v1, v2, v3) { + $.ajax({ + dataType: 'json', + url: Utils$1.protocol() + object$2.cub_domain + '/api/metric/stat?method=' + method + '&value_one=' + (v1 || '') + '&value_two=' + (v2 || '') + '&value_three=' + (v3 || '') + }); + } + + function histogram(method, value) { + $.ajax({ + dataType: 'json', + url: Utils$1.protocol() + object$2.cub_domain + '/api/metric/histogram?method=' + method + '&value=' + (value || 0) + }); + } + + var ServiceMetric = { + init: init$O, + counter: counter, + histogram: histogram + }; + + var sdk2_try = 0; + var sdk3_try = 0; + + function loadSDK(api) { + return api == 3 ? loadSDK3() : loadSDK2(); + } + + function loadSDK2() { + return new Promise(function (resolve, reject) { + if (window.VASTPlayer) { + return resolve(); + } + + if (sdk2_try > 1) { + return reject(new Error('VASTPlayer SDK load failed after multiple attempts')); + } + + sdk2_try++; + Utils$1.putScriptAsync([object$2.github_lampa + '/vender/vast/vast.js'], false, reject, resolve); + }); + } + + function loadSDK3() { + return new Promise(function (resolve, reject) { + if (window.google && window.google.ima) { + return resolve(); + } + + if (sdk3_try > 1) { + return reject(new Error('IMA SDK load failed after multiple attempts')); + } + + sdk3_try++; + Utils$1.putScriptAsync(['https://imasdk.googleapis.com/js/sdkloader/ima3.js'], false, reject, resolve); + }); + } + + function buildUrl(url) { + var movie = Storage.get('activity', '{}').movie; + var movie_genres = []; + var movie_id = movie ? movie.id : 0; + var movie_imdb = movie ? movie.imdb_id : ''; + var movie_type = movie ? movie.original_name ? 'tv' : 'movie' : 'movie'; + + try { + movie_genres = movie.genres.map(function (g) { + return g.id; + }); + } catch (e) {} + + var pixel_ratio = window.devicePixelRatio || 1; + var u = url.replace('{RANDOM}', Math.round(Date.now() * Math.random())); + u = u.replace(/{TIME}/g, Date.now()); + u = u.replace(/{WIDTH}/g, Math.round(window.innerWidth * pixel_ratio)); + u = u.replace(/{HEIGHT}/g, Math.round(window.innerHeight * pixel_ratio)); + u = u.replace(/{PLATFORM}/g, Platform.get()); + u = u.replace(/{UID}/g, encodeURIComponent(getUid())); + u = u.replace(/{PIXEL}/g, pixel_ratio); + u = u.replace(/{GUID}/g, encodeURIComponent(getGuid())); + u = u.replace(/{MOVIE_ID}/g, movie_id); + u = u.replace(/{MOVIE_GENRES}/g, movie_genres.join(',')); + u = u.replace(/{MOVIE_IMDB}/g, movie_imdb); + u = u.replace(/{MOVIE_TYPE}/g, movie_type); + u = u.replace(/{SCREEN}/g, encodeURIComponent(Platform.screen('tv') ? 'tv' : 'mobile')); + return u; + } + + function getGuid() { + var guid = Storage.get('vast_device_guid', ''); + + if (!guid || guid.indexOf('00000000') === 0) { + guid = Utils$1.guid(); + Storage.set('vast_device_guid', guid); + } + + return guid; + } + + function getUid() { + var uid = Storage.get('vast_device_uid', ''); + + if (!uid) { + uid = Utils$1.uid(15); + Storage.set('vast_device_uid', uid); + } + + return uid; + } + + function getMediaType(player_data) { + var is_torrent = Boolean(player_data.torrent_hash && Torserver.ip() && player_data.url.indexOf(Torserver.ip()) > -1); + var is_youtube = Boolean(player_data.youtube && Activity.active().component == 'full' && player_data.url.indexOf('youtube.com') > -1); + var is_continue = Boolean(player_data.continue_play && Lampa.PlayerPlaylist.get().length > 0 && Lampa.PlayerPlaylist.get().indexOf(player_data) > -1); + return { + iptv: player_data.iptv, + torrent: is_torrent, + youtube: is_youtube, + "continue": is_continue, + any: is_torrent || is_youtube || is_continue || player_data.iptv + }; + } + + function canShow(player_data) { + var player_type = getMediaType(player_data); + var ignore = window.lampa_settings.developer.ads ? false : Account$1.hasPremium() || Personal.confirm(); + return player_type.any ? false : !ignore; + } + + function metric(stat_name, method, ad_name) { + if (ad_name == 'plugin') { + var activity = Storage.get('activity', '{}'); + + if (activity.component) { + ad_name = activity.component; + } + + ServiceMetric.counter('ad_' + stat_name + '_plugin', ad_name, method, Platform.screen('tv') ? 'tv' : 'mobile'); + } else { + ServiceMetric.counter('ad_' + stat_name, ad_name, method, Platform.screen('tv') ? 'tv' : 'mobile'); + } + } + + var IMA = { + loadSDK: loadSDK, + loadSDK2: loadSDK2, + loadSDK3: loadSDK3, + buildUrl: buildUrl, + getGuid: getGuid, + getUid: getUid, + getMediaType: getMediaType, + canShow: canShow, + metric: metric + }; + + var last_responce = {}; + + function stat$2(method, name) { + IMA.metric('new_preroll', method, name); + } + + window.adv_logs_responce_event = function (e) { + last_responce = { + status: e.status, + text: e.text + }; + console.log('Ad', 'logs responce', last_responce); + }; + /** + * Извлекает skipoffset из VAST XML и возвращает в секундах + * @param {string} vastXml - XML строка VAST + * @param {number} [duration] - продолжительность рекламы в секундах (нужно, если skipoffset в процентах) + * @returns {number|null} - время пропуска в секундах или null + */ + + + function getSkipOffsetSeconds(vastXml) { + var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + if (!vastXml) return null; // Находим атрибут skipoffset="..." + + var match = vastXml.match(/skipoffset\s*=\s*["']([^"']+)["']/i); + if (!match) return null; + var value = match[1].trim(); // Если формат HH:MM:SS + + if (/^\d{2}:\d{2}:\d{2}$/.test(value)) { + var _value$split$map = value.split(':').map(Number), + _value$split$map2 = _slicedToArray(_value$split$map, 3), + h = _value$split$map2[0], + m = _value$split$map2[1], + s = _value$split$map2[2]; + + return h * 3600 + m * 60 + s; + } // Если формат процентов, например "25%" + + + if (/^\d+%$/.test(value)) { + var percent = parseInt(value); + + if (duration > 0) { + return Math.round(duration * percent / 100); + } + + return null; // нельзя посчитать без duration + } // Неизвестный формат + + + return null; + } + + var Vast = /*#__PURE__*/function () { + function Vast(preroll) { + _classCallCheck(this, Vast); + + this.listener = Subscribe$2(); + this.paused = false; + this.preroll = preroll; + this.elems = {}; + this.tiks = {}; + this.skip_time = 15; + this.skip_ready = false; + this.timewait = 10 * 1000; + this.created_at = Date.now(); + setTimeout(this.start.bind(this), 100); + } + /** + * Запустить рекламу + */ + + + _createClass(Vast, [{ + key: "start", + value: function start() { + Storage.set('metric_adview', Storage.get('metric_adview', '0') + 1); + stat$2('launch', this.preroll.name); + this.elems.block = Template.js('ad_video_block'); + this.elems.skip = this.elems.block.find('.ad-video-block__skip'); + this.elems.progressbar = this.elems.block.find('.ad-video-block__progress-fill'); + this.elems.loader = this.elems.block.find('.ad-video-block__loader'); + this.elems.container = this.elems.block.find('.ad-video-block__vast'); + this.elems.status = Template.elem('div', { + "class": 'ad-video-block__status' + }); + this.elems.block.find('video').remove(); + this.elems.block.append(this.elems.status); + this.elems.container.style.opacity = 0; + this.elems.status.style.position = 'absolute'; + this.elems.status.style.top = '1em'; + this.elems.status.style.left = '1em'; + this.elems.status.style.textShadow = '0 0 5px black'; + this.elems.status.style.fontSize = '0.9em'; + this.elems.block.find('.ad-video-block__text').text(Lang.translate('ad') + ' - ' + Lang.translate('ad_disable')).toggleClass('hide', Boolean(this.preroll.msg)); + this.elems.block.find('.ad-video-block__info').text(''); + if (this.preroll.msg) this.elems.block.find('.ad-video-block__text').text(this.preroll.msg + ' - ' + Lang.translate('ad_disable')).toggleClass('hide', false); + this.elems.block.on('click', this.skip.bind(this)); + document.body.append(this.elems.block); + this.listener.send('launch'); + this.controller(); + this.timeout(); + console.log('Ad', 'run', this.preroll.name, 'from', this.preroll.name == 'plugin' ? 'plugin' : 'cub'); + this.elems.status.text('Initialize...'); + + try { + this.initialize(); + stat$2('run', this.preroll.name); + } catch (e) { + this.error(400, 'Initialize', e ? e.message : ''); + } + } + /** + * Контроллер рекламы + */ + + }, { + key: "controller", + value: function controller() { + Controller.add('ad_video_block', { + toggle: function toggle() { + Controller.clear(); + }, + enter: this.skip.bind(this), + back: this.skip.bind(this) + }); + Controller.toggle('ad_video_block'); + } + /** + * Ждем загрузки определенное время + * после выдаем ошибку + */ + + }, { + key: "timeout", + value: function timeout() { + var _this = this; + + this.tiks.timeout = setTimeout(function () { + _this.error(300, 'Timeout'); + }, this.timewait); + } + /** + * Инициализация плеера + */ + + }, { + key: "initialize", + value: function initialize() { + var _this2 = this; + + this.player = new VASTPlayer(this.elems.container); + this.player.load(this.url()).then(function () { + _this2.elems.status.text('Loaded'); + + if (_this2.removed) return _this2.player.stopAd();else { + _this2.listeners(); + + return _this2.player.startAd(); + } + })["catch"](function (reason) { + _this2.elems.status.text('Load error'); + + if (!_this2.removed) _this2.error(100, reason.message); + }); + } + /** + * Слушатели плеера + */ + + }, { + key: "listeners", + value: function listeners() { + var _this3 = this; + + this.player.on('AdPaused', function () { + console.log('Ad', 'event', 'pause'); + _this3.paused = true; + }); + this.player.on('AdPlaying', function () { + console.log('Ad', 'event', 'play'); + _this3.paused = false; + }); + this.player.on('AdVideoStart', function () { + console.log('Ad', 'event', 'video start'); + + var video = _this3.player.container.find('video'); + + if (video) { + video.addEventListener('pause', function () { + if (_this3.removed) return; + console.log('Ad', 'event', 'pause'); + _this3.paused = true; + }); + } + }); + this.player.once('AdStarted', this.onStarted.bind(this)); + this.player.once('AdStopped', this.onStoped.bind(this)); + } + /** + * Реклама запущена + */ + + }, { + key: "onStarted", + value: function onStarted() { + var _this4 = this; + + console.log('Ad', 'event', 'started'); + this.elems.status.text('Started: ' + (this.player.adDuration ? Math.round(this.player.adDuration) + 's' : '')); + stat$2('started', this.preroll.name); + clearTimeout(this.tiks.timeout); + this.elems.loader.remove(); + this.elems.container.style.opacity = 1; + var duration = this.player.adDuration || this.skip_time; + clearInterval(this.tiks.progress); + clearTimeout(this.tiks.watch); + var creative_skip = getSkipOffsetSeconds(last_responce.text, duration); + creative_skip = creative_skip !== null ? creative_skip : duration * 0.8; + console.log('Ad', 'creative skip offset:', creative_skip); + this.started_time = Date.now(); + this.skip_time = Math.round(Math.max(this.skip_time, Math.min(60, creative_skip))); + console.log('Ad', 'skip time set to:', this.skip_time); + this.tiks.progress = setInterval(this.onProgress.bind(this), 100); + this.tiks.watch = setTimeout(function () { + _this4.elems.status.text('Watch timeout: ' + duration + 's'); + + console.log('Ad', 'error', 'watch timeout', duration); + + _this4.stop(); + + _this4.onEnd(); + }, Math.round((duration + 5) * 1000)); + this.player.adVolume = 0.5; + } + /** + * Событие окончания рекламы + */ + + }, { + key: "onEnd", + value: function onEnd() { + console.log('Ad', 'complete'); + stat$2('complete', this.preroll.name); + this.listener.send('ended'); + } + /** + * Реклама закончена + */ + + }, { + key: "onStoped", + value: function onStoped() { + console.log('Ad', 'stoped'); + this.destroy(); + this.onEnd(); + } + /** + * Обновление прогресса + */ + + }, { + key: "onProgress", + value: function onProgress() { + var duration = this.player.adDuration || this.skip_time; + var remaining = duration - (Date.now() - this.started_time) / 1000; + var progress = Math.min(100, (1 - remaining / duration) * 100); + var elapsed = duration - remaining; + this.elems.progressbar.style.width = progress + '%'; + this.skip_ready = elapsed > this.skip_time; + var user_view = Math.max(0, duration > this.skip_time ? this.skip_time - elapsed : remaining); + this.elems.skip.find('span').text(Lang.translate(this.skip_ready ? 'ad_skip' : Math.ceil(user_view))); + if (remaining <= 0) clearInterval(this.tiks.progress); + } + /** + * Сформировать URL для запроса рекламы + */ + + }, { + key: "url", + value: function url() { + return IMA.buildUrl(this.preroll.url); + } + /** + * Обработка ошибки + */ + + }, { + key: "error", + value: function error(code, msg) { + console.log('Ad', 'error', code, msg); + this.stop(); + this.listener.send('error'); + stat$2('error', this.preroll.name); + stat$2('error_' + code, this.preroll.name); + } + /** + * Пропустить рекламу если можно + */ + + }, { + key: "skip", + value: function skip() { + if (this.removed) return; + + if (this.skip_ready || (Date.now() - this.created_at) / 1000 > this.skip_time) { + this.stop(); + this.onEnd(); + } + } + /** + * Остановить рекламу принудительно + */ + + }, { + key: "stop", + value: function stop() { + try { + this.player._events = {}; + this.player.stopAd().then(this.destroy.bind(this))["catch"](this.destroy.bind(this)); + } catch (e) { + console.error('Ad', 'stop error', e ? e.message : ''); + this.destroy(); + } + } + /** + * Уничтожить + */ + + }, { + key: "destroy", + value: function destroy() { + if (this.removed) return; + if (this.player) this.player._events = {}; + clearTimeout(this.tiks.timeout); + clearTimeout(this.tiks.watch); + clearInterval(this.tiks.progress); + this.elems.block.remove(); + this.removed = true; + } + }]); + + return Vast; + }(); + + function stat$1(method, name) { + IMA.metric('new_preroll', method, name); + } + + var Vast3 = /*#__PURE__*/function () { + function Vast3(preroll) { + _classCallCheck(this, Vast3); + + this.listener = Subscribe$2(); + this.preroll = preroll; + this.elems = {}; + this.tiks = {}; + this.skip_time = 15; + this.skip_ready = false; + this.timewait = 12 * 1000; + this.created_at = Date.now(); + this.removed = false; + this.adsManager = null; + this.adsLoader = null; + this.adContainer = null; + setTimeout(this.start.bind(this), 100); + } + /** + * Запустить рекламу + */ + + + _createClass(Vast3, [{ + key: "start", + value: function start() { + var _this = this; + + Storage.set('metric_adview', Storage.get('metric_adview', '0') + 1); + stat$1('launch', this.preroll.name); + this.elems.block = Template.js('ad_video_block'); + this.elems.skip = this.elems.block.find('.ad-video-block__skip'); + this.elems.skip.style.display = 'none'; + this.elems.progressbar = this.elems.block.find('.ad-video-block__progress-fill'); + this.elems.loader = this.elems.block.find('.ad-video-block__loader'); + this.elems.container = this.elems.block.find('.ad-video-block__vast'); + this.elems.status = Template.elem('div', { + "class": 'ad-video-block__status' + }); // Создаём video-элемент для IMA SDK + + this.elems.video = Template.elem('video', { + playsinline: '', + muted: '', + style: 'position:absolute;width:100%;height:100%;top:0;left:0;object-fit:contain;' + }); + this.elems.block.find('video').remove(); + this.elems.container.appendChild(this.elems.video); + this.elems.block.append(this.elems.status); + this.elems.container.style.opacity = 0; + this.elems.status.style.position = 'absolute'; + this.elems.status.style.top = '1em'; + this.elems.status.style.left = '1em'; + this.elems.status.style.textShadow = '0 0 5px black'; + this.elems.status.style.fontSize = '0.9em'; + this.elems.block.find('.ad-video-block__text').text(Lang.translate('ad') + ' - ' + Lang.translate('ad_disable')).toggleClass('hide', Boolean(this.preroll.msg)); + this.elems.block.find('.ad-video-block__info').text(''); + if (this.preroll.msg) this.elems.block.find('.ad-video-block__text').text(this.preroll.msg + ' - ' + Lang.translate('ad_disable')).toggleClass('hide', false); + this.elems.block.on('click', this.skip.bind(this)); + document.body.append(this.elems.block); + this.listener.send('launch'); + this.controller(); + this.timeout(); + console.log('Ad3', 'run', this.preroll.name, 'from', this.preroll.name == 'plugin' ? 'plugin' : 'cub'); + this.elems.status.text('Loading IMA SDK...'); + IMA.loadSDK3().then(function () { + if (_this.removed) return; + + _this.elems.status.text('Initialize...'); + + try { + _this.initialize(); + + stat$1('run', _this.preroll.name); + } catch (e) { + _this.error(400, 'Initialize', e ? e.message : ''); + } + })["catch"](function (e) { + _this.error(500, 'SDK Load', e ? e.message : ''); + }); + } + /** + * Контроллер рекламы + */ + + }, { + key: "controller", + value: function controller() { + Controller.add('ad_video_block', { + toggle: function toggle() { + Controller.clear(); + }, + enter: this.skip.bind(this), + back: this.skip.bind(this) + }); + Controller.toggle('ad_video_block'); + } + /** + * Ждём загрузки определённое время, затем выдаём ошибку + */ + + }, { + key: "timeout", + value: function timeout() { + var _this2 = this; + + this.tiks.timeout = setTimeout(function () { + _this2.error(300, 'Timeout'); + }, this.timewait); + } + /** + * Инициализация Google IMA SDK (VAST 3.0) + */ + + }, { + key: "initialize", + value: function initialize() { + var ima = window.google.ima; + ima.settings.setVpaidMode(ima.ImaSdkSettings.VpaidMode.ENABLED); + ima.settings.setLocale('ru'); + this.adContainer = this.elems.container; + var displayContainer = new ima.AdDisplayContainer(this.adContainer, this.elems.video); + displayContainer.initialize(); + this.adsLoader = new ima.AdsLoader(displayContainer); + this.adsLoader.addEventListener(ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, this.onAdsManagerLoaded.bind(this), false); + this.adsLoader.addEventListener(ima.AdErrorEvent.Type.AD_ERROR, this.onAdError.bind(this), false); + var request = new ima.AdsRequest(); + request.adTagUrl = this.url(); + request.linearAdSlotWidth = this.adContainer.offsetWidth || window.innerWidth; + request.linearAdSlotHeight = this.adContainer.offsetHeight || window.innerHeight; + request.nonLinearAdSlotWidth = this.adContainer.offsetWidth || window.innerWidth; + request.nonLinearAdSlotHeight = Math.floor((this.adContainer.offsetHeight || window.innerHeight) / 3); + this.adsLoader.requestAds(request); + this.elems.status.text('Requesting...'); + } + /** + * AdsManager загружен + */ + + }, { + key: "onAdsManagerLoaded", + value: function onAdsManagerLoaded(loadedEvent) { + var _this3 = this; + + if (this.removed) return; + var ima = window.google.ima; + var adsRenderingSettings = new ima.AdsRenderingSettings(); + adsRenderingSettings.uiElements = []; // скрываем встроенную кнопку пропуска IMA SDK + + this.adsManager = loadedEvent.getAdsManager(this.elems.video, adsRenderingSettings); + this.adsManager.addEventListener(ima.AdErrorEvent.Type.AD_ERROR, this.onAdError.bind(this), false); + this.adsManager.addEventListener(ima.AdEvent.Type.STARTED, this.onStarted.bind(this), false); + this.adsManager.addEventListener(ima.AdEvent.Type.COMPLETE, this.onComplete.bind(this), false); + this.adsManager.addEventListener(ima.AdEvent.Type.ALL_ADS_COMPLETED, this.onComplete.bind(this), false); + this.adsManager.addEventListener(ima.AdEvent.Type.SKIPPED, this.onComplete.bind(this), false); + this.adsManager.addEventListener(ima.AdEvent.Type.AD_PROGRESS, this.onAdProgress.bind(this), false); + this.adsManager.addEventListener(ima.AdEvent.Type.PAUSED, function () { + _this3.paused = true; + }, false); + this.adsManager.addEventListener(ima.AdEvent.Type.RESUMED, function () { + _this3.paused = false; + }, false); + this.elems.status.text('Loaded'); + + try { + this.adsManager.init(this.adContainer.offsetWidth || window.innerWidth, this.adContainer.offsetHeight || window.innerHeight, ima.ViewMode.NORMAL); + this.adsManager.setVolume(0.5); + this.adsManager.start(); + } catch (e) { + this.error(401, 'AdsManager init', e ? e.message : ''); + } + } + /** + * Ошибка IMA SDK + */ + + }, { + key: "onAdError", + value: function onAdError(adErrorEvent) { + var msg = adErrorEvent && adErrorEvent.getError ? adErrorEvent.getError().getMessage() : 'Unknown error'; + console.log('Ad3', 'ima error', msg); + if (!this.removed) this.error(100, msg); + } + /** + * Реклама запущена + */ + + }, { + key: "onStarted", + value: function onStarted(adEvent) { + var _this4 = this; + + if (this.removed) return; + console.log('Ad3', 'event', 'started'); + var ad = adEvent.getAd(); + var duration = ad ? ad.getDuration() : this.skip_time; + this.elems.status.text('Started: ' + (duration ? Math.round(duration) + 's' : '')); + stat$1('started', this.preroll.name); + clearTimeout(this.tiks.timeout); + this.elems.loader.remove(); + this.elems.container.style.opacity = 1; + var skip_from_ad = ad ? ad.getSkipTimeOffset() : -1; + this.skip_time = skip_from_ad > 0 ? Math.round(Math.min(60, skip_from_ad)) : Math.round(Math.max(this.skip_time, Math.min(60, duration * 0.8))); + this.started_time = Date.now(); + this.ad_duration = duration; + console.log('Ad3', 'skip time set to:', this.skip_time); + clearInterval(this.tiks.progress); + this.tiks.progress = setInterval(this.onProgress.bind(this), 100); + clearTimeout(this.tiks.watch); + this.tiks.watch = setTimeout(function () { + console.log('Ad3', 'error', 'watch timeout', duration); + + _this4.elems.status.text('Watch timeout: ' + duration + 's'); + + _this4.stop(); + + _this4.onEnd(); + }, Math.round((duration + 5) * 1000)); + } + /** + * Прогресс из IMA SDK + */ + + }, { + key: "onAdProgress", + value: function onAdProgress(adEvent) { + var data = adEvent.getAdData(); + + if (data) { + var duration = data.duration || this.ad_duration || this.skip_time; + var current = data.currentTime || (Date.now() - this.started_time) / 1000; + var remaining = duration - current; + var progress = Math.min(100, current / duration * 100); + this.elems.progressbar.style.width = progress + '%'; + this.skip_ready = current > this.skip_time; + var user_view = Math.max(0, duration > this.skip_time ? this.skip_time - current : remaining); + this.elems.skip.find('span').text(Lang.translate(this.skip_ready ? 'ad_skip' : Math.ceil(user_view))); + } + } + /** + * Обновление прогресса по таймеру (резервный) + */ + + }, { + key: "onProgress", + value: function onProgress() { + var duration = this.ad_duration || this.skip_time; + var elapsed = (Date.now() - this.started_time) / 1000; + var remaining = duration - elapsed; + var progress = Math.min(100, elapsed / duration * 100); + this.elems.progressbar.style.width = progress + '%'; + this.skip_ready = elapsed > this.skip_time; + var user_view = Math.max(0, duration > this.skip_time ? this.skip_time - elapsed : remaining); + this.elems.skip.find('span').text(Lang.translate(this.skip_ready ? 'ad_skip' : Math.ceil(user_view))); + if (remaining <= 0) clearInterval(this.tiks.progress); + } + /** + * Реклама завершена + */ + + }, { + key: "onComplete", + value: function onComplete() { + if (this.removed) return; + console.log('Ad3', 'complete event'); + this.destroy(); + this.onEnd(); + } + /** + * Событие окончания рекламы + */ + + }, { + key: "onEnd", + value: function onEnd() { + console.log('Ad3', 'complete'); + stat$1('complete', this.preroll.name); + this.listener.send('ended'); + } + /** + * Сформировать URL для запроса рекламы + */ + + }, { + key: "url", + value: function url() { + return IMA.buildUrl(this.preroll.url); + } + /** + * Обработка ошибки + */ + + }, { + key: "error", + value: function error(code, msg) { + console.log('Ad3', 'error', code, msg); + this.stop(); + this.listener.send('error'); + stat$1('error', this.preroll.name); + stat$1('error_' + code, this.preroll.name); + } + /** + * Пропустить рекламу если можно + */ + + }, { + key: "skip", + value: function skip() { + if (this.removed) return; + + if (this.skip_ready || (Date.now() - this.created_at) / 1000 > this.skip_time) { + this.stop(); + this.onEnd(); + } + } + /** + * Остановить рекламу принудительно + */ + + }, { + key: "stop", + value: function stop() { + try { + if (this.adsManager) { + this.adsManager.stop(); + this.adsManager.destroy(); + this.adsManager = null; + } + } catch (e) { + console.error('Ad3', 'stop error', e ? e.message : ''); + } + + this.destroy(); + } + /** + * Уничтожить + */ + + }, { + key: "destroy", + value: function destroy() { + if (this.removed) return; + clearTimeout(this.tiks.timeout); + clearTimeout(this.tiks.watch); + clearInterval(this.tiks.progress); + + if (this.adsLoader) { + try { + this.adsLoader.destroy(); + } catch (e) {} + + this.adsLoader = null; + } + + this.elems.block.remove(); + this.removed = true; + } + }]); + + return Vast3; + }(); + + var VastManager = /*#__PURE__*/function () { + function VastManager(params) { + _classCallCheck(this, VastManager); + + this.played = { + time: 0, + prerolls: [] + }; + this.data_loaded = { + ad: [] + }; + Arrays.extend(params, { + api: 'preroll', + cooling: 1000 * 60 * 5 + }); + this.params = params; + } + + _createClass(VastManager, [{ + key: "init", + value: function init() { + this.load(); + Timer.add(1000 * 60 * 60, this.load.bind(this)); + } + }, { + key: "load", + value: function load() { + var pos = 0; + var self = this; + + var request = function request() { + var domain = object$2.cub_mirrors[pos]; + if (!domain) return; + var url = Utils$1.protocol() + domain + '/api/ad/get/' + self.params.api; + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.timeout = 10000; + + xhr.onload = function () { + if (xhr.status >= 200 && xhr.status < 300) { + try { + var data = JSON.parse(xhr.responseText); + + if (data.ad && Arrays.isArray(data.ad)) { + self.data_loaded.ad = data.ad; + console.log('Ad', 'manager ' + self.params.api, 'loaded', self.data_loaded.ad.length); + } else { + console.log('Ad', 'manager ' + self.params.api, 'wrong format from', domain); + pos++; + request(); + } + } catch (e) { + console.log('Ad', 'manager ' + self.params.api, 'parse error from', domain); + pos++; + request(); + } + } else { + console.log('Ad', 'manager ' + self.params.api, 'no load from', domain); + pos++; + request(); + } + }; + + xhr.onerror = function () { + console.log('Ad', 'manager ' + self.params.api, 'no load from', domain); + pos++; + request(); + }; + + xhr.ontimeout = function () { + console.log('Ad', 'manager ' + self.params.api, 'timeout from', domain); + pos++; + request(); + }; + + xhr.send(); + }; + + request(); + } + }, { + key: "coolingReady", + value: function coolingReady() { + return Date.now() - this.played.time > this.params.cooling; + } + }, { + key: "markCooling", + value: function markCooling() { + this.played.time = Date.now(); + } + }, { + key: "whitoutGenres", + value: function whitoutGenres(whitout_genre) { + var movie = Storage.get('activity', '{}').movie; + + try { + var genres = whitout_genre.split(',').map(function (g) { + return parseInt(g); + }); + + if (genres.length && movie.genres.find(function (g) { + return genres.find(function (gg) { + return gg == g.id; + }); + })) { + return true; + } + } catch (e) {} + } + }, { + key: "orderTag", + value: function orderTag(tags) { + tags.sort(function (a, b) { + return b.impressions - a.impressions; + }); + return tags[0]; + } + }, { + key: "filter", + value: function filter(view) { + var _this = this; + + view = view.filter(function (v) { + return !_this.played.prerolls.find(function (pr) { + return pr == v.name; + }); + }); + + if (!window.lampa_settings.developer.ads) { + view = view.filter(function (v) { + return _this.whitoutGenres(v.whitout_genre) !== true; + }); + view = view.filter(function (v) { + return v.screen == (Platform.screen('tv') ? 'tv' : 'mobile') || v.screen == 'all'; + }); + view = view.filter(function (v) { + return v.platforms.indexOf(Platform.get()) !== -1 || v.platforms.indexOf('all') !== -1 || !v.platforms.length; + }); + view = view.filter(function (v) { + return v.region.split(',').indexOf(vpn.code()) !== -1 || v.region.indexOf('all') !== -1 || !v.region.length; + }); + } + + console.log('Ad', 'manager ' + this.params.api, 'filter view', view); + + if (view.length) { + var preroll = this.orderTag(view); + this.played.prerolls.push(preroll.name); + return preroll; + } + + return null; + } + }, { + key: "get", + value: function get() { + var first_run = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + if (first_run) this.played.prerolls = []; + return this.data_loaded.ad.length ? this.filter(this.data_loaded.ad) : null; + } + }]); + + return VastManager; + }(); + + var running = 0; + var player_data = {}; + var prerolls_played = []; + var Manager$1 = new VastManager({ + api: 'preroll', + cooling: 1000 * 60 * 5 + }); + + function init$N() { + Manager$1.init(); + } + /** + * Показать преролл + * @param {Object} preroll - данные для показа рекламы + * @param {Number} num - номер показа рекламы (для повторов) + * @param {Function} started - вызывается при запуске рекламы + * @param {Function} ended - вызывается при окончании рекламы + * @return {void} + */ + + + function video(preroll, num, started, ended) { + console.log('Ad', 'preroll launch'); + var advert = preroll.vast_api == 3 ? new Vast3(preroll) : new Vast(preroll); + + var next = function next(mark) { + var any = getAnyPreroll(); + mark && Manager$1.markCooling(); + any ? video(any, num + 1, started, ended) : ended(); + }; + + advert.listener.follow('launch', started); + advert.listener.follow('ended', function () { + num < 2 ? next() : ended(); + }); + advert.listener.follow('error', function () { + Date.now() - running < 15000 && num < 4 ? next() : ended(); + }); + } + /** + * Показать заставку (реклама) + * @param {Object} preroll - данные для показа рекламы + * @param {Function} call - вызывается при окончании рекламы + * @return {void} + */ + + + function launch(preroll, call) { + var enabled = Controller.enabled().name; + Background.theme('#454545'); + var html = $("\n
    \n
    \n
    ".concat(Lang.translate('ad'), "
    \n
    \n
    \n ")); + $('body').append(html); + setTimeout(function () { + html.find('.ad-preroll__bg').addClass('animate'); + setTimeout(function () { + html.find('.ad-preroll__text').addClass('animate'); + }, 500); + }, 100); + setTimeout(function () { + html.find('.ad-preroll__over').addClass('animate'); + setTimeout(function () { + Controller.toggle(enabled); + Background.theme('black'); + video(preroll, 1, function () {}, function () { + html.remove(); + Background.theme('reset'); + Controller.toggle(enabled); + call(); + }); + }, 300); + }, 3500); + Controller.add('ad_preroll', { + toggle: function toggle() { + Controller.clear(); + }, + enter: function enter() {}, + back: function back() {} + }); + Controller.toggle('ad_preroll'); + } + /** + * Получить данные для плагина + * @param {Object} data - данные плеера + * @return {Object|Boolean} данные для плагина или false, если не показывать + */ + + + function getVastPlugin(data) { + var show = true; + if (data.vast_region && typeof data.vast_region == 'string' && data.vast_region.split(',').indexOf(data.ad_region) == -1) show = false; + if (data.vast_platform && typeof data.vast_platform == 'string' && data.vast_platform.split(',').indexOf(Platform.get()) == -1) show = false; + if (data.vast_screen && typeof data.vast_screen == 'string' && data.vast_screen.split(',').indexOf(Platform.screen('tv') ? 'tv' : 'mobile') == -1) show = false; + if (data.vast_url && typeof data.vast_url == 'string' && show) return { + url: data.vast_url, + name: 'plugin', + msg: data.vast_msg || Lang.translate('ad_plugin') + }; + return false; + } + /** + * Получить данные для показа рекламы (преролл или плагин) + * @param {Boolean} first_run - первый запуск (для сброса кулинга) + * @return {Object|Boolean} данные для показа рекламы или false, если не показывать + */ + + + function getAnyPreroll() { + var first_run = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var manager = Manager$1.get(first_run); + var plugin = getVastPlugin(player_data); + var any = Manager$1.coolingReady() ? manager || plugin : false; + + if (any) { + if (prerolls_played.indexOf(any.url) == -1) prerolls_played.push(any.url);else any = false; + } + + return any; + } + /** + * Показать рекламу (преролл или плагин) + * @param {Object} data - данные плеера + * @param {Function} call - вызывается при окончании рекламы + * @return {void} + */ + + + function show$5(data, call) { + player_data = data; + prerolls_played = []; // Пометить регион для таргетинга рекламы + + player_data.ad_region = vpn.code(); // Не показывать рекламу для iptv/torrent/youtube/continue + + var type = IMA.getMediaType(data); + var whoi = Account$1.hasPremium() ? 'premium' : Personal.confirm() ? 'personal' : 'none'; + ServiceMetric.counter('ad_preroll_start', vpn.code(), whoi, type.any ? 'skip' : 'show'); + + if (type.any) { + console.log('Ad', 'preroll skipped, no vast api or iptv/torrent/youtube/continue', type); + return call(); + } // Бывает что плеер по несколько раз запускается, + // проверяем чтобы реклама не запускалась несколько раз подряд + + + if (running) return console.log('Ad', 'preroll skipped, already running'); // Помечаем время запуска рекламы + + running = Date.now(); + + var ended = function ended() { + running = 0; + console.log('Ad', 'preroll ended'); + call(); + }; // Получаем данные для показа рекламы (преролл или плагин) + + + var preroll = getAnyPreroll(true); + var canshow = IMA.canShow(data); + ServiceMetric.counter('ad_preroll_show', vpn.code(), preroll ? 'ready' : 'none', canshow ? 'ready' : 'none'); + ServiceMetric.counter('ad_preroll_colling', vpn.code(), Manager$1.coolingReady() ? 'ready' : 'cooling'); + + if (preroll && canshow) { + // Загружаем SDK для выбранного преролла, чтобы он был готов к показу + IMA.loadSDK(preroll.vast_api)["catch"](function () { + console.log('Ad', 'IMA SDK load error', preroll.vast_api); + }); + launch(preroll, ended); + } else ended(); + } + + var Preroll = { + init: init$N, + show: show$5 + }; + + var _DEFAULT_PLAYER_CONFI; + var POLLING_INTERVAL_MS = 5000; + var MAX_FAILED_ATTEMPTS = 3; + var PLAYER_TYPES = { + VLC: 'vlc', + MPC_HC: 'mpc-hc', + MPC_BE: 'mpc-be', + MPC_QT: 'mpc-qt', + KMPLAYER: 'kmplayer' + }; + var DEFAULT_PLAYER_CONFIG = (_DEFAULT_PLAYER_CONFI = {}, _defineProperty(_DEFAULT_PLAYER_CONFI, PLAYER_TYPES.VLC, { + port: 3999, + password: '123456', + fullscreen: true + }), _defineProperty(_DEFAULT_PLAYER_CONFI, PLAYER_TYPES.MPC_HC, { + port: 3999, + password: null, + fullscreen: true + }), _defineProperty(_DEFAULT_PLAYER_CONFI, PLAYER_TYPES.MPC_BE, { + port: 3999, + password: null, + fullscreen: true + }), _defineProperty(_DEFAULT_PLAYER_CONFI, PLAYER_TYPES.MPC_QT, { + port: 3999, + password: null, + fullscreen: true + }), _defineProperty(_DEFAULT_PLAYER_CONFI, PLAYER_TYPES.KMPLAYER, { + port: 3999, + password: null, + fullscreen: true + }), _DEFAULT_PLAYER_CONFI); + var playerCallbacks = {}; + var pollingInterval = null; + var lastSuccessfulTimecode = null; + var currentPlayerProcess = null; + var currentHash = null; + var failedAttempts = 0; + /** + * Получение URL API в зависимости от типа плеера + */ + + function getPlayerURL(config) { + switch (config.type) { + case PLAYER_TYPES.VLC: + return "http://localhost:".concat(config.port, "/requests/status.json"); + + case PLAYER_TYPES.MPC_HC: + case PLAYER_TYPES.MPC_BE: + case PLAYER_TYPES.MPC_QT: + return "http://localhost:".concat(config.port, "/variables.html"); + + case PLAYER_TYPES.KMPLAYER: + return "http://localhost:".concat(config.port, "/status.html"); + + default: + throw new Error("Unknown player type: ".concat(config.type)); + } + } + /** + * Парсинг ответа MPC-HC/MPC-BE/MPC-QT из HTML + */ + + + function parseMPCResponse(html) { + var parser = new DOMParser(); + var doc = parser.parseFromString(html, 'text/html'); + + var getValue = function getValue(id) { + var element = doc.getElementById(id); + return element ? element.textContent : null; + }; + + var state = getValue('state'); + var position = getValue('position'); + var duration = getValue('duration'); + var statestring = getValue('statestring'); + var file = getValue('file'); + var filepath = getValue('filepath'); + return { + state: state ? parseInt(state) : null, + statestring: statestring, + position: position ? parseInt(position) : null, + duration: duration ? parseInt(duration) : null, + file: file, + filepath: filepath, + volumelevel: getValue('volumelevel'), + muted: getValue('muted'), + playbackrate: getValue('playbackrate') + }; + } + /** + * Парсинг ответа KMPlayer + */ + + + function parseKMPlayerResponse(text) { + var startIndex = text.indexOf('OnStatus('); + if (startIndex === -1) return null; + var argsStart = startIndex + 9; + var lastParen = text.lastIndexOf(')'); + if (lastParen === -1) return null; + var argsStr = text.substring(argsStart, lastParen); + var args = []; + var current = ''; + var inQuotes = false; + + for (var i = 0; i < argsStr.length; i++) { + var _char = argsStr.charAt(i); + + if (_char === '"') { + inQuotes = !inQuotes; + } else if (_char === ',' && !inQuotes) { + args.push(current.trim()); + current = ''; + } else { + current += _char; + } + } + + args.push(current.trim()); + + for (var _i = 0; _i < args.length; _i++) { + args[_i] = args[_i].trim(); + + if (args[_i].charAt(0) === '"' && args[_i].charAt(args[_i].length - 1) === '"') { + args[_i] = args[_i].substring(1, args[_i].length - 1); + } + } + + return { + file: args[0] || null, + statestring: args[1] || null, + position: args[2] ? parseInt(args[2], 10) : null, + duration: args[4] ? parseInt(args[4], 10) : null, + url: args[8] || null + }; + } + /** + * Парсинг ответа VLC из JSON + */ + + + function parseVLCResponse(json) { + return { + time: json.time, + length: json.length, + state: json.state, + stats: json.stats + }; + } + /** + * Нормализация данных таймкода из разных плееров + */ + + + function normalizeTimecode(playerData, config) { + if (config.type === PLAYER_TYPES.VLC) { + if (playerData.time != null && playerData.length) { + // VLC возвращает секунды + return { + currentTime: playerData.time, + duration: playerData.length, + percent: Math.round(playerData.time / playerData.length * 100) + }; + } + } else if (config.type === PLAYER_TYPES.MPC_HC || config.type === PLAYER_TYPES.MPC_BE || config.type === PLAYER_TYPES.MPC_QT || config.type === PLAYER_TYPES.KMPLAYER) { + if (playerData.position && playerData.duration) { + // MPC-HC, MPC-BE, MPC-QT и KMPlayer возвращают миллисекунды + return { + currentTime: playerData.position / 1000, + duration: playerData.duration / 1000, + percent: Math.round(playerData.position / playerData.duration * 100) + }; + } + } + + return null; + } + /** + * Получение статуса плеера + */ + + + function getPlayerStatus(htmlOrJson, config) { + if (config.type === PLAYER_TYPES.VLC) { + return parseVLCResponse(htmlOrJson); + } else if (config.type === PLAYER_TYPES.MPC_HC || config.type === PLAYER_TYPES.MPC_BE || config.type === PLAYER_TYPES.MPC_QT) { + return parseMPCResponse(htmlOrJson); + } else if (config.type === PLAYER_TYPES.KMPLAYER) { + return parseKMPlayerResponse(htmlOrJson); + } + + return null; + } + /** + * Сохранение таймкода при закрытии плеера + */ + + + function saveTimecodeOnPlayerClose(hash) { + if (lastSuccessfulTimecode && hash && playerCallbacks[hash]) { + console.log('Player', 'Процесс закрылся, сохраняем последний timecode:', lastSuccessfulTimecode); + playerCallbacks[hash](lastSuccessfulTimecode.percent, lastSuccessfulTimecode.currentTime, lastSuccessfulTimecode.duration); + stopTimecodePolling(); + delete playerCallbacks[hash]; + currentPlayerProcess = null; + currentHash = null; + } else if (hash && playerCallbacks[hash]) { + console.log('Player', 'Процесс закрылся, но timecode не был получен'); + stopTimecodePolling(); + delete playerCallbacks[hash]; + currentPlayerProcess = null; + currentHash = null; + } + } + /** + * Получение и сохранение статуса из плеера + */ + + + function fetchAndSaveTimecode(config, hash) { + var fetchOptions = {}; // Добавляем авторизацию только для VLC + + if (config.type === PLAYER_TYPES.VLC && config.password) { + fetchOptions.headers = { + 'Authorization': "Basic ".concat(btoa(':' + config.password)) + }; + } + + return fetch(getPlayerURL(config), fetchOptions).then(function (response) { + if (!response.ok) { + throw new Error('Player API вернул ошибку'); + } + + if (config.type === PLAYER_TYPES.VLC) { + return response.json(); + } else if (config.type === PLAYER_TYPES.MPC_HC || config.type === PLAYER_TYPES.MPC_BE || config.type === PLAYER_TYPES.MPC_QT || config.type === PLAYER_TYPES.KMPLAYER) { + return response.text(); + } + }).then(function (data) { + failedAttempts = 0; + var playerStatus = getPlayerStatus(data, config); + + if (playerStatus) { + var timecode = normalizeTimecode(playerStatus, config); + + if (timecode) { + lastSuccessfulTimecode = timecode; // console.log('Player', 'Timecode обновлен:', lastSuccessfulTimecode) + } + } + })["catch"](function (error) { + console.error('Player', 'Ошибка получения timecode:', error); + failedAttempts++; + console.log('Player', "\u041D\u0435\u0443\u0434\u0430\u0447\u043D\u044B\u0445 \u043F\u043E\u043F\u044B\u0442\u043E\u043A: ".concat(failedAttempts, "/").concat(MAX_FAILED_ATTEMPTS)); + + if (!currentPlayerProcess || failedAttempts >= MAX_FAILED_ATTEMPTS) { + if (!currentPlayerProcess) { + console.log('Player', 'Процесс закрыт, останавливаем polling'); + } else { + console.log('Player', 'Превышен лимит неудачных попыток, останавливаем polling'); + } + + if (lastSuccessfulTimecode && playerCallbacks[hash]) { + console.log('Player', 'Сохраняем последний timecode перед остановкой'); + playerCallbacks[hash](lastSuccessfulTimecode.percent, lastSuccessfulTimecode.currentTime, lastSuccessfulTimecode.duration); + } + + stopTimecodePolling(); + + if (playerCallbacks[hash]) { + delete playerCallbacks[hash]; + } + + currentHash = null; + } + + throw error; + }); + } + /** + * Запуск периодического опроса timecode из плеера + * @param {string} hash - идентификатор сессии + * @param {Object} data - данные сессии + * @param {Object} config - конфигурация плеера + */ + + + function startTimecodePolling(hash, data, config) { + stopTimecodePolling(); + lastSuccessfulTimecode = null; + failedAttempts = 0; + console.log('Player', 'Делаем первый запрос timecode'); + fetchAndSaveTimecode(config, hash)["catch"](function (error) { + console.error('Player', 'Первый запрос не удался'); + }); + pollingInterval = setInterval(function () { + if (!currentPlayerProcess) { + console.log('Player', 'Процесс не найден, останавливаем polling'); + stopTimecodePolling(); + return; + } + + fetchAndSaveTimecode(config, hash)["catch"](function (error) {// Ошибка уже обработана в fetchAndSaveTimecode + }); + }, POLLING_INTERVAL_MS); + } + /** + * Остановка периодического опроса timecode + */ + + + function stopTimecodePolling() { + if (pollingInterval) { + clearInterval(pollingInterval); + pollingInterval = null; + lastSuccessfulTimecode = null; + failedAttempts = 0; + } + } + /** + * Получение аргументов командной строки для разных плееров + */ + + + function getPlayerArgs(config, url, data) { + var _data$timeline$time, _data$timeline; + + // const startTime = (data.timeline?.time ?? 0) * 1000 + var startTimeSec = (_data$timeline$time = (_data$timeline = data.timeline) === null || _data$timeline === void 0 ? void 0 : _data$timeline.time) !== null && _data$timeline$time !== void 0 ? _data$timeline$time : 0; + + if (config.type === PLAYER_TYPES.VLC) { + var vlcArgs = ['--extraintf=http', '--http-host=localhost', "--http-port=".concat(config.port), "--http-password=".concat(config.password), "--start-time=".concat(startTimeSec), '--play-and-exit', '--no-loop', encodeURI(url)]; + + if (config.fullscreen !== false) { + vlcArgs.push('--fullscreen'); + } + + return vlcArgs; + } else if (config.type === PLAYER_TYPES.MPC_HC || config.type === PLAYER_TYPES.MPC_BE || config.type === PLAYER_TYPES.MPC_QT || config.type === PLAYER_TYPES.KMPLAYER) { + var mpcArgs = [url, '/webport', config.port.toString(), '/start', Math.floor(startTimeSec * 1000).toString(), '/play', '/close']; + + if (config.fullscreen !== false) { + mpcArgs.push('/fullscreen'); + } + + return mpcArgs; + } + + return []; + } + /** + * Запуск плеера + * @param {string} url - URL медиафайла + * @param {Object} data - дополнительные данные + * @param {Object} options - опции запуска + */ + + + function openPlayer$1(url, data) { + var _DEFAULT_PLAYER_CONFI2, _DEFAULT_PLAYER_CONFI3, _DEFAULT_PLAYER_CONFI4; + + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$type = options.type, + type = _options$type === void 0 ? PLAYER_TYPES.VLC : _options$type, + _options$port = options.port, + port = _options$port === void 0 ? (_DEFAULT_PLAYER_CONFI2 = DEFAULT_PLAYER_CONFIG[type]) === null || _DEFAULT_PLAYER_CONFI2 === void 0 ? void 0 : _DEFAULT_PLAYER_CONFI2.port : _options$port, + _options$password = options.password, + password = _options$password === void 0 ? (_DEFAULT_PLAYER_CONFI3 = DEFAULT_PLAYER_CONFIG[type]) === null || _DEFAULT_PLAYER_CONFI3 === void 0 ? void 0 : _DEFAULT_PLAYER_CONFI3.password : _options$password, + _options$fullscreen = options.fullscreen, + fullscreen = _options$fullscreen === void 0 ? (_DEFAULT_PLAYER_CONFI4 = DEFAULT_PLAYER_CONFIG[type]) === null || _DEFAULT_PLAYER_CONFI4 === void 0 ? void 0 : _DEFAULT_PLAYER_CONFI4.fullscreen : _options$fullscreen; + + var file = require('fs'); + + var config = { + type: type, + port: port, + password: password, + fullscreen: fullscreen + }; // Сохраняем hash сразу, чтобы он был доступен при закрытии + + if (data.timeline) { + currentHash = data.timeline.hash; + playerCallbacks[data.timeline.hash] = data.timeline.handler; + } + + var playerPath = Storage.field('player_nw_path'); + var playerArgs = getPlayerArgs(config, url, data); + console.log('Player', 'Путь:', playerPath); + console.log('Player', 'Аргументы:', playerArgs); + + if (playerPath && file.existsSync(playerPath)) { + var spawn = require('child_process').spawn; + + if (currentPlayerProcess) { + console.log('Player', 'Убиваем предыдущий процесс'); + currentPlayerProcess.kill(); + currentPlayerProcess = null; + } + + currentPlayerProcess = spawn(playerPath, playerArgs); + + var handleProcessClose = function handleProcessClose(code, signal) { + console.log('Player', 'Процесс закрыт с кодом:', code, 'сигнал:', signal); + + if (currentHash && playerCallbacks[currentHash]) { + saveTimecodeOnPlayerClose(currentHash); + } else { + // Если нет колбэка, просто очищаем состояние + stopTimecodePolling(); + currentHash = null; + } + + currentPlayerProcess = null; + }; + + currentPlayerProcess.on('close', handleProcessClose); + currentPlayerProcess.on('error', function (error) { + console.error('Player', 'Ошибка процесса:', error); + + if (currentPlayerProcess) { + currentPlayerProcess = null; + } + + handleProcessClose(null, 'error'); + }); + currentPlayerProcess.on('exit', handleProcessClose); + } else { + Noty.show(Lang.translate('player_not_found') + ': ' + playerPath); + return; + } + + setTimeout(function () { + if (data.timeline && currentPlayerProcess) { + startTimecodePolling(data.timeline.hash, data, config); + } + }, 2000); + } + + var ExternalPlayer = { + openPlayer: openPlayer$1, + stopTimecodePolling: stopTimecodePolling, + PLAYER_TYPES: PLAYER_TYPES + }; + + var SAVE_PREFIX = 'infuse://x-callback-url/save?'; + var PLAY_PREFIX = 'infuse://x-callback-url/play?'; + var SEASON_EPISODE_RE = /\[S(\d+):E(\d+)\]/i; + var DEFAULTS = { + mode: 'play', + // save | play | save_and_play + seasonOnly: true, + maxItems: 40, + maxUrlLength: 65536, + // false = не добавлять [источник] в filename; true + data.source = показывать [источник] + filenameSource: true, + // false = без озвучки; true + voice_name/title = показывать в filename + filenameVoice: true + }; + + function parsePositiveInt(value) { + var parsed = parseInt(value, 10); + return !isNaN(parsed) && parsed > 0 ? parsed : null; + } + + function stripText(value) { + if (!value) return ''; + var text = Utils$1.clearHtmlTags ? Utils$1.clearHtmlTags(String(value)) : String(value).replace(/<[^>]*>/g, ''); + return text.replace(/\s+/g, ' ').trim(); + } + + function pad2(value) { + var num = parseInt(value, 10) || 0; + return num < 10 ? '0' + num : '' + num; + } + + function sanitizeStreamUrl(url) { + return String(url || '').replace('&preload', '&play').replace(/\s/g, '%20'); + } + + function normalizePlayData(data) { + if (!data) return data; + + if (typeof data.url === 'string') { + data.url = sanitizeStreamUrl(data.url); + } + + if (Array.isArray(data.playlist)) { + data.playlist.forEach(function (item) { + if (item && typeof item.url === 'string') { + item.url = sanitizeStreamUrl(item.url); + } + }); + } + + return data; + } + + function serializePlaylist(playlist) { + if (!Array.isArray(playlist) || !playlist.length) return ''; + var safe = playlist.filter(function (item) { + return item && !item.separator && typeof item.url === 'string'; + }).map(function (item) { + var entry = { + url: sanitizeStreamUrl(item.url) + }; + if (item.title) entry.title = stripText(item.title); + return entry; + }); + if (!safe.length) return ''; + + try { + return encodeURIComponent(JSON.stringify(safe)); + } catch (e) { + return ''; + } + } + + function compareStreamUrl(a, b) { + if (!a || !b) return false; + a = sanitizeStreamUrl(a); + b = sanitizeStreamUrl(b); + if (a === b) return true; + var baseA = a.split('?')[0]; + var baseB = b.split('?')[0]; + if (baseA !== baseB) return false; + var indexA = (a.match(/[?&]index=(\d+)/i) || [])[1]; + var indexB = (b.match(/[?&]index=(\d+)/i) || [])[1]; + if (indexA != null || indexB != null) return indexA === indexB; + return true; + } + + function parseEpisodeMeta(item) { + if (!item) return { + season: null, + episode: null + }; + var season = parsePositiveInt(item.season != null ? item.season : item.season_number); + var episode = parsePositiveInt(item.episode != null ? item.episode : item.episode_number); + + if ((!season || !episode) && item.subtitle) { + var subtitle = stripText(item.subtitle); + var episodeMatch = subtitle.match(/(\d+)\s*$/); + if (!episode) episode = parsePositiveInt(episodeMatch && episodeMatch[1]); + } + + if ((!season || !episode) && item.title) { + var title = String(item.title); + var match = title.match(SEASON_EPISODE_RE); + + if (match) { + if (!season) season = parsePositiveInt(match[1]); + if (!episode) episode = parsePositiveInt(match[2]); + } else { + // Lampa online: "S1 / Серия 5" или "S1 / Episode 5 - title" + var onlineSeasonMatch = title.match(/\bS(\d{1,2})\s*\/\s*/i); + if (!season && onlineSeasonMatch) season = parsePositiveInt(onlineSeasonMatch[1]); + + if (!episode) { + var _episodeMatch = title.match(/(?:серия|episode|ep\.?)\s*(\d{1,3})/i) || title.match(/^(\d+)\s*\//) || title.match(/(?:^|\s)(\d{1,3})\s*[-–]\s/); + + if (_episodeMatch) episode = parsePositiveInt(_episodeMatch[1]); + } + } + } + + if ((!season || !episode) && item.url) { + var _match = String(item.url).match(/[Ss](\d{1,2})[Ee](\d{1,3})/i); + + if (_match) { + if (season == null) season = parsePositiveInt(_match[1]); + if (episode == null) episode = parsePositiveInt(_match[2]); + } + } + + return { + season: season, + episode: episode + }; + } + + function getRawPlaylist(data) { + if (!data || !Array.isArray(data.playlist)) return []; + return data.playlist.filter(function (item) { + return item && !item.separator; + }); + } + + function enrichPlayItem(data, item) { + item = item || {}; + var meta = parseEpisodeMeta(item); + var patch = {}; + if (item.season == null && meta.season != null) patch.season = meta.season;else if (item.season == null && data && data.season != null) patch.season = data.season; + if (item.episode == null && meta.episode != null) patch.episode = meta.episode;else if (item.episode == null && data && data.episode != null) patch.episode = data.episode; + if (!Object.keys(patch).length) return item; + return Object.assign({}, item, patch); + } + + function resolvePlaylist(data) { + var playlist = getRawPlaylist(data); + + if (!playlist.length) { + if (data && data.url) return [enrichPlayItem(data, data)]; + return []; + } + + return playlist.map(function (item) { + return enrichPlayItem(data, item); + }); + } + + function findItemIndexInList(items, data) { + if (!items.length) return -1; + data = data || {}; + var currentUrl = data.url ? sanitizeStreamUrl(data.url) : ''; + + if (currentUrl) { + for (var i = 0; i < items.length; i++) { + if (compareStreamUrl(items[i].url, currentUrl)) return i; + } + } + + var dataMeta = parseEpisodeMeta(data); + + if (dataMeta.episode != null) { + for (var _i = 0; _i < items.length; _i++) { + var meta = parseEpisodeMeta(items[_i]); + if (dataMeta.episode !== meta.episode) continue; + if (dataMeta.season != null && meta.season != null && dataMeta.season !== meta.season) continue; + return _i; + } + } + + return -1; + } + + function findPlayItem(data, playlist) { + playlist = playlist || resolvePlaylist(data); + if (!playlist.length) return data; + var index = findItemIndexInList(playlist, data); + return index >= 0 ? playlist[index] : data; + } + + function normalizeLaunchMode(mode) { + if (mode === 'save' || mode === 'play' || mode === 'save_and_play') return mode; + return DEFAULTS.mode; + } + + function isTorrentStream(data) { + if (!data) return false; + if (data.torrent_hash) return true; + var url = String(data.url || ''); + return /\/stream\/[^?]+\?link=/.test(url); + } + + function resolveInfuseMode(data) { + var mode; + + if (data && data.infuse_mode) { + mode = normalizeLaunchMode(data.infuse_mode); + } else { + var stored = Storage.field('infuse_launch_mode') || DEFAULTS.mode; + if (stored === 'ask') mode = normalizeLaunchMode(DEFAULTS.mode);else mode = normalizeLaunchMode(stored); + } // Торрент: только play? — save не возвращает position + + + if (isTorrentStream(data) && mode !== 'play') return 'play'; + return mode; + } + + function resolveOptions(data) { + var callbacks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + data = data || {}; + var season = data.season != null ? parseInt(data.season, 10) : null; + + if ((season == null || isNaN(season)) && data) { + season = parseEpisodeMeta(data).season; + } + + return { + mode: resolveInfuseMode(data), + seasonOnly: isTorrentStream(data) ? false : data.infuse_season_only !== false, + season: season, + maxItems: data.infuse_max_items || DEFAULTS.maxItems, + maxUrlLength: data.infuse_max_url_length || DEFAULTS.maxUrlLength, + source: data.source || '', + x_success: callbacks.x_success, + x_error: callbacks.x_error + }; + } + + function getExtension(item) { + if (!item || typeof item.url !== 'string') return '.mkv'; + var path = item.url.split('?')[0].split('#')[0].toLowerCase(); + var extMatch = /\.([a-z0-9]{2,5})$/i.exec(path); + if (extMatch) return '.' + extMatch[1].toLowerCase(); + return '.mkv'; + } + + function resolveCard$1(data) { + if (data && (data.card || data.movie)) return data.card || data.movie; + var activity = Activity.active(); + if (activity && (activity.card || activity.movie)) return activity.card || activity.movie; + return null; + } + + function getHumanTitle(movie) { + if (!movie) return ''; + var rawTitle = (movie.original_name || movie.original_title || movie.name || movie.title || '').trim(); + return stripText(rawTitle) || ''; + } + + function isSeriesMedia(movie, item, data) { + if (movie) { + if (movie.media_type === 'tv') return true; + if (movie.first_air_date || movie.number_of_seasons || movie.number_of_episodes) return true; + if (movie.name && !movie.title && !movie.release_date) return true; + } + + var meta = parseEpisodeMeta(item || data); + if (meta.season != null || meta.episode != null) return true; + if (data && (data.season != null || data.episode != null)) return true; + return false; + } + + function resolveMediaTitle(movie, data, item) { + var title = getHumanTitle(movie); + if (title) return title; + var sources = [data && data.title, item && item.title, data && data.path]; + + for (var i = 0; i < sources.length; i++) { + if (!sources[i]) continue; + title = stripText(String(sources[i])).replace(SEASON_EPISODE_RE, '').replace(/\s*\[[^\]]*\]\s*/g, ' ').replace(/\s*\(\d{4}\)\s*/g, ' ').replace(/\s+/g, ' ').trim(); + if (title) return title; + } + + return ''; + } + + function resolveMovieYear(movie, data, item) { + var year = getMovieYear(movie); + if (year) return year; + var text = [data && data.title, item && item.title].filter(Boolean).join(' '); + var match = text.match(/\((\d{4})\)/); + return match ? match[1] : ''; + } + + function formatSourceLabel(raw) { + if (!raw) return ''; + var name = stripText(raw); + if (!name) return ''; + var bracketIdx = name.indexOf('['); + if (bracketIdx !== -1) name = name.slice(0, bracketIdx).trim(); + name = name.replace(/[^\w\u0400-\u04FF.-]+/g, ' ').replace(/\s+/g, ' ').trim(); + if (!name) return ''; + var first = name.split(/\s+/)[0]; + + if (first.endsWith("'s") || first.endsWith('s')) { + first = first.replace(/['']s$/i, '').replace(/s$/i, ''); + } + + return first || name.split(/\s+/)[0]; + } + + function formatVoiceLabel(item, isSeries, humanTitle) { + if (!item) return ''; + var voiceName = stripText(item.voice_name); + var title = stripText(item.title); + + if (!voiceName && !isSeries && title && !SEASON_EPISODE_RE.test(title)) { + voiceName = title; + } + + if (!voiceName) return ''; + if (humanTitle && voiceName.toLowerCase() === humanTitle.toLowerCase()) return ''; + return voiceName.replace(/[\\\/:*?"<>|]/g, '').trim(); + } + + function sanitizeFilenamePart(text) { + if (!text) return ''; + return stripText(text).replace(/[\\\/:*?"<>|\[\]]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, ''); + } + + function appendFilenameTag(base, label) { + var part = sanitizeFilenamePart(label); + if (!part) return base; + return base + ' [' + part + ']'; + } + + function getSubtitleUrl(item, data) { + var subs = item && item.subtitles || data && data.subtitles; + if (!subs || !Array.isArray(subs) || !subs.length) return ''; + + for (var i = 0; i < subs.length; i++) { + if (subs[i] && subs[i].url) return String(subs[i].url); + } + + return ''; + } + + function getMovieYear(movie) { + if (!movie) return ''; + var year = String(movie.release_date || movie.first_air_date || '').slice(0, 4); + return year && year !== '0000' ? year : ''; + } + + function getTorrentFileMeta(item) { + var segment = ''; + + if (item && item.path) { + segment = String(item.path).split('/').pop(); + } else if (item && item.url) { + segment = String(item.url).split('?')[0].split('/').pop() || ''; + + try { + segment = decodeURIComponent(segment); + } catch (e) {} + } + + if (!segment) { + return { + name: 'file', + extension: getExtension(item) + }; + } + + var dotIndex = segment.lastIndexOf('.'); + + if (dotIndex <= 0) { + return { + name: segment, + extension: getExtension(item) + }; + } + + return { + name: segment.slice(0, dotIndex), + extension: segment.slice(dotIndex) + }; + } + + function generateTorrentFilename(item, movie, data, launchMode) { + data = data || item || {}; + item = item || {}; + var fileMeta = getTorrentFileMeta(item); + var isSeries = isSeriesMedia(movie, item, data); + var name = fileMeta.name.replace(/\s*\{tmdb-\d+\}\s*/gi, '').trim(); + var ext = fileMeta.extension || getExtension(item); + if (!name) name = 'file'; + + if (!isSeries && movie && movie.id && name.indexOf('{tmdb-') === -1) { + name += ' {tmdb-' + movie.id + '}'; + } + + return name + ext; + } + + function generateFilename(item, movie, sourceOverride, data, launchMode) { + data = data || item || {}; + var extension = getExtension(item); + var meta = parseEpisodeMeta(item); + var season = meta.season != null ? meta.season : data.season; + var episode = meta.episode != null ? meta.episode : data.episode; + + if (isTorrentStream(data) && episode == null && item && item.path) { + var match = item.path.split('/').pop().replace(/\.[^.]+$/, '').match(/[Ss][\s._-]?(\d+)[\s._-]?[Ee][\s._-]?(\d+)/i); + + if (match) { + season = parseInt(match[1], 10) || season || 1; + episode = parseInt(match[2], 10); + } + } + + var playItem = Object.assign({}, data, item); + if (season != null) playItem.season = season; + if (episode != null) playItem.episode = episode; + var isSeries = isSeriesMedia(movie, playItem, data); + var humanTitle = resolveMediaTitle(movie, data, playItem); + var voiceLabel = formatVoiceLabel(playItem, isSeries, humanTitle); + var sourceLabel = formatSourceLabel(sourceOverride || playItem.source || data.source || ''); + var cleanFilename = normalizeLaunchMode(launchMode) === 'play'; + var base = ''; + + if (isSeries && (season || episode)) { + var titlePart = sanitizeFilenamePart(humanTitle) || 'Series'; + base = titlePart + '-S' + pad2(season || 1) + '-E' + pad2(episode || 1); + } else { + var _titlePart = sanitizeFilenamePart(humanTitle) || 'Movie'; + + var year = resolveMovieYear(movie, data, playItem); + base = year ? _titlePart + '-' + year : _titlePart; + } + + if (!cleanFilename) { + if (voiceLabel && DEFAULTS.filenameVoice) base = appendFilenameTag(base, voiceLabel); + if (sourceLabel && DEFAULTS.filenameSource) base = appendFilenameTag(base, sourceLabel); + } + + if (isSeries) { + base = base.replace(/\s*\{tmdb-\d+\}\s*/gi, '').trim(); + } else if (movie && movie.id && base.indexOf('{tmdb-') === -1) { + base += ' {tmdb-' + movie.id + '}'; + } + + return base + extension; + } + + function getResumePosition(source) { + if (!source || !source.timeline) return 0; + var tl = source.timeline; + + if (tl.time != null && !isNaN(tl.time) && tl.time > 1) { + return Math.max(0, Math.floor(tl.time)); + } + + if (tl.percent != null && tl.duration != null && tl.duration > 0) { + var percent = tl.percent > 1 ? tl.percent / 100 : tl.percent; + return Math.max(0, Math.floor(tl.duration * percent)); + } + + return 0; + } + + function resolveLinkPosition(item, data, url) { + var position = getResumePosition(item); + if (position > 0) return position; + + if (data && url && data.url && compareStreamUrl(url, data.url)) { + return getResumePosition(data); + } + + return 0; + } + + function linkToQueryPart(link, position) { + var part = 'url=' + encodeURIComponent(link.url); + + if (position != null && !isNaN(position) && position > 0) { + part += '&position=' + Math.floor(position); + } + + if (link.filename) part += '&filename=' + encodeURIComponent(link.filename); + if (link.sub) part += '&sub=' + encodeURIComponent(link.sub); + return part; + } + + function appendCallbacks(query, callbacks) { + callbacks = callbacks || {}; + if (callbacks.x_success) query += '&x-success=' + encodeURIComponent(callbacks.x_success); + if (callbacks.x_error) query += '&x-error=' + encodeURIComponent(callbacks.x_error); + return query; + } + + function buildSaveQuery(links, callbacks, data) { + var query = links.map(function (link) { + return linkToQueryPart(link); + }).join('&'); + if (!isTorrentStream(data)) query += '&download=0'; + return appendCallbacks(query, callbacks); + } + + function buildPlayQuery(links, callbacks) { + var query = links.map(function (link) { + return linkToQueryPart(link, link.position); + }).join('&'); + return appendCallbacks(query, callbacks); + } + + function buildAppleTvPlayUrl(links, callbacks) { + // Несколько серий — flat url&position по доке Infuse (position на каждую) + if (links.length > 1) { + return PLAY_PREFIX + buildPlayQuery(links, callbacks); + } + + var playlist = encodeURIComponent(JSON.stringify(links.map(function (item) { + return { + url: item.url, + filename: item.filename + }; + }))); + var query = linkToQueryPart(links[0], links[0].position) + '&playlist=' + playlist; + return PLAY_PREFIX + appendCallbacks(query, callbacks); + } + + function buildPlayLaunchUrl(playLinks, callbacks) { + callbacks = resolveCallbacks(callbacks); + + if (Platform.is('apple_tv') === true) { + return buildAppleTvPlayUrl(playLinks, callbacks); + } + + return PLAY_PREFIX + buildPlayQuery(playLinks, callbacks); + } + + function buildSaveAndPlayUrl(saveLinks, playLinks, data, callbacks) { + var playUrl = buildPlayLaunchUrl(playLinks, callbacks); + return SAVE_PREFIX + buildSaveQuery(saveLinks, { + x_success: playUrl, + x_error: callbacks.x_error + }, data); + } + + function buildLaunchUrl(saveLinks, playLinks, data, options) { + playLinks = playLinks && playLinks.length ? playLinks : saveLinks; + if (!playLinks.length) return ''; + if (!saveLinks.length) saveLinks = playLinks; + options = options || {}; + var mode = normalizeLaunchMode(options.mode); + var callbacks = resolveCallbacks(options); + + if (mode === 'save') { + return SAVE_PREFIX + buildSaveQuery(saveLinks, callbacks, data); + } + + if (mode === 'play') { + return buildPlayLaunchUrl(playLinks, callbacks); + } + + return buildSaveAndPlayUrl(saveLinks, playLinks, data, callbacks); + } + + function buildLaunchUrlLength(saveLinks, playLinks, data, options) { + options = options || {}; + var mode = normalizeLaunchMode(options.mode); + + if (mode === 'play') { + return buildLaunchUrl([], playLinks, data, options).length; + } + + return buildLaunchUrl(saveLinks, playLinks, data, options).length; + } + + function getPlaylistItems(data) { + return resolvePlaylist(data).filter(function (item) { + return typeof item.url === 'string'; + }); + } + + function findStartIndex(items, data) { + if (!items.length) return 0; + var index = findItemIndexInList(items, data); + return index >= 0 ? index : 0; + } + + function rotatePlayLinks(links, startIndex) { + if (!startIndex || startIndex <= 0 || startIndex >= links.length) return links; + return links.slice(startIndex).concat(links.slice(0, startIndex)); + } + + function buildLink(url, item, movie, sourceName, data, launchMode) { + var playItem = item || {}; + if (!playItem.url) playItem.url = url; + var streamUrl = sanitizeStreamUrl(url); + return { + url: streamUrl, + filename: isTorrentStream(data) ? generateTorrentFilename(playItem, movie, data) : generateFilename(playItem, movie, sourceName, data, launchMode), + sub: getSubtitleUrl(playItem, data), + position: resolveLinkPosition(playItem, data, streamUrl) + }; + } + + function buildLinksForItems(data, items, movie, source, options, launchMode, startIndex) { + startIndex = startIndex || 0; + var links = []; + + for (var i = 0; i < items.length && links.length < options.maxItems; i++) { + var playItem = enrichPlayItem(data, items[i]); + var link = buildLink(items[i].url, playItem, movie, source, data, launchMode); + var nextSave = links.concat([link]); + var nextPlay = rotatePlayLinks(nextSave, startIndex); + var probeLength = buildLaunchUrlLength(nextSave, nextPlay, data, { + mode: launchMode, + x_success: options.x_success, + x_error: options.x_error + }); + if (probeLength > options.maxUrlLength && links.length) break; + links.push(link); + } + + return links; + } + + function buildLinksFromPlayData(data, movie, options) { + if (!data) return { + saveLinks: [], + playLinks: [] + }; + options = options || resolveOptions(data); + var source = formatSourceLabel(options.source); + var launchMode = normalizeLaunchMode(options.mode); + var items = getPlaylistItems(data); + + if (options.seasonOnly && options.season) { + var targetSeason = options.season; + items = items.filter(function (item) { + var meta = parseEpisodeMeta(item); + if (meta.season == null && data.season != null) meta.season = data.season; + return meta.season === targetSeason; + }); + } + + var startIndex = findStartIndex(items, data); + var saveLinks = buildLinksForItems(data, items, movie, source, options, launchMode, startIndex); + var playLinks = rotatePlayLinks(saveLinks, startIndex); + + if (!saveLinks.length && data.url) { + var link = buildLink(data.url, enrichPlayItem(data, findPlayItem(data)), movie, source, data, launchMode); + saveLinks = [link]; + playLinks = [link]; + } + + return { + saveLinks: saveLinks, + playLinks: playLinks + }; + } + /** + * Сборка infuse://x-callback-url/… по документации Firecore: + * https://support.firecore.com/hc/ru/articles/215090997 + * + * play: url + filename + sub + position (сек) на каждую серию в плейлисте + * save: без position (API Infuse) + * save_and_play: save?…&x-success=encode(play?…) — онлайн + * torrent: всегда play? + position из timeline (save/save_and_play → play в resolveInfuseMode) + * + * data.url — текущий поток + * data.playlist — эпизоды (season, episode, url) + * data.subtitles — [{url}] → параметр sub + * data.source — в filename если DEFAULTS.filenameSource = true + * DEFAULTS.filenameSource / filenameVoice — выкл/вкл суффиксы в имени + */ + + + function buildExternalUrl(data, callbacks) { + if (!data || !data.url) return null; + var options = resolveOptions(data, callbacks); + + var _buildLinksFromPlayDa = buildLinksFromPlayData(data, resolveCard$1(data), options), + saveLinks = _buildLinksFromPlayDa.saveLinks, + playLinks = _buildLinksFromPlayDa.playLinks; + + if (!saveLinks.length) return null; + return buildLaunchUrl(saveLinks, playLinks, data, options); + } + + function resolveCallbacks(callbacks) { + var _Storage$field; + + callbacks = callbacks || {}; + var appleTvClient = (_Storage$field = Storage.field('apple_tv_client')) !== null && _Storage$field !== void 0 ? _Storage$field : 'lampa'; + return { + x_success: callbacks.x_success || appleTvClient + '://infuseDidFinish', + x_error: callbacks.x_error || appleTvClient + '://infuseDidFail' + }; + } + + function buildFallbackUrl(data, callbacks) { + if (!data || !data.url) return null; + callbacks = resolveCallbacks(callbacks); + var movie = resolveCard$1(data); + var playItem = enrichPlayItem(data, findPlayItem(data)); + var source = formatSourceLabel(data.source || ''); + var options = resolveOptions(data, callbacks); + var link = buildLink(data.url, playItem, movie, source, data, options.mode); + + if (Platform.is('apple_tv') === true) { + var query = linkToQueryPart(link, link.position); + var playlist = serializePlaylist(data.playlist); + if (playlist) query += '&playlist=' + playlist; + return PLAY_PREFIX + appendCallbacks(query, callbacks); + } + + return PLAY_PREFIX + buildPlayQuery([link], callbacks); + } + /** + * Полный URL для Infuse: save_and_play + filenames, иначе простой play?url=… + */ + + + function resolveUrl(data, callbacks) { + normalizePlayData(data); + callbacks = resolveCallbacks(callbacks); + return buildExternalUrl(data, callbacks) || buildFallbackUrl(data, callbacks); + } + + var InfusePlayer = { + buildExternalUrl: buildExternalUrl, + buildFallbackUrl: buildFallbackUrl, + buildLinksFromPlayData: buildLinksFromPlayData, + buildLaunchUrl: buildLaunchUrl, + generateFilename: generateFilename, + formatSourceLabel: formatSourceLabel, + isTorrentStream: isTorrentStream, + resolveCard: resolveCard$1, + resolveCallbacks: resolveCallbacks, + resolveOptions: resolveOptions, + resolveUrl: resolveUrl, + normalizePlayData: normalizePlayData, + serializePlaylist: serializePlaylist + }; + + var html$e; + var timer$3; + var timer_hide; + var message = []; + var limit$2 = 4; + /** + * Имитация чата в плеере + */ + + function init$M() { + html$e = Template.elem('div', { + "class": 'player-chat' + }); + Player.listener.follow('destroy', destroy$a); + PlayerPanel.listener.follow('visible', function (e) { + html$e.toggleClass('hide', !e.status); + clearTimeout(timer_hide); + }); + } + /** + * Добавление сообщения в чат + * @param {Object} data - Данные сообщения + * @param {String} data.message - Текст сообщения + * @param {String} data.icon - Иконка сообщения (HTML) + * @param {Boolean} data.once - Если true, сообщение будет отображено только один раз + */ + + + function push$6(data) { + if (data.once) { + message = message.filter(function (m) { + return m.from !== data.from; + }); + } + + message.push(data); + if (message.length > limit$2) message.shift(); + clearTimeout(timer$3); + timer$3 = setTimeout(draw$3, 200); + } + /** + * Отрисовка сообщений в чате + */ + + + function draw$3() { + clear$7(); + html$e.toggleClass('hide', false); + timer_hide = setTimeout(function () { + if (!PlayerPanel.visibleStatus()) html$e.toggleClass('hide', true); + }, 5000); + message.forEach(function (data) { + var item = Template.elem('div', { + "class": 'player-chat__message', + children: [Template.elem('div', { + "class": 'player-chat__icon', + html: data.icon && typeof data.icon == 'string' ? data.icon : '' + }), Template.elem('div', { + "class": 'player-chat__body', + children: [Template.elem('div', { + "class": 'player-chat__text', + html: data.message + })] + })] + }); + if (data.icon && _typeof(data.icon) == 'object') item.find('.player-chat__icon').empty().append(data.icon); + + if (!data.animated) { + data.animated = true; + item.addClass('animate'); + } + + html$e.append(item); + }); + } + /** + * Очистка чата + */ + + + function clear$7() { + html$e.empty(); + } + + function render$8() { + return html$e; + } + + function destroy$a() { + clear$7(); + html$e.toggleClass('hide', true); + clearTimeout(timer$3); + clearTimeout(timer_hide); + message = []; + } + + var PlayerChat = { + init: init$M, + render: render$8, + push: push$6, + clear: clear$7, + destroy: destroy$a + }; + + var Line$5 = { + onCreate: function onCreate() { + this.html = Template.js('register'); + this.html.addClass('selector register--line'); + this.html.find('.register__name').text(this.data.title); + this.html.find('.register__counter').text(this.data.count); + + if (this.data.limit) { + this.html.find('.register__counter').append(Template.elem('span', { + "class": 'register__limit', + text: '/ ' + this.data.limit + })); + } + } + }; + + var Chart = { + onCreate: function onCreate() { + var _this = this; + + if (!this.data.chart) return; + this.html.addClass('register--with-chart'); + var chart = Template.elem('div', { + "class": 'register__chart' + }); + this.data.chart.bars.forEach(function (height) { + var bar = Template.elem('div', { + "class": 'register__chart-bar' + }); + bar.style.height = height + '%'; + + if (_this.data.chart.threshold && height >= _this.data.chart.threshold) { + bar.classList.add('register__chart-bar--threshold'); + + if (_this.data.chart.threshold_color) { + bar.style.backgroundColor = _this.data.chart.threshold_color; + } + } + + chart.append(bar); + }); + this.html.prepend(chart); + } + }; + + var Tag = { + onCreate: function onCreate() { + this.html.addClass('register--tag'); + + if (typeof this.data.count !== 'undefined') { + this.html.prepend(this.html.find('.register__counter')); + } else { + this.html.find('.register__counter').remove(); + } + } + }; + + var Icon = { + onCreate: function onCreate() { + if (!this.data.icon) return; + this.html.addClass('register--icon'); + this.html.find('.register__name').prepend($(this.data.icon)); + } + }; + + var RegisterMap = { + Line: Line$5, + Chart: Chart, + Tag: Tag, + Icon: Icon, + Callback: Callback$1 + }; + + var Register = /*#__PURE__*/function (_Constructor) { + _inherits(Register, _Constructor); + + var _super = _createSuper(Register); + + function Register() { + _classCallCheck(this, Register); + + return _super.apply(this, arguments); + } + + return Register; + }(Constructor(RegisterMap)); + + var Helper$8 = new Mask(Arrays.getKeys(RegisterMap)); + Helper$8.MASK.base = Helper$8.MASK.none; + + var html$d; + var row; + var graphs = []; + var scroll$1; + /** + * Графики в плеере + */ + + function init$L() { + html$d = Template.elem('div', { + "class": 'player-charts' + }); + Player.listener.follow('destroy', destroy$9); + } + /** + * Добавление графика в плеер + * @param {Object} data - Данные графика + * @param {String} data.name - Имя графика + * @param {String} data.type - Тип графика (segments) + * @param {Array} data.data - Данные графика + */ + + + function push$5(data) { + clear$6(data.name); + graphs.push(data); + draw$2(); + + if (!row) { + row = PlayerFooter.appendRow(html$d); + row.use({ + onToggle: function onToggle() { + var focus; + $(this.html).find('.selector').each(function () { + var segment = this.segment; + var active = segment && PlayerVideo.video().currentTime >= segment.start && PlayerVideo.video().currentTime <= segment.end; + if (active) focus = this; + this.toggleClass('player-charts-segment--current', Boolean(active)); + }); + + if (focus) { + Controller.collectionFocus(focus, this.html); + } + } + }); + } + + PlayerPanel.visible(true); + Controller.toggle('player_footer'); + } + /** + * Отрисовка графиков в плеере + */ + + + function draw$2() { + graphs.filter(function (g) { + return !g.html; + }).forEach(function (data) { + var graph = Template.elem('div', { + "class": 'player-charts__graph graph--' + data.type + }); + + if (data.type == 'graph') { + var segments = data.data || []; + var segments_duration = 0; + segments.forEach(function (segment) { + if (segment.end > segments_duration) segments_duration = segment.end; + }); + var duration = Math.max(PlayerVideo.video().duration || 0, data.duration || segments_duration) || 1; + var W = window.innerWidth - 30; + var H = 210; + var canvas = document.createElement('canvas'); + canvas.width = W; + canvas.height = H; + canvas.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;display:block'; + var ctx = canvas.getContext('2d'); + var real = segments.map(function (segment) { + return { + x: (segment.start + segment.end) / 2 / duration * W, + y: H - Math.min(100, segment.height || 5) / 100 * H + }; + }); + + if (real.length >= 2) { + // Edge anchors + ghost points for smooth Catmull-Rom spline clamping + var pts = [{ + x: -W * 0.05, + y: real[0].y + }, { + x: 0, + y: real[0].y + }].concat(_toConsumableArray(real), [{ + x: W, + y: real[real.length - 1].y + }, { + x: W * 1.05, + y: real[real.length - 1].y + }]); + + var curve = function curve() { + for (var i = 1; i < pts.length - 2; i++) { + var p0 = pts[i - 1], + p1 = pts[i], + p2 = pts[i + 1], + p3 = pts[i + 2]; + var cp1x = p1.x + (p2.x - p0.x) / 6; + var cp1y = p1.y + (p2.y - p0.y) / 6; + var cp2x = p2.x - (p3.x - p1.x) / 6; + var cp2y = p2.y - (p3.y - p1.y) / 6; + ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, p2.x, p2.y); + } + }; + + var grad = ctx.createLinearGradient(0, 0, 0, H); + grad.addColorStop(0, 'rgba(255,255,255,0.85)'); + grad.addColorStop(0.55, 'rgba(200,200,200,0.3)'); + grad.addColorStop(1, 'rgba(0,0,0,0)'); + ctx.save(); + ctx.beginPath(); + ctx.moveTo(0, H); + ctx.lineTo(0, pts[1].y); + curve(); + ctx.lineTo(W, H); + ctx.closePath(); + ctx.fillStyle = grad; + ctx.fill(); + ctx.restore(); + ctx.save(); + ctx.shadowColor = 'rgba(255,255,255,0.5)'; + ctx.shadowBlur = 8; + ctx.beginPath(); + ctx.moveTo(0, pts[1].y); + curve(); + ctx.strokeStyle = 'rgba(255,255,255,0.9)'; + ctx.lineWidth = 3; + ctx.lineJoin = 'round'; + ctx.lineCap = 'round'; + ctx.stroke(); + ctx.restore(); + } + + graph.append(canvas); + } else if (data.type == 'segments') { + var _segments = data.data || []; + + var _segments_duration = 0; + + _segments.forEach(function (segment) { + if (segment.end > _segments_duration) _segments_duration = segment.end; + }); + + var _duration = Math.max(PlayerVideo.video().duration, data.duration || _segments_duration); + + PlayerVideo.video().currentTime || 0; + + _segments.forEach(function (segment, i) { + var width = (segment.end - segment.start) / _duration * 100; + var height = (segment.height ? 11 * segment.height / 100 : 0.4).toFixed(2); + var level = (segment.level ? 11 * segment.level / 100 : 0).toFixed(2); + var segment_html = Template.elem('div', { + "class": 'player-charts-segment', + attrs: { + style: 'width:' + width + '%; left:' + segment.start / _duration * 100 + '%' + }, + children: [Template.elem('div', { + "class": 'player-charts-segment__bar', + attrs: { + style: 'height:' + height + 'em; margin-bottom:' + level + 'em' + } + })] + }); + var label = segment.label; + var text = segment.title; + if (label) segment_html.prepend(Template.elem('div', { + "class": 'player-charts-segment__label', + html: label + })); + if (segment.title && segment.description && width > 40) text += '
    ' + segment.description; + if (text && width > 5) segment_html.prepend(Template.elem('div', { + "class": 'player-charts-segment__text player-charts__text', + children: [Template.elem('div', { + html: text + })] + })); + + if (segment.onSelect) { + segment_html.addClass('selector').on('hover:enter', function () { + segment.onSelect(segment, segment_html); + }); + } + + if (segment.onFocus) { + segment_html.on('hover:focus hover:hover hover:touch', function () { + segment.onFocus(segment, segment_html); + }); + } + + segment_html.segment = segment; + graph.append(segment_html); + }); + } else if (data.type == 'metadata') { + var _segments2 = data.data || []; + + scroll$1 = new Scroll({ + nopadding: true, + horizontal: true + }); + + _segments2.forEach(function (meter) { + var register = Utils$1.createInstance(Register, meter, { + module: Helper$8.toggle(Helper$8.MASK.base, 'Line', 'Chart', 'Icon', 'Callback') + }); + register.use({ + onFocus: function onFocus() { + scroll$1.update(register.render(), true); + } + }); + register.create(); + scroll$1.body().addClass('mapping--line'); + scroll$1.append(register.render()); + }); + + graph.append(scroll$1.render()); + } + + data.html = graph; + html$d.append(graph); + }); + } + /** + * Удаляет график по имени + * @param {String} graph_name - Имя графика для удаления. Если не указано, удаляются все графики. + */ + + + function clear$6(graph_name) { + if (graph_name) { + var remove = graphs.filter(function (g) { + return g.name == graph_name; + }); + remove.forEach(function (r) { + Arrays.remove(graphs, r); + r.html && r.html.remove(); + }); + } else { + graphs.forEach(function (g) { + g.html && g.html.remove(); + }); + graphs = []; + } + + if (scroll$1) { + scroll$1.destroy(); + scroll$1 = null; + } + } + + function destroy$9() { + clear$6(); + + if (row) { + row.destroy(); + row = null; + } + + graphs = []; + } + + var Charts = { + init: init$L, + push: push$5, + clear: clear$6, + destroy: destroy$9 + }; + + var button; + var agent_icon; + var working = false; + var play_data = {}; + var network$5 = new Request(); + var timers$1 = {}; + var chat_history = []; + var buttons$2 = []; + var fields = [{ + name: 'humor', + color: '#f7e74a' + }, { + name: 'violence', + color: '#f74a4a' + }, { + name: 'fear', + color: '#e2b2ff' + }, { + name: 'romance', + color: '#f74aa3' + }, { + name: 'sadness', + color: '#f7a34a' + }, { + name: 'pace', + color: '#4af74a' + }, { + name: 'action', + color: '#ff8124' + }, { + name: 'sex', + color: '#f74af7' + }, { + name: 'profanity', + color: '#ff6262' + }]; + /** + * Инициализация AI-агента + */ + + function init$K() { + agent_icon = Template.get('ai_agent', {}).addClass('animate ai-agent--absolute'); + button = Template.elem('div', { + "class": 'button player-panel__button--ai selector hide', + html: '', + children: [Template.elem('div', { + "class": 'tooltip', + text: Lang.translate('player_ai_agent_ask') + })] + }); + button.on('hover:enter', function () { + if (working) { + PlayerChat.push({ + from: 'ai', + message: Lang.translate('player_ai_agent_working'), + icon: agent_icon, + once: true + }); + } else menu$2(); + }); + Html.elem('settings').after(button); + Player.listener.follow('ready', start$8); + Player.listener.follow('destroy', destroy$8); + buttons$2 = [{ + title: Lang.translate('player_ai_agent_ask_plot'), + need: 'analysis' + }, { + title: Lang.translate('title_metadata'), + need: 'metadata' + }, { + title: Lang.translate('player_ai_agent_ask_moods'), + onSelect: function onSelect(a) { + submenu(fields.map(function (field) { + return { + title: Lang.translate('title_meta_' + field.name), + toagent: Lang.translate('player_ai_agent_ask_moods') + ' - ' + Lang.translate('title_meta_' + field.name), + need: 'timeline', + label: field.name + }; + }), Lang.translate('player_ai_agent_ask_moods')); + } + }, { + title: Lang.translate('player_ai_agent_ask_highlights'), + onSelect: function onSelect(a) { + submenu(fields.map(function (field) { + return { + title: Lang.translate('title_meta_' + field.name), + toagent: Lang.translate('player_ai_agent_ask_highlights') + ' - ' + Lang.translate('title_meta_' + field.name), + need: 'moments/' + field.name + }; + }), Lang.translate('player_ai_agent_ask_highlights')); + } + }]; + } + + function start$8(data) { + var _play_data$card; + + play_data = {}; + play_data.card = data.card || Activity.active().movie || Activity.active().card; + var possibly = Account$1.hasPremium() || false; + var type = (_play_data$card = play_data.card) !== null && _play_data$card !== void 0 && _play_data$card.original_name ? 'tv' : 'movie'; + if (data.iptv || data.youtube) possibly = false;else if (!permit.token) possibly = false;else if (type == 'tv' && (!data.season || !data.episode)) possibly = false; + if (!Platform.screen('tv')) possibly = false; + play_data.type = type; + + if (possibly) { + play_data.season = data.season || 0; + play_data.episode = data.episode || 0; + + if (play_data.card) { + var year = parseInt((play_data.card.release_date || play_data.card.first_air_date || '----').slice(0, 4)); + if (year >= 1985) button.removeClass('hide'); + } + } + + chat_history.push({ + html: $('
    ' + Lang.translate('player_ai_agent_info') + '
    '), + noenter: true + }); + } + + function submenu(items, title) { + Select.show({ + title: title || Lang.translate('title_ai_assistant'), + items: items, + onSelect: function onSelect(a) { + Controller.toggle('player_panel'); + process$1(a); + }, + onBack: menu$2 + }); + } + + function menu$2() { + chat_history.forEach(function (item) { + return item.html.removeClass('selected').unbind(); + }); + if (buttons$2.find(function (i) { + return i.selected; + })) chat_history.forEach(function (item) { + return item.selected = false; + }); + var items = [].concat(chat_history).concat(buttons$2); + Select.show({ + title: Lang.translate('title_ai_assistant'), + items: items, + nomark: true, + onFocus: function onFocus(a) { + items.forEach(function (item) { + return item.selected = false; + }); + a.selected = true; + }, + onSelect: function onSelect(a) { + items.forEach(function (item) { + return item.selected = false; + }); + a.selected = true; + Controller.toggle('player_panel'); + process$1(a); + }, + onBack: function onBack() { + Controller.toggle('player_panel'); + } + }); + } + + function request(item) { + clearTimeout(timers$1[item.need]); + working = true; + var url = 'ai/video/' + play_data.card.id + '/'; + url += item.need + '?type=' + play_data.type + '&season=' + play_data.season + '&episode=' + play_data.episode; + if (item.need.indexOf('moments') !== -1) url += '&limit=8'; + Api$1.load(url).then(function (data) { + if (data.status == 'processing') { + timers$1[item.need] = setTimeout(function () { + request(item); + }, 5000); + } else { + PlayerChat.push({ + from: 'ai', + message: Lang.translate(data.status == 'completed' ? 'ready' : data.status == 'quota' ? 'player_ai_agent_quota' : 'player_ai_agent_no_analysis'), + icon: agent_icon.removeClass('animate'), + once: true + }); + + if (data.status == 'completed') { + draw$1(item, data); + } + + working = false; + } + })["catch"](function (error) { + PlayerChat.push({ + from: 'ai', + message: Lang.translate('player_ai_agent_no_analysis'), + icon: agent_icon.removeClass('animate'), + once: true + }); + working = false; + }); + } + + function draw$1(item, data) { + if (item.need == 'analysis') { + chat_history = []; + chat_history.push({ + title: item.toagent || item.title, + html: $('
    ' + item.title + '
    '), + noenter: true + }); + var result = data.chapters || data.segments; + chat_history.forEach(function (item) { + return item.selected = false; + }); + result.forEach(function (segment, i) { + var text = segment.title; + var time = '' + Utils$1.secondsToTimeHuman(segment.start_sec) + ''; + var title = '' + segment.title + ''; + var descr = '
    ' + segment.description + '
    '; + var item = { + title: text, + html: $('
    ' + time + title + descr + '
    '), + selected: i == 0, + onSelect: function onSelect() { + PlayerVideo.to(segment.start_sec); + Controller.toggle('player_panel'); + } + }; + chat_history.push(item); + }); + buttons$2.forEach(function (i) { + i.selected = false; + + if (i.need == 'analysis') { + i.ghost = true; + i.noenter = true; + } + }); + menu$2(); + } else if (item.need == 'metadata') { + var review = data.review || []; + review.forEach(function (meter, i) { + var _fields$find; + + var color = ((_fields$find = fields.find(function (f) { + return f.name == meter.name; + })) === null || _fields$find === void 0 ? void 0 : _fields$find.color) || '#fff'; + meter.title = Lang.translate('title_meta_' + meter.name); + meter.limit = 10; + meter.count = meter.avg; + meter.icon = ''; + meter.chart = { + threshold: 70, + threshold_color: color, + bars: meter.values.map(function (v) { + return (v || 0) / 10 * 100; + }) + }; + }); + Charts.clear(); + Charts.push({ + name: item.need, + type: 'metadata', + data: review + }); + } else { + var chart_data = []; + + if (item.need.indexOf('moments') !== -1) { + var duration = PlayerVideo.video().duration; + var total = data.segments.length; + data.segments.forEach(function (segment, i) { + var start = 0; + var end = 0; + + if (total > 1) { + start = duration * i / total; + end = start + duration / total; + } else { + var size = duration * 0.5; + start = segment.start_sec > duration - size ? duration - size : segment.start_sec; + end = start + size; + } + + chart_data.push({ + start: Math.round(start), + end: Math.round(end), + title: segment.title, + description: segment.description, + label: Utils$1.secondsToTimeHuman(segment.start_sec), + onSelect: function onSelect() { + PlayerVideo.to(segment.start_sec); + } + }); + }); + } else if (item.need == 'timeline') { + data.segments.forEach(function (segment, i) { + var score = segment[item.label]; + chart_data.push({ + start: segment.start_sec, + end: segment.end_sec, + title: segment.title, + description: segment.description, + height: score / 10 * 100, + label: score > 1 ? score : '', + onSelect: score > 1 ? function () { + PlayerVideo.to(segment.start_sec); + } : undefined, + onFocus: function onFocus() { + PlayerChat.push({ + from: 'ai', + message: Utils$1.secondsToTimeHuman(segment.start_sec) + '
    ' + segment.title, + icon: agent_icon.removeClass('animate'), + once: true + }); + } + }); + }); + } + + if (chart_data.length) { + Charts.clear(); + Charts.push({ + name: item.need, + type: 'segments', + data: chart_data + }); + } else { + PlayerChat.push({ + from: 'ai', + message: Lang.translate('player_ai_agent_no_data'), + icon: agent_icon.removeClass('animate'), + once: true + }); + } + } + } + + function process$1(item) { + var user_icon = Profile.icon(); + PlayerChat.push({ + from: 'user', + message: item.toagent || item.title, + icon: user_icon ? '' : '', + once: true + }); + PlayerChat.push({ + from: 'ai', + message: Lang.translate('player_ai_agent_processing'), + icon: agent_icon.addClass('animate'), + once: true + }); + request(item); + } + + function destroy$8() { + button.addClass('hide'); + play_data = {}; + chat_history = []; + network$5.clear(); + + for (var key in timers$1) { + clearTimeout(timers$1[key]); + } + + working = false; + buttons$2.forEach(function (i) { + i.selected = false; + i.ghost = false; + i.noenter = false; + }); + } + + var Agent = { + init: init$K, + destroy: destroy$8 + }; + + var work$1 = null; + var timer_ask = null; + var timer_save = null; + + function init$J() { + PlayerVideo.listener.follow('reset_continue', function () { + if (work$1 && work$1.timeline && !work$1.timeline.continued_bloc) work$1.timeline.continued = false; + }); + PlayerVideo.listener.follow('timeupdate', function (e) { + if (!work$1 || !work$1.timeline || work$1.timeline.waiting_for_user || work$1.timeline.stop_recording || !e.duration) return; + + if (Storage.field('player_timecode') !== 'again' && !work$1.timeline.continued) { + var exact = parseFloat(work$1.timeline.time + ''); + exact = isNaN(exact) ? 0 : parseFloat(exact.toFixed(3)); + var prend = e.duration - 15, + posit = exact > 0 && exact < e.duration ? exact : Math.round(e.duration * work$1.timeline.percent / 100); + if (posit > 10 && work$1.timeline.percent < 90) PlayerVideo.to(posit > prend ? prend : posit); + work$1.timeline.continued = true; + } else { + work$1.timeline.percent = Math.round(e.current / e.duration * 100); + work$1.timeline.time = e.current; + work$1.timeline.duration = e.duration; + } + }); + Player.listener.follow('start', start$7); + } + + function start$7(data) { + work$1 = data; + if (work$1 && work$1.timeline) work$1.timeline.continued = false; + startSaveLoop(); + } + + function needToContinue(onToggle) { + if (work$1 && work$1.timeline && work$1.timeline.percent) { + work$1.timeline.waiting_for_user = false; + + if (Storage.field('player_timecode') == 'ask') { + work$1.timeline.waiting_for_user = true; + Select.show({ + title: Lang.translate('title_action'), + items: [{ + title: Lang.translate('player_start_from') + ' ' + Utils$1.secondsToTime(work$1.timeline.time) + '?', + yes: true + }, { + title: Lang.translate('settings_param_no') + }], + onBack: function onBack() { + work$1.timeline.continued = true; + work$1.timeline.continued_bloc = true; + onToggle(); + clearTimeout(timer_ask); + }, + onSelect: function onSelect(a) { + work$1.timeline.waiting_for_user = false; + + if (!a.yes) { + work$1.timeline.continued = true; + work$1.timeline.continued_bloc = true; + } + + onToggle(); + clearTimeout(timer_ask); + } + }); + clearTimeout(timer_ask); + timer_ask = setTimeout(function () { + work$1.timeline.continued = true; + work$1.timeline.continued_bloc = true; + Select.hide(); + onToggle(); + }, 8000); + } + } + } + + function setEnd() { + if (work$1 && work$1.timeline) { + work$1.timeline.waiting_for_user = true; + work$1.timeline.percent = 100; + work$1.timeline.time = work$1.timeline.duration || 0; + } + } + + function resetContinue() { + if (work$1 && work$1.timeline) { + work$1.timeline.continued = false; + work$1.timeline.continued_bloc = false; + } + } + + function saveTimeView() { + if (work$1 && work$1.timeline && work$1.timeline.handler && !work$1.timeline.stop_recording) { + work$1.timeline.handler(work$1.timeline.percent, work$1.timeline.time, work$1.timeline.duration); + } + } + + function startSaveLoop() { + if (work$1 && work$1.timeline && !work$1.timeline.stop_recording) { + timer_save = setInterval(saveTimeView, 1000 * 60 * 2); + } + } + + function setRecording(status) { + if (work$1 && work$1.timeline) { + work$1.timeline.stop_recording = !status; + } + } + + function destroy$7() { + saveTimeView(); + if (work$1 && work$1.timeline) work$1.timeline.stop_recording = false; + clearTimeout(timer_ask); + clearInterval(timer_save); + work$1 = null; + } + + var Timeline = { + init: init$J, + needToContinue: needToContinue, + setEnd: setEnd, + resetContinue: resetContinue, + saveTimeView: saveTimeView, + startSaveLoop: startSaveLoop, + setRecording: setRecording, + destroy: destroy$7 + }; + + var FORMAT_NAME$7 = "vtt"; + var helper$5 = { + toMilliseconds: function toMilliseconds(s) { + var match = /^\s*(\d{1,2}:)?(\d{1,2}):(\d{1,2})([.,](\d{1,3}))?\s*$/.exec(s); + var hh = match[1] ? parseInt(match[1].replace(":", "")) : 0; + var mm = parseInt(match[2]); + var ss = parseInt(match[3]); + var ff = match[5] ? parseInt(match[5]) : 0; + var ms = hh * 3600 * 1000 + mm * 60 * 1000 + ss * 1000 + ff; + return ms; + }, + toTimeString: function toTimeString(ms) { + var hh = Math.floor(ms / 1000 / 3600); + var mm = Math.floor(ms / 1000 / 60 % 60); + var ss = Math.floor(ms / 1000 % 60); + var ff = Math.floor(ms % 1000); + var time = (hh < 10 ? "0" : "") + hh + ":" + (mm < 10 ? "0" : "") + mm + ":" + (ss < 10 ? "0" : "") + ss + "." + (ff < 100 ? "0" : "") + (ff < 10 ? "0" : "") + ff; + return time; + } + }; + /****************************************************************************************** + * Parses captions in WebVTT format (Web Video Text Tracks Format) + ******************************************************************************************/ + + function parse$9(content, options) { + var index = 1; + var captions = []; + var eol = options.eol || "\r\n"; + var parts = content.split(/\r?\n\s+\r?\n/); + + for (var i = 0; i < parts.length; i++) { + //WebVTT data + var regex = /^([^\r\n]+\r?\n)?((\d{1,2}:)?\d{1,2}:\d{1,2}([.,]\d{1,3})?)\s*\-\-\>\s*((\d{1,2}:)?\d{1,2}:\d{1,2}([.,]\d{1,3})?)\r?\n([\s\S]*)(\r?\n)*$/gi; + var match = regex.exec(parts[i]); + + if (match) { + var caption = {}; + caption.type = "caption"; + caption.index = index++; + + if (match[1]) { + caption.cue = match[1].replace(/[\r\n]*/gi, ""); + } + + caption.start = helper$5.toMilliseconds(match[2]); + caption.end = helper$5.toMilliseconds(match[5]); + caption.duration = caption.end - caption.start; + var lines = match[8].split(/\r?\n/); + caption.content = lines.join(eol); + caption.text = caption.content.replace(/\<[^\>]+\>/g, "") //bold or italic + .replace(/\{[^\}]+\}/g, ""); //{b}bold{/b} or {i}italic{/i} + + captions.push(caption); + continue; + } //WebVTT meta + + + var meta = /^([A-Z]+)(\r?\n([\s\S]*))?$/.exec(parts[i]); + + if (!meta) { + //Try inline meta + meta = /^([A-Z]+)\s+([^\r\n]*)?$/.exec(parts[i]); + } + + if (meta) { + var caption = {}; + caption.type = "meta"; + caption.name = meta[1]; + + if (meta[3]) { + caption.data = meta[3]; + } + + captions.push(caption); + continue; + } + + if (options.verbose) { + console.log("WARN: Unknown part", parts[i]); + } + } + + return captions; + } + /****************************************************************************************** + * Builds captions in WebVTT format (Web Video Text Tracks Format) + ******************************************************************************************/ + + function build$9(captions, options) { + var eol = options.eol || "\r\n"; + var content = "WEBVTT" + eol + eol; + + for (var i = 0; i < captions.length; i++) { + var caption = captions[i]; + + if (caption.type == "meta") { + if (caption.name == "WEBVTT") continue; + content += caption.name + eol; + content += caption.data ? caption.data + eol : ""; + content += eol; + continue; + } + + if (typeof caption.type === "undefined" || caption.type == "caption") { + content += (i + 1).toString() + eol; + content += helper$5.toTimeString(caption.start) + " --> " + helper$5.toTimeString(caption.end) + eol; + content += caption.text + eol; + content += eol; + continue; + } + + if (options.verbose) { + console.log("SKIP:", caption); + } + } + + return content; + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + function detect$8(content) { + if (typeof content !== "string") { + throw new Error("Expected string content!"); + } + + if (/^[\s\r\n]*WEBVTT\r?\n/g.test(content)) { + /* + WEBVTT + ... + */ + return "vtt"; + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var vttFormatter = { + name: FORMAT_NAME$7, + helper: helper$5, + detect: detect$8, + parse: parse$9, + build: build$9 + }; + + var FORMAT_NAME$6 = "lrc"; + var helper$4 = { + toMilliseconds: function toMilliseconds(s) { + var match = /^\s*(\d+):(\d{1,2})([.,](\d{1,3}))?\s*$/.exec(s); + var mm = parseInt(match[1]); + var ss = parseInt(match[2]); + var ff = match[4] ? parseInt(match[4]) : 0; + var ms = mm * 60 * 1000 + ss * 1000 + ff * 10; + return ms; + }, + toTimeString: function toTimeString(ms) { + var mm = Math.floor(ms / 1000 / 60); + var ss = Math.floor(ms / 1000 % 60); + var ff = Math.floor(ms % 1000); + var time = (mm < 10 ? "0" : "") + mm + ":" + (ss < 10 ? "0" : "") + ss + "." + (ff < 100 ? "0" : "") + (ff < 10 ? "0" : Math.floor(ff / 10)); + return time; + } + }; + /****************************************************************************************** + * Parses captions in LRC format: https://en.wikipedia.org/wiki/LRC_%28file_format%29 + ******************************************************************************************/ + + function parse$8(content, options) { + var prev = null; + var captions = []; + options.eol || "\r\n"; + var parts = content.split(/\r?\n/); + + for (var i = 0; i < parts.length; i++) { + if (!parts[i] || parts[i].trim().length == 0) { + continue; + } //LRC content + + + var regex = /^\[(\d{1,2}:\d{1,2}([.,]\d{1,3})?)\](.*)(\r?\n)*$/gi; + var match = regex.exec(parts[i]); + + if (match) { + var caption = {}; + caption.type = "caption"; + caption.start = helper$4.toMilliseconds(match[1]); + caption.end = caption.start + 2000; + caption.duration = caption.end - caption.start; + caption.content = match[3]; + caption.text = caption.content; + captions.push(caption); //Update previous + + if (prev) { + prev.end = caption.start; + prev.duration = prev.end - prev.start; + } + + prev = caption; + continue; + } //LRC meta + + + var meta = /^\[([\w\d]+):([^\]]*)\](\r?\n)*$/gi.exec(parts[i]); + + if (meta) { + var caption = {}; + caption.type = "meta"; + caption.tag = meta[1]; + + if (meta[2]) { + caption.data = meta[2]; + } + + captions.push(caption); + continue; + } + + if (options.verbose) { + console.log("WARN: Unknown part", parts[i]); + } + } + + return captions; + } + /****************************************************************************************** + * Builds captions in LRC format: https://en.wikipedia.org/wiki/LRC_%28file_format%29 + ******************************************************************************************/ + + function build$8(captions, options) { + var content = ""; + var lyrics = false; + var eol = options.eol || "\r\n"; + + for (var i = 0; i < captions.length; i++) { + var caption = captions[i]; + + if (caption.type == "meta") { + if (caption.tag && caption.data) { + content += "[" + caption.tag + ":" + caption.data.replace(/[\r\n]+/g, " ") + "]" + eol; + } + + continue; + } + + if (typeof caption.type === "undefined" || caption.type == "caption") { + if (!lyrics) { + content += eol; //New line when lyrics start + + lyrics = true; + } + + content += "[" + helper$4.toTimeString(caption.start) + "]" + caption.text + eol; + continue; + } + + if (options.verbose) { + console.log("SKIP:", caption); + } + } + + return content; + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + function detect$7(content) { + if (typeof content === "string") { + if (/\r?\n\[(\d+:\d{1,2}([.,]\d{1,3})?)\](.*)\r?\n/.test(content)) { + /* + [04:48.28]Sister, perfume? + */ + //return "lrc"; + return true; + } + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var lrcFormatter = { + name: FORMAT_NAME$6, + helper: helper$4, + detect: detect$7, + parse: parse$8, + build: build$8 + }; + + var FORMAT_NAME$5 = "smi"; + var helper$3 = { + htmlEncode: function htmlEncode(text) { + return text.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/\/g, '>') //.replace(/\s/g, ' ') + .replace(/\r?\n/g, '
    '); + }, + htmlDecode: function htmlDecode(html, eol) { + return html.replace(/\/gi, eol || '\r\n').replace(/ /g, ' ').replace(/"/g, '"').replace(/'/g, "'").replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&'); + } + }; + /****************************************************************************************** + * Parses captions in SAMI format (.smi) + ******************************************************************************************/ + + function parse$7(content, options) { + var captions = []; + var eol = options.eol || "\r\n"; + var title = /\]*\>([\s\S]*)\<\/TITLE\>/gi.exec(content); + + if (title) { + var caption = {}; + caption.type = "meta"; + caption.name = "title"; + caption.data = title[1].replace(/^[\s\r\n]*/g, "").replace(/[\s\r\n]*$/g, ""); + captions.push(caption); + } + + var style = /\]*\>([\s\S]*)\<\/STYLE\>/gi.exec(content); + + if (style) { + var caption = {}; + caption.type = "meta"; + caption.name = "style"; + caption.data = style[1]; + captions.push(caption); + } + + var sami = content.replace(/^[\s\S]*\]*\>/gi, "") //Remove content before body + .replace(/\<\/BODY[^\>]*\>[\s\S]*$/gi, ""); //Remove content after body + + var prev = null; + var parts = sami.split(/\ + + var match = /^\]+Start\s*=\s*["']?(\d+)["']?[^\>]*\>([\s\S]*)/gi.exec(part); + + if (match) { + var caption = {}; + caption.type = "caption"; + caption.start = parseInt(match[1]); + caption.end = caption.start + 2000; + caption.duration = caption.end - caption.start; + caption.content = match[2].replace(/^\<\/SYNC[^\>]*>/gi, ""); + var blank = true; + var p = /^\]+Class\s*=\s*["']?([\w\d\-_]+)["']?[^\>]*\>([\s\S]*)/gi.exec(caption.content); + + if (!p) { + p = /^\]*)\>([\s\S]*)/gi.exec(caption.content); + } + + if (p) { + var html = p[2].replace(/\ tag + + html = html.replace(/\[\s\r\n]+/gi, eol).replace(/\/gi, eol).replace(/\<[^\>]+\>/g, ""); //Remove all tags + + html = html.replace(/^[\s\r\n]+/g, "").replace(/[\s\r\n]+$/g, ""); //Trim new lines and spaces + + blank = html.replace(/ /gi, " ").replace(/[\s\r\n]+/g, "").length == 0; + caption.text = helper$3.htmlDecode(html, eol); + } + + if (!options.preserveSpaces && blank) { + if (options.verbose) { + console.log("INFO: Skipping white space caption at " + caption.start); + } + } else { + captions.push(caption); + } //Update previous + + + if (prev) { + prev.end = caption.start; + prev.duration = prev.end - prev.start; + } + + prev = caption; + continue; + } + + if (options.verbose) { + console.log("WARN: Unknown part", parts[i]); + } + } + + return captions; + } + /****************************************************************************************** + * Builds captions in SAMI format (.smi) + ******************************************************************************************/ + + function build$7(captions, options) { + var eol = options.eol || "\r\n"; + var content = ""; + content += '' + eol; + content += '' + eol; + content += '' + (options.title || "") + '' + eol; + content += '' + eol; + content += '' + eol; + content += '' + eol; + + for (var i = 0; i < captions.length; i++) { + var caption = captions[i]; + + if (caption.type == "meta") { + continue; + } + + if (typeof caption.type === "undefined" || caption.type == "caption") { + //Start of caption + content += '' + eol; + content += '

    ' + helper$3.htmlEncode(caption.text || "") + (options.closeTags ? '

    ' : "") + eol; + + if (options.closeTags) { + content += '
    ' + eol; + } //Blank line indicates the end of caption + + + content += '' + eol; + content += '

    ' + ' ' + (options.closeTags ? '

    ' : "") + eol; + + if (options.closeTags) { + content += '
    ' + eol; + } + + continue; + } + + if (options.verbose) { + console.log("SKIP:", caption); + } + } + + content += '' + eol; + content += '
    ' + eol; + return content; + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + function detect$6(content) { + if (typeof content === "string") { + if (/\]*\>[\s\S]*\]*\>/g.test(content)) { + /* + + + + + */ + return "smi"; + } + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var smiFormatter = { + name: FORMAT_NAME$5, + helper: helper$3, + detect: detect$6, + parse: parse$7, + build: build$7 + }; + + var FORMAT_NAME$4 = "ssa"; + var helper$2 = { + toMilliseconds: function toMilliseconds(s) { + var match = /^\s*(\d+:)?(\d{1,2}):(\d{1,2})([.,](\d{1,3}))?\s*$/.exec(s); + var hh = match[1] ? parseInt(match[1].replace(":", "")) : 0; + var mm = parseInt(match[2]); + var ss = parseInt(match[3]); + var ff = match[5] ? parseInt(match[5]) : 0; + var ms = hh * 3600 * 1000 + mm * 60 * 1000 + ss * 1000 + ff * 10; + return ms; + }, + toTimeString: function toTimeString(ms) { + var hh = Math.floor(ms / 1000 / 3600); + var mm = Math.floor(ms / 1000 / 60 % 60); + var ss = Math.floor(ms / 1000 % 60); + var ff = Math.floor(ms % 1000 / 10); //2 digits + + var time = hh + ":" + (mm < 10 ? "0" : "") + mm + ":" + (ss < 10 ? "0" : "") + ss + "." + (ff < 10 ? "0" : "") + ff; + return time; + } + }; + /****************************************************************************************** + * Parses captions in SubStation Alpha format (.ssa) + ******************************************************************************************/ + + function parse$6(content, options) { + var meta; + var columns = null; + var captions = []; + var eol = options.eol || "\r\n"; + var parts = content.split(/\r?\n\s*\r?\n/); + + for (var i = 0; i < parts.length; i++) { + var regex = /^\s*\[([^\]]+)\]\r?\n([\s\S]*)(\r?\n)*$/gi; + var match = regex.exec(parts[i]); + + if (match) { + var tag = match[1]; + var lines = match[2].split(/\r?\n/); + + for (var l = 0; l < lines.length; l++) { + var line = lines[l]; + + if (/^\s*;/.test(line)) { + continue; //Skip comment + } + + var m = /^\s*([^:]+):\s*(.*)(\r?\n)?$/.exec(line); + + if (m) { + if (tag == "Script Info") { + if (!meta) { + meta = {}; + meta.type = "meta"; + meta.data = {}; + captions.push(meta); + } + + var name = m[1].trim(); + var value = m[2].trim(); + meta.data[name] = value; + continue; + } + + if (tag == "V4 Styles" || tag == "V4+ Styles") { + var name = m[1].trim(); + var value = m[2].trim(); + + if (name == "Format") { + columns = value.split(/\s*,\s*/g); + continue; + } + + if (name == "Style") { + var values = value.split(/\s*,\s*/g); + var caption = {}; + caption.type = "style"; + caption.data = {}; + + for (var c = 0; c < columns.length && c < values.length; c++) { + caption.data[columns[c]] = values[c]; + } + + captions.push(caption); + continue; + } + } + + if (tag == "Events") { + var name = m[1].trim(); + var value = m[2].trim(); + + if (name == "Format") { + columns = value.split(/\s*,\s*/g); + continue; + } + + if (name == "Dialogue") { + //Work-around for missing text (when the text contains ',' char) + var getPosition = function getPosition(s, search, index) { + return s.split(search, index).join(search).length; + }; + + var values = value.split(/\s*,\s*/g); + var caption = {}; + caption.type = "caption"; + caption.data = {}; + + for (var c = 0; c < columns.length && c < values.length; c++) { + caption.data[columns[c]] = values[c]; + } + + caption.start = helper$2.toMilliseconds(caption.data["Start"]); + caption.end = helper$2.toMilliseconds(caption.data["End"]); + caption.duration = caption.end - caption.start; + caption.content = caption.data["Text"]; + var indexOfText = getPosition(value, ',', columns.length - 1) + 1; + caption.content = value.substr(indexOfText); + caption.data["Text"] = caption.content; + caption.text = caption.content.replace(/\\N/g, eol) //"\N" for new line + .replace(/\{[^\}]+\}/g, ""); //{\pos(400,570)} + + captions.push(caption); + continue; + } + } + } + } + } + + if (options.verbose) { + console.log("WARN: Unknown part", parts[i]); + } + } + + return captions; + } + /****************************************************************************************** + * Builds captions in SubStation Alpha format (.ssa) + ******************************************************************************************/ + + function build$6(captions, options) { + var eol = options.eol || "\r\n"; + var ass = options.format == "ass"; + var content = ""; + content += "[Script Info]" + eol; + content += "; Script generated by subsrt " + eol; + content += "ScriptType: v4.00" + (ass ? "+" : "") + eol; + content += "Collisions: Normal" + eol; + content += eol; + + if (ass) { + content += "[V4+ Styles]" + eol; + content += "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" + eol; + content += "Style: DefaultVCD, Arial,28,&H00B4FCFC,&H00B4FCFC,&H00000008,&H80000008,-1,0,0,0,100,100,0.00,0.00,1,1.00,2.00,2,30,30,30,0" + eol; + } else { + content += "[V4 Styles]" + eol; + content += "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding" + eol; + content += "Style: DefaultVCD, Arial,28,11861244,11861244,11861244,-2147483640,-1,0,1,1,2,2,30,30,30,0,0" + eol; + } + + content += eol; + content += "[Events]" + eol; + content += "Format: " + (ass ? "Layer" : "Marked") + ", Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" + eol; + + for (var i = 0; i < captions.length; i++) { + var caption = captions[i]; + + if (caption.type == "meta") { + continue; + } + + if (typeof caption.type === "undefined" || caption.type == "caption") { + content += "Dialogue: " + (ass ? "0" : "Marked=0") + "," + helper$2.toTimeString(caption.start) + "," + helper$2.toTimeString(caption.end) + ",DefaultVCD, NTP,0000,0000,0000,," + caption.text.replace(/\r?\n/g, "\\N") + eol; + continue; + } + + if (options.verbose) { + console.log("SKIP:", caption); + } + } + + return content; + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + function detect$5(content) { + if (typeof content !== "string") { + throw new Error("Expected string content!"); + } + + if (/^[\s\r\n]*\[Script Info\]\r?\n/g.test(content) && /[\s\r\n]*\[Events\]\r?\n/g.test(content)) { + /* + [Script Info] + ... + [Events] + */ + //Advanced (V4+) styles for ASS format + return content.indexOf("[V4+ Styles]") > 0 ? "ass" : "ssa"; + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var ssaFormatter = { + name: FORMAT_NAME$4, + helper: helper$2, + detect: detect$5, + parse: parse$6, + build: build$6 + }; + + var assFormatter = { + name: "ass", + helper: ssaFormatter.helper, + detect: ssaFormatter.detect, + parse: ssaFormatter.parse, + build: ssaFormatter.build + }; + + var FORMAT_NAME$3 = "sub"; + var DEFAULT_FPS = 25; + /****************************************************************************************** + * Parses captions in MicroDVD format: https://en.wikipedia.org/wiki/MicroDVD + ******************************************************************************************/ + + function parse$5(content, options) { + var fps = options.fps > 0 ? options.fps : DEFAULT_FPS; + var captions = []; + var eol = options.eol || "\r\n"; + var parts = content.split(/\r?\n/g); + + for (var i = 0; i < parts.length; i++) { + var regex = /^\{(\d+)\}\{(\d+)\}(.*)$/gi; + var match = regex.exec(parts[i]); + + if (match) { + var caption = {}; + caption.type = "caption"; + caption.index = i + 1; + caption.frame = { + start: parseInt(match[1]), + end: parseInt(match[2]) + }; + caption.frame.count = caption.frame.end - caption.frame.start; + caption.start = Math.round(caption.frame.start / fps); + caption.end = Math.round(caption.frame.end / fps); + caption.duration = caption.end - caption.start; + var lines = match[3].split(/\|/g); + caption.content = lines.join(eol); + caption.text = caption.content.replace(/\{[^\}]+\}/g, ""); //{0}{25}{c:$0000ff}{y:b,u}{f:DeJaVuSans}{s:12}Hello! + + captions.push(caption); + continue; + } + + if (options.verbose) { + console.log("WARN: Unknown part", parts[i]); + } + } + + return captions; + } + /****************************************************************************************** + * Builds captions in MicroDVD format: https://en.wikipedia.org/wiki/MicroDVD + ******************************************************************************************/ + + function build$5(captions, options) { + var fps = options.fps > 0 ? options.fps : DEFAULT_FPS; + var sub = ""; + var eol = options.eol || "\r\n"; + + for (var i = 0; i < captions.length; i++) { + var caption = captions[i]; + + if (typeof caption.type === "undefined" || caption.type == "caption") { + var startFrame = _typeof(caption.frame) == "object" && caption.frame.start >= 0 ? caption.frame.start : caption.start * fps; + var endFrame = _typeof(caption.frame) == "object" && caption.frame.end >= 0 ? caption.frame.end : caption.end * fps; + var text = caption.text.replace(/\r?\n/, "|"); + sub += "{" + startFrame + "}" + "{" + endFrame + "}" + text + eol; + continue; + } + + if (options.verbose) { + console.log("SKIP:", caption); + } + } + + return sub; + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + function detect$4(content) { + if (typeof content === "string") { + if (/^\{\d+\}\{\d+\}(.*)/.test(content)) { + /* + {7207}{7262}Sister, perfume? + */ + return FORMAT_NAME$3; + } + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var subFormatter = { + name: FORMAT_NAME$3, + detect: detect$4, + parse: parse$5, + build: build$5 + }; + + var FORMAT_NAME$2 = "srt"; + var helper$1 = { + toMilliseconds: function toMilliseconds(s) { + var match = /^\s*(\d{1,2}):(\d{1,2}):(\d{1,2})([.,](\d{1,3}))?\s*$/.exec(s); + var hh = parseInt(match[1]); + var mm = parseInt(match[2]); + var ss = parseInt(match[3]); + var ff = match[5] ? parseInt(match[5]) : 0; + var ms = hh * 3600 * 1000 + mm * 60 * 1000 + ss * 1000 + ff; + return ms; + }, + toTimeString: function toTimeString(ms) { + var hh = Math.floor(ms / 1000 / 3600); + var mm = Math.floor(ms / 1000 / 60 % 60); + var ss = Math.floor(ms / 1000 % 60); + var ff = Math.floor(ms % 1000); + var time = (hh < 10 ? "0" : "") + hh + ":" + (mm < 10 ? "0" : "") + mm + ":" + (ss < 10 ? "0" : "") + ss + "," + (ff < 100 ? "0" : "") + (ff < 10 ? "0" : "") + ff; + return time; + } + }; + /****************************************************************************************** + * Parses captions in SubRip format (.srt) + ******************************************************************************************/ + + function parse$4(content, options) { + var captions = []; + var eol = options.eol || "\r\n"; + var parts = content.split(/\r?\n\s+\r?\n/g); + + for (var i = 0; i < parts.length; i++) { + var regex = /^(\d+)\r?\n(\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?)\s*\-\-\>\s*(\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?)\r?\n([\s\S]*)(\r?\n)*$/gi; + var match = regex.exec(parts[i]); + + if (match) { + var caption = {}; + caption.type = "caption"; + caption.index = parseInt(match[1]); + caption.start = helper$1.toMilliseconds(match[2]); + caption.end = helper$1.toMilliseconds(match[4]); + caption.duration = caption.end - caption.start; + var lines = match[6].split(/\r?\n/); + caption.content = lines.join(eol); + caption.text = caption.content.replace(/\<[^\>]+\>/g, "") //bold or italic + .replace(/\{[^\}]+\}/g, "") //{b}bold{/b} or {i}italic{/i} + .replace(/\>\>\s*[^:]*:\s*/g, ""); //>> SPEAKER NAME: + + captions.push(caption); + continue; + } + + if (options.verbose) { + console.log("WARN: Unknown part", parts[i]); + } + } + + return captions; + } + /****************************************************************************************** + * Builds captions in SubRip format (.srt) + ******************************************************************************************/ + + function build$4(captions, options) { + var srt = ""; + var eol = options.eol || "\r\n"; + + for (var i = 0; i < captions.length; i++) { + var caption = captions[i]; + + if (typeof caption.type === "undefined" || caption.type == "caption") { + srt += (i + 1).toString() + eol; + srt += helper$1.toTimeString(caption.start) + " --> " + helper$1.toTimeString(caption.end) + eol; + srt += caption.text + eol; + srt += eol; + continue; + } + + if (options.verbose) { + console.log("SKIP:", caption); + } + } + + return srt; + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + function detect$3(content) { + if (typeof content === "string") { + if (/\d+\r?\n\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?\s*\-\-\>\s*\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?/g.test(content)) { + /* + 3 + 00:04:48,280 --> 00:04:50,510 + Sister, perfume? + */ + return FORMAT_NAME$2; + } + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var srtFormatter = { + name: FORMAT_NAME$2, + helper: helper$1, + detect: detect$3, + parse: parse$4, + build: build$4 + }; + + var FORMAT_NAME$1 = "sbv"; + var helper = { + toMilliseconds: function toMilliseconds(s) { + var match = /^\s*(\d{1,2}):(\d{1,2}):(\d{1,2})([.,](\d{1,3}))?\s*$/.exec(s); + var hh = parseInt(match[1]); + var mm = parseInt(match[2]); + var ss = parseInt(match[3]); + var ff = match[5] ? parseInt(match[5]) : 0; + var ms = hh * 3600 * 1000 + mm * 60 * 1000 + ss * 1000 + ff; + return ms; + }, + toTimeString: function toTimeString(ms) { + var hh = Math.floor(ms / 1000 / 3600); + var mm = Math.floor(ms / 1000 / 60 % 60); + var ss = Math.floor(ms / 1000 % 60); + var ff = Math.floor(ms % 1000); + var time = (hh < 10 ? "0" : "") + hh + ":" + (mm < 10 ? "0" : "") + mm + ":" + (ss < 10 ? "0" : "") + ss + "." + (ff < 100 ? "0" : "") + (ff < 10 ? "0" : "") + ff; + return time; + } + }; + /****************************************************************************************** + * Parses captions in SubViewer format (.sbv) + ******************************************************************************************/ + + function parse$3(content, options) { + var captions = []; + var eol = options.eol || "\r\n"; + var parts = content.split(/\r?\n\s+\r?\n/); + + for (var i = 0; i < parts.length; i++) { + var regex = /^(\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?)\s*[,;]\s*(\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?)\r?\n([\s\S]*)(\r?\n)*$/gi; + var match = regex.exec(parts[i]); + + if (match) { + var caption = {}; + caption.type = "caption"; + caption.start = helper.toMilliseconds(match[1]); + caption.end = helper.toMilliseconds(match[3]); + caption.duration = caption.end - caption.start; + var lines = match[5].split(/\[br\]|\r?\n/gi); + caption.content = lines.join(eol); + caption.text = caption.content.replace(/\>\>\s*[^:]+:\s*/g, ""); //>> SPEAKER NAME: + + captions.push(caption); + continue; + } + + if (options.verbose) { + console.log("WARN: Unknown part", parts[i]); + } + } + + return captions; + } + /****************************************************************************************** + * Builds captions in SubViewer format (.sbv) + ******************************************************************************************/ + + function build$3(captions, options) { + var content = ""; + var eol = options.eol || "\r\n"; + + for (var i = 0; i < captions.length; i++) { + var caption = captions[i]; + + if (typeof caption.type === "undefined" || caption.type == "caption") { + content += helper.toTimeString(caption.start) + "," + helper.toTimeString(caption.end) + eol; + content += caption.text + eol; + content += eol; + continue; + } + + if (options.verbose) { + console.log("SKIP:", caption); + } + } + + return content; + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + function detect$2(content) { + if (typeof content !== "string") { + throw new Error("Expected string content!"); + } + + if (/\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?\s*[,;]\s*\d{1,2}:\d{1,2}:\d{1,2}([.,]\d{1,3})?/g.test(content)) { + /* + 00:04:48.280,00:04:50.510 + Sister, perfume? + */ + return "sbv"; + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var sbvFormatter = { + name: FORMAT_NAME$1, + helper: helper, + detect: detect$2, + parse: parse$3, + build: build$3 + }; + + var FORMAT_NAME = "json"; + /****************************************************************************************** + * Parses captions in JSON format + ******************************************************************************************/ + + function parse$2(content, options) { + return JSON.parse(content); + } + /****************************************************************************************** + * Builds captions in JSON format + ******************************************************************************************/ + + function build$2(captions, options) { + return JSON.stringify(captions, " ", 2); + } + /****************************************************************************************** + * Detects a subtitle format from the content. + ******************************************************************************************/ + + + function detect$1(content) { + if (typeof content === "string") { + if (/^\[[\s\r\n]*\{[\s\S]*\}[\s\r\n]*\]$/g.test(content)) { + /* + [ + { ... } + ] + */ + return "json"; + } + } + } + /****************************************************************************************** + * Export + ******************************************************************************************/ + + var jsonFormatter = { + name: FORMAT_NAME, + detect: detect$1, + parse: parse$2, + build: build$2 + }; + + var supportedFormats = { + vtt: vttFormatter, + lrc: lrcFormatter, + smi: smiFormatter, + ssa: ssaFormatter, + ass: assFormatter, + sub: subFormatter, + srt: srtFormatter, + sbv: sbvFormatter, + json: jsonFormatter + }; + + function clone(obj) { + return JSON.parse(JSON.stringify(obj)); + } + /****************************************************************************************** + * Gets a list of supported subtitle supportedFormats. + ******************************************************************************************/ + + + function list$4() { + return Object.keys(supportedFormats); + } + /****************************************************************************************** + * Detects a subtitle supportedFormats from the content. + ******************************************************************************************/ + + + function detect(content) { + var formats = Object.keys(supportedFormats); + + for (var i = 0; i < formats.length; i++) { + var formatName = formats[i]; + var handler = supportedFormats[formatName]; + + if (handler === undefined) { + continue; + } + + if (typeof handler.detect != "function") { + continue; + } //Function 'detect' can return true or supportedFormats name + + + var d = handler.detect(content); + + if (d === true) { + //Logical true + return formatName; + } + + if (formatName === d) { + //Format name + return d; + } + } + } + /****************************************************************************************** + * Parses a subtitle content. + ******************************************************************************************/ + + + function parse$1(content, options) { + options = options || {}; + var format = options.format || detect(content); + + if (!format || format.trim().length == 0) { + throw new Error("Cannot determine subtitle supportedFormats!"); + } + + var handler = supportedFormats[format]; + + if (handler === undefined) { + throw new Error("Unsupported subtitle supportedFormats: " + format); + } + + var func = handler.parse; + + if (typeof func != "function") { + throw new Error("Subtitle supportedFormats does not support 'parse' op: " + format); + } + + return func(content, options); + } + /****************************************************************************************** + * Builds a subtitle content + ******************************************************************************************/ + + + function build$1(captions, options) { + options = options || {}; + var format = options.format || "srt"; + + if (!format || format.trim().length == 0) { + throw new Error("Cannot determine subtitle supportedFormats!"); + } + + var handler = supportedFormats[format]; + + if (typeof handler == "undefined") { + throw new Error("Unsupported subtitle supportedFormats: " + format); + } + + var func = handler.build; + + if (typeof func != "function") { + throw new Error("Subtitle supportedFormats does not support 'build' op: " + format); + } + + return func(captions, options); + } + /****************************************************************************************** + * Converts subtitle supportedFormats + ******************************************************************************************/ + + + function convert(content, options) { + if (typeof options == "string") { + options = { + to: options + }; + } + + options = options || {}; + var opt = clone(options); + delete opt.format; + + if (opt.from) { + opt.format = opt.from; + } + + var captions = parse$1(content, opt); + + if (opt.resync) { + captions = resync(captions, opt.resync); + } + + opt.format = opt.to || options.format; + return build$1(captions, opt); + } + /****************************************************************************************** + * Shifts the time of the captions. + ******************************************************************************************/ + + + function resync(captions, options) { + options = options || {}; + var func, ratio, frame, offset; + + if (typeof options == "function") { + func = options; //User's function to handle time shift + } else if (typeof options == "number") { + offset = options; //Time shift (+/- offset) + + func = function func(a) { + return [a[0] + offset, a[1] + offset]; + }; + } else if (_typeof(options) == "object") { + offset = (options.offset || 0) * (options.frame ? options.fps || 25 : 1); + ratio = options.ratio || 1.0; + frame = options.frame; + + func = function func(a) { + return [Math.round(a[0] * ratio + offset), Math.round(a[1] * ratio + offset)]; + }; + } else { + throw new Error("Argument 'options' not defined!"); + } + + var resynced = []; + + for (var i = 0; i < captions.length; i++) { + var caption = clone(captions[i]); + + if (typeof caption.type === "undefined" || caption.type == "caption") { + if (frame) { + var shift = func([caption.frame.start, caption.frame.end]); + + if (shift && shift.length == 2) { + caption.frame.start = shift[0]; + caption.frame.end = shift[1]; + caption.frame.count = caption.frame.end - caption.frame.start; + } + } else { + var shift = func([caption.start, caption.end]); + + if (shift && shift.length == 2) { + caption.start = shift[0]; + caption.end = shift[1]; + caption.duration = caption.end - caption.start; + } + } + } + + resynced.push(caption); + } + + return resynced; + } + + var subsrt = { + list: list$4, + detect: detect, + parse: parse$1, + build: build$1, + convert: convert, + resync: resync + }; + + /** + * Получить время + * @param {string} val - Время в формате "HH:MM:SS,mmm" или "HH:MM:SS.mmm" + * @returns {number} + */ + + function time$1(val) { + var regex = /(\d+):(\d{2}):(\d{2})[.,](\d{3})/; + var parts = regex.exec(val); + if (parts === null) return 0; + + for (var i = 1; i < 5; i++) { + parts[i] = parseInt(parts[i], 10); + if (isNaN(parts[i])) parts[i] = 0; + } //hours + minutes + seconds + ms + + + return parts[1] * 3600000 + parts[2] * 60000 + parts[3] * 1000 + parts[4]; + } + /** + * Парсить + * @param {string} data - Данные субтитров в формате SRT или VTT + * @param {boolean} ms - Использовать миллисекунды + * @returns + */ + + + function parse(data, ms) { + var type = subsrt.detect(data); + if (type === 'vtt') return parseVTT(data, ms); + if (type !== undefined && type !== 'srt') return parseVTT(convertToVTT(data), ms);else return parseSRT(data, ms); + } + /** + * Парсить SRT + * @param {string} data - Данные субтитров в формате SRT + * @param {boolean} ms - Использовать миллисекунды + * @returns {[{id:string, startTime:number, endTime:number, text:string}]} + */ + + + function parseSRT(data, ms) { + var useMs = ms ? true : false; + data = data.replace(/\r\n/g, '\n'); + data = data.replace(/\r/g, '\n'); + var regex = /(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})/g; + data = data.split(regex); + data.shift(); + var items = []; + + for (var i = 0; i < data.length; i += 4) { + items.push({ + id: data[i].trim(), + startTime: useMs ? time$1(data[i + 1].trim()) : data[i + 1].trim(), + endTime: useMs ? time$1(data[i + 2].trim()) : data[i + 2].trim(), + text: data[i + 3].trim() + }); + } + + return items; + } + /** + * Конвертировать в VTT + * @param {string} data - Данные субтитров в формате SRT или VTT + * @returns {string} - Данные субтитров в формате VTT + */ + + + function convertToVTT(data) { + return subsrt.convert(data, { + format: 'vtt', + fps: 25 + }); + } + /** + * Парсить VTT + * @param {string} data - Данные субтитров в формате VTT + * @param {boolean} ms - Использовать миллисекунды + * @returns {[{id:string, startTime:number, endTime:number, text:string}]} + */ + + + function parseVTT(data, ms) { + var useMs = ms ? true : false; + data = data.replace(/\r\n/g, '\n'); + data = data.replace(/\r/g, '\n'); + data = data.replace(/(\d{2}):(\d{2})\.(\d{3})[ \t]+-->[ \t]+(\d{2}):(\d{2})\.(\d{3})/g, '00:$1:$2.$3 --> 00:$4:$5.$6'); + var regex = /(\n\n.+\n)?[ \t]*(\d{2}:\d{2}:\d{2}\.\d{3})[ \t]+-->[ \t]+(\d{2}:\d{2}:\d{2}\.\d{3})/g; + data = data.split(regex); + data.shift(); + var items = []; + + for (var i = 0; i < data.length; i += 4) { + items.push({ + id: (data[i] || '').trim(), + startTime: useMs ? time$1(data[i + 1].trim()) : data[i + 1].trim(), + endTime: useMs ? time$1(data[i + 2].trim()) : data[i + 2].trim(), + text: data[i + 3].trim() + }); + } + + return items; + } + /** + * Кастомные субтитры + * @class + */ + + + function CustomSubtitles() { + var parsed; + var network = new Request(); + this.listener = Subscribe$2(); + /** + * Загрузить + * @param {string} url + */ + + this.load = function (url) { + network.silent(url, function (data) { + if (data) { + parsed = parse(data, true); + } + }, false, false, { + dataType: 'text' + }); + }; + /** + * Показать текст + * @param {number} time_sec + */ + + + this.update = function (time_sec) { + var time_ms = time_sec * 1000; + time_ms -= parseInt(Storage.get('player_subs_shift_time', '0')) * 1000; + + if (parsed) { + var text = ''; + + for (var i = 0; i < parsed.length; i++) { + var sub = parsed[i]; + + if (time_ms > sub.startTime && time_ms < sub.endTime) { + text = sub.text.replace("\n", '
    '); + break; + } + } + + this.listener.send('subtitle', { + text: text.trim() + }); + } + }; + /** + * Уничтожить + */ + + + this.destroy = function () { + network.clear(); + network = null; + this.listener = null; + }; + } + + var custom_subtitles; + + function init$I() { + Player.listener.follow('ready', bind$2); + Player.listener.follow('destroy', destroy$6); + PlayerVideo.listener.follow('timeupdate', function (e) { + if (custom_subtitles) custom_subtitles.update(e.current); + }); // Video.listener.follow('destroy', function(e) { + // if(custom_subtitles){ + // custom_subtitles.destroy() + // custom_subtitles = null + // } + // }) + + PanelSettings.listener.follow('subs', applySettings); + } + /** + * Применяет к блоку субтитров пользовательские настройки + */ + + + function applySettings() { + var stroke = Storage.field('subtitles_stroke'), + backdrop = Storage.field('subtitles_backdrop'), + size = Storage.field('subtitles_size'); + Cue.render().removeClass('has--stroke has--backdrop size--normal size--large size--small'); + Cue.render().addClass('size--' + size); + if (stroke) Cue.render().addClass('has--stroke'); + if (backdrop) Cue.render().addClass('has--backdrop'); + } + + function bind$2(data) { + // Субтитры из плеера Tizen + PlayerVideo.video().addEventListener('subtitle', function (e) { + //В srt существует тег {\anX}, где X - цифра от 1 до 9, Тег определяет нестандартное положение субтитра на экране. + //Здесь удаляется тег из строки и обрабатывается положение 8 (субтитр вверху по центру). + //{\an8} используется когда нужно, чтобы субтитр не перекрывал надписи в нижней части экрана или субтитры вшитые в видеоряд. + Cue.render().removeClass('on-top'); + var pos_tag = e.text.match(/^{\\an(\d)}/); + + if (pos_tag) { + e.text = e.text.replace(/^{\\an(\d)}/, ''); + + if (pos_tag[1] && parseInt(pos_tag[1]) === 8) { + Cue.render().addClass('on-top'); + } + } + + Cue.draw(e.text.trim()); + }); + applySettings(); + if (data.subtitles) custom(data.subtitles); + } + /** + * Установить собственные субтитры + * @param {[{index:integer, label:string, url:string}]} list + */ + + + function custom(list) { + if (!Arrays.isArray(list)) return console.log('Player', 'custom subtitles not array', list); + var video = PlayerVideo.video(); + if (custom_subtitles) custom_subtitles.destroy(); + video.customSubs = Arrays.clone(list); + console.log('Player', 'custom subtitles', list); + custom_subtitles = new CustomSubtitles(); + custom_subtitles.listener.follow('subtitle', function (e) { + Cue.draw(e.text, e.style); + }); + var index = -1; + video.customSubs.forEach(function (sub) { + index++; + if (typeof sub.index == 'undefined') sub.index = index; + + if (!sub.ready) { + sub.ready = true; + Object.defineProperty(sub, "mode", { + set: function set(v) { + if (v == 'showing') { + custom_subtitles.load(sub.url); + } + }, + get: function get() {} + }); + } + }); + video.customSubs.length > 0 && PlayerVideo.listener.send('subs', { + subs: video.customSubs + }); + } + + function destroy$6() { + Cue.draw(''); + + if (custom_subtitles) { + custom_subtitles.destroy(); + custom_subtitles = null; + } + } + + var Subtitles = { + init: init$I, + custom: custom, + destroy: destroy$6 + }; + + var NoiseEffect = /*#__PURE__*/function () { + function NoiseEffect(name) { + _classCallCheck(this, NoiseEffect); + + this.name = name; + this.enabled = true; + } + + _createClass(NoiseEffect, [{ + key: "update", + value: function update() {} + }, { + key: "draw", + value: function draw() {} + }, { + key: "destroy", + value: function destroy() {} + }]); + + return NoiseEffect; + }(); + + var NoiseBandsEffect = /*#__PURE__*/function (_NoiseEffect) { + _inherits(NoiseBandsEffect, _NoiseEffect); + + var _super = _createSuper(NoiseBandsEffect); + + function NoiseBandsEffect() { + var _options$count; + + var _this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, NoiseBandsEffect); + + _this = _super.call(this, 'bands'); + _this.count = (_options$count = options.count) !== null && _options$count !== void 0 ? _options$count : 10; + _this.bands = []; + return _this; + } + + _createClass(NoiseBandsEffect, [{ + key: "init", + value: function init(noise) { + this.noise = noise; + this.reset(); + } + }, { + key: "reset", + value: function reset() { + this.bands = []; + + for (var i = 0; i < this.count; i++) { + this.bands.push(this.createBand()); + } + } + }, { + key: "createBand", + value: function createBand() { + var height = 5 + Math.random() * 35; + return { + y: Math.random() * this.noise.height, + height: height, + speed: (Math.random() - 0.5) * 1.2, + strength: 0.25 + Math.random() * 1.1, + life: 30 + Math.random() * 160 + }; + } + }, { + key: "update", + value: function update() { + for (var i = 0; i < this.bands.length; i++) { + var band = this.bands[i]; + band.y += band.speed; + band.life--; + + if (band.life <= 0 || band.y > this.noise.height || band.y + band.height < 0) { + this.bands[i] = this.createBand(); + } + } + } + }, { + key: "getStrength", + value: function getStrength(y) { + var strength = 0; + + var _iterator = _createForOfIteratorHelper(this.bands), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var band = _step.value; + + if (y < band.y || y > band.y + band.height) { + continue; + } + + var center = band.y + band.height / 2; + var distance = Math.abs(y - center); + var fade = 1 - distance / (band.height / 2); + strength += band.strength * Math.max(0, fade); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return Math.min(strength, 1.8); + } + }, { + key: "destroy", + value: function destroy() { + this.bands = []; + this.noise = null; + } + }]); + + return NoiseBandsEffect; + }(NoiseEffect); + + var HorizontalSmearEffect = /*#__PURE__*/function (_NoiseEffect2) { + _inherits(HorizontalSmearEffect, _NoiseEffect2); + + var _super2 = _createSuper(HorizontalSmearEffect); + + function HorizontalSmearEffect() { + var _options$minCount, _options$maxCount; + + var _this2; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, HorizontalSmearEffect); + + _this2 = _super2.call(this, 'smear'); + _this2.minCount = (_options$minCount = options.minCount) !== null && _options$minCount !== void 0 ? _options$minCount : 12; + _this2.maxCount = (_options$maxCount = options.maxCount) !== null && _options$maxCount !== void 0 ? _options$maxCount : 35; + return _this2; + } + + _createClass(HorizontalSmearEffect, [{ + key: "draw", + value: function draw(noise) { + var ctx = noise.ctx, + canvas = noise.canvas, + width = noise.width, + height = noise.height; + var count = this.minCount + Math.floor(Math.random() * (this.maxCount - this.minCount + 1)); + + for (var i = 0; i < count; i++) { + var y = Math.floor(Math.random() * height); + var sliceHeight = 1 + Math.floor(Math.random() * 5); + var sourceX = Math.floor(Math.random() * width); + var sourceWidth = 5 + Math.floor(Math.random() * Math.max(5, width - sourceX)); + var destinationX = sourceX + Math.floor((Math.random() - 0.5) * 120); + var destinationWidth = sourceWidth * (1.2 + Math.random() * 5); + ctx.globalAlpha = 0.1 + Math.random() * 0.55; + ctx.drawImage(canvas, sourceX, y, sourceWidth, sliceHeight, destinationX, y, destinationWidth, sliceHeight); + } + + ctx.globalAlpha = 1; + } + }]); + + return HorizontalSmearEffect; + }(NoiseEffect); + + var DisplacedBandsEffect = /*#__PURE__*/function (_NoiseEffect3) { + _inherits(DisplacedBandsEffect, _NoiseEffect3); + + var _super3 = _createSuper(DisplacedBandsEffect); + + function DisplacedBandsEffect() { + var _options$minCount2, _options$maxCount2, _options$maxOffset; + + var _this3; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, DisplacedBandsEffect); + + _this3 = _super3.call(this, 'displacement'); + _this3.minCount = (_options$minCount2 = options.minCount) !== null && _options$minCount2 !== void 0 ? _options$minCount2 : 3; + _this3.maxCount = (_options$maxCount2 = options.maxCount) !== null && _options$maxCount2 !== void 0 ? _options$maxCount2 : 9; + _this3.maxOffset = (_options$maxOffset = options.maxOffset) !== null && _options$maxOffset !== void 0 ? _options$maxOffset : 90; + return _this3; + } + + _createClass(DisplacedBandsEffect, [{ + key: "draw", + value: function draw(noise) { + var ctx = noise.ctx, + canvas = noise.canvas, + width = noise.width, + height = noise.height; + var count = this.minCount + Math.floor(Math.random() * (this.maxCount - this.minCount + 1)); + + for (var i = 0; i < count; i++) { + var y = Math.floor(Math.random() * height); + var bandHeight = 2 + Math.floor(Math.random() * 20); + var offset = Math.floor((Math.random() - 0.5) * this.maxOffset * 2); + ctx.globalAlpha = 0.3 + Math.random() * 0.65; + ctx.drawImage(canvas, 0, y, width, bandHeight, offset, y, width, bandHeight); + + if (Math.random() < 0.55) { + var color = Math.random(); + + if (color < 0.33) { + ctx.fillStyle = 'rgba(0, 180, 255, 0.22)'; + } else if (color < 0.66) { + ctx.fillStyle = 'rgba(0, 255, 170, 0.18)'; + } else { + ctx.fillStyle = 'rgba(255, 30, 90, 0.16)'; + } + + ctx.fillRect(0, y, width, 1 + Math.floor(Math.random() * 2)); + } + } + + ctx.globalAlpha = 1; + } + }]); + + return DisplacedBandsEffect; + }(NoiseEffect); + + var RandomLinesEffect = /*#__PURE__*/function (_NoiseEffect4) { + _inherits(RandomLinesEffect, _NoiseEffect4); + + var _super4 = _createSuper(RandomLinesEffect); + + function RandomLinesEffect() { + var _options$minCount3, _options$maxCount3; + + var _this4; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, RandomLinesEffect); + + _this4 = _super4.call(this, 'lines'); + _this4.minCount = (_options$minCount3 = options.minCount) !== null && _options$minCount3 !== void 0 ? _options$minCount3 : 8; + _this4.maxCount = (_options$maxCount3 = options.maxCount) !== null && _options$maxCount3 !== void 0 ? _options$maxCount3 : 22; + return _this4; + } + + _createClass(RandomLinesEffect, [{ + key: "draw", + value: function draw(noise) { + var ctx = noise.ctx, + width = noise.width, + height = noise.height; + var count = this.minCount + Math.floor(Math.random() * (this.maxCount - this.minCount + 1)); + + for (var i = 0; i < count; i++) { + var x = Math.floor(Math.random() * width); + var y = Math.floor(Math.random() * height); + var lineWidth = 20 + Math.random() * Math.max(20, width - x); + + if (Math.random() < 0.65) { + var r = Math.floor(Math.random() * 90); + var g = 90 + Math.floor(Math.random() * 165); + var b = 100 + Math.floor(Math.random() * 155); + var alpha = 0.06 + Math.random() * 0.3; + ctx.fillStyle = "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(alpha, ")"); + } else { + ctx.fillStyle = "rgba(255,255,255,".concat(0.04 + Math.random() * 0.25, ")"); + } + + ctx.fillRect(x, y, lineWidth, Math.random() < 0.85 ? 1 : 2); + } + } + }]); + + return RandomLinesEffect; + }(NoiseEffect); + + var FrameJumpEffect = /*#__PURE__*/function (_NoiseEffect5) { + _inherits(FrameJumpEffect, _NoiseEffect5); + + var _super5 = _createSuper(FrameJumpEffect); + + function FrameJumpEffect() { + var _options$chance, _options$maxX, _options$maxY; + + var _this5; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, FrameJumpEffect); + + _this5 = _super5.call(this, 'jump'); + _this5.chance = (_options$chance = options.chance) !== null && _options$chance !== void 0 ? _options$chance : 0.07; + _this5.maxX = (_options$maxX = options.maxX) !== null && _options$maxX !== void 0 ? _options$maxX : 14; + _this5.maxY = (_options$maxY = options.maxY) !== null && _options$maxY !== void 0 ? _options$maxY : 5; + return _this5; + } + + _createClass(FrameJumpEffect, [{ + key: "draw", + value: function draw(noise) { + if (Math.random() > this.chance) { + return; + } + + var ctx = noise.ctx, + canvas = noise.canvas; + var offsetX = Math.floor((Math.random() - 0.5) * this.maxX * 2); + var offsetY = Math.floor((Math.random() - 0.5) * this.maxY * 2); + ctx.globalAlpha = 0.75; + ctx.drawImage(canvas, offsetX, offsetY); + ctx.globalAlpha = 1; + } + }]); + + return FrameJumpEffect; + }(NoiseEffect); + + var ScanlinesEffect = /*#__PURE__*/function (_NoiseEffect6) { + _inherits(ScanlinesEffect, _NoiseEffect6); + + var _super6 = _createSuper(ScanlinesEffect); + + function ScanlinesEffect() { + var _options$step, _options$alpha; + + var _this6; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, ScanlinesEffect); + + _this6 = _super6.call(this, 'scanlines'); + _this6.step = (_options$step = options.step) !== null && _options$step !== void 0 ? _options$step : 3; + _this6.alpha = (_options$alpha = options.alpha) !== null && _options$alpha !== void 0 ? _options$alpha : 0.2; + return _this6; + } + + _createClass(ScanlinesEffect, [{ + key: "draw", + value: function draw(noise) { + var ctx = noise.ctx, + width = noise.width, + height = noise.height; + ctx.fillStyle = "rgba(0,0,0,".concat(this.alpha, ")"); + + for (var y = 0; y < height; y += this.step) { + ctx.fillRect(0, y, width, 1); + } + } + }]); + + return ScanlinesEffect; + }(NoiseEffect); + + var VignetteEffect = /*#__PURE__*/function (_NoiseEffect7) { + _inherits(VignetteEffect, _NoiseEffect7); + + var _super7 = _createSuper(VignetteEffect); + + function VignetteEffect() { + var _options$strength; + + var _this7; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, VignetteEffect); + + _this7 = _super7.call(this, 'vignette'); + _this7.strength = (_options$strength = options.strength) !== null && _options$strength !== void 0 ? _options$strength : 0.7; + return _this7; + } + + _createClass(VignetteEffect, [{ + key: "draw", + value: function draw(noise) { + var ctx = noise.ctx, + width = noise.width, + height = noise.height; + var gradient = ctx.createRadialGradient(width / 2, height / 2, height * 0.12, width / 2, height / 2, width * 0.72); + gradient.addColorStop(0, 'rgba(0,0,0,0)'); + gradient.addColorStop(0.65, 'rgba(0,0,0,0.05)'); + gradient.addColorStop(1, "rgba(0,0,0,".concat(this.strength, ")")); + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, width, height); + } + }]); + + return VignetteEffect; + }(NoiseEffect); + + var FlickerEffect = /*#__PURE__*/function (_NoiseEffect8) { + _inherits(FlickerEffect, _NoiseEffect8); + + var _super8 = _createSuper(FlickerEffect); + + function FlickerEffect() { + var _options$chance2; + + var _this8; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, FlickerEffect); + + _this8 = _super8.call(this, 'flicker'); + _this8.chance = (_options$chance2 = options.chance) !== null && _options$chance2 !== void 0 ? _options$chance2 : 0.2; + return _this8; + } + + _createClass(FlickerEffect, [{ + key: "draw", + value: function draw(noise) { + if (Math.random() > this.chance) { + return; + } + + var ctx = noise.ctx, + width = noise.width, + height = noise.height; + + if (Math.random() < 0.5) { + ctx.fillStyle = "rgba(255,255,255,".concat(Math.random() * 0.035, ")"); + } else { + ctx.fillStyle = "rgba(0,0,0,".concat(Math.random() * 0.1, ")"); + } + + ctx.fillRect(0, 0, width, height); + } + }]); + + return FlickerEffect; + }(NoiseEffect); + + var Noise = /*#__PURE__*/function () { + function Noise(canvas) { + var _options$width, _options$height, _options$fps, _options$baseBrightne, _options$bandBrightne, _options$trailAlpha, _options$effects; + + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Noise); + + if (!(canvas instanceof HTMLCanvasElement)) { + throw new TypeError('Noise: первым аргументом должен быть canvas'); + } + + this.canvas = canvas; + this.ctx = canvas.getContext('2d', { + alpha: false + }); + + if (!this.ctx) { + throw new Error('Noise: Canvas 2D не поддерживается'); + } + + this.width = (_options$width = options.width) !== null && _options$width !== void 0 ? _options$width : 480; + this.height = (_options$height = options.height) !== null && _options$height !== void 0 ? _options$height : 270; + this.fps = (_options$fps = options.fps) !== null && _options$fps !== void 0 ? _options$fps : 25; + this.baseBrightness = (_options$baseBrightne = options.baseBrightness) !== null && _options$baseBrightne !== void 0 ? _options$baseBrightne : 16; + this.bandBrightness = (_options$bandBrightne = options.bandBrightness) !== null && _options$bandBrightne !== void 0 ? _options$bandBrightne : 145; + this.trailAlpha = (_options$trailAlpha = options.trailAlpha) !== null && _options$trailAlpha !== void 0 ? _options$trailAlpha : 0.84; + this.running = false; + this.destroyed = false; + this.animationId = null; + this.lastFrameTime = 0; + this._renderBound = this._render.bind(this); + this.canvas.width = this.width; + this.canvas.height = this.height; + this.ctx.imageSmoothingEnabled = false; + + this._createBuffer(); + + this.effects = (_options$effects = options.effects) !== null && _options$effects !== void 0 ? _options$effects : [new NoiseBandsEffect(), new HorizontalSmearEffect(), new DisplacedBandsEffect(), new RandomLinesEffect(), new FrameJumpEffect(), new ScanlinesEffect(), new VignetteEffect(), new FlickerEffect()]; + + var _iterator2 = _createForOfIteratorHelper(this.effects), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var effect = _step2.value; + + if (typeof effect.init === 'function') { + effect.init(this); + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + this.start(); + } + + _createClass(Noise, [{ + key: "_createBuffer", + value: function _createBuffer() { + this.noiseCanvas = document.createElement('canvas'); + this.noiseCanvas.width = this.width; + this.noiseCanvas.height = this.height; + this.noiseCtx = this.noiseCanvas.getContext('2d', { + alpha: false + }); + + if (!this.noiseCtx) { + throw new Error('Noise: не удалось создать внутренний canvas'); + } + + this.noiseImage = this.noiseCtx.createImageData(this.width, this.height); + this.pixels = this.noiseImage.data; + } + }, { + key: "getEffect", + value: function getEffect(name) { + var _this$effects$find; + + return (_this$effects$find = this.effects.find(function (effect) { + return effect.name === name; + })) !== null && _this$effects$find !== void 0 ? _this$effects$find : null; + } + }, { + key: "enable", + value: function enable(name) { + var effect = this.getEffect(name); + + if (effect) { + effect.enabled = true; + } + + return this; + } + }, { + key: "disable", + value: function disable(name) { + var effect = this.getEffect(name); + + if (effect) { + effect.enabled = false; + } + + return this; + } + }, { + key: "toggle", + value: function toggle(name, enabled) { + var effect = this.getEffect(name); + + if (effect) { + effect.enabled = enabled === undefined ? !effect.enabled : Boolean(enabled); + } + + return this; + } + }, { + key: "addEffect", + value: function addEffect(effect) { + if (!effect || typeof effect.draw !== 'function') { + throw new TypeError('Noise.addEffect: передан некорректный эффект'); + } + + if (typeof effect.init === 'function') { + effect.init(this); + } + + this.effects.push(effect); + return this; + } + }, { + key: "removeEffect", + value: function removeEffect(name) { + var index = this.effects.findIndex(function (effect) { + return effect.name === name; + }); + + if (index === -1) { + return this; + } + + var _this$effects$splice = this.effects.splice(index, 1), + _this$effects$splice2 = _slicedToArray(_this$effects$splice, 1), + effect = _this$effects$splice2[0]; + + if (typeof effect.destroy === 'function') { + effect.destroy(); + } + + return this; + } + }, { + key: "start", + value: function start() { + if (this.destroyed || this.running) { + return this; + } + + this.running = true; + this.lastFrameTime = 0; + this.animationId = requestAnimationFrame(this._renderBound); + return this; + } + }, { + key: "stop", + value: function stop() { + this.running = false; + + if (this.animationId !== null) { + cancelAnimationFrame(this.animationId); + this.animationId = null; + } + + return this; + } + }, { + key: "resize", + value: function resize(width, height) { + if (this.destroyed) { + return this; + } + + if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) { + throw new TypeError('Noise.resize: некорректный размер'); + } + + this.width = Math.floor(width); + this.height = Math.floor(height); + this.canvas.width = this.width; + this.canvas.height = this.height; + this.ctx.imageSmoothingEnabled = false; + + this._destroyBuffer(); + + this._createBuffer(); + + var _iterator3 = _createForOfIteratorHelper(this.effects), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var effect = _step3.value; + + if (typeof effect.reset === 'function') { + effect.reset(); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + return this; + } + }, { + key: "_getBandsEffect", + value: function _getBandsEffect() { + var effect = this.getEffect('bands'); + return effect !== null && effect !== void 0 && effect.enabled ? effect : null; + } + }, { + key: "_generateNoise", + value: function _generateNoise() { + var bandsEffect = this._getBandsEffect(); + + var index = 0; + + for (var y = 0; y < this.height; y++) { + var bandStrength = bandsEffect ? bandsEffect.getStrength(y) : 0; + var rowBrightness = Math.random() < 0.14 ? Math.random() * 0.9 : Math.random() * 0.12; + + for (var x = 0; x < this.width; x++) { + var intensity = Math.random() * this.baseBrightness + bandStrength * Math.random() * this.bandBrightness + rowBrightness * 65; + var brightPixelChance = 0.025 + bandStrength * 0.11; + + if (Math.random() < brightPixelChance) { + intensity += 60 + Math.random() * 195; + } + + var colorMode = Math.random(); + var r = void 0; + var g = void 0; + var b = void 0; + + if (colorMode < 0.24) { + r = intensity * (0.7 + Math.random() * 0.8); + g = intensity * (0.15 + Math.random() * 0.5); + b = intensity * (0.05 + Math.random() * 0.35); + } else if (colorMode < 0.48) { + r = intensity * (0.05 + Math.random() * 0.35); + g = intensity * (0.55 + Math.random() * 0.8); + b = intensity * (0.45 + Math.random() * 0.8); + } else if (colorMode < 0.72) { + r = intensity * (0.1 + Math.random() * 0.4); + g = intensity * (0.1 + Math.random() * 0.5); + b = intensity * (0.65 + Math.random() * 0.9); + } else { + var gray = intensity * (0.55 + Math.random() * 0.55); + r = gray; + g = gray; + b = gray; + } + + this.pixels[index] = Math.min(255, r); + this.pixels[index + 1] = Math.min(255, g); + this.pixels[index + 2] = Math.min(255, b); + this.pixels[index + 3] = 255; + index += 4; + } + } + + this.noiseCtx.putImageData(this.noiseImage, 0, 0); + } + }, { + key: "_render", + value: function _render(time) { + if (!this.running || this.destroyed) { + return; + } + + this.animationId = requestAnimationFrame(this._renderBound); + var frameDuration = 1000 / this.fps; + + if (time - this.lastFrameTime < frameDuration) { + return; + } + + this.lastFrameTime = time - (time - this.lastFrameTime) % frameDuration; + + var _iterator4 = _createForOfIteratorHelper(this.effects), + _step4; + + try { + for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { + var effect = _step4.value; + + if (effect.enabled && typeof effect.update === 'function') { + effect.update(this); + } + } + } catch (err) { + _iterator4.e(err); + } finally { + _iterator4.f(); + } + + this._generateNoise(); + + this.ctx.globalAlpha = this.trailAlpha; + this.ctx.drawImage(this.noiseCanvas, 0, 0, this.width, this.height); + this.ctx.globalAlpha = 1; + + var _iterator5 = _createForOfIteratorHelper(this.effects), + _step5; + + try { + for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { + var _effect = _step5.value; + + if (_effect.enabled && _effect.name !== 'bands' && typeof _effect.draw === 'function') { + _effect.draw(this); + } + } + } catch (err) { + _iterator5.e(err); + } finally { + _iterator5.f(); + } + } + }, { + key: "_destroyBuffer", + value: function _destroyBuffer() { + if (this.noiseCanvas) { + this.noiseCanvas.width = 0; + this.noiseCanvas.height = 0; + } + + this.noiseImage = null; + this.pixels = null; + this.noiseCtx = null; + this.noiseCanvas = null; + } + }, { + key: "destroy", + value: function destroy() { + if (this.destroyed) { + return; + } + + this.stop(); + + var _iterator6 = _createForOfIteratorHelper(this.effects), + _step6; + + try { + for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { + var effect = _step6.value; + + if (typeof effect.destroy === 'function') { + effect.destroy(); + } + } + } catch (err) { + _iterator6.e(err); + } finally { + _iterator6.f(); + } + + this.effects.length = 0; + + if (this.ctx && this.canvas) { + this.ctx.globalAlpha = 1; + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + } + + this._destroyBuffer(); + + this.ctx = null; + this.canvas = null; + this._renderBound = null; + this.destroyed = true; + } + }]); + + return Noise; + }(); + + var noise; + + function init$H() { + PlayerVideo.listener.follow('error', function (e) { + if (e.fatal) { + destroy$5(); + create$7(e.error); + } + }); // Если видео загрузилось, то шум убираем + + PlayerVideo.listener.follow('loadeddata', function () { + console.log('Player', 'video loadeddata'); + destroy$5(); + }); + PlayerVideo.listener.follow('destroy', destroy$5); + } + + function create$7(text) { + noise = {}; + noise.html = $("
    \n \n
    \n
    \n
    ".concat(text, "
    \n
    \n
    ")); + PlayerVideo.render().append(noise.html); + PlayerVideo.render().toggleClass('player-video--error', true); + noise["class"] = new Noise(noise.html.find('canvas')[0], { + width: 320, + height: 180, + fps: 25, + baseBrightness: 14, + bandBrightness: 30, + trailAlpha: 0.4 + }); + noise["class"].disable('displacement'); + noise["class"].disable('jump'); + noise["class"].disable('scanlines'); + noise["class"].disable('vignette'); + noise["class"].disable('flicker'); + noise["class"].disable('smear'); + } + + function destroy$5() { + if (noise) { + noise["class"].destroy(); + noise.html.remove(); + noise = null; + } + + PlayerVideo.render().toggleClass('player-video--error', false); + } + + var Error$1 = { + init: init$H, + destroy: destroy$5 + }; + + var html$c; + var listener$7 = Subscribe$2(); + var callback$2; + var work = false; + var launch_player; + var wait_for_loading_url = false; + var wait_loading = false; + var is_opened = false; + var viewing = { + time: 0, + difference: 0, + current: 0 + }; + /** + * Подписываемся на события + */ + + function init$G() { + PlayerPanel.init(); + PlayerVideo.init(); + PlayerInfo.init(); + PlayerFooter.init(); + PlayerIPTV.init(); + Agent.init(); + PlayerChat.init(); + Charts.init(); + Skip.init(); + Timeline.init(); + PlayerPlaylist.init(); + Segments$1.init(); + Disclaimer.init(); + Subtitles.init(); + Error$1.init(); + html$c = Template.get('player'); + html$c.append(PlayerVideo.render()); + html$c.append(PlayerPanel.render()); + html$c.append(PlayerInfo.render()); + html$c.append(PlayerFooter.render()); + html$c.append(PlayerChat.render()); + html$c.append(Skip.render()); + var timer_hide_cursor; + /** Скрываем курсор через 3 секунды */ + + html$c.on('mousemove', function () { + if (Storage.field('navigation_type') == 'mouse' && !Utils$1.isTouchDevice()) PlayerPanel.mousemove(); + html$c.css('cursor', 'auto'); + clearTimeout(timer_hide_cursor); + timer_hide_cursor = setTimeout(function () { + html$c.css('cursor', 'none'); + }, 3000); + }); + /** Обновляем таймкод */ + + PlayerVideo.listener.follow('timeupdate', function (e) { + Screensaver$2.resetTimer(); + viewing.difference = e.current - viewing.current; + viewing.current = e.current; + if (viewing.difference > 0 && viewing.difference < 3) viewing.time += viewing.difference; + }); + /** Дорожки полученые из видео */ + + PlayerVideo.listener.follow('tracks', function (e) { + if (!work.voiceovers) PlayerPanel.setTracks(e.tracks); + }); + /** Ошибка при попытки возпроизвести */ + + PlayerVideo.listener.follow('error', function (e) { + // Если есть резервная ссылка, то пробуем её + if (e.fatal && work.url_reserve) { + PlayerVideo.destroy(true); + PlayerVideo.url(work.url_reserve, true); + Timeline.resetContinue(); + delete work.url_reserve; + } // Если есть резервная ссылка и есть обработчик ошибки, то пробуем её через обработчик + + + if (e.fatal && work.error) work.error(work, function (reserve_url) { + PlayerVideo.destroy(true); + PlayerVideo.url(reserve_url, true); + Timeline.resetContinue(); + }); + }); + /** Видео загружено, проверяем нужно ли скрывать кнопку перемотки */ + + PlayerVideo.listener.follow('loadeddata', function () { + if (PlayerVideo.video().duration < 60 * 3 && work.need_check_live_stream) { + PlayerPanel.hideRewind(); + } + }); + /** Состояние панели, скрыта или нет */ + + PlayerPanel.listener.follow('visible', function (e) { + html$c.toggleClass('player--panel-visible', e.status); + }); + /** К концу видео */ + + PlayerPanel.listener.follow('to_end', function (e) { + if (PlayerPlaylist.canNext()) { + PlayerVideo.pause(); + Timeline.setEnd(); + PlayerPlaylist.next(); + } else { + PlayerVideo.to(-1); + } + }); + /** Переключили качеcтво видео */ + + PlayerPanel.listener.follow('quality', function (e) { + PlayerVideo.destroy(true); + work.quality_switched = e.name; + work.url = e.url; + PlayerVideo.url(Torserver.toPlayUrl(e.url), true); + Timeline.resetContinue(); + }); + /** Переключили поток */ + + PlayerPanel.listener.follow('flow', function (e) { + PlayerVideo.destroy(true); + work.flow_switched = e.url; + work.url = e.url; + PlayerVideo.url(Torserver.toPlayUrl(e.url), true); + Timeline.resetContinue(); + }); + /** Нажали на кнопку (отправить) */ + + PlayerPanel.listener.follow('share', function (e) { + Broadcast.open({ + type: 'play', + object: { + player: work, + playlist: PlayerPlaylist.get() + } + }); + }); + /** Событие на переключение серии */ + + PlayerPlaylist.listener.follow('select', function (e) { + var type = _typeof(e.item.url); + + var call = function call() { + var params = PlayerVideo.saveParams(); + var keepPip = document.pictureInPictureElement === PlayerVideo.video() && typeof e.item.url == 'string' && !PlayerVideo.verifyTube(e.item.url); // Нужно текущий плейлист сохранить, чтобы после destroy в плеере остался правильный плейлист + + var playlist = PlayerPlaylist.get(); + if (keepPip) PlayerVideo.pause(); + destroy$4(keepPip); // Помечаем как продолжение воспроизведения + + e.item.continue_play = true; + play$1(e.item); + PlayerVideo.setParams(params); + PlayerPlaylist.set(playlist); + if (e.item.callback) e.item.callback(); + }; + + if (type == 'string') call();else if (type == 'function' && !wait_for_loading_url) { + PlayerInfo.loading(); + wait_for_loading_url = true; + e.item.url(call); + } + }); + PlayerIPTV.listener.follow('play', function (data) { + PlayerIPTV.locked(data.channel, function () { + PlayerVideo.destroy(); + PlayerVideo.url(data.channel.url); + Controller.toggle('player_tv'); + }); + }); + listener$7.follow('start', function (data) { + Background.theme('black'); + is_opened = true; // Упрощенный интерфейс для IPTV + + html$c.toggleClass('tv', Boolean(data.tv)); // Интерфейс для YouTube + + html$c.toggleClass('youtube', Boolean(data.url.indexOf('youtube.com') >= 0)); + Storage.set('player_subs_shift_time', '0'); + if (!html$c.parent().length) $('body').append(html$c); + }); + listener$7.follow('ready', function (data) { + PlayerVideo.size(Storage.get('player_size', 'default')); + PlayerVideo.speed(Storage.get('player_speed', 'default')); + }); + } + /** + * Переключить контроллер на плеер + */ + + + function toggle$5() { + Controller.add('player', { + invisible: true, + toggle: function toggle() { + PlayerPanel.hide(); + }, + up: function up() { + PlayerPanel.toggle(); + }, + down: function down() { + PlayerPanel.toggle(); + }, + right: function right() { + if (PlayerIPTV.playning()) PlayerPanel.toggle();else PlayerVideo.rewind(true); + }, + left: function left() { + if (PlayerIPTV.playning()) PlayerPanel.toggle();else PlayerVideo.rewind(false); + }, + enter: function enter() { + if (PlayerIPTV.playning()) PlayerPanel.toggle();else PlayerVideo.playpause(); + }, + playpause: function playpause() { + if (!PlayerIPTV.playning()) PlayerVideo.playpause(); + }, + play: function play() { + if (!PlayerIPTV.playning()) PlayerVideo.play(); + }, + pause: function pause() { + if (!PlayerIPTV.playning()) PlayerVideo.pause(); + }, + rewindForward: function rewindForward() { + if (!PlayerIPTV.playning()) PlayerVideo.rewind(true); + }, + rewindBack: function rewindBack() { + if (!PlayerIPTV.playning()) PlayerVideo.rewind(false); + }, + stop: backward$1, + back: backward$1 + }); + Controller.add('player-loading', { + invisible: true, + toggle: function toggle() { + Controller.clear(); + PlayerPanel.show(); + }, + back: backward$1 + }); + Controller.toggle('player'); + } + /** + * Закрыть плеер + * @doc + * @name close + * @alias Player + */ + + + function backward$1() { + launch_player = ''; + destroy$4(); + if (callback$2) callback$2();else Controller.toggle('content'); + callback$2 = false; + } + /** + * Запустить webos плеер + * @param {Object} params + */ + + + function runWebOSPlayer(params) { + webOS.service.request("luna://com.webos.applicationManager", { + method: "launch", + parameters: { + "id": params.need, + "params": { + "payload": [{ + "fullPath": params.url, + "artist": "", + "subtitle": "", + "dlnaInfo": { + "flagVal": 4096, + "cleartextSize": "-1", + "contentLength": "-1", + "opVal": 1, + "protocolInfo": "http-get:*:video/x-matroska:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000", + "duration": 0 + }, + "mediaType": "VIDEO", + "thumbnail": "", + "deviceType": "DMR", + "album": "", + "fileName": params.name, + "lastPlayPosition": params.position + }] + } + }, + onSuccess: function onSuccess() { + console.log('Player', 'The app is launched'); + }, + onFailure: function onFailure(inError) { + console.log('Player', "Failed to launch the app (" + params.need + "): ", "[" + inError.errorCode + "]: " + inError.errorText); + + if (params.need == 'com.webos.app.photovideo') { + params.need = 'com.webos.app.smartshare'; + runWebOSPlayer(params); + } else if (params.need == 'com.webos.app.smartshare') { + params.need = 'com.webos.app.mediadiscovery'; + runWebOSPlayer(params); + } + } + }); + } + /** + * Получить ссылку на внешний плеер + */ + + + function externalPlayer(player_need, data, players, infuseCallbacks) { + var player = Storage.field(player_need); + var url = encodeURIComponent(Torserver.toPlayUrl(data.url)); + + var _url = encodeURI(Torserver.toPlayUrl(data.url)); + + var furl = Torserver.toPlayUrl(data.url); + var playlist = data.playlist ? encodeURIComponent(JSON.stringify(data.playlist)) : ''; + var segments = data.segments ? encodeURIComponent(JSON.stringify(data.segments)) : ''; + + for (var p in players) { + players[p] = players[p].replace('${url}', url).replace('${_url}', _url).replace('${furl}', furl).replace('${playlist}', playlist).replace('${segments}', segments); + } // Infuse: save_and_play, readable filenames, season playlist + + + if (player == 'infuse') { + InfusePlayer.normalizePlayData(data); + var customUrl = null; + listener$7.send('infuse_build_url', { + data: data, + callbacks: infuseCallbacks, + setUrl: function setUrl(url) { + customUrl = url; + } + }); + if (customUrl) return customUrl; + return InfusePlayer.resolveUrl(data, infuseCallbacks) || players.infuse; + } + + return players[player]; + } + + function prepareInfuseLaunch(data, player_need, callback, onCancel) { + if (Storage.field(player_need) !== 'infuse') return callback(); // Торрент + Infuse: всегда play? с position + + if (InfusePlayer.isTorrentStream(data)) { + data.infuse_mode = 'play'; + return callback(); + } + + var setting = Storage.field('infuse_launch_mode') || 'play'; + + if (setting !== 'ask') { + data.infuse_mode = setting; + return callback(); + } + + delete data.infuse_mode; + var enabled = Controller.enabled(); + Select.show({ + title: Lang.translate('title_action_infuse'), + items: [{ + title: Lang.translate('settings_infuse_launch_save_and_play'), + mode: 'save_and_play' + }, { + title: Lang.translate('settings_infuse_launch_play'), + mode: 'play' + }], + onSelect: function onSelect(item) { + Controller.toggle(enabled.name); + data.infuse_mode = item.mode; + callback(); + delete data.infuse_mode; + }, + onBack: function onBack() { + Controller.toggle(enabled.name); + if (onCancel) onCancel(); + } + }); + } + + function launchExternalPlayer(data, player_need, players, infuseCallbacks, onFallback) { + var launch = function launch(external_url) { + if (!external_url) return onFallback ? onFallback() : null; + Preroll.show(data, function () { + listener$7.send('external', data); + window.location.assign(external_url); + }); + }; + + prepareInfuseLaunch(data, player_need, function () { + launch(externalPlayer(player_need, data, players, infuseCallbacks)); + }, function () { + listener$7.send('destroy', {}); + }); + } + /** + * Запустить нужный плеер в зависимости от условий + */ + + + function start$6(data, need, inner) { + var player_need = 'player' + (need ? '_' + need : ''); + + var launchInner = function launchInner() { + if (Disclaimer.needs(player_need, launch_player)) Disclaimer.show(inner);else inner(); + }; + + if (data.launch_player) launch_player = data.launch_player; + if (launch_player == 'lampa' || launch_player == 'inner' || PlayerVideo.verifyTube(data.url)) launchInner();else if (Platform.is('apple')) { + launchExternalPlayer(data, player_need, { + vlc: 'vlc://${furl}', + nplayer: 'nplayer-${furl}', + infuse: 'infuse://x-callback-url/play?url=${url}', + senplayer: 'senplayer://x-callback-url/play?url=${url}', + vidhub: 'open-vidhub://x-callback-url/open?&url=${url}', + svplayer: 'svplayer://x-callback-url/stream?url=${url}', + tracyplayer: 'tracy://open?url=${url}' + }, null, function () { + if (Storage.field(player_need) == 'ios') { + html$c.addClass('player--ios'); + launchInner(); + } else launchInner(); + }); + } else if (Platform.macOS()) { + launchExternalPlayer(data, player_need, { + mpv: 'mpv://${_url}', + iina: 'iina://weblink?url=${url}', + nplayer: 'nplayer-${_url}', + infuse: 'infuse://x-callback-url/play?url=${url}', + senplayer: 'senplayer://x-callback-url/play?url=${url}' + }, null, launchInner); + } else if (Platform.is('apple_tv')) { + var _Storage$field; + + var apple_tv_client = (_Storage$field = Storage.field('apple_tv_client')) !== null && _Storage$field !== void 0 ? _Storage$field : 'lampa'; + launchExternalPlayer(data, player_need, { + vlc: 'vlc-x-callback://x-callback-url/stream?url=${url}', + infuse: "infuse://x-callback-url/play?x-success=".concat(apple_tv_client, "://infuseDidFinish&x-error=").concat(apple_tv_client, "://infuseDidFail&url=${url}&playlist=${playlist}"), + senplayer: 'SenPlayer://x-callback-url/play?url=${url}', + vidhub: 'open-vidhub://x-callback-url/open?url=${url}', + svplayer: 'svplayer://x-callback-url/stream?url=${url}', + tracyplayer: 'tracy://open?url=${url}', + tvospro: 'lampa://video?player=tvospro&src=${url}&playlist=${playlist}&segments=${segments}', + tvos: 'lampa://video?player=tvos&src=${url}&playlist=${playlist}&segments=${segments}', + tvosl: 'lampa://video?player=tvosav&src=${url}&playlist=${playlist}&segments=${segments}', + tvosSelect: 'lampa://video?player=lists&src=${url}&playlist=${playlist}&segments=${segments}' + }, null, launchInner); + } else if (Platform.is('webos') && (Storage.field(player_need) == 'webos' || launch_player == 'webos')) { + Preroll.show(data, function () { + runWebOSPlayer({ + need: 'com.webos.app.photovideo', + url: Torserver.toPlayUrl(data.url), + name: data.path || data.title, + position: data.timeline ? data.timeline.time || -1 : -1 + }); + listener$7.send('external', data); + }); + } else if (Platform.is('android') && (Storage.field(player_need) == 'android' || launch_player == 'android' || data.torrent_hash && !Torserver.gstWork())) { + data.url = Torserver.toPlayUrl(data.url); + data.title = Utils$1.clearHtmlTags(data.title || '').trim(); + + if (data.playlist && Array.isArray(data.playlist)) { + data.playlist = data.playlist.filter(function (p) { + return typeof p.url == 'string'; + }); + data.playlist.forEach(function (a) { + a.url = Torserver.toPlayUrl(a.url); + a.title = Utils$1.clearHtmlTags(a.title || '').trim(); + }); + } + + Preroll.show(data, function () { + data.position = data.timeline ? data.timeline.time || -1 : -1; + Android.openPlayer(data.url, data); + listener$7.send('external', data); + }); + } else if (Platform.desktop() && Storage.field(player_need) == 'other') { + var path = Storage.field('player_nw_path'); + var supportedTypes = Object.values(ExternalPlayer.PLAYER_TYPES); + var detectedType = supportedTypes.find(function (type) { + return path.toLowerCase().indexOf(type) !== -1; + }); + Preroll.show(data, function () { + var url = Torserver.toPlayUrl(data.url); + + if (detectedType) { + ExternalPlayer.openPlayer(url, data, { + type: detectedType, + fullscreen: Storage.field('player_external_fullscreen') + }); + } else { + var file = require('fs'); + + if (file.existsSync(path)) { + var spawn = require('child_process').spawn; + + spawn(path, [encodeURI(url)]); + } else { + Noty.show(Lang.translate('player_not_found') + ': ' + path); + } + } + + listener$7.send('external', data); + }); + } else launchInner(); + if (data.launch_player) delete data.launch_player; + } + /** + * Получить URL по качеству видео + * @doc + * @name getUrlQuality + * @alias Player + * @param {object} quality JSON({"480p": "http://example/video.mp4", "720p": {"url": "http://example/video.mp4", "label": "HD"}, "1080p": {"label": "FHD", "call": "{function} - вызвать при выборе"}}) + * @param {boolean} set_better установить лучшее качество, если нет дефолтного + * @returns {string} URL + */ + + + function getUrlQuality(quality) { + var set_better = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + if (_typeof(quality) !== 'object') return ''; + var url = ''; + + for (var q in quality) { + var qa = quality[q]; + var qu = _typeof(qa) == 'object' ? qa.url : typeof qa == 'string' ? qa : ''; + if (parseInt(q) == Storage.field('video_quality_default') && qu) return qu; + } + + if (!url && set_better) { + var sort_quality = Arrays.getKeys(quality); + sort_quality.sort(function (a, b) { + return parseInt(b) - parseInt(a); + }); + sort_quality.forEach(function (q) { + var qa = quality[q]; + var qu = _typeof(qa) == 'object' ? qa.url : typeof qa == 'string' ? qa : ''; + if (qu && !url) url = qu; + }); + } + + return url; + } + /** + * Запустить плеер + * @doc + * @name play + * @alias Player + * @param {object} data JSON({"url": "http://example/video.mp4", "quality": {"1080p": "http://example/video.mp4"}, "title": "Video title", "translate": [{"name": "Перевод", "language": "ru", "extra": {"channels": 2}}], "subtitles": [{"url": "http://example/subs.srt", "label": "RU Force"}], "card": "{object} - TMDB Card", "timeline": "{object} - Lampa.Timeline.view", "iptv": "{boolean} - запустить IPTV плеер", "tv": "{boolean} - имитация IPTV", "torrent_hash": "{string}", "playlist": [{"title":"{string} - Серия 1", "url":"{string} - http://example/video.mp4"}]}) + */ + + + function play$1(data) { + var run = true; + listener$7.send('create', { + data: data, + abort: function abort() { + return run = false; + } + }); + if (!run) return console.log('Player', 'play aborted by callback'); + console.log('Player', 'start play'); + console.log('Player', 'item url', data.url); + console.log('Player', 'play data', data); // Если это торрент, то увеличиваем таймаут для HLS манифеста, чтобы не было проблем с буферизацией + + if (data.torrent_hash && Torserver.gstWork()) data.hls_manifest_timeout = 60000; + + if (data.ffprobe && !Arrays.isArray(data.translate)) { + var tracks = tracksFromFfprobe(data.ffprobe); + + if (tracks.length) { + if (!data.translate || _typeof(data.translate) !== 'object') data.translate = {}; + if (!data.translate.tracks) data.translate.tracks = tracks; + } + } + + if (data.quality) { + // Если качество одно, то удаляем объект качества, чтобы не показывать панель выбора качества + if (Arrays.getKeys(data.quality).length == 1) delete data.quality;else { + var quality_url = getUrlQuality(data.quality, false); + + if (quality_url) { + // Меняем ссылку на видео на выбранное качество, чтобы плеер сразу начал воспроизведение с нужного качества + data.url = quality_url; + console.log('Player', 'quality selected url', quality_url); + } + } + } + + var lauch = function lauch() { + // Запоминаем текущий объект, чтобы потом можно было получить его в других методах + work = data; // Если есть реклама, то показываем её, затем запускаем плеер + + Preroll.show(data, function () { + listener$7.send('start', data); + console.log('Player', 'play url', data.url); + PlayerVideo.url(Torserver.toPlayUrl(data.url)); + toggle$5(); + Timeline.needToContinue(toggle$5); + listener$7.send('ready', data); + }); + }; + + if (launch_player) data.launch_player = launch_player; + start$6(data, data.torrent_hash ? 'torrent' : '', lauch); + } + + function iptv(data) { + PlayerIPTV.locked(data, function () { + console.log('Player', 'play iptv'); + data.iptv = true; //пометка для ведра, что это iptv + + data.iptv_player = true; //помечаем как iptv плеер, для него совсем другой интерфейс + + var lauch = function lauch() { + work = data; + html$c.toggleClass('iptv', Boolean(data.iptv)); + listener$7.send('start', data); + PlayerIPTV.start(data); + toggle$5(); + listener$7.send('ready', data); + }; + + start$6(data, 'iptv', function () { + if (data.vast_url) Preroll.show(data, lauch);else lauch(); + }); + }); + } + /** + * Установить плейлист + * @doc + * @name playlist + * @alias Player + * @param {array} data JSON([{"title":"{string} - Серия 1", "url":"{string} - http://example/video.mp4"}]) + */ + + + function playlist(playlist) { + PlayerPlaylist.set(playlist); + } + /** + * Установить субтитры для видео + * @doc + * @name subtitles + * @alias Player + * @param {array} subs JSON([{"index":"{integer}", "label":"{string}", "url":"http://example/subs.srt"}]) + */ + + + function subtitles(subs) { + Subtitles.custom(subs); + } + /** + * Запустить другой плеер + * @doc + * @name runas + * @alias Player + * @param {string} need android, ios, webos, apple, apple_tv, macos, desktop, other + */ + + + function runas(need) { + launch_player = need; + } + /** + * Обратный вызов при закрытии плеера + * @doc + * @name callback + * @alias Player + * @param {function} back + */ + + + function onBack(back) { + callback$2 = back; + } + /** + * Рендер плеера + * @doc + * @name render + * @alias Player + * @returns Html + */ + + + function render$7() { + return html$c; + } + /** + * Возвращает статус, открыт ли плеер + * @doc + * @name opened + * @alias Player + * @returns {boolean} + */ + + + function opened$1() { + return is_opened; + } + /** + * Показать процесс загрузки + * @doc + * @name loading + * @alias Player + * @param {boolean} status cтатус загрузки, `true` - показать, `false` - скрыть + */ + + + function loading$1(status) { + if (!work) return; + wait_loading = status; + html$c.toggleClass('player--loading', Boolean(status)); + + if (wait_loading) { + Controller.toggle('player-loading'); + PlayerVideo.pause(); + } else { + PlayerVideo.play(); + toggle$5(); + } + } + /** + * Уничтожить плеер + */ + + + function destroy$4(keepPip) { + Timeline.destroy(); + if (work.viewed) work.viewed(Storage.field('torrserver_tracktimecode') ? Math.round(PlayerVideo.video().currentTime) : viewing.time); + work = false; + wait_for_loading_url = false; + wait_loading = false; + viewing.time = 0; + viewing.difference = 0; + viewing.current = 0; + html$c.removeClass('player--ios'); + html$c.removeClass('iptv'); + html$c.removeClass('iptv--player'); + html$c.removeClass('player--panel-visible'); + html$c.removeClass('player--loading'); + PlayerVideo.destroy(false, keepPip); + PlayerVideo.clearParamas(); + if (!keepPip) html$c.detach(); + is_opened = false; + Background.theme('reset'); + $('body').removeClass('player--viewing'); + if (Select.opened()) Select.hide(); + listener$7.send('destroy', {}); + } + + var Player = { + init: init$G, + listener: listener$7, + toggle: toggle$5, + play: play$1, + playlist: playlist, + render: render$7, + subtitles: subtitles, + runas: runas, + callback: onBack, + opened: opened$1, + iptv: iptv, + programReady: PlayerIPTV.programReady, + close: backward$1, + getUrlQuality: getUrlQuality, + loading: loading$1, + timecodeRecording: Timeline.setRecording, + playdata: function playdata() { + return work; + } + }; + + var html$b = $("\n
    \n \n \n \n
    "); + var background = { + one: { + canvas: $('.background__one', html$b), + ctx: $('.background__one', html$b)[0].getContext('2d') + }, + two: { + canvas: $('.background__two', html$b), + ctx: $('.background__two', html$b)[0].getContext('2d') + }, + fade: { + canvas: $('.background__fade', html$b), + ctx: $('.background__fade', html$b)[0].getContext('2d') + } + }; + var theme_elem = $('head meta[name="theme-color"]'); + var view = 'one'; + var src = ''; + var loaded$1 = {}; + var bokeh = { + c: [], + h: [], + d: true + }; + var timer$2; + var immed_time = Date.now(); + var theme_color = '#000000'; + var timer_change; + /** + * Запуск + */ + + function init$F() { + Storage.listener.follow('change', function (event) { + if (event.name == 'background' || event.name == 'background_type') resize$1(); + }); + var u = Platform.any() ? object$2.github_lampa : './'; + + if (Platform.is('orsay')) { + u = './'; + } + + for (var i = 1; i <= 6; i++) { + var im = new Image(); + im.src = u + 'img/bokeh-h/' + i + '.png'; + bokeh.h.push(im); + } + + for (var _i = 1; _i <= 6; _i++) { + var _im = new Image(); + + _im.src = u + 'img/bokeh/' + _i + '.png'; + bokeh.c.push(_im); + } + + background.one.canvas[0].width = window.screen_width; + background.one.canvas[0].height = window.screen_height; + background.two.canvas[0].width = window.screen_width; + background.two.canvas[0].height = window.screen_height; + background.fade.canvas[0].width = window.screen_width; + background.fade.canvas[0].height = window.screen_height; + Lampa.Listener.follow('resize_start', function () { + html$b[0].style.opacity = 0; + }); + Lampa.Listener.follow('resize_end', function () { + html$b[0].style.opacity = 1; + resize$1(); + }); + html$b[0].toggleClass('hide', !Storage.field('background')); + } + /** + * Получить активный фон + * @returns {{canvas:object, ctx: class}} + */ + + + function bg() { + view = view == 'one' ? 'two' : 'one'; + return background[view]; + } + /** + * Рисовать + * @param {object} data + * @param {object} item - фон + * @param {boolean} noimage + */ + + + function draw(data, item, noimage) { + if (noimage) return; // Для мобильных устройств делаем полный сброс canvas + + if (Platform.screen('mobile')) { + item.canvas[0].width = window.screen_width; + item.canvas[0].height = window.screen_height; + } else { + item.ctx.clearRect(0, 0, window.screen_width, window.screen_height); + } + + var palette = data.palette; + var type = Storage.field('background_type'); + blur(data, item, function () { + if (type == 'complex' && bokeh.d) { + var bright = Color.rgbToHsl(palette.average[0], palette.average[1], palette.average[2]); + item.ctx.globalAlpha = bright[2] > 30 ? bright[2] / 100 * 0.6 : 0.4; + item.ctx.globalCompositeOperation = bright[2] > 30 ? 'color-dodge' : 'screen'; + + for (var i = 0; i < 10; i++) { + var bp = Math.round(Math.random() * (bokeh.c.length - 1)); + var im = bright[2] > 30 ? bokeh.h[bp] : bokeh.c[bp]; + var xp = window.screen_width * Math.random(), + yp = window.screen_height / 2 * Math.random() + window.screen_height / 2, + sz = Math.max(window.screen_height / 8, window.screen_height / 5 * Math.random()) * 0.01, + nw = im.width * sz, + nh = im.height * sz; + + try { + item.ctx.drawImage(im, xp - nw / 2, yp - nw / 2, nw, nh); + } catch (e) {} + } + } + + item.ctx.globalAlpha = type == 'poster' ? 0.7 : 0.6; + item.ctx.globalCompositeOperation = 'multiply'; + var angle = 90 * Math.PI / 180, + x2 = window.screen_width * Math.cos(angle), + y2 = window.screen_height * Math.sin(angle); + var gradient = item.ctx.createLinearGradient(0, 0, x2, y2); + gradient.addColorStop(0, 'rgba(0,0,0,1)'); + gradient.addColorStop(1, 'rgba(0,0,0,' + (type == 'poster' ? 0.4 : 0) + ')'); + item.ctx.fillStyle = gradient; + item.ctx.fillRect(0, 0, window.screen_width, window.screen_height); + + if (Platform.screen('mobile')) { + item.ctx.globalAlpha = 1; + item.ctx.globalCompositeOperation = 'destination-out'; + gradient = item.ctx.createLinearGradient(0, 0, x2, y2); + gradient.addColorStop(0.05, 'rgba(29,31,32,1)'); + gradient.addColorStop(0.18, 'rgba(' + palette.bright.join(',') + ',0)'); + item.ctx.fillStyle = gradient; + item.ctx.fillRect(0, 0, window.screen_width, window.screen_height); + clearTimeout(timer_change); + timer_change = setTimeout(function () { + html$b.find('canvas').eq(view == 'one' ? 1 : 0).removeClass('visible'); + }, 400); + item.canvas.addClass('visible'); + } else { + fadeTo(item); + } + + if (!Player.opened()) theme(Storage.field('black_style') ? 'black' : 'reset'); + }); + } + /** + * Плавный переход с двойным прогревом обоих canvas + */ + + + function fadeTo(new_bg) { + var fade = background.fade.ctx; + var old_image = background[view === 'one' ? 'two' : 'one'].canvas[0]; + var new_image = new_bg.canvas[0]; + var duration = 700; // длительность fade + + var warmup = 80; // прогрев GPU + + var start = Date.now(); + + function step() { + var elapsed = Date.now() - start; + + if (elapsed < warmup) { + // прогрев: оба слоя с альфой 0 + fade.globalAlpha = 0; + fade.drawImage(old_image, 0, 0); + fade.drawImage(new_image, 0, 0); + requestAnimationFrame(step); + return; + } // плавный переход + + + var progress = Math.min((elapsed - warmup) / duration, 1); + var eased = progress * progress * (3 - 2 * progress); // easeInOutCubic + // сначала рисуем старый фон + + fade.globalAlpha = 1; + fade.drawImage(old_image, 0, 0); // поверх рисуем новый с альфой + + fade.globalAlpha = eased; + fade.drawImage(new_image, 0, 0); + + if (progress < 1) { + requestAnimationFrame(step); + } + } // небольшой defer для синхронизации с рендером браузера + + + requestAnimationFrame(function () { + return requestAnimationFrame(step); + }); + } + /** + * Размыть картинку + * @param {object} data + * @param {object} item - фон + * @param {function} complite + */ + + + function blur(data, item, complite) { + function blured(img) { + var ratio = Math.max(window.screen_width / img.width, window.screen_height / img.height); + var nw = img.width * ratio, + nh = img.height * ratio; + item.ctx.globalAlpha = data.img.width > 1000 ? bokeh.d ? 1 : 0.2 : 1; + item.ctx.drawImage(img, -(nw - window.screen_width) / 2, -(nh - window.screen_height) / 2, nw, nh); + complite(); + } + + if (data.img.width > 1000) blured(data.img);else Color.blur(data.img, blured); + } + /** + * Обновить если изменился размер окна + */ + + + function resize$1() { + background.one.canvas[0].width = window.screen_width; + background.one.canvas[0].height = window.screen_height; + background.two.canvas[0].width = window.screen_width; + background.two.canvas[0].height = window.screen_height; + background.fade.canvas[0].width = window.screen_width; + background.fade.canvas[0].height = window.screen_height; + background.one.canvas.width(window.screen_width); + background.one.canvas.height(window.screen_height); + background.two.canvas.width(window.screen_width); + background.two.canvas.height(window.screen_height); + background.fade.canvas.width(window.screen_width); + background.fade.canvas.height(window.screen_height); + html$b[0].toggleClass('hide', !Storage.field('background')); + if (loaded$1[src]) draw(loaded$1[src], background[view]); + } + /** + * Максимум картинок в памяти + */ + + + function limit$1() { + var a = Arrays.getKeys(loaded$1); + + if (a.length > 30) { + var u = a.slice(0, 1); + delete loaded$1[u]; + } + } + /** + * Загрузить картинку в память + */ + + + function load$1() { + if (loaded$1[src]) { + draw(loaded$1[src], bg()); + } else if (src) { + limit$1(); + var cache_src = src; + var colors; + var img = new Image(); + img.crossOrigin = "Anonymous"; + + img.onload = function () { + try { + colors = Color.get(img); + } catch (e) { + colors = [[200, 200, 200], [100, 100, 100], [10, 10, 10]]; + } + + loaded$1[cache_src] = { + img: img, + palette: Color.palette(colors) + }; + draw(loaded$1[cache_src], bg()); + }; + + img.onerror = function () { + draw(false, false, true); + }; + + img.src = src; + } + } + /** + * Изменить картинку + * @param {string} url + */ + + + function change() { + var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + if (url == src || Storage.field('light_version') || !Storage.field('background')) return; + bokeh.d = true; + if (url) src = url; + clearTimeout(timer$2); + timer$2 = setTimeout(function () { + if (url) load$1();else draw(false, false, true); + }, 1000); + } + /** + * Изменить немедленно без ожидания + * @param {string} url + */ + + + function immediately() { + var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + if (Storage.field('light_version') || immed_time + 1000 > Date.now() || !Storage.field('background')) return; + if (url) src = url; + clearTimeout(timer$2); + bokeh.d = false; + immed_time = Date.now(); + if (url) load$1();else draw(false, false, true); + } + + function theme(color) { + if (color == 'black') color = '#000000';else if (color == 'reset') color = '#1d1f20'; + if (color == theme_color) return; + theme_color = color; + theme_elem.attr('content', color); + } + /** + * Рендер + * @returns {object} + */ + + + function render$6() { + return html$b; + } + + var Background = { + render: render$6, + change: change, + update: resize$1, + init: init$F, + immediately: immediately, + theme: theme + }; + + var timer$1; + var need_update = false; + var need_visible = false; + + function init$E() { + window.screen_width = window.innerWidth; + window.screen_height = window.innerHeight; + $(window).on('resize', function () { + Lampa.Listener.send('resize_start'); + window.screen_width = window.innerWidth; + window.screen_height = window.innerHeight; + clearTimeout(timer$1); + timer$1 = setTimeout(function () { + toggleMobile(); + toggleOrientation(); + size(); + update$5(); + Lampa.Listener.send('resize_end'); + }, 100); + }); + var follow = ['animation', 'mask', 'card_interfice_poster', 'glass_style', 'black_style', 'glass_opacity', 'card_interfice_cover', 'advanced_animation', 'light_version', 'keyboard_type', 'menu_always']; + Storage.listener.follow('change', function (event) { + if (event.name == 'interface_size') { + size(); + update$5(); + } + + if (follow.indexOf(event.name) >= 0) toggleClasses(), update$5(); + }); + toggleClasses(); + toggleMobile(); + toggleOrientation(); + size(); + setTimeout(blick, 5000); + if (Platform.tv() || Platform.desktop()) mouseEvents(); + } + + function toggleMobile() { + $('body').toggleClass('true--mobile', Platform.screen('mobile')); + } + + function toggleOrientation() { + $('body').removeClass('orientation--portrait orientation--landscape').addClass('orientation--' + (window.innerWidth > window.innerHeight && window.innerHeight < 768 ? 'landscape' : 'portrait')); + } + + function mouseEvents() { + var body = $('body'); + var mouse_timer_cursor; + $(window).on('mousemove', function () { + clearTimeout(mouse_timer_cursor); + mouse_timer_cursor = setTimeout(function () { + body.toggleClass('no--cursor', true); + }, 3000); + body.toggleClass('no--cursor', false); + }); + } + + function size() { + var sl = Storage.field('interface_size'); + var sz = { + normal: 1, + small: 0.9, + bigger: 1.05 + }; + var fs = sz[sl]; + $('body').css({ + fontSize: Math.max(window.innerWidth / 84.17 * fs, 10.6) + 'px' + }).removeClass('size--small size--normal size--bigger').addClass('size--' + sl); + } + + function blick() { + $('.icon--blink').not('.ready').each(function () { + var elem = $(this), + time = parseInt(elem.data('blink-interval') || 3) * 1000; + elem.addClass('ready'); + setInterval(function () { + elem.addClass('animate'); + setTimeout(function () { + elem.removeClass('animate'); + }, 1000); + }, time); + }); + } + + function frameUpdate(render) { + var where = render || document.body; + var target = where instanceof jQuery ? where[0] : where; + var landscape = window.innerWidth > window.innerHeight && window.innerHeight < 768; + var wrap = document.querySelector('.wrap__left'); + var head = document.querySelector('.head'); + var navi = document.querySelector('.navigation-bar'); + var menu_left = wrap ? wrap.getBoundingClientRect().left : 0; + var menu_width = wrap ? wrap.getBoundingClientRect().width : 0; + var head_height = head ? head.getBoundingClientRect().height : 0; + var navi_height = navi && !landscape ? navi.getBoundingClientRect().height : 0; + var navi_width = navi && landscape ? navi.getBoundingClientRect().width : 0; + var layer_width = Array.from(target.querySelectorAll('.layer--width')); + var layer_height = Array.from(target.querySelectorAll('.layer--height')); + var layer_wheight = Array.from(target.querySelectorAll('.layer--wheight')); + if (target.classList.contains('layer--width')) layer_width.push(target); + if (target.classList.contains('layer--height')) layer_height.push(target); + if (target.classList.contains('layer--wheight')) layer_wheight.push(target); // Check for 'always' menu mode to determine the layout offset + + var menu_offset = document.body.classList.contains('menu--always') ? menu_width : 0; + + for (var i = 0; i < layer_width.length; i++) { + var elem = layer_width[i], + read = parseFloat(elem.style.width), + widh = window.innerWidth - (Platform.screen('light') && menu_left == 0 ? menu_width : menu_offset) - navi_width; + if (read !== widh) layer_width[i].style.width = widh; + } + + for (var _i = 0; _i < layer_wheight.length; _i++) { + var _elem = layer_wheight[_i], + heig = window.innerHeight - head_height - navi_height, + attr = _elem.mheight, + _read = parseFloat(_elem.style.height); + + if (attr) { + heig -= attr.getBoundingClientRect().height; + } + + if (_read !== heig) _elem.style.height = heig; + } + + for (var _i2 = 0; _i2 < layer_height.length; _i2++) { + var _elem2 = layer_height[_i2], + _heig = window.innerHeight, + _attr = _elem2.mheight, + _read2 = parseFloat(_elem2.style.height); + + if (_attr) { + _heig -= _attr.getBoundingClientRect().height; + } + + if (_read2 !== _heig) _elem2.style.height = _heig; + } + } + + function intersectedGrid(viewCell, elemCell) { + var maxDistance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2; + // разница между экранной ячейкой и ячейкой элемента + var dx = Math.abs(viewCell.x - elemCell.x); + var dy = Math.abs(viewCell.y - elemCell.y); // если элемент в пределах maxDistance ячеек — показываем + + return dx <= maxDistance && dy <= maxDistance; + } + + function frameVisible() { + var cellW = window.innerWidth; + var cellH = window.innerHeight; // экран всегда "в нулевой ячейке" + + var viewCell = { + x: 0, + y: 0 + }; + + if (need_visible) { + var elems = need_visible; + + for (var i = 0; i < elems.length; i++) { + var elem = elems[i]; + + if (!elem.call_visible) { + elem.bond = elem.getBoundingClientRect(); // определяем в какую ячейку попадает элемент + + var elemCell = { + x: Math.floor(elem.bond.left / cellW), + y: Math.floor(elem.bond.top / cellH) + }; + var inter = intersectedGrid(viewCell, elemCell, 2); + elem.visible = inter; + var visibility = inter ? 'visible' : 'hidden'; + + if (elem.visibility !== visibility) { + if (!elem.visibility && visibility == 'visible') continue; + elem.visibility = visibility; + } + } + } + + for (var _i3 = 0; _i3 < elems.length; _i3++) { + var _elem3 = elems[_i3]; + + if (_elem3.visible && !_elem3.called_visible) { + _elem3.called_visible = true; + Utils$1.trigger(_elem3, 'visible'); + } + + if (_elem3.visibility && _elem3.style.visibility !== _elem3.visibility) { + _elem3.style.visibility = _elem3.visibility; + Utils$1.trigger(_elem3, 'visible:change'); + } + } + } + } + + function toggleClasses() { + $('body').toggleClass('no--animation', !Storage.field('animation')); + $('body').toggleClass('no--mask', !Storage.field('mask')); + $('body').toggleClass('no--poster', !Storage.field('card_interfice_poster')); + $('body').toggleClass('glass--style', Storage.field('glass_style')); + $('body').toggleClass('black--style', Storage.field('black_style')); + $('body').toggleClass('card--no-cover', !Storage.field('card_interfice_cover')); + $('body').toggleClass('advanced--animation', Storage.field('advanced_animation')); + $('body').toggleClass('light--version', Storage.field('light_version')); + $('body').toggleClass('system--keyboard', Storage.field('keyboard_type') == 'lampa' ? false : true); + $('body').toggleClass('menu--always', Platform.screen('tv') && Storage.field('menu_always')); + $('body').removeClass('glass--style-opacity--easy glass--style-opacity--medium glass--style-opacity--blacked'); + if (Storage.field('glass_style')) $('body').addClass('glass--style-opacity--' + Storage.field('glass_opacity')); + Background.theme(Storage.field('black_style') ? 'black' : 'reset'); + } + + function combineElements(find_class, elements, combine) { + var target = combine instanceof jQuery ? combine[0] : combine; + var elems = []; + + if (target.classList.contains(find_class)) { + elems.push(target); + } + + elems = elems.concat(Array.from(target.querySelectorAll('.' + find_class))); + elems.filter(function (elem) { + return elements.indexOf(elem) < 0; + }); + return [].concat(elements, elems); + } + + function visible(where) { + var active = Lampa.Activity.active(); + var combine = where ? where : active && active.activity ? active.activity.render(true) : false; + if (!combine) return; + need_visible = combineElements('layer--visible', need_visible || [], combine); + updateFrame(); + } + + function update$5(where) { + need_update = where; + updateFrame(); + } + + function updateFrame() { + if (need_update !== false) frameUpdate(need_update); + if (need_visible !== false) frameVisible(); + need_update = false; + need_visible = false; + } + + var Layer = { + update: update$5, + visible: visible, + init: init$E + }; + + /** + * Создает кастомный скролл + * @param {object} [params] - параметры скрола + * @param {boolean} [params.horizontal=false] - горизонтальный скролл + * @param {boolean} [params.mask=false] - отображать маску прокрутки + * @param {boolean} [params.over=false] - разрешить скролл поверх других элементов + * @param {boolean} [params.nopadding=false] - отключить паддинги + * @param {boolean} [params.notransition=false] - отключить анимацию прокрутки + * @param {number} [params.step=150] - шаг прокрутки колесом мыши + * @param {boolean} [params.scroll_by_item=false] - прокручивать по элементам + * @param {number} [params.end_ratio=1] - соотношение для определения конца скрола (1 - конец, 2 - середина и т.д.) + * @param {function} [this.onWheel] - вызывается при прокрутке колесом мыши, вместо стандартной функции + * @param {function} [this.onScroll] - вызывается при прокрутке скрола + * @param {function} [this.onEnd] - вызывается при достижении конца скрола + * @returns {Scroll} + */ + + function Scroll() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var _self = this; + + var html = Template.js('scroll'); + var body = html.querySelector('.scroll__body'); + var content = html.querySelector('.scroll__content'); + var screen = Platform.screen('tv'); + var scroll_position = 0; + var scroll_animating = false; + var time_call_end = Date.now(); + var scroll_time = 0, + scroll_step = params.step || 150; + if (params.horizontal) html.classList.toggle('scroll--horizontal', true); + if (params.mask) html.classList.toggle('scroll--mask', true); + if (params.over) html.classList.toggle('scroll--over', true); + if (params.nopadding) html.classList.toggle('scroll--nopadding', true); + if (params.notransition) body.classList.toggle('notransition', true); + + function wheel(e) { + var parent = $(e.target).parents('.scroll'); + var inner = onTheRightSide(e, true); + if (!params.horizontal && $(html).is(parent[0])) inner = true; + + if (Date.now() - scroll_time > 200 && inner) { + scroll_time = Date.now(); + + if (e.wheelDelta / 120 > 0) { + if (_self.onWheel) _self.onWheel(-scroll_step);else _self.wheel(-scroll_step); + } else { + if (_self.onWheel) _self.onWheel(scroll_step);else _self.wheel(scroll_step); + } + } + } // Обрабатываем скролл колесом мыши + + + html.addEventListener('mousewheel', wheel); + html.addEventListener('wheel', wheel); // Экспортируемые методы и свойства + + html.Scroll = _self; // Если это телевизор и есть сенсорный экран, то делаем скролл тачем + + if (screen) { + var movestart = function movestart(e) { + start_position = params.horizontal ? e.clientX : e.clientY; + end_position = start_position; + move_position = start_position; + body.toggleClass('notransition', true); + }; + + var move = function move(e) { + end_position = params.horizontal ? e.clientX : e.clientY; + + if (move_position && end_position) { + var delta = move_position - end_position; + var direct = params.horizontal ? 'left' : 'top'; + var scrl = scroll_position, + scrl_padding = parseInt(window.getComputedStyle(content, null).getPropertyValue('padding-' + direct)); + var max = params.horizontal ? 30000 : body.offsetHeight; + max -= params.horizontal ? html.offsetWidth : html.offsetHeight; + max += scrl_padding * 2; + scrl -= delta; + scrl = Math.min(0, Math.max(-max, scrl)); + scrl = maxOffset(scrl); + scroll_position = scrl; + translateScroll(); + move_position = end_position; + } + }; + + var moveend = function moveend(e) { + end_position = 0; + start_position = 0; + move_position = 0; + body.toggleClass('notransition', false); + scrollEnded(); + if (_self.onAnimateEnd) _self.onAnimateEnd(); + }; + + html.addEventListener('scroll', function (e) { + html.scrollTop = 0; + html.scrollLeft = 0; + }); + var start_position = 0; + var move_position = 0; + var end_position = 0; + html.addEventListener('touchstart', function (e) { + movestart(e.touches[0] || e.changedTouches[0]); + }); + html.addEventListener('touchmove', function (e) { + move(e.touches[0] || e.changedTouches[0]); + }); + html.addEventListener('touchend', moveend); + } else { + var native_scroll_animate = false; + var native_scroll_timer = null; + html.addEventListener('scroll', function () { + clearTimeout(native_scroll_timer); + native_scroll_timer = setTimeout(function () { + if (_self.onAnimateEnd) _self.onAnimateEnd(); + }, 300); + + if (!native_scroll_animate) { + native_scroll_animate = true; + requestAnimationFrame(function () { + native_scroll_animate = false; + scroll_position = -(params.horizontal ? html.scrollLeft : html.scrollTop); + scrollEnded(); + }); + } + }); + } + /** + * Определяет, находится ли курсор на правой стороне скрола + * @param {Event} e - событие мыши + * @param {boolean} inleft - если true, то проверяет левую сторону + * @returns {boolean} + */ + + + function onTheRightSide(e) { + var inleft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var offset = content.getBoundingClientRect().left; + var width = window.innerWidth - offset; + var position = e.clientX - offset; + return params.horizontal ? position > width / 2 : inleft ? position < width / 2 : false; + } + /** + * Максимально возможный отступ + * @param {number} offset - желаемый отступ + * @returns {number} + */ + + + function maxOffset(offset) { + var w = params.horizontal ? html.offsetWidth : html.offsetHeight; + var p = parseInt(window.getComputedStyle(content, null).getPropertyValue('padding-' + (params.horizontal ? 'left' : 'top'))); + var s = body[params.horizontal ? 'scrollWidth' : 'scrollHeight']; + offset = Math.min(0, offset); + offset = Math.max(-(Math.max(s + p * 2, w) - w), offset); + return offset; + } + /** + * Вызов обновления скрола и вызов события конеца скрола + */ + + + function scrollEnded() { + if (_self.onScroll) _self.onScroll(!screen ? html[params.horizontal ? 'scrollLeft' : 'scrollTop'] : -scroll_position);else Layer.visible(html); + if (_self.onEnd && _self.isEnd()) _self.onEnd(); + } + /** + * Перемещает скролл в указанную позицию без анимации + */ + + + function translateScroll() { + if (!screen) { + html[params.horizontal ? 'scrollLeft' : 'scrollTop'] = -scroll_position; + } else { + body.style['-webkit-transform'] = 'translate3d(' + Math.round(params.horizontal ? scroll_position : 0) + 'px, ' + Math.round(params.horizontal ? 0 : scroll_position) + 'px, 0px)'; + } + } + /** + * Начинает анимацию прокрутки к указанной позиции + * @param {number} to_position - куда нужно прокрутить + */ + + + function startScroll(to_position) { + // Зачем начинать анимацию, если мы уже там? + if (scroll_position == to_position) { + if (!_self.isFilled()) scrollEnded(); + return; + } + + scroll_position = to_position; + translateScroll(); + + if (Storage.field('animation')) { + scroll_animating = true; + body.addEventListener('webkitTransitionEnd', function () { + if (Date.now() - time_call_end < 300) return; + time_call_end = Date.now(); + scroll_animating = false; + scrollEnded(); + if (_self.onAnimateEnd) _self.onAnimateEnd(); + }, { + once: true + }); + } else { + scrollEnded(); + if (_self.onAnimateEnd) _self.onAnimateEnd(); + } + } + /** + * Получить позицию элемента относительно скрола + * @param {HTMLElement|jQuery} elem - элемент, который должен быть виден + * @param {boolean} tocenter - выровнять элемент по центру скрола + * @returns {number} + */ + + + function getElementPosition(elem, tocenter) { + var dir = params.horizontal ? 'left' : 'top', + siz = params.horizontal ? 'offsetWidth' : 'offsetHeight'; + var target = elem instanceof jQuery ? elem[0] : elem; + var p = tocenter ? parseInt(window.getComputedStyle(content, null).getPropertyValue('padding-' + (params.horizontal ? 'left' : 'top'))) : 0; + var ofs_elm = target.getBoundingClientRect()[dir], + ofs_box = body.getBoundingClientRect()[dir], + center = ofs_box + (tocenter ? content[siz] / 2 - target[siz] / 2 - p : 0), + scrl = Math.min(0, center - ofs_elm); + scrl = maxOffset(scrl); + return scrl; + } + /** + * Добавить обработку свайпа вниз имитации скрытия шторки + * @param {function} call - функция, которая будет вызвана при свайпе вниз + */ + + + this.addSwipeDown = function (call) { + if (window.innerWidth > 480) return; + var s = 0; + var t = 0; + html.addEventListener('touchstart', function (e) { + var point = e.touches[0] || e.changedTouches[0]; + + if (s == 0) { + s = point.clientY; + t = Date.now(); + } + }); + html.addEventListener('touchmove', function (e) { + var point = e.touches[0] || e.changedTouches[0]; + + if (s !== 0) { + if (point.clientY - s > 50 && html.scrollTop == 0 && Date.now() - t < 100) { + s = 0; + call(); + } + } + }); + html.addEventListener('touchend', function (e) { + s = 0; + }); + }; + /** + * Вызвать прокрутку + * @param {number} size - на сколько пикселей прокрутить + */ + + + this.wheel = function (size) { + var direct = params.horizontal ? 'left' : 'top'; + var scrl = scroll_position, + scrl_offset = html.getBoundingClientRect()[direct], + scrl_padding = parseInt(window.getComputedStyle(content, null).getPropertyValue('padding-' + direct)); + + if (params.scroll_by_item) { + var pos = body.scroll_position; + pos = pos || 0; + var items = Array.from(body.children); + pos += size > 0 ? 1 : -1; + pos = Math.max(0, Math.min(items.length - 1, pos)); + body.scroll_position = pos; + var item = items[pos], + ofst = item.getBoundingClientRect()[direct]; + size = ofst - scrl_offset - scrl_padding; + } + + var max = params.horizontal ? 30000 : body.offsetHeight; + max -= params.horizontal ? html.offsetWidth : html.offsetHeight; + max += scrl_padding * 2; + scrl -= size; + scrl = Math.min(0, Math.max(-max, scrl)); + scrl = maxOffset(scrl); + startScroll(scrl); + }; + /** + * Обновить позицию скрола, чтобы элемент был виден + * @param {HTMLElement|jQuery} elem - элемент, который должен быть виден + * @param {boolean} tocenter - выровнять элемент по центру скрола + * @returns {void} + */ + + + this.update = function (elem, tocenter) { + startScroll(getElementPosition(elem, tocenter)); + }; + /** + * Обновить позицию скрола, чтобы элемент был виден без анимации + * @param {HTMLElement|jQuery} elem - элемент, который должен быть виден + * @param {boolean} tocenter - выровнять элемент по центру скрола + * @returns {void} + */ + + + this.immediate = function (elem, tocenter) { + body.toggleClass('notransition', true); + scroll_position = getElementPosition(elem, tocenter); + translateScroll(); + setTimeout(function () { + body.toggleClass('notransition', false); + }, 5); + }; + /** + * Сдвинуть скролл на указанное количество пикселей без анимации + * @param {number} shift - на сколько пикселей сдвинуть скролл + * @returns {void} + */ + + + this.shift = function (shift) { + body.toggleClass('notransition', true); + scroll_position = maxOffset(scroll_position - shift); + translateScroll(); + setTimeout(function () { + body.toggleClass('notransition', false); + }, 5); + }; + /** + * Получить параметры скрола + * @returns {Object} + */ + + + this.vieport = function () { + var vieport = {}; + + if (!screen) { + vieport.position = html[params.horizontal ? 'scrollLeft' : 'scrollTop'], vieport.body = body[params.horizontal ? 'scrollWidth' : 'scrollHeight'], vieport.content = html[params.horizontal ? 'offsetWidth' : 'offsetHeight']; + } else { + vieport.position = scroll_position; + vieport.body = body[params.horizontal ? 'offsetWidth' : 'offsetHeight']; + vieport.content = html[params.horizontal ? 'offsetWidth' : 'offsetHeight']; + } + + return vieport; + }; + /** + * Проверить, достигнут ли конец скрола + * @param {number} [end_ratio] - соотношение для определения конца скрола (1 - конец, 2 - середина и т.д.) + * @returns {boolean} + */ + + + this.isEnd = function (end_ratio) { + var vieport = this.vieport(); + if (vieport.body < vieport.content) return vieport.position <= 0; + return vieport.body - vieport.content * Math.max(1, end_ratio || params.end_ratio || 1) < Math.abs(vieport.position); + }; + /** + * Проверить, заполнен ли скролл контентом + * @returns {boolean} + */ + + + this.isFilled = function () { + var vieport = this.vieport(); + return vieport.body > vieport.content; + }; + /** + * Добавить элемент в скролл + * @param {HTMLElement|jQuery} object - элемент для добавления + * @returns {void} + */ + + + this.append = function (object) { + body.append(object); + }; + /** + * Добавить элемент в начало скрола + * @param {HTMLElement|jQuery} object - элемент для добавления + * @returns {void} + */ + + + this.prepend = function (object) { + body.prepend(object); + }; + /** + * Установить высоту скрола с учетом вычитаемого элемента и вычитом шапки + * @param {HTMLElement|jQuery} minus - элемент, высота которого будет вычтена из высоты скрола + * @returns {void} + */ + + + this.minus = function (minus) { + html.classList.add('layer--wheight'); + html.mheight = minus instanceof jQuery ? minus[0] : minus; + }; + /** + * Установить высоту скрола с учетом вычитаемого элемента + * @param {HTMLElement|jQuery} minus - элемент, высота которого будет вычтена из высоты скрола + * @returns {void} + */ + + + this.height = function (minus) { + html.classList.add('layer--height'); + html.mheight = minus instanceof jQuery ? minus[0] : minus; + }; + /** + * Получить тело скрола + * @param {boolean} js - вернуть в виде DOM-элемента, а не jQuery + * @returns {HTMLElement|jQuery} + */ + + + this.body = function (js) { + return js ? body : $(body); + }; + /** + * Получить HTML скрола + * @param {boolean} js - вернуть в виде DOM-элемента, а не jQuery + * @returns {HTMLElement|jQuery} + */ + + + this.render = function (js) { + return js ? html : $(html); + }; + /** + * Очистить скролл от элементов + * @returns {void} + */ + + + this.clear = function () { + body.innerHTML = ''; + }; + /** + * Получить параметры скрола + * @returns {Object} + */ + + + this.params = function () { + return params; + }; + /** + * Получить текущую позицию скрола + * @returns {number} + */ + + + this.position = function () { + return scroll_position; + }; + /** + * Восстановить позицию скрола + * Используется после detach активности, скролл сбивается и после start активности его нужно восстановить + * @returns {void} + */ + + + this.restorePosition = function () { + if (Platform.screen('mobile')) translateScroll(); + }; + /** + * Отключить паддинги у скрола + * @returns {void} + */ + + + this.nopadding = function () { + html.classList.toggle('scroll--nopadding', true); + }; + /** + * Cбросить позицию скрола в 0 + * @returns {void} + */ + + + this.reset = function () { + scroll_position = 0; + translateScroll(); + }; + /** + * Проверить, анимируется ли скролл в данный момент + * @returns {boolean} + */ + + + this.animated = function () { + return scroll_animating ? true : false; + }; + /** + * Удалить скролл + * @returns {void} + */ + + + this.destroy = function () { + scroll_animating = false; + html.remove(); + }; + } + + var html$a, + active$4, + _scroll, + last$1, + _opened = false; + + var listener$6 = Subscribe$2(); + /** + * Открывает модальное окно + * @param {object} params - параметры окна + * @param {string} params.title - заголовок окна + * @param {jQuery|HTMLElement} params.html - содержимое окна + * @param {string} [params.size=small] - размер окна (small, medium, large, full) + * @param {boolean} [params.overlay=false] - отображать окно как оверлей + * @param {string} [params.align=top] - выравнивание окна (top, center) + * @param {boolean} [params.mask=false] - отображать маску прокрутки + * @param {Array} [params.buttons] - массив кнопок внизу окна {name: 'Имя', onSelect: function(){}} + * @param {string} [params.buttons_position=inside] - положение кнопок (inside, outside) + * @param {HTMLElement|jQuery} [params.select] - элемент для фокуса после открытия + * @param {function} [params.onBack] - вызывается при закрытии окна + * @param {function} [params.onSelect] - вызывается при выборе элемента внутри окна + * @param {number} [params.zIndex] - z-index окна + * @returns {void} + */ + + function open$5(params) { + active$4 = params; + active$4.open_time = Date.now(); + listener$6.send('preshow', { + active: active$4 + }); + html$a = Template.get('modal', { + title: params.title + }); + html$a.on('mousedown', function (e) { + if (!$(e.target).closest($('.modal__content', html$a)).length && DeviceInput.canClick(e.originalEvent) && active$4.open_time + 1000 < Date.now()) Controller.back(); + }); + title(params.title); + html$a.toggleClass('modal--buttons-column', params.size == 'small' ? true : false); + html$a.toggleClass('modal--medium', params.size == 'medium' ? true : false); + html$a.toggleClass('modal--large', params.size == 'large' ? true : false); + html$a.toggleClass('modal--full', params.size == 'full' ? true : false); + html$a.toggleClass('modal--overlay', params.overlay ? true : false); + html$a.toggleClass('modal--align-center', params.align == 'center' ? true : false); + if (params.zIndex) html$a.css('z-index', params.zIndex); + _scroll = new Scroll(_objectSpread2({ + over: true, + mask: params.mask + }, params.scroll)); + html$a.find('.modal__content').toggleClass('layer--height', params.size == 'full' ? true : false); + html$a.find('.modal__body').append(_scroll.render()); + bind$1(params.html); + + _scroll.onWheel = function (step) { + roll(step > 0 ? 'down' : 'up'); + }; + + if (params.size == 'full' && Platform.mouse()) { + html$a.find('.modal__content').prepend(HeadBackward(params.title || '')); + } + + _scroll.append(params.html); + + _scroll.addSwipeDown(function () { + html$a.addClass('animate-down'); + setTimeout(function () { + Controller.back(); + }, 200); + }); + + if (params.buttons) buttons$1(); + $('body').append(html$a); + max(); + listener$6.send('fullshow', { + active: active$4, + html: html$a + }); + toggle$4(params.select); + html$a.addClass('animate'); + _opened = true; + } + + function max() { + var height = window.innerHeight; + + if (window.innerWidth <= 480) { + if (active$4.size == 'full') { + height = window.innerHeight - html$a.find('.head-backward').outerHeight(); + + _scroll.render().css('height', height + 'px'); + } else { + height = window.innerHeight * 0.6; + } + } else { + height -= _scroll.render().offset().top; + if (active$4.size !== 'full') height -= window.innerHeight * 0.1; + if (active$4.buttons && active$4.buttons_position == 'outside') height -= html$a.find('.modal__footer').outerHeight() || 0; + } + + _scroll.render().find('.scroll__content').css('max-height', Math.round(height) + 'px'); + } + + function buttons$1() { + var footer = $(''); + active$4.buttons.forEach(function (button) { + var btn = $(''); + btn.text(button.name); + btn.on('click hover:enter', function (e) { + if (DeviceInput.noDubleClick(e)) button.onSelect(); + }); + footer.append(btn); + }); + + if (active$4.buttons_position == 'outside') { + html$a.find('.modal__content').append(footer); + } else _scroll.append(footer); + } + + function bind$1(where) { + where.find('.selector').on('hover:focus', function (e) { + last$1 = e.target; + + _scroll.update($(e.target), active$4.scroll_to_center); + }).on('hover:enter', function (e) { + last$1 = e.target; + if (active$4.onSelect) active$4.onSelect($(e.target)); + }); + } + + function jump(tofoward) { + var select = _scroll.render().find('.selector.focus'); + + if (tofoward) select = select.nextAll().filter('.selector');else select = select.prevAll().filter('.selector'); + select = select.slice(0, 10); + select = select.last(); + + if (select.length) { + Controller.collectionFocus(select[0], _scroll.render()); + } + } + + function roll(direction) { + var select = _scroll.render().find('.selector'); + + if (select.length) { + Navigator.move(direction); + } else { + var step = Math.round(window.innerHeight * 0.15); + + _scroll.wheel(direction == 'down' ? step : -step); + } + } + + function toggle$4(need_select) { + Controller.add('modal', { + invisible: true, + toggle: function toggle() { + Controller.collectionSet(_scroll.render()); + Controller.collectionFocus(need_select || last$1, _scroll.render()); + Layer.visible(_scroll.render(true)); + listener$6.send('toggle', { + active: active$4, + html: html$a + }); + }, + up: function up() { + if (active$4.buttons && active$4.buttons_position == 'outside' && (_scroll.isEnd() || !_scroll.isFilled())) { + Controller.toggle('modal'); + roll('up'); + } else roll('up'); + }, + down: function down() { + if (active$4.buttons && active$4.buttons_position == 'outside' && (_scroll.isEnd() || !_scroll.isFilled())) { + Controller.collectionSet(html$a.find('.modal__footer')); + Controller.collectionFocus(false, html$a.find('.modal__footer')); + } else roll('down'); + }, + right: function right() { + if (Navigator.canmove('right')) Navigator.move('right');else jump(true); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else jump(false); + }, + back: function back() { + if (active$4.onBack) active$4.onBack(); + } + }); + Controller.toggle('modal'); + } + + function update$4(new_html) { + last$1 = false; + + _scroll.clear(); + + _scroll.append(new_html); + + bind$1(new_html); + max(); + listener$6.send('update', { + active: active$4, + html: html$a, + new_html: new_html + }); + toggle$4(active$4.select); + } + + function title(tit) { + html$a.find('.modal__title').text(tit); + html$a.toggleClass('modal--empty-title', !tit ? true : false); + } + + function destroy$3() { + last$1 = false; + + _scroll.destroy(); + + html$a.remove(); + listener$6.send('close', { + active: active$4 + }); + _opened = false; + } + + function close$6() { + destroy$3(); + } + + function render$5() { + return html$a; + } + + var Modal = { + listener: listener$6, + open: open$5, + close: close$6, + update: update$4, + title: title, + toggle: toggle$4, + render: render$5, + scroll: function scroll() { + return _scroll; + }, + opened: function opened() { + return _opened; + } + }; + + function init$D() { + var agent = navigator.userAgent.toLowerCase(); + + if (typeof webOS !== 'undefined' && webOS.platform.tv === true) { + Storage.set('platform', 'webos'); + webOS.deviceInfo(function (e) { + webOS.sdk_version = parseFloat(e.sdkVersion); + }); + } else if (typeof webapis !== 'undefined' && typeof tizen !== 'undefined') { + Storage.set('platform', 'tizen'); + tizen.tvinputdevice.registerKey("MediaPlayPause"); + tizen.tvinputdevice.registerKey("MediaPlay"); + tizen.tvinputdevice.registerKey("MediaStop"); + tizen.tvinputdevice.registerKey("MediaPause"); + tizen.tvinputdevice.registerKey("MediaRewind"); + tizen.tvinputdevice.registerKey("MediaFastForward"); + tizen.tvinputdevice.registerKey("ChannelUp"); + tizen.tvinputdevice.registerKey("ChannelDown"); + } else if (agent.indexOf("lampa_client") > -1) { + Storage.set('platform', 'android'); + } else if (agent.indexOf("whaletv") > -1 || agent.indexOf("philips") > -1 || agent.indexOf("nettv") > -1) { + Storage.set('platform', 'philips'); + } else if (agent.indexOf("ipad") > -1 && window.innerWidth == 1920 && window.innerHeight == 1080) { + Storage.set('platform', 'apple_tv'); + } else if (agent.indexOf("iphone") > -1 || agent.indexOf("mac os") > -1 && Utils$1.isTouchDevice() || agent.indexOf("macintosh") > -1 && Utils$1.isTouchDevice()) { + Storage.set('platform', 'apple'); + } else if (typeof nw !== 'undefined') { + Storage.set('platform', 'nw'); + } else if (agent.indexOf("electron") > -1) { + Storage.set('platform', 'electron'); + } else if (agent.indexOf("netcast") > -1) { + Storage.set('platform', 'netcast'); + } else if (agent.indexOf("version/5.1.7 safari/534.57.2") > -1) { + Storage.set('platform', 'orsay'); // Версия для тестов на Safari + } else if ((agent.indexOf("windows nt") > -1 || agent.indexOf("macintosh") > -1) && !Utils$1.isTouchDevice()) { + Storage.set('platform', 'browser'); + } else if (agent.indexOf("maple") > -1) { + Storage.set('platform', 'orsay'); + Orsay.init(); + } else { + Storage.set('platform', ''); + } + + Storage.set('native', Storage.get('platform') ? true : false); + $('body').addClass('platform--' + (get$8() || 'noname')); + $('body').toggleClass('touch-device', screen('mobile')); + $('body').toggleClass('mouse--controll', mouse()); + } + /** + * Какая платформа + * @returns String + */ + + + function get$8() { + return Storage.get('platform', ''); + } + /** + * Если это платформа + * @param {String|Array} need - какая нужна? tizen, webos, android, netcast, orsay, apple, apple_tv, nw, electron + * @returns Boolean + */ + + + function is(need) { + if (Arrays.isArray(need)) return need.indexOf(get$8()) >= 0; + return get$8() == need; + } + /** + * Платформы у которых есть возможность изменить плеер + * @returns Boolean + */ + + + function any() { + return is('tizen') || is('webos') || is('android') || is('netcast') || is('orsay') || is('apple') || is('apple_tv') || macOS() || desktop(); + } + /** + * Если это телевизор + * @returns Boolean + */ + + + function tv() { + return is('tizen') || is('webos') || is('orsay') || is('netcast') || is('apple_tv') || tvbox() || Boolean(navigator.userAgent.toLowerCase().match(/tizen|webos/i)); + } + /** + * Если это телевизор на базе приставки (Android TV, Mi Box, Nvidia Shield и т.п.) + * @returns Boolean + */ + + + function tvbox() { + return Boolean(navigator.userAgent.toLowerCase().match(/googletv|google tv|mibox|mitv|smarttv|smart tv|google tv|android tv/i)) || Boolean(navigator.userAgent.toLowerCase().match(/android/i) && !Utils$1.isTouchDevice()); + } + /** + * Если это NW.js или Electron + * @returns Boolean + */ + + + function desktop() { + return is('nw') || is('electron'); + } + /** + * Если навигация мышь или тачпад + * @returns Boolean + */ + + + function mouse() { + return screen('tv') && !tv() || Storage.field('navigation_type') !== 'controll'; + } + /** + * Если это macOS без тача + * @returns Boolean + */ + + + function macOS() { + var agent = navigator.userAgent.toLowerCase(); + return agent.indexOf("mac os x") > -1 && !Utils$1.isTouchDevice(); + } + /** + * Версия приложения + * @param {String} name - какая нужна? app, android, orsay + * @returns String + */ + + + function version(name) { + if (name == 'app') { + return object$2.app_version; + } else if (name == 'android') { + return AndroidJS.appVersion(); + } else if (name == 'orsay') { + return curWidget.version; + } else { + return ''; + } + } + /** + * Экран телевизор или мобильный + * @param {String} need - какой нужен? tv, mobile, light + * @returns Boolean + */ + + + function screen(need) { + if (need == 'light') { + return Storage.field('light_version') && screen('tv'); + } + + var is_tv = true; + + if (!(tv() || desktop())) { + if (Storage.get('is_true_mobile', 'false')) is_tv = false;else if (Boolean(Storage.get('platform', '') == 'apple')) is_tv = false;else if (Boolean(navigator.userAgent.toLowerCase().match(/iphone|ipad/i))) is_tv = false;else if (Utils$1.isTouchDevice()) { + if (!Boolean(navigator.userAgent.toLowerCase().match(/(large screen)|googletv|mibox|mitv|smarttv|google tv|android tv/i))) { + var ratio = window.devicePixelRatio || 1; + var width = Math.ceil(window.screen_width * ratio); + var height = Math.ceil(window.screen_height * ratio); + is_tv = width > height && width >= 1280; + } + } + } + + if (need == 'tv') return is_tv; + if (need == 'mobile') return !is_tv; + return false; + } + /** + * Установка приложения + * @param {String} what - что устанавливать? apk + * @returns void + */ + + + function install$2(what) { + if ($('.modal').length) Modal.close(); + + if (what == 'apk') { + var html = Template.js('account_none'); + + if (tv()) { + var code = html.find('.account-modal-split__qr-code'); + html.addClass('layer--' + (mouse() ? 'wheight' : 'height')); + Utils$1.qrcode(object$2.apk_link_download, code, function () { + html.find('.account-modal-split__qr').addClass('hide'); + }); + } else html.addClass('account-modal-split--mobile'); + + html.find('.account-modal-split__title').text(Lang.translate('install_app_apk_title')); + html.find('.account-modal-split__text').html(Lang.translate('install_app_apk_text')); + html.find('.account-modal-split__qr-text').text(Lang.translate('install_app_apk_qr')); + html.find('.simple-button').text(Lang.translate('copy_link_buffer')).on('hover:enter', function () { + Utils$1.copyTextToClipboard(object$2.apk_link_download, function () { + Bell.push({ + text: Lang.translate('copy_secuses') + }); + }); + }); + Modal.open({ + title: '', + html: $(html), + size: tv() ? 'full' : 'medium', + scroll: { + nopadding: true + }, + onBack: function onBack() { + Modal.close(); + Controller.toggle('content'); + } + }); + } else { + Controller.toggle('content'); + } + } + /** + * Версия Chrome для Android TV + * @returns Number + */ + + + function chromeVersion() { + var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); + return raw ? parseInt(raw[2], 10) : 0; + } + /** + * Версия виджета для TV + * @returns Number + */ + + + function widgetVersion() { + return window.widget_version || 0; + } + + var Platform = { + init: init$D, + get: get$8, + any: any, + is: is, + tv: tv, + mouse: mouse, + desktop: desktop, + version: version, + screen: screen, + install: install$2, + macOS: macOS, + chromeVersion: chromeVersion, + widgetVersion: widgetVersion + }; + + var reqCallback = {}; + var timeCallback = {}; + + function init$C() { + if (Platform.is('android')) { + Params.listener.follow('button', function (e) { + if (e.name === 'reset_player') { + resetDefaultPlayer(); + } + }); + Lampa.Listener.follow('state:changed', function (e) { + if (e.target == 'favorite' && e.reason == 'update' && (e.method == 'add' || e.method == 'added' || e.method == 'remove')) { + updateChannel(e.type); + } + }); + } + } + + function exit() { + if (checkVersion(1)) AndroidJS.exit();else $('')[0].click(); + } + + function playHash(SERVER) { + var magnet = "magnet:?xt=urn:btih:" + SERVER.hash; + + if (checkVersion(10)) { + var intentExtra = ""; + + if (SERVER.movie) { + intentExtra = { + title: "[LAMPA] " + (SERVER.movie.title || 'No title').replace(/\s+/g, ' ').trim(), + poster: SERVER.movie.img, + media: SERVER.movie.name ? 'tv' : 'movie', + data: { + lampa: true, + movie: SERVER.movie + } + }; + } + + AndroidJS.openTorrentLink(magnet, JSON.stringify(intentExtra)); + } else { + $('')[0].click(); + } + } + + function openTorrent(SERVER) { + if (checkVersion(10)) { + var intentExtra = { + title: "[LAMPA] " + (SERVER.movie.title || 'No title').replace(/\s+/g, ' ').trim(), + poster: SERVER.object.poster, + media: SERVER.movie.name ? 'tv' : 'movie', + data: { + lampa: true, + movie: SERVER.movie + } + }; + AndroidJS.openTorrentLink(SERVER.object.MagnetUri || SERVER.object.Link, JSON.stringify(intentExtra)); + } else { + $('')[0].click(); + } + } + + function openPlayer(link, data) { + if (data) data.card = resolveCard(data); + + var updateTimeline = function updateTimeline(elem) { + if (elem.timeline) { + var new_timeline = Lampa.Timeline.view(elem.timeline.hash); + elem.timeline.time = Math.round(new_timeline.time); + elem.timeline.duration = Math.round(new_timeline.duration); + elem.timeline.percent = new_timeline.percent; + timeCallback[elem.timeline.hash] = elem; + } + }; + + if (checkVersion(98, true)) { + if (data.timeline) { + updateTimeline(data); + } + + if (data.playlist) { + data.playlist.forEach(function (elem) { + updateTimeline(elem); + }); + } + } + + if (checkVersion(10)) AndroidJS.openPlayer(link, JSON.stringify(data));else $('')[0].click(); + } + + function openYoutube(link) { + if (checkVersion(15)) AndroidJS.openYoutube(link);else $('')[0].click(); + } + + function openBrowser(link) { + if (checkVersion(484)) AndroidJS.openBrowser(link); + } + + function resetDefaultPlayer() { + if (checkVersion(15)) AndroidJS.clearDefaultPlayer(); + } + + function httpReq(data, call) { + var index = Math.floor(Math.random() * 5000); + reqCallback[index] = { + data: data, + call: call + }; + if (checkVersion(16)) AndroidJS.httpReq(JSON.stringify(data), index);else call.error({ + responseText: "No Native request" + }); + } + + function httpCall(index, callback) { + var req = reqCallback[index]; + + if (req && req.call[callback]) { + var resp = AndroidJS.getResp(index); + + if (!req.data.dataType || req.data.dataType && req.data.dataType.toLowerCase() == 'json' || callback === 'error') { + try { + resp = JSON.parse(resp); + } catch (e) {} + } + + delete reqCallback[index]; + req.call[callback](resp); + } + } + + function timeCall(timeline) { + var hash = timeline.hash; + + if (timeCallback[hash]) { + timeCallback[hash].timeline.handler(timeline.percent, timeline.time, timeline.duration); + timeCallback[hash].timeline.percent = timeline.percent; + timeCallback[hash].timeline.duration = timeline.duration; + timeCallback[hash].timeline.time = timeline.time; + delete timeCallback[hash]; + } + } + + function voiceStart() { + if (checkVersion(25)) AndroidJS.voiceStart();else Lampa.Noty.show("Работает только на Android TV"); + } + + function updateChannel(where) { + if (checkVersion(28)) AndroidJS.updateChannel(where); + } + + function checkVersion(needVersion) { + var silent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (typeof AndroidJS !== 'undefined') { + try { + var current = AndroidJS.appVersion().split('-'); + var versionCode = current.pop(); + + if (parseInt(versionCode, 10) >= needVersion) { + return true; + } else { + if (!silent) Bell.push({ + text: 'Обновите приложение до версии ' + needVersion + }); + return false; + } + } catch (e) { + Bell.push({ + text: 'Обновите приложение до версии ' + needVersion + }); + return false; + } + } else return false; + } + + function resolveCard(data) { + if (data && (data.card || data.movie)) return data.card || data.movie; + var activity = Activity.active(); + if (activity && (activity.card || activity.movie)) return activity.card || activity.movie; + return null; + } + + var Android = { + init: init$C, + exit: exit, + openTorrent: openTorrent, + openPlayer: openPlayer, + playHash: playHash, + openYoutube: openYoutube, + resetDefaultPlayer: resetDefaultPlayer, + httpReq: httpReq, + voiceStart: voiceStart, + httpCall: httpCall, + timeCall: timeCall, + updateChannel: updateChannel, + openBrowser: openBrowser + }; + + var _connected = true; + var protocols = ['https://', 'http://']; + + function init$B() { + Timer.add(1000 * 60 * 15, function () { + task$2(); + }); + } + /** + * Редирект на живое зеркало + * @param {string} to ссылка на зеркало + */ + + + function redirect(to) { + var domain = to.replace(/http:\/\/|https:\/\//, ''); + Storage.set('cub_domain', domain, true); + Storage.set('cub_alive', to, true); + console.log('Mirrors', 'redirect to', to); + } + /** + * Проверить живые зеркала по протоколу и вернуть массив живых зеркал + * @param {string} protocol протокол для проверки + * @param {function} callback функция обратного вызова с массивом живых зеркал + */ + + + function find(protocol, callback) { + var status = new Status(object$2.cub_mirrors.length); + + status.onComplite = function (data) { + var keys = Object.keys(data); + if (keys.length == 0) return callback([]); + var answered = keys.filter(function (key) { + return data[key] == true; + }); + + if (answered.length == 0) { + console.error('Mirrors', protocol + ' all offline'); + return callback([]); + } + + console.log('Mirrors', protocol + ' online', answered); + callback(answered); + }; + + object$2.cub_mirrors.forEach(function (mirror) { + check$1(protocol + mirror, function (answered) { + if (answered) { + console.log('Mirrors', protocol + mirror, 'is online'); + status.append(mirror, answered); + } else { + console.warn('Mirrors', protocol + mirror, 'is offline'); + status.error(); + } + }); + }); + } + /** + * Проверить живое зеркало по ссылке и вернуть результат + * @param {string} url ссылка для проверки + * @param {function} call функция обратного вызова с результатом проверки + */ + + + function check$1(url, call) { + var random = Math.random() + ''; + $.ajax({ + url: url + '/api/checker', + type: 'POST', + data: { + data: random + }, + dataType: 'text', + timeout: 1000 * 7, + success: function success(str) { + if (str == random) call(true);else call(false); + }, + error: function error() { + call(false); + } + }); + } + /** + * Загрузочная задача для проверки живых зеркал и редиректа на первое живое + * @param {function} call функция обратного вызова + */ + + + function task$2(call) { + if (!window.lampa_settings.mirrors) return call && call(); + var status = new Status(protocols.length); + _connected = true; + + status.onComplite = function (data) { + var https = data['https://']; + var http = data['http://']; + var all = [].concat(https.map(function (a) { + return 'https://' + a; + })).concat(http.map(function (a) { + return 'http://' + a; + })); + console.log('Mirrors', 'answered:', all); + if (!all.length) _connected = false;else redirect(all[0]); + if (!_connected) Markers.error('mirrors');else Markers.normal('mirrors'); + if (call) call(); + }; + + check$1(object$2.cub_alive, function (answered) { + console.log('Mirrors', 'first check:', object$2.cub_alive, 'status:', answered); + + if (answered) { + if (call) call(); + } else { + protocols.forEach(function (protocol) { + find(protocol, function (mirrors) { + status.append(protocol, mirrors); + }); + }); + } + }); + } + + var Mirrors = { + init: init$B, + task: task$2, + connected: function connected() { + return _connected; + } + }; + + var bad_mirrors = {}; + /** + * Универсальный запрос + * @example + * let network = new Request() + * network.get('https://site.com/api/method',function(data){console.log(data)},function(error){console.log(error)}) + * network.silent('https://site.com/api/method',function(data){console.log(data)},function(error){console.log(error)}) + * network.quiet('https://site.com/api/method',function(data){console.log(data)},function(error){console.log(error)}) + * network.last('https://site.com/api/method',function(data){console.log(data)},function(error){console.log(error)}) + * network.native('https://site.com/api/method',function(data){console.log(data)},function(error){console.log(error)}) + * network.timeout(10000) // установить таймаут для всех запросов + * network.clear() // очистить все запросы + * network.again() // повторить последний запрос + * let last = network.latest() // вернуть обьект последненго запроса + * let error_text = network.errorDecode(jqXHR, exception) // декодировать ошибку в запросе + * let error_code = network.errorCode(jqXHR) // вернуть код ошибки + * let error_json = network.errorJSON(jqXHR) // вернуть json ошибки + * @returns {Request} + */ + + function Request() { + var listener = Subscribe$2(); + var _calls = []; + + var _last; + + var last_reguest; + var need = { + timeout: 1000 * 30 + }; + + this.timeout = function (time) { + need.timeout = time; + }; + /** + * Видимый запрос + * @param {String} url адрес + * @param {Function} complite успешно + * @param {Function} error ошибка + * @param {Object} post_data данные для пост запроса + */ + + + this.get = function (url, _complite, _error, post_data) { + clear(); + go({ + url: url, + post_data: post_data, + start: function start() { + listener.send('start'); + }, + before_complite: function before_complite() { + listener.send('before_complite'); + }, + complite: function complite(data) { + if (_complite) _complite(data); + }, + after_complite: function after_complite() { + listener.send('after_complite'); + }, + before_error: function before_error() { + listener.send('before_error'); + }, + error: function error(data) { + if (_error) _error(data); + }, + after_error: function after_error() { + listener.send('after_error'); + }, + end: function end() { + listener.send('end'); + } + }); + }; + /** + * Тихий запрос, отработает в любом случае + * @param {String} url адрес + * @param {Function} complite успешно + * @param {Function} error ошибка + * @param {Object} post_data данные для пост запроса + * @param {Object} params дополнительные параметры + */ + + + this.quiet = function (url, _complite2, _error2, post_data, params) { + var add_params = {}; + + if (params) { + add_params = params; + } + + var data = { + url: url, + post_data: post_data, + complite: function complite(data) { + if (_complite2) _complite2(data); + }, + error: function error(data) { + if (_error2) _error2(data); + } + }; + Arrays.extend(data, add_params, true); + go(data); + }; + /** + * Бесшумный запрос, сработает прерывание при новом запросе + * @param {String} url адрес + * @param {Function} complite успешно + * @param {Function} error ошибка + * @param {Object} post_data данные для пост запроса + * @param {Object} params дополнительные параметры + */ + + + this.silent = function (url, complite, error, post_data, params) { + var add_params = {}; + + if (params) { + add_params = params; + } + + var reguest = { + url: url, + complite: complite, + error: error + }; + + _calls.push(reguest); + + var data = { + url: url, + post_data: post_data, + complite: function complite(data) { + if (_calls.indexOf(reguest) !== -1 && reguest.complite) reguest.complite(data); + }, + error: function error(data) { + if (_calls.indexOf(reguest) !== -1 && reguest.error) reguest.error(data); + }, + end: function end() { + listener.send('end'); + } + }; + Arrays.extend(data, add_params, true); + go(data); + }; + /** + * Отработать только последний запрос в стеке + * @param {String} url адрес + * @param {Function} complite успешно + * @param {Function} error ошибка + * @param {Object} post_data данные для пост запроса + */ + + + this.last = function (url, complite, error, post_data) { + var reguest = { + url: url, + complite: complite, + error: error + }; + _last = reguest; + go({ + url: url, + post_data: post_data, + complite: function complite(data) { + if (_last && _last.complite) _last.complite(data); + }, + error: function error(data) { + if (_last && _last.error) _last.error(data); + }, + end: function end() { + dispatchEvent({ + type: 'load:end' + }); + } + }); + }; + + this["native"] = function (url, complite, error, post_data, params) { + var add_params = {}; + + if (params) { + add_params = params; + } + + var reguest = { + url: url, + complite: complite, + error: error + }; + + _calls.push(reguest); + + var data = { + url: url, + post_data: post_data, + complite: function complite(data) { + if (_calls.indexOf(reguest) !== -1 && reguest.complite) reguest.complite(data); + }, + error: function error(data) { + if (_calls.indexOf(reguest) !== -1 && reguest.error) reguest.error(data); + }, + end: function end() { + listener.send('end'); + } + }; + Arrays.extend(data, add_params, true); + + _native(data); + }; + /** + * Очистить все запросы + */ + + + this.clear = function () { + _calls = []; + }; + /** + * Повторить запрос + * @param {Object} custom + */ + + + this.again = function (custom) { + if (custom || last_reguest) { + go(custom || last_reguest); + } + }; + /** + * Вернуть обьект последненго запроса + * @returns Object + */ + + + this.latest = function () { + return last_reguest; + }; + /** + * Декодировать ошибку в запросе + * @param {Object} jqXHR + * @param {String} exception + * @returns String + */ + + + this.errorDecode = function (jqXHR, exception) { + return errorDecode(jqXHR, exception); + }; + + this.errorCode = function (jqXHR) { + return errorCode(jqXHR); + }; + + this.errorJSON = function (jqXHR) { + return errorJSON(jqXHR); + }; + + function errorDecode(jqXHR, exception) { + if (!Arrays.isObject(jqXHR)) return Lang.translate('network_error'); + var msg = ''; + var txt = jqXHR.responseText || jqXHR.message || jqXHR.status || ''; + + if (jqXHR.status === 0 && exception !== 'timeout') { + msg = Lang.translate('network_noconnect'); + } else if (jqXHR.responseJSON && jqXHR.responseJSON.code) { + msg = Lang.translate('network_500').replace('500', jqXHR.responseJSON.code) + (jqXHR.responseJSON.text ? ' [' + jqXHR.responseJSON.text + ']' : ''); + } else if (jqXHR.status == 404) { + msg = Lang.translate('network_404'); + } else if (jqXHR.status == 401) { + msg = Lang.translate('network_401'); + } else if (jqXHR.status == 500) { + msg = Lang.translate('network_500'); + } else if (exception === 'parsererror') { + msg = Lang.translate('network_parsererror'); + } else if (exception === 'timeout') { + msg = Lang.translate('network_timeout'); + } else if (exception === 'abort') { + msg = Lang.translate('network_abort'); + } else if (exception === 'custom') { + msg = jqXHR.responseText; + } else { + msg = Lang.translate('network_error') + (txt ? ': ' + txt : ''); + } + + return msg; + } + + function errorCode(jqXHR) { + return jqXHR && jqXHR.responseJSON ? jqXHR.responseJSON.code : jqXHR ? jqXHR.status : 404; + } + + function errorJSON(jqXHR) { + return jqXHR && jqXHR.responseJSON ? jqXHR.responseJSON : { + code: jqXHR ? jqXHR.status : 404, + text: jqXHR ? jqXHR.responseText || jqXHR.message || Lang.translate('network_404') : Lang.translate('network_404') + }; + } + + function go(params) { + params.url = params.url || 'no url'; + var _error3 = false; + var hasmirror = object$2.cub_mirrors.find(function (m) { + return params.url.indexOf(m) >= 0; + }); + + if (hasmirror) { + // Заменияем протокол на живой урл + params.url = params.url.replace('http://' + object$2.cub_domain, object$2.cub_alive).replace('https://' + object$2.cub_domain, object$2.cub_alive); + var mirrors = object$2.cub_mirrors; + Arrays.remove(mirrors, hasmirror); + + for (var name in bad_mirrors) { + var mirror = bad_mirrors[name]; + + if (Date.now() - mirror.time > 1000 * 60 * 10) { + mirror.time = Date.now(); + mirror.urls = []; + } + + if (mirror.urls.length > 10) { + console.log('Request', 'bad mirror:', name, 'count:', mirror.urls.length); + Arrays.remove(mirrors, name); + mirror.urls = mirror.urls.slice(-11); + } + } + + _error3 = function error(jqXHR, exception) { + if (mirrors.length > 0 && (jqXHR.status < 400 || jqXHR.error_time > 1000 * 15)) { + if (!bad_mirrors[hasmirror]) bad_mirrors[hasmirror] = { + urls: [], + time: Date.now() + }; + + if (bad_mirrors[hasmirror].urls.indexOf(params.url) < 0) { + bad_mirrors[hasmirror].urls.push(params.url); + } + + var next = mirrors.shift(); + console.log('Request', 'try next mirror for:', params.url, 'next mirror:', next); + object$2.cub_mirrors.forEach(function (mirror) { + params.url = params.url.replace(mirror, next); + }); + hasmirror = next; + request(params, _error3); + } else { + if (params.before_error) params.before_error(jqXHR, exception); + if (params.error) params.error(jqXHR, exception); + if (params.after_error) params.after_error(jqXHR, exception); + if (params.end) params.end(); + } + }; + } + + request(params, _error3); + } + + function cacheGet(params, callback) { + if (params.cache && params.cache.life > 0 && Storage.field('request_caching')) { + Cache.getData('other', cacheName(params), -1, true).then(function (result) { + if (result) { + if (Date.now() < result.time + params.cache.life * 1000 * 60) callback(result.value, result.value);else callback(null, result.value); + } else callback(null, null); + })["catch"](function (e) { + callback(null, null); + }); + } else callback(null, null); + } + + function cacheSet(params, data) { + Cache.rewriteData('other', cacheName(params), data)["catch"](function (e) {}); + } + + function cacheName(params) { + var url = params.url || ''; // убираем зеркало из урла, что бы не было дублей в кеше + + object$2.cub_mirrors.forEach(function (mirror) { + url = url.replace(mirror, ''); + }); + url = url.replace(/https?:\/\//i, ''); + return 'request_[' + url + '][' + JSON.stringify(params.post_data || {}) + (params.dataType || 'json') + Storage.field('tmdb_lang') + ']'; + } + /** + * Сделать запрос + * @param {Object} params + */ + + + function request(params) { + var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + Lampa.Listener.send('request_before', { + params: params + }); + var start_time = Date.now(); + var cache_old = false; + + var error = function error(jqXHR, exception) { + if (params.attempts && params.attempts > 0) { + params.attempts--; + console.log('Request', 'attempt left:', params.attempts, 'for', params.url); + return go(params); + } // Если есть старый кеш отдаем его + + + if (cache_old) { + console.log('Request', 'use old cache for:', params.url, 'key:', cacheName(params)); + return secuses(cache_old, true); + } + + jqXHR.decode_error = errorDecode(jqXHR, exception); + jqXHR.decode_code = errorCode(jqXHR); + params.url = params.url || 'no url'; + Lampa.Listener.send('request_error', { + params: params, + error: jqXHR, + exception: exception + }); + var end_time = Date.now() - start_time; + var time = end_time > 1000 ? Math.round(end_time / 1000) + 's' : end_time + 'ms'; + jqXHR.error_time = time; + console.log('Request', params.post_data ? 'POST' : 'GET', 'time:', time, 'error of ' + params.url + ' :', errorDecode(jqXHR, exception)); + if (errorCallback) return errorCallback(jqXHR, exception); + if (params.before_error) params.before_error(jqXHR, exception); + if (params.error) params.error(jqXHR, exception); + if (params.after_error) params.after_error(jqXHR, exception); + if (params.end) params.end(); + }; + + if (typeof params.url !== 'string' || !params.url) return error({ + status: 404 + }, ''); + listener.send('go'); + last_reguest = params; + if (params.start) params.start(); + + var secuses = function secuses(data) { + var fromcache = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + function sendSecuses(send_data) { + if (params.cache && params.cache.life > 0 && !fromcache) { + cacheSet(params, send_data); + } + + if (params.before_complite) params.before_complite(send_data); + + if (params.complite) { + try { + params.complite(send_data); + } catch (e) { + console.error('Request', 'complite error:', e.message + "\n\n" + e.stack); + Noty.show('Error: ' + (e.error || e).message + '

    ' + (e.error && e.error.stack ? e.error.stack : e.stack || '').split("\n").join('
    ')); + } + } + + if (params.after_complite) params.after_complite(send_data); + if (params.end) params.end(); + } + + var abort_called = false; + Lampa.Listener.send('request_secuses', { + params: params, + data: data, + abort: function abort() { + abort_called = true; + return sendSecuses; + } + }); + if (!abort_called) sendSecuses(data); + }; + + var datatype = params.dataType || 'json'; + var timeout = !Mirrors.connected() && params.url.indexOf(object$2.cub_domain) >= 0 ? 2000 : params.timeout || need.timeout; + var data = { + dataType: datatype, + url: params.url, + timeout: timeout, + crossDomain: true, + success: function success(data) { + if (datatype == 'json' && !data) error({ + status: 500 + });else secuses(data); + }, + error: error, + beforeSend: function beforeSend(xhr) { + var use = Storage.field('torrserver_auth'); + var srv = Storage.get(Storage.field('torrserver_use_link') == 'two' ? 'torrserver_url_two' : 'torrserver_url'); + + if (use && srv && params.url.indexOf(srv) >= 0) { + var authorization = "Basic " + Base64.encode(Storage.get('torrserver_login') + ':' + Storage.value('torrserver_password')); + xhr.setRequestHeader("Authorization", authorization); + } + + if (params.beforeSend) { + xhr.setRequestHeader(params.beforeSend.name, params.beforeSend.value); + } + } + }; + + if (params.withCredentials) { + data.xhrFields = { + withCredentials: true + }; + } + + if (params.post_data) { + data.type = 'POST'; + data.data = params.post_data; + } + + if (params.type) data.type = params.type; + + if (params.headers) { + data.headers = params.headers; + } + + cacheGet(params, function (cached, old) { + // Запомнить что есть старый кеш на случай ошибки что бы отдать его + cache_old = old; + + if (cached) { + secuses(cached, true); + } else { + $.ajax(data); + } + }); + need.timeout = 1000 * 30; + } + /** + * Сделать нативный Android запрос + * @param {Object} params + */ + + + function android_go(params) { + Lampa.Listener.send('request_before', { + params: params + }); + var start_time = Date.now(); + + var error = function error(jqXHR, exception) { + Lampa.Listener.send('request_error', { + params: params, + error: jqXHR + }); + var end_time = Date.now() - start_time; + var time = end_time > 1000 ? Math.round(end_time / 1000) + 's' : end_time + 'ms'; + console.log('Request', params.post_data ? 'POST' : 'GET', 'time:', time, 'error of ' + params.url + ' :', errorDecode(jqXHR, exception)); + if (params.before_error) params.before_error(jqXHR, exception); + if (params.error) params.error(jqXHR, exception); + if (params.after_error) params.after_error(jqXHR, exception); + if (params.end) params.end(); + }; + + if (typeof params.url !== 'string' || !params.url) return error({ + status: 404 + }, ''); + listener.send('go'); + last_reguest = params; + if (params.start) params.start(); + + var secuses = function secuses(data) { + Lampa.Listener.send('request_secuses', { + params: params, + data: data + }); + if (params.before_complite) params.before_complite(data); + + if (params.complite) { + try { + params.complite(data); + } catch (e) { + console.error('Request', 'complite error:', e.message + "\n\n" + e.stack); + Noty.show('Error: ' + (e.error || e).message + '

    ' + (e.error && e.error.stack ? e.error.stack : e.stack || '').split("\n").join('
    ')); + } + } + + if (params.after_complite) params.after_complite(data); + if (params.end) params.end(); + }; + + params.timeout = !Mirrors.connected() && params.url.indexOf(object$2.cub_domain) >= 0 ? 3000 : params.timeout || need.timeout; + Android.httpReq(params, { + complite: secuses, + error: error + }); + need.timeout = 1000 * 30; + } + + function _native(params) { + if (Platform.is('android')) android_go(params);else go(params); + } + } + + /** + * Прогресс выполнения нескольких асинхронных задач + * @example + * let progress = new Progress() + * progress.append((done)=>{ // какая-то асинхронная задача + * done(data) // по завершении вызываем done с результатом + * }) + * progress.append([ // можно добавить массив задач одним вызовом + * (done)=>{ // какая-то асинхронная задача + * done(data) // по завершении вызываем done с результатом + * }, + * (done)=>{ // какая-то асинхронная задача + * done(data) // по завершении вызываем done с результатом + * } + * ]) + * progress.start((result)=>{ // запуск всех задач + * console.log(result) // массив результатов всех задач + * }) + */ + + function Progress() { + var works = []; + var result = []; + var loaded = 0; + + this.append = function (call) { + if (Arrays.isArray(call)) works = works.concat(call);else if (typeof call == 'function') works.push(call); + }; + + this.start = function (complite) { + works.forEach(function (fun, i) { + try { + fun(function (data) { + result[i] = data; + loaded++; + if (loaded == works.length) complite(result); + }); + } catch (e) { + console.warn('Progress', 'task error:', e.message, e.stack); + loaded++; + if (loaded == works.length) complite(result); + } + }); + }; + } + + var network$4 = new Request(); + var day = 60 * 24; + var source$1 = 'cub'; + + function url(u) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var genre = params.genres; + if (permit.child_small) genre = genre ? genre + (genre == '16' ? '' : ',16') : '16'; + if (genre && u.indexOf('genre') == -1) u = add$7(u, 'genre=' + genre); + if (params.page) u = add$7(u, 'page=' + params.page); + if (params.query) u = add$7(u, 'query=' + params.query); + + if (params.filter) { + for (var i in params.filter) { + u = add$7(u, i + '=' + params.filter[i]); + } + } + + var email = Storage.get('account', '{}').email || ''; + return Utils$1.addUrlComponent(Utils$1.protocol() + 'tmdb.' + object$2.cub_domain + '/' + u, 'email=' + encodeURIComponent(email)); + } + + function add$7(u, params) { + return u + (/\?/.test(u) ? '&' : '?') + params; + } + + function get$7(method) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var oncomplite = arguments.length > 2 ? arguments[2] : undefined; + var onerror = arguments.length > 3 ? arguments[3] : undefined; + var cache = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + var u = url(method, params); + network$4.silent(u, function (json) { + json.url = method; + json.source = source$1; // Фильтруем результаты по ключевым словам, чтобы не показывать фильмы с неуместными словами в названии + + if (json.results && Arrays.isArray(json.results)) { + json.results = json.results.filter(function (item) { + var title = (item.title || item.name || '').toLowerCase(); + return !Keys.filter.find(function (word) { + var reg = new RegExp(word, 'i'); + return reg.test(title); + }); + }); + } + + oncomplite(Utils$1.addSource(json, source$1)); + }, onerror, false, { + cache: cache + }); + } + + function list$3() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var u = url(params.url, params); + network$4.silent(u, function (data) { + oncomplite(Utils$1.addSource(data, source$1)); + }, onerror, false, { + cache: { + life: day * 2 + } + }); + } + + function main$1() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var parts_limit = 6; + var parts_data = [function (call) { + get$7('?sort=now_playing', params, function (json) { + json.title = Lang.translate('title_now_watch'); + call(json); + }, call, { + life: day * 2 + }); + }, function (call) { + get$7('?sort=latest', params, function (json) { + json.title = Lang.translate('title_latest'); + call(json); + }, call, { + life: day * 2 + }); + }, function (call) { + if (permit.child_small) return call(); + get$7('top/fire/movie', params, function (json) { + json.title = Lang.translate('title_fire'); + json.icon_svg = Template.string('icon_fire'); + json.icon_bgcolor = '#fff'; + json.icon_color = '#fd4518'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day * 7 + }); + }, function (call) { + get$7('?cat=' + params.url + '&sort=latest&uhd=true', params, function (json) { + json.title = Lang.translate('title_in_high_quality'); + json.results.forEach(function (card) { + card.params = { + style: { + name: 'wide' + } + }; + }); + json.params = { + items: { + view: 3 + } + }; + call(json); + }, call, { + life: day * 3 + }); + }, function (call) { + if (permit.child_small) return call(); + get$7('top/hundred/movie', params, function (json) { + json.title = Lang.translate('title_top_100') + ' - ' + Lang.translate('menu_movies'); + json.icon_svg = Template.string('icon_top'); + json.icon_bgcolor = '#e02129'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day * 7 + }); + }, function (call) { + if (permit.child_small) return call(); + get$7('top/hundred/tv', params, function (json) { + json.title = Lang.translate('title_top_100') + ' - ' + Lang.translate('menu_tv'); + json.icon_svg = Template.string('icon_top'); + json.icon_bgcolor = '#e02129'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day * 7 + }); + }, function (call) { + if (permit.child) return call(); + trailers('added', call); + }]; + ContentRows.call('main', params, parts_data); + var start_shuffle = parts_data.length + 1; + if (!permit.child_small) Arrays.insert(parts_data, 0, Api.partPersons(parts_data, parts_limit, 'movie', start_shuffle)); + TMDB.genres.movie.filter(function (a) { + return !(a.id == 10763 || a.id == 10767); + }).forEach(function (genre) { + var event = function event(call) { + get$7('?sort=top&genre=' + genre.id + (permit.child_small ? ',16' : ''), params, function (json) { + json.title = Lang.translate(genre.title.replace(/[^a-z_]/g, '')); + call(json); + }, call, { + life: day * 7 + }); + }; + + parts_data.push(event); + }); + + if (!permit.child_small) { + network$4.silent(Utils$1.protocol() + object$2.cub_domain + '/api/collections/list?category=new', function (data) { + data.results.forEach(function (collection, index) { + var event = function event(call_inner) { + get$7('collections/' + collection.id, {}, function (json) { + json.title = Utils$1.capitalizeFirstLetter(collection.title); + json.icon_svg = Template.string('icon_collection'); + json.icon_color = '#fff'; + json.icon_bgcolor = 'rgba(255,255,255,0.15)'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call_inner(json); + }, call_inner, { + life: day * 3 + }); + }; + + parts_data.push(event); + }); + Arrays.shuffleArrayFromIndex(parts_data, start_shuffle); + }, false, false, { + cache: { + life: day * 3 + } + }); + } + + function loadPart(partLoaded, partEmpty) { + Api.partNext(parts_data, parts_limit, partLoaded, partEmpty); + } + + loadPart(oncomplite, onerror); + return loadPart; + } + + function category$1() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var fullcat = !(params.genres || params.keywords); + var airdate = params.url == 'anime' ? '&airdate=' + new Date().getFullYear() : ''; + var years = [2000, 2010, 2015]; + var parts_limit = 6; + var parts_data = [function (call) { + get$7('?cat=' + params.url + '&sort=now_playing' + airdate, params, function (json) { + json.title = Lang.translate('title_now_watch'); + call(json); + }, call, { + life: day * 2 + }); + }, function (call) { + if (params.url == 'anime') { + get$7('?cat=' + params.url + '&sort=top', params, function (json) { + json.title = Lang.translate('title_in_top'); + json.results.forEach(function (card) { + card.params = { + style: { + name: 'wide' + } + }; + }); + json.params = { + items: { + view: 3 + } + }; + call(json); + }, call, { + life: day * 7 + }); + } else { + get$7('?cat=' + params.url + '&sort=latest&uhd=true' + airdate, params, function (json) { + json.title = Lang.translate('title_in_high_quality'); + json.results.forEach(function (card) { + card.params = { + style: { + name: 'wide' + } + }; + }); + json.params = { + items: { + view: 3 + } + }; + call(json); + }, call, { + life: day * 3 + }); + } + }, function (call) { + if (params.url == 'tv' || params.url == 'anime') { + get$7('?cat=' + params.url + '&sort=airing' + airdate, params, function (json) { + json.title = Lang.translate('title_ongoing'); + call(json); + }, call, { + life: day * 2 + }); + } else call(); + }, function (call) { + get$7('?cat=' + params.url + '&sort=top' + airdate, params, function (json) { + json.title = Lang.translate('title_popular'); + call(json); + }, call, { + life: day * 3 + }); + }, function (call) { + get$7('?cat=' + params.url + '&sort=now&airdate=' + new Date().getFullYear(), params, function (json) { + json.title = Lang.translate('title_new_this_year'); + call(json); + }, call, { + life: day * 2 + }); + }, function (call) { + if (params.url == 'anime' || !fullcat || permit.child_small) call();else { + get$7('top/fire/' + params.url, params, function (json) { + json.title = Lang.translate('title_fire'); + json.icon_svg = Template.string('icon_fire'); + json.icon_bgcolor = '#fff'; + json.icon_color = '#fd4518'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day * 7 + }); + } + }, function (call) { + if (params.url == 'anime' || !fullcat || permit.child_small) call();else { + get$7('top/hundred/' + params.url, params, function (json) { + json.title = Lang.translate('title_top_100'); + json.icon_svg = Template.string('icon_top'); + json.icon_bgcolor = '#e02129'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day * 7 + }); + } + }, function (call) { + if (params.url == 'movie' && fullcat && !permit.child) trailers('added', call);else call(); + }, function (call) { + get$7('?cat=' + params.url + '&sort=top&airdate=' + (new Date().getFullYear() - 1), params, function (json) { + json.title = Lang.translate('title_last_year'); + call(json); + }, call, { + life: day * 7 + }); + }, function (call) { + get$7('?cat=' + params.url + '&sort=top&airdate=' + (new Date().getFullYear() - 7) + '-' + (new Date().getFullYear() - 2) + '&vote=6-8', params, function (json) { + json.title = Lang.translate('title_worth_rewatch'); + call(json); + }, call, { + life: day * 7 + }); + }, function (call) { + get$7('?cat=' + params.url + '&sort=top&airdate=' + (new Date().getFullYear() - 7) + '-' + (new Date().getFullYear() - 2) + '&vote=8-10', params, function (json) { + json.title = Lang.translate('title_hight_voite'); + json.icon_svg = Template.string('icon_star'); + json.icon_bgcolor = '#fff'; + json.icon_color = '#212121'; + json.params = { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon') + }; + call(json); + }, call, { + life: day * 7 + }); + }]; // Дух Рождества + // if(params.url !== 'anime'){ + // Arrays.insert(parts_data, 1, Api.partKeyword({id: 207317, title: '#{filter_keyword_christmas}'}, params.url, params)) + // } + + ContentRows.call('category', params, parts_data); + var start_shuffle = parts_data.length + 2; + + if (params.url == 'anime') { + Arrays.insert(parts_data, 0, Api.partKeywords(parts_data, 'tv', start_shuffle, [], { + genres: 16, + orig_lang: 'ja' + })); + } else { + Arrays.insert(parts_data, 0, Api.partKeywords(parts_data, params.url, start_shuffle, [], permit.child_small ? { + genres: 16 + } : params)); + } + + if (fullcat && !permit.child_small) { + Arrays.insert(parts_data, 0, Api.partPersons(parts_data, parts_limit + 3, params.url, start_shuffle)); + } + + if (TMDB.genres[params.url] && fullcat) { + TMDB.genres[params.url].filter(function (a) { + return !(a.id == 10763 || a.id == 10767); + }).forEach(function (genre) { + var event = function event(call) { + get$7('?cat=' + params.url + '&sort=top&genre=' + genre.id + (permit.child_small ? ',16' : ''), params, function (json) { + json.title = Lang.translate(genre.title.replace(/[^a-z_]/g, '')); + call(json); + }, call, { + life: day * 7 + }); + }; + + parts_data.push(event); + }); + } else if (params.url == 'anime') { + TMDB.genres.tv.filter(function (a) { + return !(a.id == 99 || a.id == 10766); + }).forEach(function (genre) { + var event = function event(call) { + get$7('?cat=' + params.url + '&sort=top&genre=' + genre.id + (permit.child_small ? ',16' : ''), params, function (json) { + json.title = Lang.translate(genre.title.replace(/[^a-z_]/g, '')); + call(json); + }, call, { + life: day * 7 + }); + }; + + parts_data.push(event); + }); + } + + years.forEach(function (year) { + var eventYear = function eventYear(call) { + get$7('?cat=' + params.url + '&sort=top&airdate=' + year + '-' + (year + 5), params, function (json) { + json.title = Lang.translate('title_best_of_' + year); + call(json); + }, call, { + life: day * 7 + }); + }; + + parts_data.push(eventYear); + + var eventComedy = function eventComedy(call) { + get$7('?cat=' + params.url + '&sort=top&airdate=' + year + '-' + (year + 5) + '&genre=35' + (permit.child_small ? ',16' : ''), params, function (json) { + json.title = Lang.translate('title_comedy_of_' + year); + call(json); + }, call, { + life: day * 7 + }); + }; + + if (fullcat) parts_data.push(eventComedy); + }); + Arrays.shuffleArrayFromIndex(parts_data, start_shuffle); + + function loadPart(partLoaded, partEmpty) { + Api.partNext(parts_data, parts_limit, partLoaded, partEmpty); + } + + loadPart(oncomplite, onerror); + return loadPart; + } + + function full$1(params, oncomplite, onerror) { + var status = new Status(9); + status.onComplite = oncomplite; + if (Utils$1.dcma(params.method, params.id)) return onerror(); + var image_language = (Storage.field('tmdb_lang') || 'en').split(/[-_]/)[0]; + var image_languages = [image_language, 'en', 'null'].filter(function (language, index, list) { + return list.indexOf(language) == index; + }).join(','); + get$7('3/' + params.method + '/' + params.id + '?api_key=' + TMDB$1.key() + '&append_to_response=content_ratings,release_dates,external_ids,keywords,alternative_titles,images&include_image_language=' + image_languages + '&language=' + Storage.field('tmdb_lang'), params, function (json) { + var _json$overview; + + if (json.status_code) return status.stop(), onerror(); + json.source = 'cub'; + + if (!((_json$overview = json.overview) !== null && _json$overview !== void 0 && _json$overview.trim()) && Storage.field('tmdb_lang') !== 'en') { + TMDB.get(params.method + '/' + params.id, { + langs: 'en' + }, function (enjson) { + var _enjson$overview; + + if ((_enjson$overview = enjson.overview) !== null && _enjson$overview !== void 0 && _enjson$overview.trim()) json.overview = enjson.overview; + status.need--; + status.check(); + }, status.error.bind(status), { + life: day * 7 + }); + } else status.need--; + + if (params.method == 'tv') { + var season = Utils$1.countSeasons(json); + TMDB.get('tv/' + json.id + '/season/' + season, {}, function (ep) { + status.append('episodes', ep); + }, status.error.bind(status), { + life: day * 3 + }); + } else status.need--; + + if (json.belongs_to_collection) { + TMDB.get('collection/' + json.belongs_to_collection.id, {}, function (collection) { + collection.results = collection.parts.slice(0, 19); + status.append('collection', Utils$1.addSource(collection, 'tmdb')); + }, status.error.bind(status), { + life: day * 7 + }); + } else status.need--; + + status.append('movie', json); + }, function () { + status.need -= 2; + status.error(); + }, { + life: day * 7 + }); + + if (!permit.child_small) { + TMDB.get(params.method + '/' + params.id + '/credits', params, function (json) { + status.append('persons', json); + }, status.error.bind(status), { + life: day * 7 + }); + TMDB.get(params.method + '/' + params.id + '/recommendations', params, function (json) { + status.append('recomend', json); + }, status.error.bind(status), { + life: day * 7 + }); + TMDB.get(params.method + '/' + params.id + '/similar', params, function (json) { + status.append('simular', json); + }, status.error.bind(status), { + life: day * 7 + }); + + if (!permit.child) { + TMDB.videos(params, function (json) { + status.append('videos', json); + }, status.error.bind(status)); + } else { + status.need -= 1; + } + } else { + status.need -= 4; + } + + reactionsGet(params, function (json) { + status.append('reactions', json); + }); + + if (Lang.selected(['ru', 'uk', 'be']) && window.lampa_settings.account_use && !permit.child) { + status.need++; + discussGet(params, function (json) { + status.append('discuss', json); + }, status.error.bind(status)); + } + + if (params.method == 'movie') { + status.need++; + metadataGet(params, function (json) { + status.append('metadata', json); + }, status.error.bind(status)); + } + } + + function trailers(type, oncomplite) { + network$4.silent(Utils$1.protocol() + object$2.cub_domain + '/api/trailers/short/trailers/' + type, function (result) { + result.title = Lang.translate('title_trailers') + ' - ' + Lang.translate('title_new'); + result.results.forEach(function (card) { + card.params = { + style: { + name: 'wide' + } + }; + }); + oncomplite(Utils$1.addSource(result, source$1)); + }, function () { + oncomplite({ + results: [] + }); + }, false, { + cache: { + life: day * 2 + } + }); + } + + function metadataGet(params, oncomplite) { + if (window.lampa_settings.disable_features.metadata) return oncomplite({}); + network$4.silent(Utils$1.protocol() + object$2.cub_domain + '/api/ai/video-view/' + params.id + '/metadata?type=' + params.method, oncomplite, function () { + oncomplite({}); + }, false, { + timeout: 1000 * 5 + }); + } + + function reactionsGet(params, oncomplite) { + if (window.lampa_settings.disable_features.reactions) return oncomplite({ + result: [] + }); + network$4.silent(Utils$1.protocol() + object$2.cub_domain + '/api/reactions/get/' + params.method + '_' + params.id, oncomplite, function () { + oncomplite({ + result: [] + }); + }, false, { + timeout: 1000 * 5 + }); + } + + function discussGet(params, oncomplite, onerror) { + if (window.lampa_settings.disable_features.discuss) return onerror(); + network$4.silent(Utils$1.protocol() + object$2.cub_domain + '/api/discuss/get/' + params.method + '_' + params.id + '/' + (params.page || 1) + '/' + Storage.field('language'), oncomplite, onerror, false, { + timeout: 1000 * 5 + }); + } + + function reactionsAdd(params, oncomplite, onerror) { + network$4.silent(Utils$1.protocol() + object$2.cub_domain + '/api/reactions/add/' + params.method + '_' + params.id + '/' + params.type + '?uid=' + Storage.get('lampa_uid', 'none'), oncomplite, onerror); + } + + function menuCategory$1(params, oncomplite) { + var menu = []; + menu.push({ + title: Lang.translate('title_now_watch'), + url: '?cat=' + params.action + '&sort=now_playing' + }); + + if (params.action == 'tv') { + menu.push({ + title: Lang.translate('title_new_episodes'), + url: '?cat=' + params.action + '&sort=update' + }); + } + + menu.push({ + title: Lang.translate('title_popular'), + url: '?cat=' + params.action + '&sort=top' + }); + menu.push({ + title: Lang.translate('title_latest'), + url: '?cat=' + params.action + '&sort=latest' + }); + menu.push({ + title: Lang.translate('title_new_this_year'), + url: '?cat=' + params.action + '&sort=now' + }); + menu.push({ + title: Lang.translate('title_hight_voite'), + url: '?cat=' + params.action + '&sort=latest&vote=7' + }); + oncomplite(menu); + } + + function search$3() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var status = new Status(3); + + status.onComplite = function (data) { + var items = []; + if (data.movie && data.movie.results.length) items.push(data.movie); + if (data.tv && data.tv.results.length) items.push(data.tv); + if (data.anime && data.anime.results.length) items.push(data.anime); + oncomplite(items); + }; + + get$7('search/movie', params, function (json) { + json.title = Lang.translate('menu_movies'); + json.type = 'movie'; + status.append('movie', json); + }, status.error.bind(status)); + get$7('search/tv', params, function (json) { + json.title = Lang.translate('menu_tv'); + json.type = 'tv'; + status.append('tv', json); + }, status.error.bind(status)); + get$7('search/anime', params, function (json) { + json.title = Lang.translate('menu_anime'); + json.type = 'anime'; + status.append('anime', json); + }, status.error.bind(status)); + } + + function discovery$1() { + return { + title: 'CUB', + search: search$3, + params: { + save: true + }, + onMore: function onMore(params, close) { + close(); + Activity.push({ + url: 'search/' + params.data.type, + title: Lang.translate('search') + ' - ' + params.query, + component: 'category_full', + page: 2, + query: encodeURIComponent(params.query), + source: 'cub' + }); + }, + onCancel: network$4.clear.bind(network$4) + }; + } + + function extensions$1(call) { + var headers = {}; + + if (permit.token && window.lampa_settings.account_use) { + headers = { + headers: { + token: permit.token, + profile: permit.account.profile.id + } + }; + } + + network$4.timeout(5000); + network$4.silent(Utils$1.protocol() + object$2.cub_domain + '/api/extensions/list', function (result) { + if (result.secuses) { + Storage.set('account_extensions', result); + call(result); + } else { + call(Storage.get('account_extensions', '{}')); + } + }, function () { + call(Storage.get('account_extensions', '{}')); + }, false, headers); + } + + function person$1(params, oncomplite, onerror) { + TMDB.person(params, oncomplite, onerror); + } + + function menu$1(params, oncomplite) { + TMDB.menu(params, oncomplite); + } + + function seasons$1(tv, from, oncomplite) { + TMDB.seasons(tv, from, oncomplite); + } + + function clear$5() { + network$4.clear(); + } + + var CUB = { + main: main$1, + menu: menu$1, + full: full$1, + list: list$3, + category: category$1, + clear: clear$5, + person: person$1, + seasons: seasons$1, + menuCategory: menuCategory$1, + discovery: discovery$1, + reactionsGet: reactionsGet, + reactionsAdd: reactionsAdd, + metadataGet: metadataGet, + discussGet: discussGet, + extensions: extensions$1 + }; + + /** + * Источники + */ + + var sources$1 = { + tmdb: TMDB, + cub: CUB + }; + /** + * Чтоб не переписали их + */ + + Object.defineProperty(sources$1, 'tmdb', { + get: function get() { + return TMDB; + } + }); + Object.defineProperty(sources$1, 'cub', { + get: function get() { + return CUB; + } + }); + var network$3 = new Request(); + /** + * Получить источник + * @param {{source:string}} params + * @returns {class} + */ + + function source(params) { + return params.source && sources$1[params.source] ? sources$1[params.source] : sources$1.tmdb; + } + + function availableDiscovery() { + var list = []; + var active = Storage.get('source', 'tmdb'); + + for (var key in sources$1) { + console.log('Api', 'discovery check:', key, sources$1[key].discovery ? true : false, _typeof(sources$1[key].discovery)); + + if (sources$1[key].discovery) { + if (key === active) list.splice(0, 0, sources$1[key].discovery());else list.push(sources$1[key].discovery()); + } + } + + return list; + } + /** + * Главная страница + * @param {{source:string}} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function main() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + return source(params).main(params, oncomplite, onerror); + } + /** + * Категория + * @param {{url:string, source:string}} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function category() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + return source(params).category(params, oncomplite, onerror); + } + /** + * Просмотр карточки + * @param {{id:string, source:string, method:string, card:{}}} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function full() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + source(params).full(params, oncomplite, onerror); + } + /** + * Главный поиск + * @param {{query:string}} params + * @param {function} oncomplite + */ + + + function search$2() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + TMDB.search(params, function (json) { + var result = { + movie: json.find(function (a) { + return a.type == 'movie'; + }), + tv: json.find(function (a) { + return a.type == 'tv'; + }) + }; + oncomplite(result); + }, function () { + oncomplite({}); + }); + } + /** + * Что-то старое, надо проверить + * @param {object} params + * @param {function} oncomplite + */ + + + function menuCategory() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + source(params).menuCategory(params, oncomplite); + } + /** + * Информация об персоне + * @param {{id:integer, source:string}} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function person() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + source(params).person(params, oncomplite, onerror); + } + /** + * Жанры + * @param {object} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function genres() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + TMDB.genres(params, oncomplite, onerror); + } + /** + * Компания + * @param {{id:integer}} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function company() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + TMDB.company(params, oncomplite, onerror); + } + /** + * Полная категори + * @param {{page:integer, url:string, source:string}} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function list$2() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + source(params).list(params, oncomplite, onerror); + } + /** + * Получить список категорий для каталога в меню + * @param {{source:string}} params + * @param {function} oncomplite + */ + + + function menu() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + source(params).menu(params, oncomplite); + } + /** + * Сезоны + * @param {{id:integer, source:string}} tv + * @param {[1,2,3]} from - список сезонов 1,3,4... + * @param {function} oncomplite + */ + + + function seasons(tv, from, oncomplite) { + source(tv).seasons(tv, from, oncomplite); + } + /** + * Коллекции + * @param {object} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function collections(params, oncomplite, onerror) { + source(params).collections(params, oncomplite, onerror); + } + /** + * Закладки + * @param {{page:integer, type:string}} params + * @param {function} oncomplite + * @param {function} onerror + */ + + + function favorite() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + var data = {}; + data.results = Favorite.get(params); + + if (params.filter) { + data.results = data.results.filter(function (a) { + return params.filter == 'tv' ? a.name : !a.name; + }); + } + + data.total_pages = Math.ceil(data.results.length / 20); + data.page = Math.min(params.page, data.total_pages); + var offset = data.page - 1; + data.results = data.results.slice(20 * offset, 20 * offset + 20); + if (data.results.length) oncomplite(data);else onerror(); + } + /** + * Релизы + * @param {function} oncomplite + * @param {function} onerror + */ + + + function reliseTmdbCard(card, oncomplite) { + if (!card.imdb_id) return oncomplite(card); + var method = 'find/' + card.imdb_id + '?external_source=imdb_id'; + TMDB.get(method, {}, function (data) { + var movie = data.movie_results && data.movie_results[0]; + var tv = data.tv_results && data.tv_results[0]; + var tmdb = card.name || card.original_name || card.first_air_date ? tv || movie : movie || tv; + + if (tmdb) { + tmdb.source = 'tmdb'; + tmdb.imdb_id = card.imdb_id; + tmdb.imdb_rating = card.imdb_rating; + tmdb.kp_rating = card.kp_rating; + tmdb.release_quality = card.release_quality; + } + + oncomplite(tmdb || card); + }, function () { + oncomplite(card); + }, { + life: 60 * 24 * 7 + }); + } + + function reliseTmdbCards(items, oncomplite) { + var result = []; + var index = 0; + var active = 0; + var limit = 4; + + function next() { + if (index >= items.length && active == 0) return oncomplite(result); + + var _loop = function _loop() { + var position = index; + var card = items[index]; + index++; + active++; + reliseTmdbCard(card, function (tmdb) { + result[position] = tmdb; + active--; + next(); + }); + }; + + while (active < limit && index < items.length) { + _loop(); + } + } + + next(); + } + + function relise(params, oncomplite, onerror) { + network$3.silent(Utils$1.protocol() + 'tmdb.' + object$2.cub_domain + '?sort=releases&results=20&page=' + params.page, function (data) { + data = Utils$1.addSource(data, 'cub'); + + if (data.results && data.results.length) { + reliseTmdbCards(data.results, function (results) { + data.results = results; + oncomplite(data); + }); + } else oncomplite(data); + }, onerror); + } + + function partKeywords(parts, type) { + var shift = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var filter = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; + var req_params = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + if (shift == 0) shift = parts.length; + return function (call) { + if (['movie', 'tv'].indexOf(type) == -1) return call(); + call(); + TMDB.keywords[type].filter(function (keyword) { + return filter.indexOf(keyword.id) == -1; + }).forEach(function (keyword) { + parts.push(partKeyword(keyword, type, req_params)); + }); + Arrays.shuffleArrayFromIndex(parts, shift); + }; + } + + function partKeyword(keyword, type) { + var req_params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return function (call) { + var u = 'discover/' + type; + u = Utils$1.addUrlComponent(u, 'with_keywords=' + keyword.id); + if (req_params.orig_lang) u = Utils$1.addUrlComponent(u, 'with_original_language=' + req_params.orig_lang); + if (req_params.genres && u.indexOf('with_genres') == -1) u = Utils$1.addUrlComponent(u, 'with_genres=' + req_params.genres); + TMDB.get(u, {}, function (result) { + result.title = Lang.translate(keyword.title); + call(result); + }, call, { + life: 60 * 24 * 7 + }); + }; + } + /** + * Части с популярными актерами/режиссерами + * @param {array} parts + * @param {number} parts_limit + * @param {string} type 'movie' или 'tv' + * @param {number} shift - сдвиг для перемешивания + * @return {function} + */ + + + function partPersons(parts, parts_limit, type) { + var shift = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + if (shift == 0) shift = parts.length; + return function (call) { + if (['movie', 'tv'].indexOf(type) == -1) return call(); + TMDB.get('person/popular', {}, function (json) { + call(); + if (!json.results) return; + json.results.sort(function (a, b) { + return a.popularity - b.popularity; + }); + var filtred = json.results.filter(function (p) { + return p.known_for_department && p.known_for; + }); + var persons = filtred.filter(function (p) { + return (p.known_for_department || '').toLowerCase() == 'acting' && p.known_for.length; + }).slice(0, 10); + persons.forEach(function (person_data, index) { + var event = function event(call_inner) { + person({ + only_credits: type, + id: person_data.id + }, function (result) { + if (!result.credits) return call_inner(); + var items = (result.credits[type] || []).filter(function (m) { + return m.backdrop_path && m.vote_count > 20; + }); + if (type == 'tv') items = items.filter(function (m) { + return !(m.genre_ids.indexOf(10767) >= 0 || m.genre_ids.indexOf(10763) >= 0); + }); + items.sort(function (a, b) { + var da = a.release_date || a.first_air_date; + var db = b.release_date || b.first_air_date; + if (db > da) return 1;else if (db < da) return -1;else return 0; + }); + var src = person_data.profile_path ? TMDB.img(person_data.profile_path, 'w90_and_h90_face') : person_data.img || './img/actor.svg'; + call_inner({ + title: person_data.name, + icon_img: src, + results: items.length > 5 ? items.slice(0, 20) : [], + params: { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon', 'More') + } + }); + }); + }; + + parts.push(event); + }); + Arrays.shuffleArrayFromIndex(parts, shift); + }, call, { + life: 60 * 24 * 3 + }); + }; + } + /** + * Загрузка частей с ограничением + * @param {array} parts + * @param {number} parts_limit + * @param {function} partLoaded + * @param {function} partEmpty + * @return {void} + */ + + + function partNext(parts, parts_limit, partLoaded, partEmpty) { + var pieces = parts.filter(function (p) { + return typeof p == 'function'; + }).slice(0, 0 + parts_limit); + + if (pieces.length) { + var progress = new Progress(); + progress.append(pieces); + progress.start(function (result) { + var data = result.filter(function (r) { + return r && r.results && r.results.length; + }); + + for (var i = 0; i < pieces.length; i++) { + parts[parts.indexOf(pieces[i])] = false; + } + + if (data.length) { + if (data.length < 3) { + partNext(parts, parts_limit, function (more_data) { + data = data.concat(more_data); + partLoaded(data); + }, function () { + partLoaded(data); + }); + } else partLoaded(data); + } else partNext(parts, parts_limit, partLoaded, partEmpty); + }); + } else partEmpty(); + } + /** + * Очистить + */ + + + function clear$4() { + for (var i in sources$1) { + sources$1[i].clear(); + } + + network$3.clear(); + } + + function img() { + return TMDB.img.apply(TMDB, arguments); + } + + var Api = { + main: main, + img: img, + full: full, + list: list$2, + genres: genres, + category: category, + search: search$2, + clear: clear$4, + company: company, + person: person, + favorite: favorite, + seasons: seasons, + screensavers: TMDB.screensavers, + relise: relise, + menu: menu, + collections: collections, + menuCategory: menuCategory, + sources: sources$1, + availableDiscovery: availableDiscovery, + partPersons: partPersons, + partNext: partNext, + partKeyword: partKeyword, + partKeywords: partKeywords + }; + + var Main$1 = /*#__PURE__*/function (_Emit) { + _inherits(Main, _Emit); + + var _super = _createSuper(Main); + + function Main(object) { + var _this; + + _classCallCheck(this, Main); + + _this = _super.call(this); + Arrays.extend(object, { + params: {} + }); + _this.object = object; + _this.params = object.params; + _this.scroll = new Scroll({ + mask: true, + over: true, + scroll_by_item: true, + end_ratio: 2 + }); + _this.html = document.createElement('div'); + + _this.emit('init'); + + return _this; + } + + _createClass(Main, [{ + key: "create", + value: function create() { + this.activity.loader(true); + this.scroll.minus(); + this.html.append(this.scroll.render(true)); + this.emit('create'); + } + }, { + key: "empty", + value: function empty(status) { + this.scroll.nopadding(); + this.emit('empty', status); + this.activity.loader(false); + this.activity.toggle(); + } + }, { + key: "build", + value: function build(data) { + this.emit('build', data); + this.activity.loader(false); + this.activity.toggle(); + } + }, { + key: "start", + value: function start() { + var _this2 = this; + + this.emit('start'); + var controller = { + link: this, + toggle: function toggle() { + _this2.scroll.restorePosition(); + + if (_this2.items.length && Platform.screen('tv')) _this2.items[_this2.active].toggle(); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + right: function right() { + Navigator.move('right'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down'); + }, + back: this.emit.bind(this, 'back') + }; + this.emit('controller', controller); + Controller.add('content', controller); + Controller.toggle('content'); + } + }, { + key: "pause", + value: function pause() { + this.emit('pause'); + } + }, { + key: "resize", + value: function resize() { + this.emit('resize'); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html : $(this.html); + } + }, { + key: "destroy", + value: function destroy() { + this.scroll.destroy(); + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Main; + }(Emit); + + var Items$1 = { + onInit: function onInit() { + this.items = []; + this.loaded = []; + this.active = 0; + this.limit_view = Platform.screen('tv') ? 1 : 6; + }, + onDown: function onDown() { + this.active++; + this.active = Math.min(this.active, this.items.length - 1); + this.items[this.active].toggle(); + }, + onUp: function onUp() { + this.active--; + + if (this.active < 0) { + this.active = 0; + Controller.toggle('head'); + } else { + this.items[this.active].toggle(); + } + }, + onAppend: function onAppend(item) { + var _this = this; + + item.use({ + onDown: this.emit.bind(this, 'down'), + onUp: this.emit.bind(this, 'up'), + onBack: this.emit.bind(this, 'back'), + onLeft: this.emit.bind(this, 'left'), + onActive: function onActive() { + _this.active = _this.items.indexOf(item); + }, + onToggle: function onToggle() { + _this.scroll.update(item.render(true)); + } + }); + this.fragment.appendChild(item.render(true)); + this.items.push(item); + }, + onPushLoaded: function onPushLoaded() { + var add = this.loaded.shift(); + + if (add && add.length) { + this.frament = document.createDocumentFragment(); + add.forEach(this.emit.bind(this, 'createAndAppend')); + this.scroll.append(this.fragment); + Layer.visible(this.scroll.render(true)); + } + }, + onResize: function onResize() { + if (this.items[this.active]) this.scroll.update(this.items[this.active].render(true)); + }, + onCreate: function onCreate() { + var _this2 = this; + + this.scroll.onWheel = function (step) { + _this2.emit(step > 0 ? 'down' : 'up'); + }; + + this.scroll.onAnimateEnd = function () { + _this2.emit('pushLoaded'); + }; + }, + onBuild: function onBuild(data) { + this.fragment = document.createDocumentFragment(); + data.forEach(this.emit.bind(this, 'createAndAppend')); + this.scroll.append(this.fragment); + Layer.visible(this.scroll.render(true)); + }, + onDestroy: function onDestroy() { + Arrays.destroy(this.items); + } + }; + + var Base$1 = /*#__PURE__*/function (_Emit) { + _inherits(Base, _Emit); + + var _super = _createSuper(Base); + + function Base(data) { + var _this; + + _classCallCheck(this, Base); + + _this = _super.call(this); + Arrays.extend(data, { + params: {} + }); + Arrays.extend(data.params, { + type: 'default', + items: { + mapping: 'line', + align_left: false, + view: 7 + }, + scroll: { + horizontal: true, + step: 300 + } + }); + _this.data = data; + _this.params = data.params; + _this.html = Template.js('items_line', data); + _this.body = _this.html.find('.items-line__body'); + _this.scroll = new Scroll(data.params.scroll); + return _this; + } + + _createClass(Base, [{ + key: "create", + value: function create() { + var _this$html$find; + + this.scroll.onWheel = this.wheel.bind(this); + this.html.addClass('items-line--type-' + this.params.type); + if (!this.data.title && !this.has(Icon$1)) (_this$html$find = this.html.find('.items-line__head')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.remove(); + this.html.on('visible', this.visible.bind(this)); + this.body.append(this.scroll.render(true)); + this.emit('create'); + } + }, { + key: "wheel", + value: function wheel(step) { + if (!Controller.own(this)) this.toggle(); + Controller.enabled().controller[step > 0 ? 'right' : 'left'](); + this.emit('wheel'); + } + }, { + key: "visible", + value: function visible() { + this.emit('visible'); + Layer.visible(this.scroll.render(true)); + } + }, { + key: "toggle", + value: function toggle() { + var _this2 = this; + + var controller = { + link: this, + toggle: function toggle() { + Controller.collectionSet(_this2.scroll.render(true)); + Controller.collectionFocus(_this2.last || false, _this2.scroll.render(true)); + + _this2.emit('toggle'); + }, + right: function right() { + if (Navigator.canmove('right')) Navigator.move('right'); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else _this2.emit('left'); + }, + down: this.emit.bind(this, 'down'), + up: this.emit.bind(this, 'up'), + back: this.emit.bind(this, 'back') + }; + this.emit('controller', controller); + Controller.add('items_line', controller); + Controller.toggle('items_line'); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html : $(this.html); + } + }, { + key: "destroy", + value: function destroy() { + this.scroll.destroy(); + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Base; + }(Emit); + + var Line$4 = /*#__PURE__*/function (_Base) { + _inherits(Line, _Base); + + var _super = _createSuper(Line); + + function Line(data) { + var _this; + + _classCallCheck(this, Line); + + _this = _super.call(this, data); + var module = typeof _this.params.module !== 'undefined' ? _this.params.module : Helper$b.MASK.base; + Helper$b.getNames(module).map(function (name) { + return LineMap[name]; + }).forEach(function (mod) { + return _this.use(mod); + }); + + _this.emit('init'); + + return _this; + } + + return Line; + }(Base$1); + + var Create$1 = { + onCreateAndAppend: function onCreateAndAppend(element) { + try { + var item = Utils$1.createInstance(Line$4, element); + this.emit('instance', item, element); + item.create(); + this.emit('append', item, element); + } catch (e) { + console.warn('Warning', 'onCreateAndAppend error:', e.message, e.stack); + } + } + }; + + var Callback = { + onLeft: function onLeft() { + Controller.toggle('menu'); + }, + onBack: function onBack() { + Activity.backward(); + } + }; + + var Next$1 = { + onInit: function onInit() { + this.next_wait; + this.builded_time = Date.now(); + }, + onBuild: function onBuild() { + this.scroll.onEnd = this.emit.bind(this, 'loadNext'); + this.builded_time = Date.now(); + }, + onLoadNext: function onLoadNext() { + var _this = this; + + if (!this.next_wait && this.items.length && this.builded_time < Date.now() - 1000) { + this.next_wait = true; + this.emit('next', function (new_data) { + _this.next_wait = false; + if (!_this.items.length || _this.destroyed) return; + var split_total = Math.ceil(new_data.length / _this.limit_view); // Разбиваем на части, чтобы не лагал браузер + + for (var i = 0; i < split_total; i++) { + _this.loaded.push(new_data.slice(i * _this.limit_view, (i + 1) * _this.limit_view)); + } // Если нет анимации у скрола, то можно грузить сразу + + + if (!_this.scroll.animated()) _this.scroll.onAnimateEnd(); + }, function () { + _this.next_wait = false; + }); + } + } + }; + + var Item = /*#__PURE__*/function () { + function Item(data, params) { + _classCallCheck(this, Item); + + this.data = data; + this.params = params; + } + + _createClass(Item, [{ + key: "create", + value: function create() { + this.html = Template.js(this.template, {}); + this.html.addEventListener('visible', this.visible.bind(this)); + } + }, { + key: "update", + value: function update() { + var _this = this; + + var url = (this.data.url || this.data.link) + ''; + var loc = url.slice(0, 6) == 'https:' || window.location.protocol == 'https:'; + var hts = url.slice(0, 6) == 'https:' || url.slice(0, 5) == 'http:'; + + if (Plugins.errors().find(function (s) { + return s == (_this.data.url || _this.data.link); + })) { + var erl = this.html.querySelector('.extensions__item-error'); + if (erl) erl.toggleClass('hide', false); + } + + if (window.location.protocol == 'https:' && hts) url = url.replace(/^(http:\/\/|https:\/\/)/, 'https://'); + this.html.querySelector('.extensions__item-name').innerText = this.data.name || Lang.translate('extensions_no_name'); + this.html.querySelector('.extensions__item-author').innerText = this.data.author || (this.params.type == 'plugins' ? '@cub' : '@lampa'); + this.html.querySelector('.extensions__item-descr').innerText = (this.data.descr || url).replace(/\n|\t|\r/g, ' '); + var proto = this.html.querySelector('.extensions__item-proto'); + + if (proto && hts) { + proto.toggleClass('hide', !Boolean(this.params.type == 'plugins' || this.params.type == 'installs')); + proto.addClass('protocol-' + (loc ? 'https' : 'http')); + } + + var status = this.html.querySelector('.extensions__item-disabled'); + status.innerText = Lang.translate('player_disabled'); + if (this.data.status || !this.params.autocheck) status.classList.add('hide');else status.classList.remove('hide'); + } + }, { + key: "cub", + value: function cub() { + var cub = document.createElement('div'); + cub.classList.add('extensions__cub'); + cub.innerText = 'CUB'; + this.html.appendChild(cub); + } + }, { + key: "premium", + value: function premium() { + var author = this.html.querySelector('.extensions__item-author'); + var premium = document.createElement('span'); + premium.classList.add('extensions__item-premium'); + premium.innerText = 'CUB Premium'; + var where = author || this.html; + where.appendChild(premium); + } + }, { + key: "visible", + value: function visible() { + this.update(); + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + } + }]); + + return Item; + }(); + + function showReload(cancel) { + Modal.open({ + title: '', + align: 'center', + zIndex: 300, + html: $('
    ' + Lang.translate('plugins_need_reload') + '
    '), + buttons: [{ + name: Lang.translate('settings_param_no'), + onSelect: function onSelect() { + Modal.close(); + cancel(); + } + }, { + name: Lang.translate('settings_param_yes'), + onSelect: function onSelect() { + window.location.reload(); + } + }] + }); + } + + function showInfo(plug, back) { + var modal = Template.get('extensions_info'); + var footer = $('.extensions-info__footer', modal); + if (plug.image) modal.prepend($('')); + $('.extensions-info__descr', modal).text(plug.descr); + $('.extensions-info__instruction', modal).html((plug.instruction || Lang.translate('extensions_no_info')).replace(/\n/g, '
    ').replace(/\s\s/g, '  ')); + + function addLabel(name, value) { + var label = $("
    \n
    ".concat(name, "
    \n
    ").concat(value, "
    \n
    ")); + footer.append(label); + } + + if (plug.link) addLabel(Lang.translate('settings_parser_jackett_link'), plug.link); + if (plug.author) addLabel(Lang.translate('title_author'), plug.author); + if (plug.time) addLabel(Lang.translate('settings_added'), Utils$1.parseTime(plug.time).full); + Modal.open({ + title: plug.name || Lang.translate('extensions_info'), + html: modal, + size: 'large', + onBack: function onBack() { + Modal.close(); + back(); + } + }); + } + + var Utils = { + showReload: showReload, + showInfo: showInfo + }; + + var Extension = /*#__PURE__*/function (_Item) { + _inherits(Extension, _Item); + + var _super = _createSuper(Extension); + + function Extension(data, params) { + var _this; + + _classCallCheck(this, Extension); + + _this = _super.call(this, data, params); + _this.network = new Request(); + _this.template = 'extensions_item'; + return _this; + } + + _createClass(Extension, [{ + key: "visible", + value: function visible() { + _get(_getPrototypeOf(Extension.prototype), "visible", this).call(this); + + if (this.params.cub) this.cub(); + if (this.data.premium) this.premium(); + if (this.params.autocheck) this.check(); + if (Plugins.loaded().indexOf(this.data.url || this.data.link) >= 0) this.html.querySelector('.extensions__item-included').classList.remove('hide'); + this.html.addEventListener('hover:enter', this.menu.bind(this)); + } + }, { + key: "menu", + value: function menu() { + var _this2 = this; + + if (this.removed) return; + var menu = []; + var controller = Controller.enabled().name; + + var back = function back() { + Controller.toggle(controller); + }; + + if (this.params.type == 'plugins' || this.params.type == 'installs') { + menu.push({ + title: Lang.translate('extensions_' + (this.data.status ? 'disable' : 'enable')), + toggle: true + }); + } + + menu.push({ + title: Lang.translate('extensions_check'), + status: true + }); + + if (this.params.cub || this.params.noedit) { + if (this.params.type == 'extensions') { + menu.push({ + title: Lang.translate('extensions_install'), + install: true + }); + } + + menu.push({ + title: Lang.translate('extensions_info'), + instruction: true + }); + } else { + menu.push({ + title: Lang.translate('extensions_edit'), + separator: true + }); + menu.push({ + title: Lang.translate('extensions_change_name'), + change: 'name' + }); + menu.push({ + title: Lang.translate('extensions_change_link'), + change: 'url' + }); + menu.push({ + title: Lang.translate('extensions_remove'), + remove: true + }); + } + + Select.show({ + title: Lang.translate('title_action'), + items: menu, + onBack: back, + onSelect: function onSelect(a) { + if (a.toggle) { + _this2.data.status = _this2.data.status == 1 ? 0 : 1; + if (_this2.params.cub) Account$1.Api.pluginToggle(_this2.data, _this2.data.status);else Plugins.save(_this2.data); + + _this2.update(); + + if (_this2.data.status == 1) { + back(); + Plugins.push(_this2.data); + } else { + Utils.showReload(back); + } + } else if (a.change) { + Input.edit({ + title: a.change == 'name' ? Lang.translate('extensions_set_name') : Lang.translate('extensions_set_url'), + value: _this2.data[a.change] || '', + free: true, + nosave: true + }, function (new_value) { + if (new_value) { + _this2.data[a.change] = new_value; + Plugins.save(_this2.data); + + _this2.update(); + + if (a.change == 'url') { + _this2.check(); + + Plugins.push(_this2.data); + } + } + + back(); + }); + } else if (a.status) { + back(); + + _this2.check(); + } else if (a.install) { + var ready = Plugins.get().find(function (b) { + return b.url == _this2.data.link; + }); + + if (ready) { + Noty.show(Lang.translate('extensions_ready')); + back(); + } else { + back(); + Plugins.add({ + url: _this2.data.link, + status: 1, + name: _this2.data.name, + author: _this2.data.author + }); + + _this2.html.querySelector('.extensions__item-included').classList.remove('hide'); + } + } else if (a.instruction) { + Utils.showInfo(_this2.data, back); + } else if (a.remove) { + Plugins.remove(_this2.data); + _this2.html.style.opacity = 0.5; + _this2.removed = true; + Utils.showReload(back); + } + } + }); + } + }, { + key: "check", + value: function check() { + var check = this.html.querySelector('.extensions__item-check'); + var code = this.html.querySelector('.extensions__item-code'); + var stat = this.html.querySelector('.extensions__item-status'); + check.classList.remove('hide'); + code.classList.add('hide'); + stat.classList.add('hide'); + + var display = function display(type, num, text) { + code.innerText = num; + code.classList.remove('hide'); + code.classList.remove('success'); + code.classList.remove('error'); + code.classList.add(type); + stat.innerText = text; + stat.classList.remove('hide'); + check.classList.add('hide'); + }; + + var url = Utils$1.fixMirrorLink(Utils$1.rewriteIfHTTPS(this.data.url || this.data.link)); + this.network.timeout(5000); + this.network["native"](url, function (str) { + if (/Lampa\./.test(str)) { + display('success', 200, Lang.translate('extensions_worked')); + } else { + display('error', 500, Lang.translate('extensions_no_plugin')); + } + }, function (a, e) { + display('error', a.decode_code || 404, Lang.translate('title_error')); + }, false, { + dataType: 'text' + }); + } + }]); + + return Extension; + }(Item); + + var Recomend = /*#__PURE__*/function (_Extension) { + _inherits(Recomend, _Extension); + + var _super = _createSuper(Recomend); + + function Recomend(data, params) { + var _this; + + _classCallCheck(this, Recomend); + + _this = _super.call(this, data, params); + _this.template = 'extensions_recomend'; + return _this; + } + + _createClass(Recomend, [{ + key: "visible", + value: function visible() { + var _this2 = this; + + _get(_getPrototypeOf(Recomend.prototype), "visible", this).call(this); + + this.img = this.html.querySelector('.extensions__item-image'); + + this.img.onload = function () { + _this2.img.classList.add('loaded'); + }; + + this.img.src = Utils$1.fixMirrorLink(Utils$1.rewriteIfHTTPS(this.data.image)); + } + }, { + key: "destroy", + value: function destroy() { + _get(_getPrototypeOf(Recomend.prototype), "destroy", this).call(this); + + if (this.img) { + this.img.onload = false; + this.img.onerror = false; + } + } + }]); + + return Recomend; + }(Extension); + + var Theme$1 = /*#__PURE__*/function () { + function Theme() { + _classCallCheck(this, Theme); + } + + _createClass(Theme, [{ + key: "init", + value: function init() { + if (this.get()) this.set(this.get()); + } + }, { + key: "toggle", + value: function toggle(url) { + if (url) { + Storage.set('cub_theme', url); + this.set(url); + } else { + Storage.set('cub_theme', ''); + $('#cub-theme').remove(); + } + } + }, { + key: "get", + value: function get() { + return Storage.get('cub_theme', ''); + } + }, { + key: "set", + value: function set(url) { + $('#cub-theme').remove(); + var href = Utils$1.rewriteIfHTTPS(Utils$1.addUrlComponent(url, 'token=' + encodeURIComponent(Storage.get('account', '{}').token))); + var css = $(''); + $('body').append(css); + } + }]); + + return Theme; + }(); + + var Theme$2 = new Theme$1(); + + var Theme = /*#__PURE__*/function (_Item) { + _inherits(Theme, _Item); + + var _super = _createSuper(Theme); + + function Theme(data, params) { + var _this; + + _classCallCheck(this, Theme); + + _this = _super.call(this, data, params); + _this.template = 'extensions_theme'; + _this.link = Utils$1.rewriteIfHTTPS(Utils$1.protocol() + object$2.cub_domain + '/extensions/' + _this.data.id); + return _this; + } + + _createClass(Theme, [{ + key: "update", + value: function update() { + this.html.querySelector('.extensions__item-name').innerText = this.data.name || Lang.translate('extensions_no_name'); + if (this.active()) this.html.classList.add('active');else this.html.classList.remove('active'); + } + }, { + key: "active", + value: function active() { + return Storage.get('cub_theme', '') == this.link; + } + }, { + key: "visible", + value: function visible() { + var _this2 = this; + + _get(_getPrototypeOf(Theme.prototype), "visible", this).call(this); + + if (this.data.premium) this.premium(); + this.img = this.html.querySelector('.extensions__item-image'); + + this.img.onload = function () { + _this2.img.classList.add('loaded'); + }; + + this.img.src = Utils$1.fixMirrorLink(Utils$1.rewriteIfHTTPS(this.data.image)); + this.html.addEventListener('hover:enter', this.menu.bind(this)); + } + }, { + key: "menu", + value: function menu() { + var _this3 = this; + + var menu = []; + var controller = Controller.enabled().name; + menu.push({ + title: Lang.translate('extensions_' + (this.active() ? 'disable' : 'enable')), + toggle: true + }); + Select.show({ + title: Lang.translate('title_action'), + items: menu, + onBack: function onBack() { + Controller.toggle(controller); + }, + onSelect: function onSelect(a) { + Controller.toggle(controller); + + if (a.toggle) { + if (!_this3.active() && _this3.data.premium && !Account$1.hasPremium()) return Lampa.Account.showCubPremium(); + Theme$2.toggle(_this3.active() ? '' : _this3.link); + + _this3.update(); + } + } + }); + } + }, { + key: "destroy", + value: function destroy() { + _get(_getPrototypeOf(Theme.prototype), "destroy", this).call(this); + + if (this.img) { + this.img.onload = false; + this.img.onerror = false; + } + } + }]); + + return Theme; + }(Item); + + var Screensaver = /*#__PURE__*/function (_Item) { + _inherits(Screensaver, _Item); + + var _super = _createSuper(Screensaver); + + function Screensaver(data, params) { + var _this; + + _classCallCheck(this, Screensaver); + + _this = _super.call(this, data, params); + _this.template = 'extensions_screensaver'; + _this.link = Utils$1.rewriteIfHTTPS(Utils$1.protocol() + object$2.cub_domain + '/extensions/' + _this.data.id); + return _this; + } + + _createClass(Screensaver, [{ + key: "update", + value: function update() { + this.html.querySelector('.extensions__item-name').innerText = this.data.name || Lang.translate('extensions_no_name'); + this.html.querySelector('.extensions__item-time').innerText = Utils$1.parseTime(Date.now()).time; + if (this.active()) this.html.classList.add('active');else this.html.classList.remove('active'); + } + }, { + key: "active", + value: function active() { + return Storage.field('screensaver_type') == 'cub' && Storage.get('cub_screensaver', '') == this.link; + } + }, { + key: "visible", + value: function visible() { + var _this2 = this; + + _get(_getPrototypeOf(Screensaver.prototype), "visible", this).call(this); + + if (this.data.premium) this.premium(); + this.img = this.html.querySelector('.extensions__item-image'); + + this.img.onload = function () { + _this2.img.classList.add('loaded'); + }; + + this.img.src = Utils$1.fixMirrorLink(Utils$1.rewriteIfHTTPS(this.data.image)); + this.html.addEventListener('hover:enter', this.menu.bind(this)); + } + }, { + key: "menu", + value: function menu() { + var _this3 = this; + + var menu = []; + var controller = Controller.enabled().name; + menu.push({ + title: Lang.translate('extensions_' + (this.active() ? 'disable' : 'enable')), + toggle: true + }); + menu.push({ + title: Lang.translate('title_watch'), + watch: true + }); + Select.show({ + title: Lang.translate('title_action'), + items: menu, + onBack: function onBack(a) { + Controller.toggle(controller); + }, + onSelect: function onSelect(a) { + Controller.toggle(controller); + + if (a.toggle) { + if (_this3.active()) Storage.set('cub_screensaver', '');else { + if (_this3.data.premium && !Account$1.hasPremium()) return Lampa.Account.showCubPremium(); + Storage.set('cub_screensaver', _this3.link); + Storage.set('screensaver_type', 'cub'); + } + + _this3.update(); + } else { + Screensaver$2.show('cub', { + url: _this3.link + }); + } + } + }); + } + }, { + key: "destroy", + value: function destroy() { + _get(_getPrototypeOf(Screensaver.prototype), "destroy", this).call(this); + + if (this.img) { + this.img.onload = false; + this.img.onerror = false; + } + } + }]); + + return Screensaver; + }(Item); + + var Line$3 = /*#__PURE__*/function () { + function Line(data, params) { + _classCallCheck(this, Line); + + this.params = params; + this.data = data; + this.items = []; + this.active = 0; + this.view = 4; + this.last; + } + + _createClass(Line, [{ + key: "create", + value: function create() { + var _this = this; + + this.scroll = new Scroll({ + horizontal: true, + step: window.innerWidth / 4 + }); + this.html = Template.js('extensions_block', {}); + this.html.querySelector('.extensions__block-title').innerText = this.params.title; + this.html.addEventListener('visible', this.visible.bind(this)); + this.html.querySelector('.extensions__block-body').appendChild(this.scroll.render(true)); + + this.scroll.onWheel = function (step) { + if (!Controller.own(_this)) _this.toggle(); + Controller.enabled().controller[step > 0 ? 'right' : 'left'](); + }; + + this.scroll.onScroll = this.attach.bind(this); + } + }, { + key: "display", + value: function display(num) { + var _this2 = this; + + this.data.filter(function (p) { + if (p.platform) { + var platforms = p.platform.split(','); + return platforms.find(function (n) { + return Platform.is(n); + }); + } else return true; + }).filter(function (e) { + return e.premium ? window.lampa_settings.account_use : true; + }).filter(function (e) { + return !_this2.items.find(function (f) { + return f.data == e; + }); + }).forEach(this.append.bind(this)); + } + }, { + key: "visible", + value: function visible() { + this.display(this.view); + Layer.visible(this.scroll.render(true)); + } + }, { + key: "append", + value: function append(elem) { + var _this3 = this; + + var Class = Extension; + if (this.params.hpu == 'recomend') Class = Recomend; + if (this.params.hpu == 'theme') Class = Theme; + if (this.params.hpu == 'screensaver') Class = Screensaver; + var item = new Class(elem, this.params); + item.create(); + item.render().addEventListener('hover:focus', function () { + _this3.last = item.render(); + var prev_active = _this3.active; + _this3.active = _this3.items.indexOf(item); + if (_this3.active > 0 || prev_active > _this3.active) _this3.scroll.update(_this3.last, true); + }); + this.scroll.body(true).appendChild(item.render()); + this.items.push(item); + if (Controller.own(this)) Controller.collectionAppend(item.render()); + } + }, { + key: "attach", + value: function attach() { + var size = Platform.screen('tv') ? (Math.round(this.active / this.view) + 1) * this.view + 1 : this.data.length; + this.display(size); + Layer.visible(this.scroll.render(true)); + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "toggle", + value: function toggle() { + var _this4 = this; + + Controller.add('extensions_line', { + link: this, + toggle: function toggle() { + Controller.collectionSet(_this4.scroll.render(true)); + Controller.collectionFocus(_this4.items.length ? _this4.last : false, _this4.scroll.render(true)); + if (_this4.onToggle) _this4.onToggle(_this4); + }, + update: function update() {}, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + Navigator.move('left'); + }, + down: this.onDown, + up: this.onUp, + back: this.onBack + }); + Controller.toggle('extensions_line'); + } + }, { + key: "destroy", + value: function destroy() { + Arrays.destroy(this.items); + this.scroll.destroy(); + this.html.remove(); + this.items = null; + } + }]); + + return Line; + }(); + + var Add$1 = /*#__PURE__*/function () { + function Add() { + var _this = this; + + _classCallCheck(this, Add); + + this.html = document.createElement('div'); + this.html.classList.add('extensions__block-add'); + this.html.classList.add('selector'); + this.html.innerText = Lang.translate('extensions_add'); + this.html.addEventListener('hover:enter', function () { + if (!Storage.get('agree_installation')) { + var controller = Controller.enabled().name; + Modal.open({ + title: Lang.translate('install_extension_rule_1'), + html: Template.get('plugins_rules'), + size: 'medium', + buttons_position: 'outside', + buttons: [{ + name: Lang.translate('settings_plugins_install'), + onSelect: function onSelect() { + Storage.set('agree_installation', true); + Modal.close(); + Controller.toggle(controller); + + _this.input(); + } + }, { + name: Lang.translate('cancel'), + onSelect: function onSelect() { + Modal.close(); + Controller.toggle(controller); + } + }], + onBack: function onBack() { + Modal.close(); + Controller.toggle(controller); + } + }); + } else { + _this.input(); + } + }); + } + + _createClass(Add, [{ + key: "input", + value: function input() { + var _this2 = this; + + Input.edit({ + title: Lang.translate('extensions_set_url'), + value: '', + free: true, + nosave: true, + nomic: true + }, function (new_value) { + _this2.onAdd(new_value); + }); + } + }, { + key: "render", + value: function render() { + return this.html; + } + }]); + + return Add; + }(); + + var Main = /*#__PURE__*/function () { + function Main(params) { + _classCallCheck(this, Main); + + this.items = []; + this.active = 0; + this.params = params; + } + + _createClass(Main, [{ + key: "create", + value: function create() { + var _this = this; + + this.html = Template.js('extensions'); + this.scroll = new Scroll({ + mask: true + }); + + this.scroll.onWheel = function (step) { + if (step > 0) _this.down();else _this.up(); + }; + + this.scroll.append(HeadBackward(Lang.translate('settings_main_plugins'), true)); + this.scroll.height(); + this.html.querySelector('.extensions__body').appendChild(this.scroll.render(true)); + if (this.params.store) this.loadCustomStore();else this.load(); + } + }, { + key: "add", + value: function add() { + var add = new Add$1(); + var line = this.items[0]; + + add.onAdd = function (url) { + if (url) { + if (url.length > 300) { + line.toggle(); + Noty.show(Lang.translate('account_export_fail_600')); + return; + } + + var data = { + url: url, + status: 1 + }; + var plugin = new Extension(data, { + type: 'installs', + autocheck: true + }); + plugin.create(); + Plugins.add(data); + $(add.render()).after(plugin.render()); + line.last = add.render(); + Layer.visible(line.render()); + line.toggle(); + } else { + line.toggle(); + } + }; + + line.scroll.body(true).appendChild(add.render()); + } + }, { + key: "loadCustomStore", + value: function loadCustomStore() { + var _this2 = this; + + this.appendLoader(); + var net = new Request(); + net.silent(this.params.store, function (data) { + _this2.loader.remove(); + + net = null; + + if (data.results && data.results.length) { + if (_this2.params.with_installed) { + _this2.appendLine(Plugins.get().reverse(), { + title: Lang.translate('extensions_from_memory'), + type: 'installs', + autocheck: true + }); + } + + data.results.forEach(function (a) { + _this2.appendLine(a.results, { + title: a.title || Lang.translate('player_unknown'), + type: 'extensions', + hpu: a.hpu, + noedit: true + }); + }); + if (_this2.params.with_installed) _this2.add(); + + _this2.items.slice(0, 3).forEach(function (i) { + return i.display(); + }); + + Layer.visible(_this2.html); + + _this2.toggle(); + } else { + _this2.error(); + } + }, function () { + _this2.loader.remove(); + + net = null; + + _this2.error(); + }); + } + }, { + key: "load", + value: function load() { + var _this3 = this; + + this.appendLoader(); + var need = 2; + if (window.lampa_settings.plugins_store) need += 2; + var status = new Status(need); + + status.onComplite = function () { + _this3.loader.remove(); + + _this3.appendLine(status.data.installs, { + title: Lang.translate('extensions_from_memory'), + type: 'installs', + autocheck: true + }); + + if (status.data.plugins.length) _this3.appendLine(status.data.plugins, { + title: Lang.translate('extensions_from_cub'), + cub: true, + type: 'plugins', + autocheck: true + }); + if (status.data.best && status.data.best.length) _this3.appendLine(status.data.best, { + title: Lang.translate('extensions_from_popular'), + cub: true, + type: 'extensions' + }); + if (status.data.all && status.data.all.length) _this3.appendLine(status.data.all.reverse(), { + title: Lang.translate('extensions_from_lib'), + cub: true, + type: 'extensions' + }); + + if (status.data.list) { + status.data.list.forEach(function (data) { + if (data.results.length) { + _this3.appendLine(data.results, { + title: Lang.translate('extensions_hpu_' + data.hpu), + cub: true, + type: 'extensions', + hpu: data.hpu + }); + } + }); + } + + _this3.add(); + + _this3.items.slice(0, 3).forEach(function (i) { + return i.display(); + }); + + Layer.visible(_this3.html); + + _this3.toggle(); + }; + + status.append('installs', Plugins.get().reverse()); + Account$1.Api.plugins(function (plugins) { + status.append('plugins', plugins.reverse()); + }); + + if (window.lampa_settings.plugins_store) { + CUB.extensions(function (extensions) { + if (extensions.results) { + status.need--; + status.append('list', extensions.results); + } else { + status.append('best', extensions.best); + status.append('all', extensions.plugins); + } + }); + } + } + }, { + key: "appendLoader", + value: function appendLoader() { + this.loader = document.createElement('div'); + this.loader.classList.add('broadcast__scan'); + this.loader.appendChild(document.createElement('div')); + this.scroll.body(true).appendChild(this.loader); + } + }, { + key: "error", + value: function error() { + var empty = new Lampa.Empty(); + this.scroll.body(true).appendChild(empty.render(true)); + } + }, { + key: "appendLine", + value: function appendLine(data, params) { + var _this4 = this; + + var line = new Line$3(data, params); + line.onBack = this.onBack.bind(this); + line.onUp = this.up.bind(this); + line.onDown = this.down.bind(this); + + line.onToggle = function () { + _this4.active = _this4.items.indexOf(line); + + _this4.scroll.update(line.render(), true); + }; + + line.create(); + this.scroll.body(true).appendChild(line.render()); + this.items.push(line); + } + }, { + key: "down", + value: function down() { + this.active++; + if (this.active <= this.items.length - 1) this.items[this.active].toggle(); + this.active = Math.min(this.items.length - 1, this.active); + } + }, { + key: "up", + value: function up() { + this.active--; + if (this.active >= 0) this.items[this.active].toggle(); + this.active = Math.max(0, this.active); + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "toggle", + value: function toggle() { + var _this5 = this; + + Controller.add('extensions', { + toggle: function toggle() { + Controller.collectionSet(_this5.html); + + if (_this5.items.length) { + _this5.items[_this5.active].toggle(); + } + }, + back: this.onBack + }); + Controller.toggle('extensions'); + } + }, { + key: "destroy", + value: function destroy() { + Arrays.destroy(this.items); + this.scroll.destroy(); + this.html.remove(); + } + }]); + + return Main; + }(); + + var extensions; + var listener$5 = Subscribe$2(); + + function init$A() { + ParentalControl.add('extensions', { + title: 'settings_main_plugins' + }); + } + + function show$4() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + if (extensions) return; + var controller = Controller.enabled().name; + extensions = new Main(params); + + extensions.onBack = function () { + extensions.destroy(); + extensions = null; + document.body.toggleClass('ambience--enable', false); + Controller.toggle(controller); + if (params.onClose) params.onClose(); + if (!params.store) listener$5.send('close', {}); + }; + + extensions.create(); + document.body.toggleClass('ambience--enable', true); + document.body.appendChild(extensions.render(true)); + extensions.toggle(); + if (!params.store) listener$5.send('open', { + extensions: extensions + }); + } + + function render$4(js) { + var html = extensions ? extensions.render() : document.createElement('div'); + return js ? html : $(html); + } + + var Extensions = { + init: init$A, + listener: listener$5, + show: show$4, + render: render$4 + }; + + var _created = []; + var _loaded = []; + + var _network = new Request(); + + var _blacklist = []; + var _awaits = []; + var _noload = []; + /** + * Запуск + */ + + function init$z() { + _loaded = Storage.get('plugins', '[]'); + Settings.main().render().find('[data-component="plugins"]').unbind('hover:enter').on('hover:enter', function () { + ParentalControl.personal('extensions', function () { + Extensions.show(); + }, false, true); + }); + } + + function get$6() { + return _loaded.map(function (a) { + return a; + }); + } + + function modify() { + var list = Storage.get('plugins', '[]'); + list = list.map(function (a) { + return typeof a == 'string' ? { + url: a, + status: 1 + } : a; + }); + list.forEach(function (a) { + a.url = (a.url + '').replace('cub.watch', object$2.cub_domain).replace('bwa.to', 'bwa.ad'); + }); + console.log('Plugins', 'modify:', list); + Storage.set('plugins', list); + } + + function remove$1(plug) { + Arrays.remove(_loaded, plug); + console.log('Plugins', 'remove:', plug, 'index:', _loaded.indexOf(plug), 'from:', _loaded); + Storage.set('plugins', _loaded); + } + + function add$6(plug) { + _loaded.push(plug); + + console.log('Plugins', 'add:', plug); + Storage.set('plugins', _loaded); + push$4(plug); + } + + function push$4(plug) { + var find = _created.find(function (a) { + return a == plug.url; + }); + + if (!find && plug.status == 1) { + if (_blacklist.find(function (a) { + return plug.url.indexOf(a) >= 0; + })) return Noty.show(Lang.translate('torrent_error_connect'), { + time: 8000 + }); + + _created.push(plug.url); + + console.log('Plugins', 'push:', plug); + Utils$1.putScriptAsync([addPluginParams(plug.url)], false, function () { + Noty.show(Lang.translate('plugins_check_fail'), { + time: 8000 + }); + }, function () { + updatePluginDB(plug.url, addPluginParams(plug.url)); + Noty.show(Lang.translate('plugins_add_success')); + }, false); + } + } + + function save$1() { + console.log('Plugins', 'save:', _loaded); + Storage.set('plugins', _loaded); + } + + function updatePluginDB(name, url) { + //if(Account.hasPremium()){ + var cu = Utils$1.addUrlComponent(url, 'cache=true'); + + _network["native"](cu, function (str) { + Cache.rewriteData('plugins', name, str).then(function () { + console.log('Plugins', 'update plugin cache:', name); + })["catch"](function (e) { + console.warn('Plugins', 'add to cache fail:', name, typeof e == 'string' ? e : e ? e.message : 'no details'); + }); + }, false, false, { + dataType: 'text' + }); //} + + } + + function createPluginDB(name) { + //if(Account.hasPremium()){ + Cache.getData('plugins', name).then(function (code) { + if (code) { + var s = document.createElement('script'); + s.type = 'text/javascript'; + + try { + s.appendChild(document.createTextNode(code)); + document.body.appendChild(s); + } catch (e) { + s.text = code; + document.body.appendChild(s); + } + + console.log('Plugins', 'add plugin from cache:', name); + } else console.warn('Plugins', 'no find in cache:', name); + })["catch"](function (e) { + console.warn('Plugins', 'include from cache fail:', name, typeof e == 'string' ? e : e.message); + }); //} + } + + function addPluginParams(url) { + var encode = url; + encode = encode.replace('cub.watch', object$2.cub_domain); + encode = Utils$1.fixMirrorLink(encode); + + if (!/[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}/.test(encode)) { + encode = encode.replace(/\{storage_(\w+|\d+|_|-)\}/g, function (match, key) { + return encodeURIComponent(Base64.encode(localStorage.getItem(key) || '')); + }); + if (Account$1.Permit.access) encode = Utils$1.addUrlComponent(encode, 'email=' + encodeURIComponent(Base64.encode(Account$1.Permit.account.email))); + encode = Utils$1.addUrlComponent(encode, 'logged=' + encodeURIComponent(Account$1.Permit.access ? 'true' : 'false')); + encode = Utils$1.addUrlComponent(encode, 'reset=' + Math.random()); + encode = Utils$1.addUrlComponent(encode, 'origin=' + encodeURIComponent(Base64.encode(window.location.host))); + encode = Utils$1.rewriteIfHTTPS(encode); + } + + return encode; + } + + function loadBlackList(call) { + if (window.lampa_settings.disable_features.blacklist) return call([]); + var status = new Status(2); + + status.onComplite = function (res) { + call([].concat(res.cub, res.custom)); + }; + + _network.silent(Utils$1.protocol() + object$2.cub_domain + '/api/plugins/blacklist', function (result) { + var list = result.map(function (a) { + return a.url; + }); + Storage.set('plugins_blacklist', list); + status.append('cub', list); + }, function () { + status.append('cub', Storage.get('plugins_blacklist', '[]')); + }, false, { + timeout: 1000 * 5 + }); + + _network.silent('./plugins_black_list.json', function (list) { + status.append('custom', list); + }, function () { + status.append('custom', []); + }, false, { + timeout: 1000 * 5 + }); + } + /** + * Загрузка всех плагинов + */ + + + function load(call) { + var errors = []; + var original = {}; + var include = []; + + _awaits.forEach(function (url) { + var encode = addPluginParams(url); + include.push(encode); + original[encode] = url; + }); + + Utils$1.putScriptAsync(include, function () { + call(); + + if (errors.length) { + setTimeout(function () { + Noty.show(Lang.translate('plugins_no_loaded') + ' (' + errors.join(', ') + ')', { + time: 6000 + }); + }, 2000); + } + }, function (u) { + if (u.indexOf('modification.js') == -1) { + console.warn('Extensions', 'error:', original[u]); + errors.push(original[u]); + + _noload.push(original[u]); + + createPluginDB(original[u]); + } + }, function (u) { + console.log('Extensions', 'include:', original[u]); + + _created.push(original[u]); + + updatePluginDB(original[u], u); + }, false); + } + + function task$1(call) { + modify(); + _loaded = Storage.get('plugins', '[]'); + loadBlackList(function (black_list) { + Account$1.Api.plugins(function (plugins) { + var puts = window.lampa_settings.plugins_use ? plugins.filter(function (plugin) { + return plugin.status; + }).map(function (plugin) { + return plugin.url; + }).concat(Storage.get('plugins', '[]').filter(function (plugin) { + return plugin.status; + }).map(function (plugin) { + return plugin.url; + })) : []; + puts.push('./plugins/modification.js'); + puts = puts.filter(function (element, index) { + return puts.indexOf(element) === index; + }); + console.log('Plugins', 'load list:', puts); + black_list.push('lipp.xyz'); + black_list.push('llpp.xyz'); + black_list.push('scabrum.github.io'); + black_list.push('bylampa.github.io'); + black_list.push('tinyurl.com'); // Stupid people :( + + black_list.push('t.me/'); + black_list.push('4pda.'); + black_list.push('teletype.in'); + black_list.push('yotube.com'); + _blacklist = black_list; + console.log('Plugins', 'black list:', black_list); + black_list.forEach(function (b) { + puts = puts.filter(function (p) { + return p.toLowerCase().indexOf(b) == -1; + }); + }); + console.log('Plugins', 'clear list:', puts); + _awaits = puts; + call(); + }); + }); + } + + function awaits() { + return _awaits; + } + + var Plugins = { + init: init$z, + load: load, + remove: remove$1, + loaded: function loaded() { + return _created; + }, + errors: function errors() { + return _noload; + }, + add: add$6, + get: get$6, + save: save$1, + push: push$4, + task: task$1, + awaits: awaits + }; + + /** + * Показать шаблон пустого экрана + * @doc + * @name class + * @alias Empty + * @param {Object} params заголовок и описание JSON({"title":"Заголовок","descr":"Описание"}) + * @returns {Object} объект класса + */ + + var Empty = /*#__PURE__*/function (_Emit) { + _inherits(Empty, _Emit); + + var _super = _createSuper(Empty); + + function Empty() { + var _this; + + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Empty); + + _this = _super.call(this); + Arrays.extend(params, { + title: Lang.translate('empty_title_two'), + descr: Lang.translate('empty_text_two'), + text: Lang.translate('empty_text_two'), + noicon: false, + width: 'large', + template: 'empty', + icon: '', + buttons: [] + }); + _this.params = params; + _this.html = Template.get(params.template, params); + + _this.html.addClass('layer--wheight'); + + if (params.noicon) _this.noicon();else if (params.icon) _this.html.addClass('empty--custom-icon').find('.empty__icon').append(params.icon); + params.buttons.push({ + title: Lang.translate('terminal_update'), + onEnter: function onEnter() { + delete params.buttons; + Activity.replace(); + } + }); + if (params.buttons.length) _this.addButtons(params.buttons); + + _this.width(params.width); + + _this.emit('init'); + + return _this; + } + + _createClass(Empty, [{ + key: "noicon", + value: function noicon() { + this.html.addClass('empty--noicon'); + } + }, { + key: "width", + value: function width(_width) { + this.html.removeClass('empty--width-large empty--width-medium empty--width-small'); + this.html.addClass('empty--width-' + _width); + } + }, { + key: "start", + value: function start() { + var _this2 = this; + + this.emit('start'); + var controller = { + link: this, + toggle: function toggle() { + var selects = _this2.html.find('.selector').filter(function () { + return !$(this).hasClass('empty__img'); + }); + + _this2.html.find('.empty__img').toggleClass('selector', selects.length > 0 ? false : true); + + Controller.collectionSet(_this2.html); + Controller.collectionFocus(selects.length > 0 ? selects.eq(0)[0] : false, _this2.html); + Background.change(TMDB.img('/oXPYD4c3bLtfAS2FzwjZh7NWqo4.jpg', 'w200')); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + Navigator.move('down'); + }, + right: function right() { + Navigator.move('right'); + }, + back: function back() { + Activity.backward(); + } + }; + this.emit('controller', controller); + Controller.add('content', controller); + Controller.toggle('content'); + } + }, { + key: "addButtons", + value: function addButtons(buttons) { + var footer = this.html.find('.empty__footer'); + + if (!footer.length) { + footer = $(''); + this.html.append(footer); + } + + buttons.forEach(function (button_data) { + var button = $("
    ".concat(button_data.title, "
    ")); + button.on('hover:enter', function () { + if (button_data.onEnter) button_data.onEnter(); + }); + footer.append(button); + }); + } + }, { + key: "addInfoButton", + value: function addInfoButton(add_information) { + var footer = this.html.find('.empty__footer'); + + if (!footer.length) { + footer = $(''); + this.html.append(footer); + } + + var button = $('
    ' + Lang.translate('extensions_info') + '
    '); + button.on('hover:enter', function () { + var controller = Controller.enabled().name; + var html = $('
    '); + + var line = function line(name, value) { + html.append($("
    ".concat(name, " - ").concat(value, "
    "))); + }; + + line('Protocol', window.location.protocol); + line('Host', window.location.host); + line('Platform', Platform.get()); + line('Safe connection', Storage.field('protocol') == 'https' ? 'Yes' : 'No'); + line('Connection', Utils$1.protocol()); + line('TMDB Proxy', Storage.field('tmdb_proxy') ? 'Yes' : 'No'); + line('TMDB Proxy plugin', Plugins.loaded().find(function (u) { + return /\/plugin\/tmdb-proxy/.test(u); + }) ? 'Yes' : 'No'); + line('TMDB Proxy api', Lampa.TMDB.api('').split('/').slice(0, 3).join('/')); + line('Premium', Account$1.hasPremium() ? 'Yes' : 'No'); + line('Mirror', object$2.cub_domain); + + if (add_information) { + add_information.forEach(function (info) { + line(info[0], info[1]); + }); + } + + Modal.open({ + title: Lang.translate('extensions_info'), + html: html, + size: 'medium', + onBack: function onBack() { + Modal.close(); + Controller.toggle(controller); + } + }); + }); + footer.append(button); + } + }, { + key: "append", + value: function append(add) { + this.html.append(add); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html[0] : this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Empty; + }(Emit); + + var Simple = { + onEmpty: function onEmpty() { + var params = this.params.empty || {}; + params.buttons = params.buttons || []; + + if (this.object.source == 'tmdb' && params.cub_button) { + params.buttons.push({ + title: Lang.translate('change_source_on_cub'), + onEnter: function onEnter() { + Storage.set('source', 'cub'); + Activity.replace({ + source: 'cub' + }); + } + }); + } + + this.empty_class = new Empty(params); + if (params.info_button) this.empty_class.addInfoButton(params.info_button); + this.scroll.append(this.empty_class.render(true)); + this.start = this.empty_class.start.bind(this.empty_class); + } + }; + + var MainMap = { + Items: Items$1, + Create: Create$1, + Next: Next$1, + Empty: Simple, + Callback: Callback + }; + + var Helper$7 = new Mask(Arrays.getKeys(MainMap)); + Helper$7.MASK.base = Helper$7.MASK.all; + + var Full$1 = /*#__PURE__*/function (_Base) { + _inherits(Full, _Base); + + var _super = _createSuper(Full); + + function Full(object) { + var _this; + + _classCallCheck(this, Full); + + _this = _super.call(this, object); + var module = typeof _this.params.module !== 'undefined' ? _this.params.module : Helper$7.MASK.base; + Helper$7.getNames(module).map(function (name) { + return MainMap[name]; + }).forEach(function (mod) { + return _this.use(mod); + }); + + _this.emit('init'); + + return _this; + } + + return Full; + }(Main$1); + + /** + * Компонент главной страницы + * @param {object} object - Параметры компонента + * @return {object} - Экземпляр компонента + */ + + function component$n(object) { + var comp = Utils$1.createInstance(Full$1, object); + var next = null; + comp.use({ + onCreate: function onCreate() { + var nextCall = Api.main(object, this.build.bind(this), this.empty.bind(this)); + if (typeof nextCall == 'function') next = nextCall; + }, + onNext: function onNext(resolve, reject) { + if (next) { + next(resolve.bind(this), reject.bind(this)); + } else reject.call(this); + }, + onInstance: function onInstance(item, data) { + item.use({ + onMore: router.call.bind(router, 'category_full', data), + onInstance: function onInstance(card, data) { + card.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + } + }); + return comp; + } + + var Options = { + onCreate: function onCreate() { + var _this = this; + + this.html.find('.button--options').on('hover:enter', function () { + var options = []; + Lampa.Listener.send('full', { + link: _this, + type: 'options', + props: _this.props, + options: options + }); + + if (!window.lampa_settings.disable_features.ai) { + if (options.length) { + options.push({ + title: Lang.translate('title_ai_assistant'), + separator: true + }); + } + + options.push({ + title: Lang.translate('title_recomendations'), + onSelect: function onSelect() { + Controller.toggle('content'); + Activity.push({ + url: '', + title: Lang.translate('title_recomendations'), + component: 'ai_recommendations', + card: _this.card + }); + } + }); + options.push({ + title: Lang.translate('title_facts'), + onSelect: function onSelect() { + Controller.toggle('content'); + Activity.push({ + url: '', + title: Lang.translate('title_facts'), + component: 'ai_facts', + card: _this.card + }); + } + }); + } + + Select.show({ + title: Lang.translate('more'), + items: options, + onSelect: function onSelect() { + Controller.toggle('content'); + }, + onBack: function onBack() { + Controller.toggle('content'); + } + }); + }); + } + }; + + var Torrents = { + onCreate: function onCreate() { + var _this = this; + + var status = Storage.field('parser_use'); + var button = this.html.find('.view--torrent'); + if (window.lampa_settings.torrents_use) button.toggleClass('selector', status).toggleClass('hide', !status); + button.on('hover:enter', function () { + var year = ((_this.card.first_air_date || _this.card.release_date || '0000') + '').slice(0, 4); + var combinations = { + 'df': _this.card.original_title, + 'df_year': _this.card.original_title + ' ' + year, + 'df_lg': _this.card.original_title + ' ' + _this.card.title, + 'df_lg_year': _this.card.original_title + ' ' + _this.card.title + ' ' + year, + 'lg': _this.card.title, + 'lg_year': _this.card.title + ' ' + year, + 'lg_df': _this.card.title + ' ' + _this.card.original_title, + 'lg_df_year': _this.card.title + ' ' + _this.card.original_title + ' ' + year + }; + Activity.push({ + url: '', + title: Lang.translate('title_torrents'), + component: 'torrents', + search: combinations[Storage.field('parse_lang')], + search_one: _this.card.title, + search_two: _this.card.original_title, + movie: _this.card, + page: 1 + }); + }); + } + }; + + var Subscribed = { + onCreate: function onCreate() { + if (!(this.card.source == 'tmdb' || this.card.source == 'cub')) this.html.find('.source--name').text(this.card.source.toUpperCase());else if (this.card.number_of_seasons && window.lampa_settings.account_use && !window.lampa_settings.disable_features.subscribe) { + this.html.find('.button--subscribe').removeClass('hide'); + this.emit('subscribed'); + } + }, + onSubscribed: function onSubscribed() { + var _this = this; + + Api$1.load('card/subscribed', {}, { + id: this.card.id, + imdb_id: this.card.imdb_id + }).then(function (result) { + _this.html.find('.button--subscribe').data('voice', result.translation.voice).addClass('active').find('path').attr('fill', 'currentColor'); + })["catch"](function (e) {}); + } + }; + + var Trailers = { + onCreate: function onCreate() { + var _this = this; + + var videos = this.data.videos; + + if (!this.data.movie.adult && videos && videos.results.length && !window.lampa_settings.disable_features.trailers) { + this.html.find('.view--trailer').on('hover:enter', function () { + var items = []; + videos.results.forEach(function (element) { + var date = Utils$1.parseTime(element.published_at).full; + items.push({ + title: Utils$1.shortText(element.name, 50), + subtitle: (element.official ? Lang.translate('full_trailer_official') : Lang.translate('full_trailer_no_official')) + ' - ' + date, + id: element.key, + player: element.player, + code: element.iso_639_1, + time: new Date(element.published_at).getTime(), + url: element.url || 'https://www.youtube.com/watch?v=' + element.key, + youtube: typeof element.youtube !== 'undefined' ? element.youtube : true, + icon: '', + template: 'selectbox_icon', + thumbnail: element.icon || 'https://img.youtube.com/vi/' + element.key + '/default.jpg' + }); + }); + items.sort(function (a, b) { + return a.time > b.time ? -1 : a.time < b.time ? 1 : 0; + }); + var my_lang = items.filter(function (n) { + return n.code == Storage.field('tmdb_lang'); + }); + var en_lang = items.filter(function (n) { + return n.code == 'en' && my_lang.indexOf(n) == -1; + }); + var al_lang = []; + + if (my_lang.length) { + al_lang = al_lang.concat(my_lang); + } + + if (al_lang.length && en_lang.length) { + al_lang.push({ + title: Lang.translate('more'), + separator: true + }); + } + + al_lang = al_lang.concat(en_lang); + Select.show({ + title: 'YouTube - ' + Lang.translate('title_trailers'), + items: al_lang, + onSelect: function onSelect(a) { + _this.toggle(); + + if (Platform.is('android') && Storage.field('player_launch_trailers') == 'youtube' && a.youtube) { + Android.openYoutube(a.id); + } // else if(Platform.is('webos') && window.location.protocol == 'file:'){ + // if (window.webOS && webOS.service) { + // webOS.service.request( + // 'luna://com.webos.applicationManager', + // { + // method: 'launch', + // parameters: { + // id: 'youtube.leanback.v4', + // params: { + // contentTarget: 'v=' + a.id + // } + // }, + // onSuccess: function (inResponse) { + // console.log('YouTube','WebOS launched YouTube app successfully') + // }, + // onFailure: function (inError) { + // if(parseInt(inError.errorCode) == 100){ + // Lampa.Noty.show(Lang.translate('player_youtube_no_support')) + // } + // else{ + // Lampa.Noty.show(Lang.translate('network_error') + ' ' + "[" + inError.errorCode + "] " + inError.errorText) + // } + // } + // } + // ) + // } + // else{ + // Lampa.Noty.show(Lang.translate('network_error') + ' ' + "[WebOS service not available]") + // } + // } + else { + var playlist = al_lang.filter(function (v) { + return !v.separator; + }); + Player.play(a); + Player.playlist(playlist); + } + }, + onBack: function onBack() { + Controller.toggle('content'); + } + }); + }); + } else { + this.html.find('.view--trailer').remove(); + } + } + }; + + var Poster = { + onCreate: function onCreate() { + var _this = this; + + var im = this.html.find('.full--poster'); + var poster; + this.img_poster = im[0] || {}; + + if (window.innerWidth <= 480) { + this.img_poster = new Image(); + this.img_poster.crossOrigin = "Anonymous"; + } + + this.img_poster.onerror = function (e) { + _this.img_poster.src = './img/img_broken.svg'; + }; + + this.img_poster.onload = function (e) { + im.parent().addClass('loaded'); + }; + + if (window.innerWidth <= 480) { + if (this.card.backdrop_path) poster = Api.img(this.card.backdrop_path, 'w780');else if (this.card.background_image) poster = this.card.background_image; + + this.img_poster.onerror = function (e) { + _this.img_poster = im[0]; + + _this.img_poster.onerror = function (e) { + _this.img_poster.src = './img/img_broken.svg'; + }; + + _this.img_poster.onload = function (e) { + im.parent().addClass('loaded').addClass('with-out'); + }; + + im[0].src = poster || _this.card.img; + }; + + this.img_poster.onload = function (e) { + var draw = function draw() { + im.parent().addClass('loaded'); + setTimeout(function () { + im[0].style.transition = 'none'; + }, 500); + + var sc = _this.html.parents('.scroll')[0]; + + var an = 0; + var ts = 0; + var dl = window.innerHeight * 0.1; + + var smoothParallax = function smoothParallax() { + im[0].style.transform = 'translate3d(0, ' + ts * 0.35 + 'px, 0)'; + im[0].style.opacity = ts >= dl ? Math.max(0, 1 - (ts - dl) / (window.innerHeight * 0.2)) : 1; + an--; + if (an > 0) smoothParallax(); + }; + + if (sc) sc.on('scroll', function (e) { + ts = sc.scrollTop; + + if (an == 0) { + an = 100; + requestAnimationFrame(smoothParallax); + } + }); + }; + + if (window.lampa_settings.blur_poster) { + Color.blurPoster(_this.img_poster, im.width(), im.height(), function (nim) { + im[0].src = nim.src; + draw(); + }); + } else { + im[0].src = _this.img_poster.src; + draw(); + } + }; + } + + if (poster) this.html.find('.full-start__poster').addClass('background--poster'); + this.img_poster.src = poster || this.card.img; + } + }; + + var Reactions = { + onCreate: function onCreate() { + var _this = this; + + if (!Storage.field('card_interfice_reactions') || window.lampa_settings.disable_features.reactions) return this.html.find('.full-start-new__reactions, .button--reaction').remove(); + var reactions_data = this.data.reactions; + + var vote = function vote(type) { + var add = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var mine = Storage.get('mine_reactions', {}); + var id = (_this.card.name ? 'tv' : 'movie') + '_' + _this.card.id; + if (!mine[id]) mine[id] = []; + var ready = mine[id].indexOf(type) >= 0; + + if (add) { + if (!ready) mine[id].push(type); + Storage.set('mine_reactions', mine); + } + + return ready; + }; + + var draw = function draw() { + if (reactions_data && reactions_data.result && reactions_data.result.length) { + var reactions = reactions_data.result; + + var reactions_body = _this.html.find('.full-start-new__reactions')[0]; + + reactions.sort(function (a, b) { + return a.counter > b.counter ? -1 : a.counter < b.counter ? 1 : 0; + }); + reactions_body.empty(); + reactions.forEach(function (r) { + var reaction = document.createElement('div'), + icon = document.createElement('img'), + count = document.createElement('div'), + wrap = document.createElement('div'); + reaction.addClass('reaction'); + icon.addClass('reaction__icon'); + count.addClass('reaction__count'); + reaction.addClass('reaction--' + r.type); + count.text(Utils$1.bigNumberToShort(r.counter)); + icon.style.opacity = 0; + Utils$1.imgLoad(icon, Utils$1.protocol() + object$2.cub_domain + '/img/reactions/' + r.type + '.svg', function () { + icon.style.opacity = 1; + }); + reaction.append(icon); + reaction.append(count); + wrap.append(reaction); + if (vote(r.type)) reaction.addClass('reaction--voted'); + reactions_body.append(wrap); + }); + } + }; + + var items = [{ + type: 'fire' + }, { + type: 'nice' + }, { + type: 'think' + }, { + type: 'bore' + }, { + type: 'shit' + }]; + items.forEach(function (a) { + a.template = 'selectbox_icon', a.icon = ''; + a.ghost = vote(a.type); + a.noenter = a.ghost; + a.title = Lang.translate('reactions_' + a.type); + }); + this.html.find('.button--reaction').on('hover:enter', function () { + Select.show({ + title: Lang.translate('title_reactions'), + items: items, + onSelect: function onSelect(a) { + Controller.toggle('content'); + Api.sources.cub.reactionsAdd({ + method: _this.card.name ? 'tv' : 'movie', + id: _this.card.id, + type: a.type + }, function () { + vote(a.type, true); + var find = reactions_data.result.find(function (r) { + return r.type == a.type; + }); + if (find) find.counter++;else { + reactions_data.result.push({ + type: a.type, + counter: 1 + }); + } + a.ghost = true; + a.noenter = true; + draw(); + }, function (e) { + Lampa.Noty.show(Lang.translate('reactions_ready')); + }); + }, + onBack: function onBack() { + Controller.toggle('content'); + } + }); + }); + draw(); + } + }; + + var Translations = { + onCreate: function onCreate() { + var _this = this; + + if (window.lampa_settings.disable_features.subscribe) return; + var button = this.html.find('.button--subscribe'); + button.on('hover:enter', function () { + if (button.hasClass('loading')) return; + + if (!Account$1.Permit.access) { + return Account$1.Modal.account(); + } + + button.addClass('loading'); + Api$1.load('card/translations', {}, { + id: _this.card.id, + imdb_id: _this.card.imdb_id, + season: Utils$1.countSeasons(_this.card) + }).then(function (data) { + var items = []; + var subscribed = data.translations.subscribed || button.data('voice'); + + if (subscribed) { + items.push({ + title: Lang.translate('title_unsubscribe'), + subtitle: subscribed, + unsubscribe: true + }); + data.translations.voices = data.translations.voices.filter(function (voice) { + return voice !== subscribed; + }); + } + + data.translations.voices.forEach(function (voice) { + items.push({ + title: voice, + voice: voice, + ghost: true, + episode: 1 + }); + }); + + if (items.length) { + Select.show({ + title: Lang.translate('title_subscribe'), + items: items, + onSelect: function onSelect(a) { + _this.toggle(); + + if (a.unsubscribe) { + Api$1.load('card/unsubscribe', {}, { + id: _this.card.id + }).then(function () { + button.removeClass('active').data('voice', '').find('path').eq(1).attr('fill', 'transparent'); + })["catch"](function (e) { + Noty.show(Lang.translate('subscribe_error')); + }); + } else { + Account$1.Api.subscribeToTranslation({ + card: _this.card, + season: Utils$1.countSeasons(_this.card), + episode: a.episode, + voice: a.voice + }, function () { + Bell.push({ + text: Lang.translate('subscribe_success') + }); + button.addClass('active').data('voice', a.voice).find('path').attr('fill', 'currentColor'); + }, function () { + Noty.show(Lang.translate('subscribe_error')); + }); + } + }, + onFullDraw: function onFullDraw(scroll) { + scroll.body(true).prepend(Template.elem('div', { + "class": 'selectbox__text', + children: [Template.elem('div', { + text: Lang.translate('subscribe_info') + })] + })); + }, + onBack: function onBack() { + Controller.toggle('content'); + } + }); + } else Noty.show(Lang.translate('subscribe_noinfo')); + })["catch"](function (e) {})["finally"](function () { + button.removeClass('loading'); + }); + }); + } + }; + + var Bookmarks = { + onCreate: function onCreate() { + var _this = this; + + var btn = this.html.find('.button--book'); + btn.on('hover:enter', function () { + if (btn.hasClass('loading')) return; + var status = Favorite.check(_this.card); + var marks = ['look', 'viewed', 'scheduled', 'continued', 'thrown']; + + var label = function label(a) { + btn.addClass('loading'); + Favorite.toggle(a.type, _this.card); + if (a.collect) Controller.toggle('content'); + }; + + var items = ['book', 'like', 'wath', 'history'].map(function (type) { + return { + title: Lang.translate('title_' + type), + type: type, + checkbox: true, + checked: status[type] + }; + }); + + if (window.lampa_settings.account_use) { + items.push({ + title: Lang.translate('settings_cub_status'), + separator: true + }); + marks.forEach(function (m) { + items.push({ + title: Lang.translate('title_' + m), + type: m, + picked: status[m], + collect: true, + noenter: !Account$1.hasPremium(), + ghost: !Account$1.hasPremium() + }); + }); + } + + Select.show({ + title: Lang.translate('settings_input_links'), + items: items, + onCheck: label, + onSelect: label, + onBack: function onBack() { + btn.removeClass('loading'); + Controller.toggle('content'); + }, + onDraw: function onDraw(item, elem) { + if (elem.collect) { + if (!Account$1.hasPremium()) { + item.on('hover:enter', function () { + Select.close(); + Account$1.Modal[Account$1.Permit.token ? 'premium' : 'account'](); + }); + } + } + } + }); + }); + this.emit('updateFavorite'); + + this.listenerFavorite = function (e) { + if (e.target == 'favorite') { + btn.removeClass('loading'); + + if (e.card) { + if (e.card.id == _this.card.id) _this.emit('updateFavorite'); + } else _this.emit('updateFavorite'); + } + }; + + Lampa.Listener.follow('state:changed', this.listenerFavorite); + }, + onUpdateFavorite: function onUpdateFavorite() { + var status = Favorite.check(this.card); + var any = Favorite.checkAnyNotHistory(status); + var marks = ['look', 'viewed', 'scheduled', 'continued', 'thrown']; + var any_marker = marks.find(function (m) { + return status[m]; + }); + $('.button--book path', this.html).attr('fill', any ? 'currentColor' : 'transparent'); + this.html.find('.full-start-new__poster .card__marker').remove(); + + if (any_marker && Platform.screen('tv')) { + var marker = Template.elem('div', { + "class": 'card__marker', + children: [Template.elem('span')] + }); + this.html.find('.full-start-new__poster').append(marker); + marker.find('span').text(Lang.translate('title_' + any_marker)); + marker.removeClass(marks.map(function (m) { + return 'card__marker--' + m; + }).join(' ')).addClass('card__marker--' + any_marker); + } + }, + onDestroy: function onDestroy() { + Lampa.Listener.remove('state:changed', this.listenerFavorite); + } + }; + + var Buttons = { + onPriorityButton: function onPriorityButton(btn) { + var _this = this; + + var cont = this.html.find('.full-start-new__buttons'); + var clon = btn.clone(); + cont.find('.button--priority').remove(); + clon.addClass('button--priority').removeClass('view--torrent').on('hover:enter', function () { + btn.trigger('hover:enter'); + }).on('hover:long', function () { + clon.remove(); + Storage.set('full_btn_priority', ''); + _this.last = _this.html.find('.button--play')[0]; + Controller.toggle('content'); + }); + cont.prepend(clon); + }, + onGroupButtons: function onGroupButtons() { + var _this2 = this; + + var play = this.html.find('.button--play'); + var btns = this.html.find('.buttons--container > .full-start__button').not('.hide'); + var priority = Storage.get('full_btn_priority', '') + ''; + + if (priority) { + var priority_button; + btns.each(function () { + var hash = Utils$1.hash($(this).clone().removeClass('focus').prop('outerHTML')); + if (hash == priority) priority_button = $(this); + }); + if (priority_button) this.emit('priorityButton', priority_button); + } + + play.unbind().on('hover:enter', function (e) { + priority = Storage.get('full_btn_priority', '') + ''; + btns = _this2.html.find('.buttons--container > .full-start__button').not('.hide').filter(function () { + return priority !== Utils$1.hash($(this).clone().removeClass('focus').prop('outerHTML')); + }); + + if (btns.length == 1) { + btns.trigger('hover:enter'); + } else { + var items = []; + btns.each(function () { + var icon = $(this).find('svg').prop('outerHTML'); + items.push({ + title: $(this).text(), + subtitle: $(this).data('subtitle'), + template: typeof icon == 'undefined' || icon == 'undefined' ? 'selectbox_item' : 'selectbox_icon', + icon: icon, + btn: $(this) + }); + }); + Select.show({ + title: Lang.translate('settings_rest_source'), + items: items, + onSelect: function onSelect(a) { + a.btn.trigger('hover:enter'); + }, + onLong: function onLong(a) { + Storage.set('full_btn_priority', Utils$1.hash(a.btn.clone().removeClass('focus').prop('outerHTML'))); + + _this2.emit('priorityButton', a.btn); + }, + onBack: function onBack() { + Controller.toggle('content'); + } + }); + } + }).on('hover:focus', function () { + _this2.last = play[0]; + }); + play.toggleClass('hide', !Boolean(btns.length)); + } + }; + + var Start = /*#__PURE__*/function (_Emit) { + _inherits(Start, _Emit); + + var _super = _createSuper(Start); + + function Start(data) { + var _this; + + _classCallCheck(this, Start); + + _this = _super.call(this); + _this.data = data; + _this.card = data.movie; + Arrays.extend(_this.card, { + title: _this.card.name, + original_title: _this.card.original_name, + runtime: 0, + img: _this.card.poster_path ? Api.img(_this.card.poster_path, Storage.field('poster_size')).replace(/\/w\d{1,4}/, '/w500') : './img/img_broken.svg' + }); + Utils$1.canWatchChildren(TMDB.parsePG(data.movie), permit.profile.age) && _this.use(Torrents); + + _this.use(Options); + + _this.use(Subscribed); + + _this.use(Trailers); + + _this.use(Poster); + + _this.use(Translations); + + _this.use(Bookmarks); + + _this.use(Reactions); + + _this.use(Buttons); + + _this.emit('init'); + + return _this; + } + + _createClass(Start, [{ + key: "create", + value: function create() { + var _this2 = this; + + var genres = (this.card.genres || ['---']).slice(0, 3).map(function (a) { + return Utils$1.capitalizeFirstLetter(a.name); + }).join(', '); + var countries = TMDB.parseCountries(this.card); + var seasons = Utils$1.countSeasons(this.card); + var tmdb_rating = parseFloat((this.card.vote_average || 0) + '').toFixed(1); + var relise = (this.card.release_date || this.card.first_air_date || '') + ''; + var year = relise ? relise.slice(0, 4) : ''; + var quality = !this.card.first_air_date ? this.card.release_quality || this.card.quality : false; + var pg = TMDB.parsePG(this.card); + var head = []; + var info = []; + if (tmdb_rating >= 10) tmdb_rating = 10; + this.html = Template.get('full_start_new', { + title: this.card.title, + original_title: this.card.original_title, + descr: Utils$1.substr(this.card.overview || Lang.translate('full_notext'), 420), + time: Utils$1.secondsToTime(this.card.runtime * 60, true), + genres: Utils$1.substr(genres, 30), + rating: tmdb_rating, + seasons: seasons, + countries: countries.join(', '), + episodes: this.card.number_of_episodes, + tagline: this.card.tagline + }); + !window.lampa_settings.torrents_use && this.html.find('.view--torrent').addClass('hide'); + this.card.name && this.html.find('.full-start-new__poster').addClass('card--tv').append('
    TV
    '); + this.card.adult && this.html.find('.full-start-new__poster').addClass('card--adult').append('
    ADULT
    '); + + if (year) { + this.html.find('.tag--year').removeClass('hide').find('> div').text(year); + head.push('' + year + ''); + } + + countries.length && head.push(countries.slice(0, 5).join(' | ')); + !this.card.tagline && this.html.find('.full--tagline').remove(); + if (!this.card.tagline && this.card.title.length > 25) this.html.find('.full-start-new__title').addClass('twolines'); + this.card.runtime > 0 && info.push('' + Utils$1.secondsToTime(this.card.runtime * 60, true) + ''); + seasons && info.push('' + Lang.translate('title_seasons') + ': ' + seasons + ''); + pg && this.html.find('.full-start__pg').removeClass('hide').text(pg); + this.card.number_of_episodes && info.push('' + Lang.translate('title_episodes') + ': ' + this.card.number_of_episodes + ''); + !this.card.runtime && $('.tag--time', this.html).remove(); + this.card.number_of_seasons && this.html.find('.is--serial').removeClass('hide'); + this.card.vote_average == 0 && this.html.find('.rate--tmdb').addClass('hide'); + this.card.status && this.html.find('.full-start__status').removeClass('hide').text(Lang.translate('tv_status_' + this.card.status.toLowerCase().replace(/ /g, '_'))); + + if (this.card.imdb_rating && parseFloat(this.card.imdb_rating) > 0) { + this.html.find('.rate--imdb').removeClass('hide').find('> div').eq(0).text(parseFloat(this.card.imdb_rating) >= 10 ? 10 : this.card.imdb_rating); + } + + if (this.card.kp_rating && parseFloat(this.card.kp_rating) > 0) { + this.html.find('.rate--kp').removeClass('hide').find('> div').eq(0).text(parseFloat(this.card.kp_rating) >= 10 ? 10 : this.card.kp_rating); + } + + if (this.card.genres) { + genres = this.card.genres.slice(0, 5).map(function (a) { + return Utils$1.capitalizeFirstLetter(a.name); + }).join(' | '); + info.push('' + genres + ''); + } + + if (quality) { + this.html.find('.tag--quality').removeClass('hide').find('> div').text(quality); + info.push('' + Lang.translate('player_quality') + ': ' + quality.toUpperCase() + ''); + } + + if (this.card.next_episode_to_air) { + var air = Utils$1.parseToDate(this.card.next_episode_to_air.air_date); + var now = Date.now(); + var day = Math.ceil((air.getTime() - now) / (24 * 60 * 60 * 1000)); + var txt = Lang.translate('full_next_episode') + ': ' + Utils$1.parseTime(this.card.next_episode_to_air.air_date)["short"] + ' / ' + Lang.translate('full_episode_days_left') + ': ' + day; + + if (day > 0) { + $('.tag--episode', this.html).removeClass('hide').find('div').text(txt); + info.push('' + txt + ''); + } + } + + $('.full-start-new__buttons', this.html).find('.selector').on('hover:focus hover:enter hover:hover hover:touch', function (e) { + _this2.last = e.target; + }); + this.html.find('.full-start-new__head').toggleClass('hide', !head.length).html(head.join(', ')); + this.html.find('.full-start-new__details').html(info.join('●')); + if (window.lampa_settings.read_only) this.html.find('.button--play').remove(); + this.emit('create'); + } + }, { + key: "toggle", + value: function toggle() { + var _this3 = this; + + var controller = { + link: this, + toggle: function toggle() { + _this3.emit('groupButtons'); + + Controller.collectionSet(_this3.html); + Controller.collectionFocus(_this3.last || false, _this3.html); + + _this3.emit('toggle'); + }, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else _this3.emit('left'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down');else _this3.emit('down'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else _this3.emit('up'); + }, + back: this.emit.bind(this, 'back') + }; + this.emit('controller', controller); + Controller.add('full_start', controller); + Controller.toggle('full_start'); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html[0] : this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Start; + }(Emit); + + function Warning(params) { + this.params = params; + this.html = Template.get('warning', params); + + if (params.button) { + var button = $('
    ' + (params.button.title || '') + '
    '); + this.html.find('.warning-box__right').toggleClass('hide', false).append(button); + } + + if (params.onSelect) { + this.html.addClass('selector').on('hover:enter', params.onSelect); + } + + this.render = function (js) { + return js ? this.html[0] : this.html; + }; + + this.destroy = function () { + this.html.remove(); + this.html = null; + }; + } + + var Descriptiopn = /*#__PURE__*/function (_Emit) { + _inherits(Descriptiopn, _Emit); + + var _super = _createSuper(Descriptiopn); + + function Descriptiopn(data) { + var _this; + + _classCallCheck(this, Descriptiopn); + + _this = _super.call(this); + _this.data = data; + _this.card = data.movie; + + _this.emit('init'); + + return _this; + } + + _createClass(Descriptiopn, [{ + key: "create", + value: function create() { + var _this2 = this; + + this.html = Template.get('items_line', { + title: Lang.translate('full_detail') + }); + var media = this.card.name ? 'tv' : 'movie'; + var countries = TMDB.parseCountries(this.card); + var date = (this.card.release_date || this.card.first_air_date || '') + ''; + this.body = Template.get('full_descr', { + text: (this.card.overview || Lang.translate('full_notext')) + '

    ', + relise: date.length > 3 ? Utils$1.parseTime(date).full : date.length > 0 ? date : Lang.translate('player_unknown'), + budget: '$ ' + Utils$1.numberWithSpaces(this.card.budget || 0), + countries: countries.join(', ') + }); + var tags = this.body.find('.full-descr__tags'); + + if (this.card.genres.length) { + tags.append(this.tag(Lang.translate('full_genre'), this.card.genres, function (genre) { + Activity.push({ + url: genre.url || media, + title: Utils$1.capitalizeFirstLetter(genre.name), + component: _this2.card.source == 'cub' ? 'category' : 'category_full', + genres: genre.id, + source: _this2.card.source, + page: 1 + }); + })); + } + + if (this.card.production_companies.length) { + tags.append(this.tag(Lang.translate('full_production'), this.card.production_companies, function (company) { + router.call('company', _objectSpread2(_objectSpread2({}, company), {}, { + card: _this2.card + })); + })); + } + + var key_tags = this.card.keywords ? this.card.keywords.results || this.card.keywords.keywords : []; + + if (key_tags.length && key_tags.find) { + var tags_filter = key_tags.filter(function (key) { + return !Keys.adult.find(function (tag) { + return tag.indexOf(key.name.toLowerCase()) >= 0; + }); + }); + tags_filter = tags_filter.filter(function (key) { + return !Keys.lgbt.find(function (tag) { + return tag.indexOf(key.name.toLowerCase()) >= 0; + }); + }); + + if (tags_filter.length) { + tags.append(this.tag(Lang.translate('full_keywords'), tags_filter, function (key) { + Activity.push({ + url: 'discover/' + media, + title: Utils$1.capitalizeFirstLetter(key.name), + keywords: key.id, + component: 'category_full', + source: 'tmdb', + page: 1 + }); + })); + } + } + + if (!this.card.budget) $('.full--budget', this.body).remove(); + if (!countries.length) $('.full--countries', this.body).remove(); + this.body.find('.selector').on('hover:focus hover:enter hover:hover hover:touch', function (e) { + _this2.last = e.target; + }); + + if (this.card.adult) { + var warning = new Warning({ + type: 'full-adult', + title: Lang.translate('adult_content_title'), + text: Lang.translate('adult_content_text_warning'), + icon: '', + button: { + title: Lang.translate('title_watch') + }, + onSelect: function onSelect() { + Modal.open({ + title: Lang.translate('adult_content_title'), + size: 'small', + scroll: { + nopadding: true + }, + html: $('
    ' + Lang.translate('adult_content_text_modal') + '
    '), + buttons: [{ + name: Lang.translate('adult_content_confirm'), + onSelect: function onSelect() { + Modal.close(); + Controller.toggle('full_descr'); + Storage.set('adult_content_view', true); + Lampa.Activity.refresh(); + } + }, { + name: Lang.translate('adult_content_deny'), + onSelect: function onSelect() { + Modal.close(); + Controller.toggle('full_descr'); + } + }], + onBack: function onBack() { + Modal.close(); + Controller.toggle('full_descr'); + } + }); + } + }); + $('.full-descr__left', this.body).append(warning.render()); + } + + this.html.find('.items-line__body').append(this.body); + this.emit('create'); + } + }, { + key: "tag", + value: function tag(name, items, call) { + var _this3 = this; + + var elem = $("
    \n
    ".concat(name, "
    \n
    ").concat(items.length, "
    \n
    ")); + elem.on('hover:enter', function () { + var select = items.map(function (a) { + return { + title: Utils$1.capitalizeFirstLetter(a.name), + elem: a + }; + }); + Select.show({ + title: name, + items: select, + onSelect: function onSelect(a) { + _this3.toggle(); + + call(a.elem); + }, + onBack: function onBack() { + _this3.toggle(); + } + }); + }); + return elem; + } + }, { + key: "toggle", + value: function toggle() { + var _this4 = this; + + var controller = { + link: this, + toggle: function toggle() { + Controller.collectionSet(_this4.render()); + Controller.collectionFocus(_this4.last, _this4.render()); + + _this4.emit('toggle'); + }, + update: function update() {}, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else _this4.emit('left'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down');else _this4.emit('down'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else _this4.emit('up'); + }, + back: this.emit.bind(this, 'back') + }; + this.emit('controller', controller); + Controller.add('full_descr', controller); + Controller.toggle('full_descr'); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html[0] : this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.body.remove(); + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Descriptiopn; + }(Emit); + + function MetadataChart(data) { + var result = { + title: Lang.translate('title_metadata'), + results: [] + }; + var fields = [{ + name: 'humor', + color: '#f7e74a' + }, { + name: 'violence', + color: '#f74a4a' + }, { + name: 'fear', + color: '#e2b2ff' + }, { + name: 'tension', + color: '#45c1ff' + }, { + name: 'romance', + color: '#f74aa3' + }, { + name: 'sadness', + color: '#f7a34a' + }, { + name: 'pace', + color: '#4af74a' + }, { + name: 'importance', + color: '#8ffff6' + }, { + name: 'action', + color: '#ff8124' + }, { + name: 'sex', + color: '#f74af7' + }, { + name: 'profanity', + color: '#ff6262' + }]; + var chart_data = data.metadata.review || []; + chart_data.forEach(function (meter) { + var _fields$find; + + var color = ((_fields$find = fields.find(function (f) { + return f.name == meter.name; + })) === null || _fields$find === void 0 ? void 0 : _fields$find.color) || '#fff'; + var chart = { + bars: meter.values.map(function (v) { + return (v || 0) / 10 * 100; + }), + threshold: 70, + threshold_color: color + }; + meter.title = Lang.translate('title_meta_' + meter.name); + meter.limit = 10; + meter.count = meter.avg; + meter.icon = ''; + meter.chart = chart; + }); + result.results = chart_data; + Utils$1.extendItemsParams(result.results, { + module: Helper$8.toggle(Helper$8.MASK.base, 'Line', 'Chart', 'Icon'), + createInstance: function createInstance(item) { + return new Register(item); + } + }); + var comp = Utils$1.createInstance(Line$4, result, { + module: Helper$b.only('Items', 'Create') + }); + return comp; + } + + function MetadataTags(data) { + var meter = { + title: Lang.translate('title_moods'), + results: [], + params: { + items: { + view: 10 + } + } + }; + var chart_data = data.metadata.moods || []; + chart_data.slice(0, 10).forEach(function (key) { + meter.results.push({ + title: Utils$1.capitalizeFirstLetter(key.name), + count: key.percent + '%' + }); + }); + Utils$1.extendItemsParams(meter.results, { + module: Helper$8.toggle(Helper$8.MASK.base, 'Line', 'Tag'), + createInstance: function createInstance(item) { + return new Register(item); + } + }); + var comp = Utils$1.createInstance(Line$4, meter, { + module: Helper$b.only('Items', 'Create') + }); + return comp; + } + + var Line$2 = { + onCreate: function onCreate() { + var _this = this; + + this.data.role = this.data.character || this.data.job || Lang.translate('title_actor'); + this.html = Template.js('full_person', this.data); + this.html.on('visible', function () { + Utils$1.imgLoad(_this.html.find('img'), _this.data.profile_path ? TMDB.img(_this.data.profile_path, 'w276_and_h350_face') : _this.data.img || './img/actor.svg', function () { + _this.html.addClass('full-person--loaded'); + }); + }); + } + }; + + var About$1 = { + onCreate: function onCreate() { + var _this = this; + + this.html = Template.js('person_start', { + name: this.data.name, + birthday: this.data.birthday ? Utils$1.parseTime(this.data.birthday).full : Lang.translate('player_unknown'), + place: this.data.place_of_birth || Lang.translate('player_unknown') + }); + this.prefix = Template.prefix(this.html, 'person-start'); + this.subscribed = Storage.get('person_subscribes_id', '[]').find(function (a) { + return a == _this.data.id; + }); + Utils$1.imgLoad(this.prefix.img, this.data.profile_path ? TMDB.img(this.data.profile_path, 'w500') : this.data.img || 'img/img_broken.svg', function (img) { + img.addClass('loaded'); + }); + if (window.lampa_settings.account_use) this.emit('subscribe', this.subscribed); + this.html.find('.button--info').on('hover:enter', function () { + if (_this.data.biography) { + Modal.open({ + title: _this.data.name, + size: 'large', + html: $('
    ' + _this.data.biography.replace(/\n/g, '
    ') + '
    '), + onBack: function onBack() { + Modal.close(); + Controller.toggle('content'); + } + }); + } else { + Noty.show(Lang.translate('empty_title_two')); + } + }).on('hover:focus hover:enter hover:hover', function (e) { + _this.last = e.target; + }); + + if (window.lampa_settings.account_use) { + this.html.find('.button--subscribe').on('hover:enter', function () { + if (!Account$1.Permit.access) return Account$1.Modal.account(); + var subscribes = Storage.get('person_subscribes_id', '[]'); + _this.subscribed = subscribes.find(function (a) { + return a == _this.data.id; + }); + if (!_this.subscribed && !Account$1.hasPremium()) return Account$1.Modal.premium(); + var person = Arrays.clone(_this.data); // Пихают там всякие иконки и прочее, удаляем лишнее + + delete person.biography; + Lampa.Network.silent(Utils$1.protocol() + object$2.cub_domain + '/api/person/' + (_this.subscribed ? 'unsubscribe' : 'subscribe'), function () { + if (_this.subscribed) Arrays.remove(subscribes, _this.data.id);else if (subscribes.indexOf(_this.data.id) == -1) subscribes.push(_this.data.id); + Storage.set('person_subscribes_id', subscribes); + _this.subscribed = subscribes.find(function (a) { + return a == _this.data.id; + }); + + _this.emit('subscribe', _this.subscribed); + }, function (err) { + if (err.responseJSON && err.responseJSON.code == 555) Account$1.Modal.premium();else Noty.show(Lang.translate('subscribe_error')); + }, { + person: JSON.stringify(person) + }, { + headers: { + token: Account$1.Permit.token + } + }); + }).on('hover:focus hover:enter hover:hover', function (e) { + _this.last = e.target; + }); + } else this.html.find('.button--subscribe').remove(); + }, + onSubscribe: function onSubscribe(subscribed) { + this.html.find('.button--subscribe svg path:nth-of-type(2)').setAttribute('fill', subscribed ? 'currentColor' : 'transparent'); + this.html.find('.button--subscribe span').text(Lang.translate(subscribed ? 'title_unsubscribe' : 'title_subscribe')); + } + }; + + var PersonMap = { + Line: Line$2, + About: About$1, + Callback: Callback$1 + }; + + var Person = /*#__PURE__*/function (_Constructor) { + _inherits(Person, _Constructor); + + var _super = _createSuper(Person); + + function Person() { + _classCallCheck(this, Person); + + return _super.apply(this, arguments); + } + + return Person; + }(Constructor(PersonMap)); + + var Helper$6 = new Mask(Arrays.getKeys(PersonMap)); + Helper$6.MASK.base = Helper$6.MASK.none; + + function Persons(data) { + Utils$1.extendItemsParams(data.results, { + module: Helper$6.toggle(Helper$6.MASK.base, 'Line', 'Callback'), + createInstance: function createInstance(item) { + return new Person(item); + }, + emit: { + onEnter: function onEnter(html, item) { + router.call('actor', item); + } + } + }); + var comp = Utils$1.createInstance(Line$4, data, { + module: Helper$b.only('Items', 'Create') + }); + return comp; + } + + var Line$1 = { + onCreate: function onCreate() { + var _this = this; + + var text = (this.data.text || this.data.comment) + ''; + text = Utils$1.capitalizeFirstLetter(!this.params.line.full_text && text.length > 120 ? text.slice(0, 120) + '...' : text); + this.html = Template.js('full_review', _objectSpread2(_objectSpread2({}, this.data), {}, { + text: text + })); + if (this.data.liked < 0) this.html.addClass('bad--comment'); + if (this.params.line.full_text) this.html.addClass('full-review--full-text'); + + if (this.data.email) { + var who = Template.elem('div', { + "class": 'full-review__user', + children: [Template.elem('div', { + "class": 'full-review__user-icon', + children: [Template.elem('img', { + "class": 'full-review__user-img' + })] + }), Template.elem('div', { + "class": 'full-review__user-email', + text: Utils$1.capitalizeFirstLetter(this.data.email) + })] + }); + var like = Template.elem('div', { + "class": 'full-review__like', + children: [Template.elem('div', { + "class": 'full-review__like-icon', + children: [Template.js('icon_like')] + }), Template.elem('div', { + "class": 'full-review__like-counter', + text: this.data.liked || '0' + })] + }); + this.html.find('.full-review__footer').html(who).append(like); + this.html.on('visible', function () { + var img = who.find('img'); + Utils$1.imgLoad(img, Utils$1.protocol() + object$2.cub_domain + '/img/profiles/' + _this.data.icon + '.png', function () { + who.addClass('loaded'); + }, function () { + img.src = './img/actor.svg'; + }); + }); + } + }, + onUpdateLiked: function onUpdateLiked(add) { + this.data.liked = (this.data.liked || 0) + add; + this.html.find('.full-review__like-counter').text(this.data.liked); + } + }; + + function containsLongWords(str) { + var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 15; + var any = false; + str.split(/\s/).map(function (a) { + if (a.length >= length) any = true; + }); + return any; + } + + function containsFiveWords(str) { + var words = str.split(/\s/); + var count = 0; + words.map(function (a) { + if (a.length >= 5) count++; + }); + return count; + } + + function filter(text) { + var err = 0; + if (/\d{4,}/g.test(text)) err = 1;else if (!/[а-яА-ЯёЁ]{5,}/.test(text)) err = 2;else if (!/[.,:;!?]/.test(text)) err = 3;else if (/[*%$#_+=|^&]/.test(text)) err = 4;else if (containsFiveWords(text) < 5) err = 5;else if (containsLongWords(text)) err = 6;else if (text.length > 300) err = 7; + return err; + } + + var Add = { + onCreate: function onCreate() { + var _this = this; + + this.html = Template.elem('div', { + "class": 'full-review-add selector' + }); + this.html.on('hover:enter', function () { + if (_this.added) return Noty.show(Lang.translate('account_discuss_added_ready')); + + if (Account$1.Permit.access) { + var add_value = ''; + var controller = Controller.enabled().name; + + if (Platform.tv()) { + var html = Template.js('modal_qr', { + qr_text: Lang.translate('account_discuss_add_qr'), + title: Lang.translate('account_discuss_add_title') + }); + html.addClass('layer--' + (Platform.mouse() ? 'wheight' : 'height')); + html.find('.account-modal-split__text').html(Lang.translate('account_discuss_add_text')); + var code = html.find('.account-modal-split__qr-code'); + var url = [Activity.active().source, Activity.active().method, Activity.active().id].join('/'); + Utils$1.qrcode('https://' + object$2.cub_site + '/addcomment/' + url, code, function () { + code.remove(); + }); + Modal.open({ + title: '', + html: $(html), + size: 'full', + scroll: { + nopadding: true + }, + onBack: function onBack() { + Modal.close(); + Controller.toggle(controller); + } + }); + } else { + var rules_html = Template.js('discuss_rules'); + document.body.append(rules_html); + var keyboard = Input.edit({ + title: '', + value: add_value, + nosave: true, + textarea: true, + align: Platform.screen('mobile') ? 'top' : 'center', + keyboard: 'integrate' + }, function (new_value) { + rules_html.remove(); + add_value = new_value; + + if (new_value) { + Account$1.Api.load('discuss/add', {}, { + id: [Activity.active().method, Activity.active().id].join('_'), + comment: new_value, + lang: Storage.field('language') + }).then(function (data) { + _this.added = true; + Bell.push({ + text: Lang.translate('account_discuss_added') + }); + })["catch"](function (e) { + Noty.show(Lampa.Network.errorJSON(e).text || Lang.translate('network_500'), { + time: 5000 + }); + }); + } + + Controller.toggle(controller); + }); + var keypad = $('.simple-keyboard'); + var helper = $('
    '); + + if (keypad.find('.simple-keyboard-input').length) { + keypad.after(helper); + keyboard.listener.follow('change', function (event) { + var code = filter(event.value.trim()); + helper.toggleClass('hide', !Boolean(code)).text(Lang.translate('discuss_rules_rule_' + code)); + }); + } + } + } else { + Account$1.Modal.account(); + } + }); + } + }; + + var Read = { + onCreate: function onCreate() { + var _this = this; + + this.html.on('hover:enter', function () { + var items = []; + var voited = Storage.cache('discuss_voited', 100, []); + var contoller = Controller.enabled().name; + + if (voited.indexOf(_this.data.id) == -1 && Account$1.Permit.access) { + items = [{ + separator: true, + title: Lang.translate('title_action') + }, { + title: '+1 ' + Lang.translate('title_like'), + like: 1 + }, { + title: Lang.translate('reactions_shit'), + like: -1 + }]; + } + + Select.show({ + title: Utils$1.capitalizeFirstLetter(_this.data.email), + items: items, + onFullDraw: function onFullDraw(select_scroll) { + if (_this.params.line.full_text) return; + select_scroll.body(true).prepend(Template.elem('div', { + "class": 'selectbox__text selector', + children: [Template.elem('div', { + text: Utils$1.capitalizeFirstLetter(_this.data.comment) + })] + })); + }, + onSelect: function onSelect(item) { + Controller.toggle(contoller); + Account$1.Api.load('discuss/voite', {}, { + id: _this.data.id, + like: item.like + }).then(function () { + Storage.add('discuss_voited', _this.data.id); + + _this.emit('updateLiked', item.like); + + Bell.push({ + text: Lang.translate('discuss_voited') + }); + })["catch"](function () {}); + }, + onBack: function onBack() { + Controller.toggle(contoller); + } + }); + }); + } + }; + + var DiscussMap = { + Line: Line$1, + Add: Add, + Read: Read, + Callback: Callback$1 + }; + + var Discuss = /*#__PURE__*/function (_Constructor) { + _inherits(Discuss, _Constructor); + + var _super = _createSuper(Discuss); + + function Discuss(data) { + var _this; + + _classCallCheck(this, Discuss); + + _this = _super.call(this, data); + Arrays.extend(data.params, { + line: { + full_text: false + } + }); + return _this; + } + + return Discuss; + }(Constructor(DiscussMap)); + + var Helper$5 = new Mask(Arrays.getKeys(DiscussMap)); + Helper$5.MASK.base = Helper$5.only('Callback'); + + function Discussions(data) { + Utils$1.extendItemsParams(data.results, { + module: Helper$5.only('Line', 'Read'), + createInstance: function createInstance(item) { + return new Discuss(item); + } + }); + Arrays.insert(data.results, 0, { + params: { + module: Helper$5.only('Add'), + createInstance: function createInstance(item) { + return new Discuss(item); + } + } + }); + var comp = Utils$1.createInstance(Line$4, data, { + module: Helper$b.only('Items', 'Create', 'More') + }); + comp.use({ + onMore: router.call.bind(router, 'discuss', data.movie) + }); + return comp; + } + + function Episodes(data) { + Utils$1.extendItemsParams(data.results, { + module: Helper$a.only('Small', 'Mark', 'Callback'), + createInstance: function createInstance(item) { + return new Episode(item); + } + }); + data.results.reverse(); + data.results.filter(function (e) { + return e.comeing; + }).forEach(function (e) { + e.params.module = Helper$a.only('SmallNext'); + }); + + if (!data.results.length) { + data.results.push({ + episode_number: 1, + season_number: data.movie.number_of_seasons || 1, + air_date: '', + name: Lang.translate('title_anons'), + comeing: true, + params: { + module: Helper$a.only('SmallNext'), + createInstance: function createInstance(item) { + return new Episode(item); + } + } + }); + } + + var comp = Utils$1.createInstance(Line$4, data, { + module: Helper$b.only('Items', 'Create', 'MoreFirst') + }); + comp.use({ + onMore: router.call.bind(router, 'episodes', data.movie) + }); + return comp; + } + + function Cards(data) { + var comp = Utils$1.createInstance(Line$4, data, { + module: Helper$b.toggle(Helper$b.MASK.base, 'More') + }); + comp.use({ + onInstance: function onInstance(item, data) { + item.use({ + onEnter: router.call.bind(router, 'full', data) + }); + } + }); + return comp; + } + + var components = { + start: Start, + description: Descriptiopn, + metadata_chart: MetadataChart, + metadata_tags: MetadataTags, + persons: Persons, + cards: Cards, + discuss: Discussions, + episodes: Episodes + }; + /** + * Компонент "Карточка фильма/сериала" + * @param {*} object + */ + + function component$m(object) { + var comp = Utils$1.createInstance(Full$1, object, { + module: Helper$7.only('Items', 'Empty', 'Callback'), + empty: { + cub_button: true + } + }); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + this.tv = Platform.screen('tv'); + this.view = 3; + this.rows = ['start', 'description']; + this.html.addClass('layer--wheight'); + Api.full(object, function (data) { + if (!data.movie) return _this.emit('error', { + empty: true + }); // Добавляем в пропсы данные + + _this.props.set(data); // Проверяем по ключевым словам, есть ли в фильме ЛГБТ тематика + + + var key_tags = data.movie.keywords ? data.movie.keywords.results || data.movie.keywords.keywords : []; + var lgbt_block = Storage.field('lgbt_content_block') || vpn.is(['ru', 'by']); + + if (lgbt_block && key_tags && key_tags.find && key_tags.length && window.lampa_settings.lgbt) { + Keys.lgbt.forEach(function (keyword) { + if (key_tags.find(function (k) { + return k.name.toLowerCase() == keyword; + })) data.movie.lgbt = 'keyword (' + keyword + ')'; + }); + } // Если фильм не помечен как ЛГБТ, но есть в списке блокировки ЛГБТ, то помечаем его + + + if (lgbt_block && window.lampa_settings.lgbt && !data.movie.lgbt) { + if (window.lampa_settings.lgbt[data.movie.id + '_' + (data.movie.first_air_date ? 'tv' : 'movie')]) data.movie.lgbt = 'list'; + } + + if (data.movie.blocked || data.movie.lgbt) return _this.emit('error', { + blocked: true, + lgbt: data.movie.lgbt + }); // Для плагинов которые используют Activity.active().card + + object.card = data.movie; // Проверяем можно ли показывать полную карточку детям + + var watch = Utils$1.canWatchChildren(TMDB.parsePG(data.movie), permit.profile.age); // Ищем по ключевым словам, есть ли в фильме тематика для взрослых + + var adult_block = key_tags && key_tags.find && key_tags.length ? key_tags.find(function (key) { + return Keys.adult.find(function (word) { + return key.name.toLowerCase().indexOf(word) >= 0; + }); + }) : false; + if (Storage.field('adult_content_view')) adult_block = false; // Если фильм помечен как для взрослых, то добавляем это в данные фильма + + if (adult_block) data.movie.adult = true; // Отправляем событие, что началась загрузка полной карточки + + if (watch) Lampa.Listener.send('full', { + link: _this, + type: 'start', + props: _this.props, + body: $(_this.html), + object: object, + data: data + }); + + if (data.metadata && data.metadata && data.metadata.status && data.metadata.status == 'completed') { + _this.rows.push(['metadata_chart', { + movie: data.movie, + metadata: data.metadata + }]); + + if (Lang.selected(['ru', 'uk', 'be'])) { + _this.rows.push(['metadata_tags', { + movie: data.movie, + metadata: data.metadata + }]); + } + } // Создаем эпизоды + + + if (!adult_block && data.episodes && data.episodes.episodes) { + var episodes = data.episodes.episodes; // Если сериал многосезонный, то выбираем нужный сезон + + if (data.episodes.seasons_count && data.episodes.seasons_count > 1 && data.episodes.episodes_original) { + // Парсим эпизоды по сезонам + var seasons = Utils$1.splitEpisodesIntoSeasons(data.episodes.episodes_original); // Выбираем нужный сезон + + episodes = seasons[data.episodes.seasons_count] || seasons[1]; // Сохраняем номер сезона + + data.episodes.name = Lang.translate('torrent_serial_season') + ' ' + data.episodes.seasons_count; + } + + var today = new Date(); + var date = [today.getFullYear(), today.getMonth() + 1, today.getDate()].join('-'); + var time = Utils$1.parseToDate(date).getTime(); + var cameout = episodes.filter(function (a) { + return a.air_date; + }).filter(function (e) { + return Utils$1.parseToDate(e.air_date).getTime() <= time; + }); + var comeing = episodes.filter(function (a) { + return a.air_date; + }).filter(function (e) { + return Utils$1.parseToDate(e.air_date).getTime() > time; + }); + comeing.forEach(function (e) { + return e.comeing = true; + }); + if (comeing.length) cameout = cameout.concat(comeing.slice(0, 1)); + cameout.forEach(function (episode) { + return episode.original_name = data.movie.original_name || data.movie.name; + }); + + _this.rows.push(['episodes', { + movie: data.movie, + title: data.episodes.name || Lang.translate('full_series_release'), + results: cameout + }]); + } // Создаем режиссеров + + + if (!adult_block && data.persons && data.persons.crew && data.persons.crew.length) { + var directors = data.persons.crew.filter(function (member) { + return member.job === 'Director'; + }); + directors.length && _this.rows.push(['persons', { + results: directors, + title: Lang.translate('title_producer') + }]); + } // Создаем актеров + + + if (!adult_block && data.persons && data.persons.cast && data.persons.cast.length) _this.rows.push(['persons', { + results: data.persons.cast, + title: Lang.translate('title_actors') + }]); // Создаем отзывы + + if (!adult_block && data.discuss) Arrays.insert(_this.rows, data.discuss.result.length ? 2 : _this.rows.length, ['discuss', _objectSpread2(_objectSpread2({}, data.discuss), {}, { + movie: data.movie, + title: Lang.translate('title_comments'), + results: data.discuss.result || [] + })]); // Создаем коллекцию + + if (!adult_block && data.collection && data.collection.results && data.collection.results.length) { + data.collection.title = Lang.translate('title_collection'); // Сортируем по году от меньшего к большему + + data.collection.results.sort(function (a, b) { + var yearA = a.release_date ? a.release_date.split('-')[0] : a.first_air_date ? a.first_air_date.split('-')[0] : '0'; + var yearB = b.release_date ? b.release_date.split('-')[0] : b.first_air_date ? b.first_air_date.split('-')[0] : '0'; + return parseInt(yearA) - parseInt(yearB); + }); + + _this.rows.push(['cards', data.collection]); + } // Создаем рекомендации + + + if (!adult_block && data.recomend && data.recomend.results && data.recomend.results.length) { + data.recomend.title = Lang.translate('title_recomendations'); + + _this.rows.push(['cards', data.recomend]); + } // Создаем похожие + + + if (!adult_block && data.simular && data.simular.results && data.simular.results.length) { + data.simular.title = Lang.translate('title_similar'); + + _this.rows.push(['cards', data.simular]); + } // Добавляем картинку для фона + + + _this.html.prepend(Template.elem('img', { + "class": 'full-start__background' + })); // Добавляем фоновую картинку + + + var background = data.movie.backdrop_path ? Api.img(data.movie.backdrop_path, 'w1280') : data.movie.background_image ? data.movie.background_image : ''; + + if (window.innerWidth > 790 && background && !Storage.field('light_version')) { + Utils$1.imgLoad(_this.html.find('.full-start__background'), background, function (img) { + return img.addClass('loaded'); + }); + } else _this.html.find('.full-start__background').remove(); // Создаем все компоненты + + + _this.build(_this.rows.slice(0, _this.view)); // Обновляем расписание + + + TimeTable.update(data.movie); // Отправляем событие, что полная карточка загружена + + if (watch) Lampa.Listener.send('full', { + link: _this, + type: 'complite', + props: _this.props, + body: $(_this.html), + object: object, + data: data + }); + + _this.activity.loader(false); // Группируем кнопки после полной загрузки + + + if (_this.items.length) _this.items[0].emit('groupButtons'); + + _this.activity.toggle(); + }, this.emit.bind(this, 'error')); + }, + onBuild: function onBuild() { + this.scroll.onScroll = this.emit.bind(this, 'scroll'); // Для планшетов в вертикальном режиме принудительно вызываем скролл + + if (!this.tv) this.emit('scroll', 0); + }, + onStart: function onStart() { + this.props.get('movie') && Background.immediately(Utils$1.cardImgBackgroundBlur(this.props.get('movie'))); + }, + onScroll: function onScroll(position) { + var _this$html$find; + + var size = this.tv ? Math.min(this.active + this.view, this.rows.length) : this.rows.length; + var add = this.rows.slice(this.items.length, size); + + if (add.length) { + this.fragment = document.createDocumentFragment(); + add.forEach(this.emit.bind(this, 'createAndAppend')); + this.scroll.append(this.fragment); + } + + (_this$html$find = this.html.find('.full-start__background')) === null || _this$html$find === void 0 ? void 0 : _this$html$find.toggleClass('dim', position > 0); + Layer.visible(this.scroll.render()); + }, + onCreateAndAppend: function onCreateAndAppend(component) { + var name = Arrays.isArray(component) ? component[0] : component; + var data = Arrays.isArray(component) ? component[1] : this.props.all(); + var item = new components[name](data); + this.emit('instance', item); + item.create(); + this.emit('append', item); // Отправляем событие, что компонент создан + + Lampa.Listener.send('full', { + link: this, + type: 'build', + props: this.props, + body: $(this.html), + name: name, + item: item, + data: data + }); + }, + onError: function onError(status) { + var params = this.params.empty; + var dmca = Utils$1.dcma(this.object.method, this.object.id); + var lgbt = this.props.get('movie') && this.props.get('movie').lgbt; + + if (dmca || status.blocked) { + params.title = Lang.translate('dmca_title'); + params.descr = Lang.translate('dmca_descr'); + params.noicon = true; + } + + params.info_button = [['Movie id', this.object.id], ['DMCA', dmca ? 'Yes' : 'No'], ['LGBT', lgbt ? 'Yes, ' + lgbt : 'No']]; + + if (lgbt) { + params.title = Lang.translate('dmca_title_lgbt'); + params.descr = Lang.translate('dmca_descr_lgbt'); + params.info_button.push(['Title', this.props.get('movie').title || this.props.get('movie').name || '---']); + } // Вызываем пустой экран + + + this.empty(status); + } + }); // Переопределяем билд + + comp.build = function (data) { + this.emit('build', data); + }; + + return comp; + } + + var Base = /*#__PURE__*/function (_Emit) { + _inherits(Base, _Emit); + + var _super = _createSuper(Base); + + function Base(object) { + var _this; + + _classCallCheck(this, Base); + + _this = _super.call(this); + Arrays.extend(object, { + params: {} + }); + _this.object = object; + _this.params = object.params; + _this.scroll = new Scroll({ + mask: true, + over: true, + step: 250, + end_ratio: 2 + }); + _this.html = document.createElement('div'); + _this.body = document.createElement('div'); + return _this; + } + + _createClass(Base, [{ + key: "create", + value: function create() { + var _this2 = this; + + this.activity.loader(true); + this.scroll.minus(); + + this.scroll.onWheel = function (step) { + if (!Controller.own(_this2)) _this2.start(); + Navigator.move(step > 0 ? 'down' : 'up'); + }; + + this.scroll.append(this.body); + this.html.append(this.scroll.render(true)); + this.emit('create'); + } + }, { + key: "build", + value: function build(data) { + this.emit('build', data); + this.activity.loader(false); + this.activity.toggle(); + } + }, { + key: "empty", + value: function empty(status) { + this.scroll.nopadding(); + this.emit('empty', status); + this.activity.loader(false); + this.activity.toggle(); + } + }, { + key: "start", + value: function start() { + var _this3 = this; + + this.emit('start'); + var controller = { + link: this, + invisible: true, + toggle: function toggle() { + _this3.scroll.restorePosition(); + + Controller.collectionSet(_this3.scroll.render(true)); + if (Platform.screen('tv')) Controller.collectionFocus(_this3.last || false, _this3.scroll.render(true)); + + _this3.emit('toggle'); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + right: function right() { + if (Navigator.canmove('right')) Navigator.move('right');else _this3.emit('right'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down'); + }, + back: function back() { + Activity.backward(); + } + }; + this.emit('controller', controller); + Controller.add('content', controller); + Controller.toggle('content'); + } + }, { + key: "pause", + value: function pause() { + this.emit('pause'); + } + }, { + key: "resize", + value: function resize() { + this.emit('resize'); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html : $(this.html); + } + }, { + key: "destroy", + value: function destroy() { + this.scroll.destroy(); + this.html.remove(); + this.body.remove(); + this.emit('destroy'); + } + }]); + + return Base; + }(Emit); + + var Items = { + onInit: function onInit() { + this.items = []; + this.pages = {}; + this.active = 0; + this.added = 0; + this.screen = Platform.screen('tv'); + this.loaded = []; + Arrays.extend(this.params, { + items: { + mapping: 'grid', + cols: 6, + limit_view: 6, + limit_collection: 36 + } + }); + this.total_pages = 1; + this.limit_view = this.params.items.limit_view; + this.limit_collection = this.params.items.limit_collection; + }, + onCreate: function onCreate() { + var _this = this; + + this.scroll.onScroll = this.emit.bind(this, 'scroll'); + + this.scroll.onAnimateEnd = function () { + // Скрываем/показываем страницы + _this.emit('pageView'); // Обновляем навигатор + + + _this.emit('scroll'); + }; + + this.body.addClass('mapping--' + this.params.items.mapping); + this.params.items.mapping == 'grid' && this.body.addClass('cols--' + this.params.items.cols); + }, + onAppend: function onAppend(item, element) { + var _this2 = this; + + var render = item.render(true); + render.on('hover:touch hover:enter hover:focus', function () { + _this2.last = render; + _this2.active = _this2.items.indexOf(item); + }); + render.on('hover:focus', function () { + _this2.scroll.update(render, _this2.params.items.mapping == 'list'); + }); + + if (element.params.on && _typeof(element.params.on) == 'object') { + var _loop = function _loop(e) { + render.on(e, function () { + element.params.on[e].call(_this2, item, element); + }); + }; + + for (var e in element.params.on) { + _loop(e); + } + } + + this.frament.appendChild(render); + this.items.push(item); + this.added++; + var page = Math.ceil(this.added / 60); // 60 - количество элементов на странице + + if (!this.pages[page]) this.pages[page] = { + items: [] + }; + this.pages[page].items.push(item); + }, + onBuild: function onBuild(data) { + if (!data.results.length) return this.empty(); + this.total_pages = data.total_pages || 1; + this.loaded.push(data.results); + this.emit('pushLoaded'); + this.emit('scroll'); + }, + onPushLoaded: function onPushLoaded() { + var add = this.loaded.shift(); + + if (add && add.length) { + this.frament = document.createDocumentFragment(); + add.forEach(this.emit.bind(this, 'createAndAppend')); + this.body.append(this.frament); + } + }, + onPageView: function onPageView() { + var item = this.items[this.active]; + var page = 1; + var anyscroll; + var item_position = 0; + var scroll_position = this.screen ? 0 : this.scroll.render(true).scrollTop; + + if (item) { + for (var p in this.pages) { + this.pages[p].items.find(function (i) { + return i.data == item.data; + }) && (page = p); + } + } // Надо получить позицию до изменений + + + if (this.last) item_position = this.screen ? this.last.getBoundingClientRect().top : this.last.offsetTop; + + for (var _p in this.pages) { + var current = this.pages[_p]; + var visible = _p >= page - 1 && _p - 1 <= page; // Если страница видна, но была удалена, то вставляем её обратно + + if (visible && current.removed) { + (function () { + current.removed = false; + var frag = document.createDocumentFragment(); + current.items.forEach(function (i) { + return frag.appendChild(i.render(true)); + }); + current.items.forEach(function (i) { + return i.render(true).style.visibility = 'visible'; + }); + current.placeholder.replaceWith(frag); + current.placeholder = null; + anyscroll = true; + })(); + } // Если страница не видна, то удаляем её из DOM + else if (!visible && !current.removed) { + current.removed = true; + current.placeholder = document.createElement('div'); + current.placeholder.style.display = 'none'; // current.items[0] Почему-то не всегда есть, баг на webos + + if (current.items[0] && current.items[0].render(true)) current.items[0].render(true).after(current.placeholder); + current.items.forEach(function (i) { + return i.render(true).remove(); + }); + anyscroll = true; + } + } // Если было удаление или добавление страниц, то надо подвинуть скролл + + + if (anyscroll && this.last) { + if (this.screen) { + this.scroll.shift(this.last.getBoundingClientRect().top - item_position); + } else { + this.scroll.render(true).scrollTop = scroll_position + (this.last.offsetTop - item_position); + } + } + }, + onScroll: function onScroll() { + // Грузим элементы которые ожидают своей очереди + this.emit('pushLoaded'); + + if (Controller.own(this)) { + Navigator.setCollection(this.items.slice(Math.max(0, this.active - this.limit_collection), this.active + this.limit_collection).map(function (c) { + return c.render(true); + })); + Navigator.focused(this.last); + } + + Layer.visible(this.scroll.render(true)); + }, + onResize: function onResize() { + if (this.last) this.scroll.update(this.last, this.params.items.mapping == 'list'); + }, + onDestroy: function onDestroy() { + Arrays.destroy(this.items); + this.pages = {}; + this.items = []; + this.loaded = []; + } + }; + + var Create = { + onCreateAndAppend: function onCreateAndAppend(element) { + try { + var item = Utils$1.createInstance(Card$3, element); + this.emit('instance', item, element); + item.create(); + this.emit('append', item, element); + } catch (e) { + console.warn('Warning', 'onCreateAndAppend error:', e.message, e.stack); + } + } + }; + + var Next = { + onInit: function onInit() { + this.next_wait; + this.builded_time = Date.now(); + }, + onBuild: function onBuild() { + this.scroll.onEnd = this.emit.bind(this, 'loadNext'); + this.builded_time = Date.now(); + }, + onLoadNext: function onLoadNext() { + var _this = this; + + if (!this.next_wait && this.items.length && this.builded_time < Date.now() - 1000 && this.object.page < this.total_pages) { + this.next_wait = true; + this.object.page++; + this.emit('next', function (new_data) { + _this.next_wait = false; + if (!_this.items.length || _this.destroyed) return; + var split_total = Math.ceil(new_data.results.length / _this.limit_view); // Разбиваем на части, чтобы не лагал браузер + + for (var i = 0; i < split_total; i++) { + _this.loaded.push(new_data.results.slice(i * _this.limit_view, (i + 1) * _this.limit_view)); + } // Если нет анимации у скрола, то можно грузить сразу + + + if (!_this.scroll.animated()) _this.scroll.onAnimateEnd();else _this.emit('scroll'); + }, function () { + _this.next_wait = false; + }); + } + } + }; + + /** + * Исследователь + * @param {object} object - объект с параметрами + * @param {object} object.movie - информация о фильме/сериале + * @param {string} object.source - источник фильма/сериала + * @param {boolean} object.params.noinfo - не показывать информацию о фильме/сериале + * @returns {Explorer} - экземпляр класса Explorer + */ + + var Explorer$1 = /*#__PURE__*/function (_Emit) { + _inherits(Explorer, _Emit); + + var _super = _createSuper(Explorer); + + function Explorer(object) { + var _this; + + _classCallCheck(this, Explorer); + + _this = _super.call(this); + Arrays.extend(object, { + params: {} + }); + _this.object = object; + _this.params = object.params || {}; + _this.html = Template.get('explorer', {}); + _this.scroll = new Scroll({ + mask: true, + over: true + }); + _this.card = _this.html.find('.explorer__card').clone(); + + _this.html.find('.explorer__left').empty().append(_this.scroll.render()); + + _this.html.find('.explorer__files-head').toggleClass('hide', true); + + _this.scroll.append(_this.card); + + _this.scroll.minus(); + + _this.movie(); + + _this.emit('init'); + + return _this; + } + + _createClass(Explorer, [{ + key: "movie", + value: function movie() { + var _this2 = this; + + var movie = this.object.movie || this.object.card || {}; + Arrays.extend(movie, { + title: 'Фильм не найден', + original_title: '', + img: './img/img_broken.svg', + genres: [{ + name: 'Комедия' + }, { + name: 'Боевик' + }, { + name: 'Драма' + }], + overview: 'Этот фильм мог бы быть интересным, но, к сожалению, нет данных о нём.', + vote_average: 8, + production_countries: [{ + iso_3166_1: 'US' + }] + }); + + if (movie.id) { + this.html.find('.selector').on('hover:enter', function () { + if (Activity.all().length > 1) { + Activity.back(); + } else { + Activity.push({ + url: movie.url, + component: 'full', + id: movie.id, + method: movie.name ? 'tv' : 'movie', + card: movie, + source: movie.source || _this2.object.source || 'tmdb' + }); + } + }); + } + + var year = ((movie.release_date || movie.first_air_date || new Date().getFullYear() + '-01-01') + '').slice(0, 4); + var pg = TMDB.parsePG(movie); + var countries = TMDB.parseCountries(movie); + var rate = parseFloat((movie.vote_average || 0) + ''); + var title = movie.title || movie.name || ''; + var genres = (movie.genres || [{ + name: '' + }]).slice(0, 3).map(function (a) { + return Utils$1.capitalizeFirstLetter(a.name); + }); + this.html.find('.explorer-card__head-create').text(year + (countries.length ? ' - ' + countries[0] : '')).toggleClass('hide', Boolean(year == '0000')); + this.html.find('.explorer-card__head-rate').toggleClass('hide', !Boolean(rate > 0)).find('span').text(rate.toFixed(1)); + this.html.find('.explorer-card__title').text(title).toggleClass('small', Boolean(title.length > 50)); + this.html.find('.explorer-card__descr').text(movie.overview || ''); + this.html.find('.explorer-card__genres').text(genres.join(', ')); + if (pg) this.html.find('.explorer-card__head-body').append('
    ' + pg + '
    '); + if (this.params.noinfo) this.html.addClass('explorer--fullsize'); + this.img = this.html.find('.explorer-card__head-img > img')[0]; + this.img.style.opacity = 0; + + this.img.onload = function () { + _this2.img.style.opacity = 1; + }; + + this.img.onerror = function () { + _this2.img.src = './img/img_broken.svg'; + }; + + this.img.src = movie.poster_path ? TMDB.img(movie.poster_path, 'w300') : movie.img || './img/img_broken.svg'; + this.emit('movie'); + } + }, { + key: "appendFiles", + value: function appendFiles(element) { + this.html.find('.explorer__files-body').append(element); + } + }, { + key: "appendLeft", + value: function appendLeft(element) { + this.scroll.append(element); + } + }, { + key: "appendHead", + value: function appendHead(element) { + this.html.find('.explorer__files-head').append(element).toggleClass('hide', false); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html[0] : this.html; + } + }, { + key: "clearFiles", + value: function clearFiles() { + this.html.find('.explorer__files-body').empty(); + } + }, { + key: "clearLeft", + value: function clearLeft() { + this.scroll.clear(); + } + }, { + key: "clearHead", + value: function clearHead() { + this.html.find('.explorer__files-head').empty().toggleClass('hide', true); + } + }, { + key: "toggle", + value: function toggle() { + var _this3 = this; + + var controller = { + link: this, + toggle: function toggle() { + Controller.collectionSet(_this3.scroll.render(true)); + Controller.collectionFocus(false, _this3.scroll.render(true)); + }, + left: function left() { + Controller.toggle('menu'); + }, + up: function up() { + if (_this3.scroll.position() == 0) Controller.toggle('head');else if (_this3.scroll.position() > -170) { + _this3.scroll.wheel(_this3.scroll.position()); + + Controller.toggle('explorer'); + } else _this3.scroll.wheel(-150); + }, + right: function right() { + Controller.toggle('content'); + }, + down: function down() { + Controller.clear(); + + _this3.scroll.wheel(150); + }, + back: function back() { + Activity.backward(); + } + }; + this.emit('controller', controller); + Controller.add('explorer', controller); + Controller.toggle('explorer'); + } + }, { + key: "destroy", + value: function destroy() { + this.scroll.destroy(); + this.html.remove(); + + this.img.onerror = function () {}; + + this.img.src = ''; + this.emit('destroy'); + } + }]); + + return Explorer; + }(Emit); + + var Explorer = { + onInit: function onInit() { + this.explorer = new Explorer$1(this.object); + }, + onCreate: function onCreate() { + this.explorer.appendFiles(this.scroll.render(true)); + this.scroll.minus(this.explorer.render(true).find('.explorer__files-head')); + this.html.append(this.explorer.render(true)); + }, + onController: function onController(controller) { + var _this = this; + + controller.left = function () { + if (Navigator.canmove('left')) Navigator.move('left');else _this.explorer.toggle(); + }; + }, + onEmpty: function onEmpty() { + var _this2 = this; + + if (this.empty_class) { + this.empty_class.use({ + onController: function onController(controller) { + controller.left = function () { + if (Navigator.canmove('left')) Navigator.move('left');else _this2.explorer.toggle(); + }; + } + }); + } + } + }; + + var Loading = { + onCreate: function onCreate() { + this.activity.loader(false); + Arrays.extend(this.params, { + loading: { + icon: 'card' + } + }); + var tpl = Template.get('ai_search_animation', { + icon: Template.string('icon_' + this.params.loading.icon) + }); + this.loading = $('
    '); + this.loading.append(tpl); + this.scroll.append(this.loading); + }, + onBuild: function onBuild() { + this.loading.remove(); + }, + onEmpty: function onEmpty() { + this.loading.remove(); + } + }; + + function getSmartPages(current, total) { + var maxButtons = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 7; + var pages = []; // всегда добавляем первую и последнюю страницу + + pages.push(1); + pages.push(total); // добавляем текущую страницу + + pages.push(current); // добавляем несколько вокруг текущей + + for (var i = 1; i <= 2; i++) { + if (current - i > 1) pages.push(current - i); + if (current + i < total) pages.push(current + i); + } // добавляем промежуточные диапазоны (каждые ~10%) + + + var steps = Math.max(2, Math.floor(total / (maxButtons - 2))); + + for (var _i = steps; _i < total; _i += steps) { + pages.push(Math.round(_i)); + } // удаляем дубликаты + + + pages = Arrays.unique(pages); // сортируем и возвращаем массив с "..." где пропуски + + var sorted = pages.sort(function (a, b) { + return a - b; + }); + return sorted; + } + + var Pagination = { + onBuild: function onBuild() { + this.navigator = Template.elem('div', { + "class": 'head__navigator' + }); + this.navigator.on('click', this.emit.bind(this, 'right')); + }, + onStart: function onStart() { + if (this.total_pages > 5 && this.navigator) Head.addElement(this.navigator); + }, + onPause: function onPause() { + this.navigator && this.navigator.remove(); + }, + onScroll: function onScroll() { + this.navigator && this.navigator.text((this.object.page || 1) + ' / ' + (this.total_pages || 1)); + }, + onRight: function onRight() { + var _this = this; + + if (!this.navigator) return; + var controller = Controller.enabled().name; + var current_page = parseInt(this.object.page || 1); + var pages = getSmartPages(current_page, parseInt(this.total_pages || 1), 7); + pages = pages.map(function (page) { + return { + title: Lang.translate('title_page') + ' ' + page, + page: page, + selected: page === current_page + }; + }); + Select.show({ + title: Lang.translate('title_navigation'), + items: pages, + onSelect: function onSelect(a) { + _this.object.page = a.page; + Controller.toggle(controller); + + _this.activity.refresh(); + }, + onBack: function onBack() { + Controller.toggle(controller); + } + }); + }, + onDestroy: function onDestroy() { + this.navigator && this.navigator.remove(); + } + }; + + var CategoryMap = { + Items: Items, + Create: Create, + Next: Next, + Empty: Simple, + Explorer: Explorer, + Loading: Loading, + Pagination: Pagination + }; + + var Helper$4 = new Mask(Arrays.getKeys(CategoryMap)); + Helper$4.MASK.base = Helper$4.except('Loading', 'Explorer', 'Pagination'); + + var Full = /*#__PURE__*/function (_Base) { + _inherits(Full, _Base); + + var _super = _createSuper(Full); + + function Full(object) { + var _this; + + _classCallCheck(this, Full); + + _this = _super.call(this, object); + var module = typeof _this.params.module !== 'undefined' ? _this.params.module : Helper$4.MASK.base; + Helper$4.getNames(module).map(function (name) { + return CategoryMap[name]; + }).forEach(function (mod) { + return _this.use(mod); + }); + + _this.emit('init'); + + return _this; + } + + return Full; + }(Base); + + function component$l(object) { + var comp = Utils$1.createInstance(Full, object, { + module: Helper$4.toggle(Helper$4.MASK.base, 'Pagination') + }); + comp.use({ + onCreate: function onCreate() { + Api.list(object, this.build.bind(this), this.empty.bind(this)); + }, + onNext: function onNext(resolve, reject) { + Api.list(object, resolve.bind(this), reject.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + return comp; + } + + function component$k(object) { + var comp = Utils$1.createInstance(Full$1, object); + var next = null; + comp.use({ + onCreate: function onCreate() { + var nextCall = Api.category(object, this.build.bind(this), this.empty.bind(this)); + if (typeof nextCall == 'function') next = nextCall; + }, + onNext: function onNext(resolve, reject) { + if (next) { + next(resolve.bind(this), reject.bind(this)); + } else reject.call(this); + }, + onInstance: function onInstance(item, data) { + item.use({ + onMore: router.call.bind(router, 'category_full', _objectSpread2(_objectSpread2({}, data), {}, { + genres: object.genres + })), + onInstance: function onInstance(card, data) { + card.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + } + }); + return comp; + } + + function component$j(object) { + var comp = Utils$1.createInstance(Full$1, object); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + Api.person(object, function (data) { + if (data.person) { + var lines = []; + lines.push({ + results: [], + params: { + module: Helper$b.toggle(Helper$b.MASK.none, 'Event'), + emit: { + onCreate: function onCreate() { + this.person = Utils$1.createInstance(Person, data.person, { + module: Helper$6.only('About') + }); + this.person.create(); + this.scroll.append(this.person.render(true)); + }, + onToggle: function onToggle() { + data.person.profile_path && Background.change(Api.img(data.person.profile_path, 'w200')); + }, + onDestroy: function onDestroy() { + var _this$person; + + (_this$person = this.person) === null || _this$person === void 0 ? void 0 : _this$person.destroy(); + } + } + } + }); + + if (data.credits && data.credits.knownFor && data.credits.knownFor.length > 0) { + for (var i = 0; i < data.credits.knownFor.length; i++) { + var departament = data.credits.knownFor[i]; + var credits = departament.credits.map(function (a) { + a.time_sort = new Date(a.first_air_date || a.release_date || '').getTime(); + return a; + }); + credits.sort(function (a, b) { + return b.time_sort - a.time_sort; + }); + + if (credits.length > 0) { + lines.push({ + title: departament.name + ' (' + credits.length + ')', + results: credits, + params: { + module: Helper$b.toggle(Helper$b.MASK.base, 'More', 'Event') + } + }); + } + } + } + + if (lines.length) _this.build(lines);else _this.empty(); + } else { + _this.empty(); + } + }, this.empty.bind(this)); + }, + onInstance: function onInstance(item) { + item.use({ + onInstance: function onInstance(card, data) { + card.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + } + }); + return comp; + } + + var Router = { + onEmpty: function onEmpty(e) { + var _this = this; + + Arrays.extend(this.params, { + empty: { + width: 'medium', + buttons: [] + } + }); + var params = this.params.empty; + + if (params.router == 'subscribe') { + params.title = Lang.translate('empty_subscribes_title'); + params.descr = Lang.translate('empty_subscribes_text'); + params.icon = Template.string('icon_empty_subscribe'); + } + + if (params.router == 'bookmarks') { + params.title = Lang.translate('empty_bookmark_title'); + params.descr = Lang.translate('empty_bookmark_text'); + params.icon = Template.string('icon_empty_bookmarks'); + } + + if (params.router == 'favorites') { + params.title = Lang.translate(params.type == 'history' ? 'empty_history_title' : 'empty_bookmark_title'); + params.icon = Template.string(params.type == 'history' ? 'icon_empty_history' : 'icon_empty_bookmarks'); + if (params.type == 'history') params.descr = Lang.translate('empty_history_text');else params.descr = Lang.translate('empty_bookmark_text'); + } + + if (params.router == 'mytorrents') { + params.title = Lang.translate('empty_mytorrents_title'); + params.descr = Lang.translate('empty_mytorrents_text'); + params.icon = Template.string('icon_empty_torrents'); + } + + if (params.account && !permit.token) { + params.buttons.push({ + title: Lang.translate('settings_cub_signin_button'), + onEnter: function onEnter() { + Device.login(_this.start.bind(_this)); + } + }); + } + } + }; + + /** + * Компонент избранного, просмотр папки или истории + * @param {*} object + * @returns + */ + + function component$i(object) { + var comp = Utils$1.createInstance(Full, object, { + module: Helper$4.toggle(Helper$4.MASK.base, 'Pagination'), + empty: { + type: object.type, + router: 'favorites' + } + }); + comp.use(Router, 0); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + Api.favorite(object, function (data) { + // Ой все, и так сработает :) + setTimeout(_this.build.bind(_this, data), 10); + }, this.empty.bind(this)); + }, + onNext: function onNext(resolve, reject) { + Api.favorite(object, resolve.bind(this), reject.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + return comp; + } + + /** + * Отображает полноэкранный ввод текста с виртуальной клавиатурой + * @param {object} [params] - параметры + * @param {string} [params.input] - начальный текст + * @param {function} params.onSearch - вызывается при подтверждении ввода + * @param {function} params.onBack - вызывается при отмене ввода + * @return {void} + */ + + function SearchInput() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var search = Template.get('search_box'); + var input = ''; + + function destroy() { + $('body').toggleClass('ambience--enable', false); + keyboard.destroy(); + search.remove(); + search = null; + } + + function back() { + destroy(); + params.onBack(); + } + + function enter() { + destroy(); + params.onSearch(input); + } + + function change(text) { + input = text; + + if (input) { + search.find('.search-box__input').toggleClass('filled', true).html(input.replace(/\s/g, ' ')); + } else { + search.find('.search-box__input').toggleClass('filled', false).text(Lang.translate('search_input') + '...'); + } + } + + if (Storage.field('keyboard_type') !== 'lampa') search.find('.search-box__input').hide(); + $('body').append(search); + $('body').toggleClass('ambience--enable', true); + var keyboard = new Keyboard({ + layout: 'clarify' + }); + keyboard.create(); + keyboard.listener.follow('change', function (event) { + change(event.value); + }); + keyboard.listener.follow('focus', function (event) { + search.toggleClass('search-box--focus', true); + }); + keyboard.listener.follow('blur', function (event) { + search.toggleClass('search-box--focus', false); + }); + keyboard.listener.follow('back', back); + keyboard.listener.follow('enter', enter); + keyboard.value(params.input); + change(params.input); + keyboard.toggle(); + } + + /** + * Фильтр + * @param {object} params - параметры фильтра + * @param {string} params.search - текущий поисковый запрос + * @param {object} params.movie - информация о фильме/сериале + * @param {string} params.search_one - основной поисковый запрос + * @param {string} params.search_two - дополнительный поисковый запрос + * @returns {Filter} - экземпляр класса Filter + */ + + function Filter() { + var _this2 = this; + + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var line = Template.get('filter').addClass('torrent-filter'); + var empty = $(''); + var data = { + sort: [], + filter: [] + }; + var similars = []; + var buttons_scroll = new Scroll({ + horizontal: true, + nopadding: true + }); + if (typeof params.search == 'string') line.find('.filter--search div').text(Utils$1.shortText(params.search, 20)).removeClass('hide'); + + function selectSearch() { + var _this = this; + + var search = []; + var year = ((params.movie ? params.movie.first_air_date || params.movie.release_date : '0000') + '').slice(0, 4); + var earlier = Storage.get('user_clarifys', '{}')[params.movie.id]; + search.push({ + title: Lang.translate('filter_set_name'), + query: '' + }); + search.push({ + title: Lang.translate('global_search'), + global_search: true + }); + + if (earlier) { + search.push({ + title: Lang.translate('search'), + separator: true + }); + earlier.map(function (a) { + return a; + }).reverse().forEach(function (ear) { + search.push({ + title: ear, + query: ear + }); + }); + } + + if (params.movie.names && params.movie.names.length) { + search.push({ + title: Lang.translate('filter_alt_names'), + separator: true + }); + params.movie.names.forEach(function (n) { + search.push({ + title: n, + query: n + }); + }); + } + + if (params.movie.alternative_titles && params.movie.alternative_titles.titles && params.movie.alternative_titles.titles.length) { + params.movie.alternative_titles.titles.forEach(function (a) { + if (['us', Storage.field('language')].indexOf(a.iso_3166_1.toLowerCase()) >= 0) { + if (!search.find(function (s) { + return s.title == a.title; + })) { + search.push({ + title: a.title, + query: a.title + }); + } + } + }); + } + + search.push({ + title: Lang.translate('filter_combinations'), + separator: true + }); + + if (similars.length) { + similars.forEach(function (sim) { + search.push({ + title: sim, + query: sim + }); + }); + } else { + var combinations = []; + + if (params.search_one) { + combinations.push(params.search_one); + combinations.push(params.search_one + ' ' + year); + + if (params.search_two) { + combinations.push(params.search_one + ' ' + params.search_two); + combinations.push(params.search_one + ' ' + params.search_two + ' ' + year); + } + } + + if (params.search_two) { + combinations.push(params.search_two); + combinations.push(params.search_two + ' ' + year); + + if (params.search_one) { + combinations.push(params.search_two + ' ' + params.search_one); + combinations.push(params.search_two + ' ' + params.search_one + ' ' + year); + } + } + + combinations.forEach(function (word) { + search.push({ + title: word, + query: word + }); + }); + } + + var selected; + search.forEach(function (elem) { + elem.selected = elem.query == params.search && !selected; + if (elem.selected) selected = true; + }); + Select.show({ + title: Lang.translate('filter_clarify'), + items: search, + onBack: this.onBack, + onSelect: function onSelect(a) { + if (a.global_search) { + new SearchInput({ + input: params.search || '', + onSearch: function onSearch(new_query) { + _this.onSearch(new_query, { + global: true + }); + }, + onBack: _this.onBack + }); + return; + } + + if (!a.query) { + new SearchInput({ + input: params.search, + onSearch: function onSearch(new_query) { + var earliers = Storage.get('user_clarifys', '{}'); + if (!earliers[params.movie.id]) earliers[params.movie.id] = []; + + if (earliers[params.movie.id].indexOf(new_query) == -1) { + earliers[params.movie.id].push(new_query); + Storage.set('user_clarifys', earliers); + } + + _this.onSearch(new_query); + }, + onBack: _this.onBack + }); + } else { + _this.onSearch(a.query); + } + } + }); + } + + empty.on('hover:enter', selectSearch.bind(this)); + line.find('.filter--search').on('hover:enter', selectSearch.bind(this)); + line.find('.filter--sort').on('hover:enter', function () { + _this2.show(Lang.translate('filter_sorted'), 'sort'); + }); + line.find('.filter--filter').on('hover:enter', function () { + _this2.show(Lang.translate('filter_filtred'), 'filter'); + }); + buttons_scroll.append(line); + + this.addButtonBack = function () { + if (params.movie && params.movie.id) { + line.prepend(Template.get('explorer_button_back')); + line.find('.filter--back').on('hover:enter', function () { + if (Activity.all().length > 1) { + Activity.back(); + } else { + Activity.push({ + url: params.movie.url, + component: 'full', + id: params.movie.id, + method: params.movie.name ? 'tv' : 'movie', + card: params.movie, + source: params.movie.source + }); + } + }); + } + }; + + this.show = function (title, type) { + var _this3 = this; + + var where = data[type]; + Select.show({ + title: title, + items: where, + onBack: this.onBack, + onSelect: function onSelect(a) { + if (!a.noselect) _this3.selected(where, a); + + if (a.items) { + Select.show({ + title: a.title, + items: a.items, + onBack: function onBack() { + _this3.show(title, type); + }, + onSelect: function onSelect(b) { + if (!b) _this3.selected(a.items, b); + + _this3.onSelect(type, a, b); + + _this3.show(title, type); + }, + onCheck: function onCheck(b) { + _this3.onCheck(type, a, b); + } + }); + } else { + _this3.onSelect(type, a); + } + } + }); + }; + + this.selected = function (items, a) { + items.forEach(function (element) { + element.selected = false; + }); + a.selected = true; + }; + + this.render = function () { + return buttons_scroll.render(); + }; + + this.append = function (add) { + html.find('.files__body').append(add); + }; + + this.empty = function () { + return empty; + }; + + this.toggle = function () { + line.find('.filter--sort').toggleClass('selector', data.sort.length ? true : false).toggleClass('hide', data.sort.length ? false : true); + line.find('.filter--filter').toggleClass('selector', data.filter.length ? true : false).toggleClass('hide', data.filter.length ? false : true); + }; + + this.set = function (type, items) { + data[type] = items; + this.toggle(); + }; + + this.get = function (type) { + return data[type]; + }; + + this.similar = function (sim) { + similars = sim; + return empty; + }; + + this.sort = function (items, by) { + items.sort(function (c, b) { + if (c[by] < b[by]) return 1; + if (c[by] > b[by]) return -1; + return 0; + }); + }; + + this.chosen = function (type, select) { + line.find('.filter--' + type + ' > div').html(Utils$1.shortText(select.join(', '), 25)).toggleClass('hide', select.length ? false : true); + }; + + this.destroy = function () { + empty.remove(); + line.remove(); + buttons_scroll.destroy(); + empty = null; + line = null; + data = null; + }; + } + + var SERVER = {}; + var timers = {}; + var callback$1; + var callback_back; + var autostart_timer; + var autostart_progress; + var formats = ['asf', 'wmv', 'divx', 'avi', 'mp4', 'm4v', 'mov', '3gp', '3g2', 'mkv', 'trp', 'tp', 'mts', 'mpg', 'mpeg', 'dat', 'vob', 'rm', 'rmvb', 'm2ts', 'ts']; + var formats_individual = ['vob', 'm2ts']; + + function start$5(element, movie) { + SERVER.object = element; + if (movie) SERVER.movie = movie; + + if (Platform.is('android') && !Storage.field('internal_torrclient')) { + Android.openTorrent(SERVER); + if (movie && movie.id) Favorite.add('history', movie, 100); + if (callback$1) callback$1(); + } else if (Torserver.url()) { + loading(); + connect(); + } else install$1(); + } + + function open$4(hash, movie) { + SERVER.hash = hash; + if (movie) SERVER.movie = movie; + + if (Platform.is('android') && !Storage.field('internal_torrclient')) { + Android.playHash(SERVER); + if (callback$1) callback$1(); + } else if (Torserver.url()) { + loading(); + files(); + } else install$1(); + } + + function loading() { + Modal.open({ + title: '', + html: Template.get('modal_loading'), + size: 'large', + mask: true, + onBack: function onBack() { + Modal.close(); + close$5(); + } + }); + } + + function connect() { + Torserver.connected(function () { + hash(); + }, function (echo) { + Torserver.error(); + }); + } + + function hash() { + Torserver.hash({ + title: SERVER.object.title, + link: SERVER.object.MagnetUri || SERVER.object.Link, + poster: SERVER.object.poster, + data: { + lampa: true, + movie: SERVER.movie + } + }, function (json) { + SERVER.hash = json.hash; + files(); + }, function (echo) { + //Torserver.error() + var jac = Storage.field('parser_torrent_type') == 'jackett'; + var tpl = Template.get('torrent_nohash', { + title: Lang.translate('title_error'), + text: Lang.translate('torrent_parser_no_hash'), + url: SERVER.object.MagnetUri || SERVER.object.Link, + echo: echo + }); + if (jac) tpl.find('.is--torlook').remove();else tpl.find('.is--jackett').remove(); + Modal.update(tpl); + }); + } + + function files() { + var repeat = 0; + timers.files = setInterval(function () { + repeat++; + Torserver.files(SERVER.hash, function (json) { + if (json.file_stats) { + clearInterval(timers.files); + + if (Storage.field('torrserver_tracktimecode')) { + Torserver.viewed(SERVER.hash, function (viewed) { + show$3(json.file_stats, viewed || []); + }, function () { + show$3(json.file_stats, []); + }); + } else { + show$3(json.file_stats); + } + } + }); + + if (repeat >= 45) { + Modal.update(Template.get('error', { + title: Lang.translate('title_error'), + text: Lang.translate('torrent_parser_timeout') + })); + Torserver.clear(); + Torserver.drop(SERVER.hash); + } + }, 2000); + } + + function install$1() { + Modal.open({ + title: '', + html: Template.get('torrent_install', {}), + size: 'large', + onBack: function onBack() { + Modal.close(); + Controller.toggle('content'); + } + }); + } + + function show$3(files, viewed) { + files.sort(function (a, b) { + var an = a.path.replace(/\d+/g, function (m) { + return m.length > 3 ? m : ('000' + m).substr(-4); + }); + var bn = b.path.replace(/\d+/g, function (m) { + return m.length > 3 ? m : ('000' + m).substr(-4); + }); + return an.localeCompare(bn); + }); + var active = Activity.active(), + movie = active.movie || SERVER.movie || {}; + var plays = Torserver.clearFileName(files.filter(function (a) { + var exe = a.path.split('.').pop().toLowerCase(); + return formats.indexOf(exe) >= 0; + })); + var seasons = []; + plays.forEach(function (element) { + var info = Torserver.parse({ + movie: movie, + files: plays, + filename: element.path_human, + path: element.path + }); + + if (info.serial && info.season && seasons.indexOf(info.season) == -1) { + seasons.push(info.season); + } + }); + + if (seasons.length) { + Api.seasons(movie, seasons, function (data) { + list$1(plays, { + movie: movie, + seasons: data, + files: files, + viewed: viewed || [] + }); + }); + } else { + list$1(plays, { + movie: movie, + files: files, + viewed: viewed || [] + }); + } + } + + function parseSubs(path, files) { + var name = path.split('/').pop().split('.').slice(0, -1).join('.'); + var index = -1; + var supportedFormats = subsrt.list(); + var subtitles = files.filter(function (a) { + var _short = a.path.split('/').pop(); + + var issub = supportedFormats.indexOf(a.path.split('.').pop().toLowerCase()) >= 0; + return _short.indexOf(name) >= 0 && issub; + }).map(function (a) { + index++; + var segments = a.path.split('/'); + segments.pop(); // drop filename + + var label = segments.slice(1).join(' - '); // drop initial folder and concat the rest + + return { + label: label, + url: Torserver.stream(a.path, SERVER.hash, a.id).replace('&preload', '&play'), + index: index + }; + }); + return subtitles.length ? subtitles : false; + } + + function preload(data, run) { + var has_server = Torserver.ip() && data.url.indexOf(Torserver.ip()) > -1; + var has_preload = data.url.indexOf('&preload') > -1; + var need_preload = has_server && has_preload; + + if (need_preload) { + var checkout; + var network = new Request(); + var first = true; + var stopped = false; + var last_bytes = 0; + var last_change = Date.now(); + + var stop = function stop() { + stopped = true; + clearTimeout(checkout); + network.clear(); + Loading$1.stop(); + }; + + Loading$1.start(stop, '', { + media: data + }); + + var next = function next() { + if (stopped) return; + + if (Date.now() - last_change > 30000) { + stop(); + } else checkout = setTimeout(update, 1000); + }; + + var update = function update() { + network.timeout(2000); + network.silent(first ? data.url : data.url.replace('&preload', '&stat'), function (res) { + if (stopped) return; + var pb = res.preloaded_bytes || 0, + ps = res.preload_size || 0, + sp = res.download_speed ? Utils$1.bytesToSize(res.download_speed * 8, true) : '0.0', + active_peers = parseInt(res.active_peers || 0), + total_peers = parseInt(res.total_peers || 0); + var progress = Math.min(100, pb * 100 / ps); + + if (progress >= 95 || isNaN(progress)) { + stop(); + run(); + } else { + if (pb > last_bytes) { + last_bytes = pb; + last_change = Date.now(); + } + + Loading$1.setProgress(progress, { + speed: sp, + active_peers: active_peers, + total_peers: total_peers + }); + next(); + } + }, next); + first = false; + }; + + update(); + } else run(); + } + + function list$1(items, params) { + var html = $('
    '); + var playlist = []; + var scroll_to_element; + var first_item; + Lampa.Listener.send('torrent_file', { + type: 'list_open', + items: items, + params: params + }); + var folder = ''; + items.forEach(function (element, inx) { + var exe = element.path.split('.').pop().toLowerCase(); + var info = Torserver.parse({ + movie: params.movie, + files: items, + filename: element.path_human, + path: element.path, + is_file: formats_individual.indexOf(exe) >= 0 + }); + var view = Timeline$1.view(info.hash); + var serverView = (params.viewed || []).filter(function (v) { + return v.file_index == element.id; + })[0]; + + if (params.movie && params.movie.runtime) { + view.duration = params.movie.runtime * 60; + } + + if (Storage.field('torrserver_tracktimecode') && serverView && serverView.timecode > 0) { + view.time = serverView.timecode; + + if (view.duration > 0) { + view.percent = Math.min(100, Math.round(view.time / view.duration * 100)); + } + + Timeline$1.update(view); + } + + var item; + Arrays.extend(element, { + season: info.season, + episode: info.episode, + title: element.path_human, + first_title: params.movie.name || params.movie.title, + card: params.movie, + size: Utils$1.bytesToSize(element.length), + url: Torserver.stream(element.path, SERVER.hash, element.id), + torrent_hash: SERVER.hash, + ffprobe: SERVER.object && SERVER.object.ffprobe ? SERVER.object.ffprobe : false, + timeline: view, + air_date: '--', + img: './img/img_broken.svg', + exe: exe, + viewed: function viewed(time) { + if (Storage.field('torrserver_tracktimecode')) { + Torserver.viewedSet(SERVER.hash, element.id, time); + } + } + }); + + if (params.seasons) { + var episodes = params.seasons[info.season]; + element.title = (info.episode ? info.episode + ' / ' : '') + element.path_human; + element.fname = element.title; + + if (episodes) { + var episode = episodes.episodes.filter(function (a) { + return a.episode_number == info.episode; + })[0]; + + if (episode) { + if (episode.runtime) { + view.duration = episode.runtime * 60; + } + + if (Storage.field('torrserver_tracktimecode') && serverView && serverView.timecode > 0) { + view.time = serverView.timecode; + + if (view.duration > 0) { + view.percent = Math.min(100, Math.round(view.time / view.duration * 100)); + } + + Timeline$1.update(view); + } + + element.title = info.episode + ' / ' + episode.name; + element.air_date = Utils$1.parseTime(episode.air_date).full; + element.fname = episode.name; + if (episode.still_path) element.img = Api.img(episode.still_path);else if (episode.img) element.img = episode.img; + } + } + + if (info.episode) { + item = Template.get('torrent_file_serial', element); + item.find('.torrent-serial__content').append(Timeline$1.render(view)); + } else { + item = Template.get('torrent_file', element); + item.append(Timeline$1.render(view)); + } + } else if (items.length == 1 && params.movie && !params.movie.name) { + element.fname = params.movie.title || element.title; + if (params.movie.backdrop_path) element.img = Api.img(params.movie.backdrop_path); + item = Template.get('torrent_file_serial', element); + item.find('.torrent-serial__line').empty().text(params.movie.tagline || ''); + item.find('.torrent-serial__episode').remove(); + item.find('.torrent-serial__content').append(Timeline$1.render(view)); + } else { + item = Template.get('torrent_file', element); + item.append(Timeline$1.render(view)); + if (params.movie.title) element.title = params.movie.title; + } + + if (element.img !== './img/img_broken.svg') element.thumbnail = element.img; + item[0].visibility = 'hidden'; + if (view.percent > 0) scroll_to_element = item; + element.subtitles = parseSubs(element.path, params.files); + element.title = (element.fname || element.title).replace(/<[^>]*>?/gm, ''); + element.subtitle = element.episode ? Lang.translate('torrent_serial_episode') + ': ' + element.episode : ''; // копируем объект, чтобы не было ссылок на один и тот же объект в плейлисте + + var playlist_element = {}; + + for (var a in element) { + playlist_element[a] = element[a]; + } + + playlist.push(playlist_element); + element.playlist = playlist; + item.on('hover:enter', function () { + stopAutostart(); // если это андроид, но не андроид, то нефиг смотреть + + if (navigator.userAgent.toLowerCase().indexOf('android') >= 0 && !Platform.is('android')) return Platform.install('apk'); + if (params.movie.id) Favorite.add('history', params.movie, 100); + preload(element, function () { + Player.play(element); + Player.callback(function () { + Controller.toggle('modal'); + }); + Player.playlist(playlist); + + if (callback$1) { + callback$1(); + callback$1 = false; + } + + Lampa.Listener.send('torrent_file', { + type: 'onenter', + element: element, + item: item, + items: items, + params: params + }); + }); + }).on('hover:long', function () { + stopAutostart(); + var enabled = Controller.enabled().name; + var menu = [{ + title: Lang.translate('time_reset'), + timeclear: true + }, { + title: Lang.translate('time_viewed'), + timefull: true + }]; + + if (Platform.is('webos')) { + menu.push({ + title: Lang.translate('player_lauch') + ' - WebOS', + player: 'webos' + }); + } + + if (Platform.is('android')) { + menu.push({ + title: Lang.translate('player_lauch') + ' - Android', + player: 'android' + }); + } + + menu.push({ + title: Lang.translate('player_lauch') + ' - Lampa', + player: 'lampa' + }); + menu.push({ + title: Lang.translate('copy_link'), + link: true + }); + Lampa.Listener.send('torrent_file', { + type: 'onlong', + element: element, + item: item, + menu: menu, + items: items, + params: params + }); + Select.show({ + title: Lang.translate('title_action'), + items: menu, + onBack: function onBack() { + Controller.toggle(enabled); + }, + onSelect: function onSelect(a) { + if (a.timeclear) { + view.percent = 0; + view.time = 0; + view.duration = 0; + element.timeline = view; + Timeline$1.update(view); + + if (Storage.field('torrserver_tracktimecode')) { + Torserver.viewedSet(SERVER.hash, element.id, 0); + } + } + + if (a.timefull) { + view.percent = 100; + view.time = view.duration; + element.timeline = view; + Timeline$1.update(view); + } + + if (a.link) { + Utils$1.copyTextToClipboard(element.url.replace('&preload', '&play'), function () { + Noty.show(Lang.translate('copy_secuses')); + }, function () { + Noty.show(Lang.translate('copy_error')); + }); + } + + Controller.toggle(enabled); + + if (a.player) { + Player.runas(a.player); + item.trigger('hover:enter'); + } + } + }); + }).on('hover:focus', function () { + Lampa.Listener.send('torrent_file', { + type: 'onfocus', + element: element, + item: item, + items: items, + params: params + }); + }).on('visible', function () { + var img = item.find('img'); + + img[0].onload = function () { + img.addClass('loaded'); + }; + + img[0].src = img.attr('data-src'); + }); + + if (element.folder_name && element.folder_name !== folder) { + html.append($('
    ' + element.folder_name + '
    ')); + folder = element.folder_name; + } + + html.append(item); + if (!first_item) first_item = item; + Lampa.Listener.send('torrent_file', { + type: 'render', + element: element, + item: item, + items: items, + params: params + }); + }); + if (items.length == 0) html = Template.get('error', { + title: Lang.translate('empty_title'), + text: Lang.translate('torrent_parser_nofiles') + });else Modal.title(Lang.translate('title_files')); + if (playlist.length == 1) autostart(first_item); + Modal.update(html); + if (scroll_to_element) Controller.collectionFocus(scroll_to_element, Modal.scroll().render()); + } + + function autostart(item) { + var tim = Date.now(); + var div = $('
    '); + autostart_timer = setInterval(function () { + var dif = (Date.now() - tim) / 1000; + div.css('height', Math.round(dif / 10 * 100) + '%'); + + if (dif > 10) { + stopAutostart(); + item.trigger('hover:enter'); + } + }, 10); + Keypad.listener.follow('keydown', listenKeydown); + autostart_progress = div; + item.prepend(div); + } + + function listenKeydown() { + stopAutostart(); + Keypad.listener.remove('keydown', listenKeydown); + } + + function stopAutostart() { + clearInterval(autostart_timer); + if (autostart_progress) autostart_progress.remove(); + autostart_progress = null; + } + + function opened(call) { + callback$1 = call; + } + + function back$4(call) { + callback_back = call; + } + + function close$5() { + Torserver.drop(SERVER.hash); + Torserver.clear(); + clearInterval(timers.files); + + if (callback_back) { + callback_back(); + } else { + Controller.toggle('content'); + } + + callback_back = false; + SERVER = {}; + clearInterval(autostart_timer); + Lampa.Listener.send('torrent_file', { + type: 'list_close' + }); + } + + var Torrent = { + start: start$5, + open: open$4, + opened: opened, + back: back$4 + }; + + function Results(source) { + var timer, + html = Template.elem('div'), + items = [], + active = 0, + query; + var source_name = 'search_' + source.title.toLowerCase(); + this.listener = Subscribe$2(); + this.params = source.params; + + this.create = function () { + this.empty(); + }; + + this.recall = function (last_query) { + var _this = this; + + Cache.getData('other', source_name + '_' + (last_query || 'last'), 60 * 24).then(function (data) { + if (!data) return; + + _this.clear(); + + html.empty(); + source.onRecall && source.onRecall(data, last_query); + data.forEach(_this.build.bind(_this)); + + _this.listener.send('finded', { + count: _this.count(data), + data: data + }); + })["catch"](function () {}); + }; + + this.empty = function () { + html.empty().append($('
    ' + Lang.translate(query ? source.params.nofound || 'search_nofound' : source.params.start_typing || 'search_start_typing') + '
    ')); + }; + + this.loading = function () { + this.listener.send('start'); + html.empty().append($('
    ' + Lang.translate('search_searching') + '
    ')); + }; + + this.cancel = function () { + clearTimeout(timer); + if (source.onCancel) source.onCancel(); + }; + + this.search = function (value, immediately) { + var _this2 = this; + + clearTimeout(timer); + + if (value.length >= 3) { + timer = setTimeout(function () { + if (query == value) return; + query = value; + + _this2.loading(); + + source.search({ + query: encodeURIComponent(value) + }, function (data) { + _this2.clear(); + + _this2.dmca(data); + + var count = _this2.count(data); + + if (count > 0) { + html.empty(); + var copy = Arrays.clone(data); + Cache.rewriteData('other', source_name + '_' + value, copy)["catch"](function () {}); + Cache.rewriteData('other', source_name + '_last', copy)["catch"](function () {}); + data.forEach(_this2.build.bind(_this2)); + } else _this2.empty(); + + _this2.listener.send('finded', { + count: count, + data: data + }); + }); + }, immediately ? 10 : 2500); + } else { + query = value; + this.clear(); + if (!value) this.recall(''); + } + }; + + this.count = function (result) { + var count = 0; + result.forEach(function (data) { + count += data.results.length; + }); + return count; + }; + + this.dmca = function (result) { + if (Arrays.isArray(window.lampa_settings.dcma)) { + result.forEach(function (data) { + data.results = data.results.filter(function (item) { + return !window.lampa_settings.dcma.find(function (b) { + return b.id == item.id && b.cat == (item.name ? 'tv' : 'movie'); + }); + }); + }); + } + }; + + this.build = function (data) { + var _this3 = this; + + data.noimage = true; + source.params.card_view = 6; + + if (Arrays.isArray(window.lampa_settings.dcma)) { + data.results = data.results.filter(function (item) { + return !window.lampa_settings.dcma.find(function (b) { + return b.id == item.id && b.cat == (item.name ? 'tv' : 'movie'); + }); + }); + } + + var line = Utils$1.createInstance(Line$4, data, _objectSpread2(_objectSpread2({}, source.params), {}, { + module: Helper$b.only('Items', 'Create', 'More') + })); + line.use({ + onDown: this.down.bind(this), + onUp: this.up.bind(this), + onBack: this.back.bind(this), + onMore: function onMore() { + if (source.onMore) source.onMore({ + data: data, + line: line, + query: query + }, function () { + _this3.listener.send('select'); + }); + }, + onInstance: function onInstance(item, item_data) { + item.use({ + onEnter: function onEnter() { + if (source.onSelect) { + source.onSelect({ + data: data, + line: line, + query: query, + element: item_data, + item_data: item_data + }, function () { + _this3.listener.send('select'); + }); + } else { + _this3.listener.send('select'); + + router.call('full', item_data); + } + } + }); + } + }); + if (source.onRender) source.onRender(line); + line.create(); + items.push(line); + html.append(line.render(true)); + }; + + this.any = function () { + return items.length; + }; + + this.back = function () { + this.listener.send('back'); + }; + + this.down = function () { + active++; + active = Math.min(active, items.length - 1); + items[active].toggle(); + this.listener.send('toggle', { + element: items[active].render() + }); + }; + + this.up = function () { + active--; + if (active < 0) this.listener.send('up'); + + if (active < 0) { + active = 0; + } else { + items[active].toggle(); + this.listener.send('toggle', { + element: items[active].render() + }); + } + }; + + this.clear = function () { + this.empty(); + active = 0; + Arrays.destroy(items); + items = []; + this.listener.send('clear'); + }; + + this.toggle = function () { + var _this4 = this; + + Controller.add('search_results', { + invisible: true, + toggle: function toggle() { + Controller.collectionSet(html); + + if (items.length) { + items[active].toggle(); + + _this4.listener.send('toggle', { + element: items[active].render() + }); + } + }, + back: function back() { + _this4.listener.send('back'); + } + }); + Controller.toggle('search_results'); + }; + + this.render = function (js) { + return js ? html : $(html); + }; + + this.destroy = function () { + clearTimeout(timer); + this.clear(); + this.listener.destroy(); + }; + } + + var stop_keys = ['пор', 'порн', 'порно', 'секс', 'член', 'гей', 'лгбт', 'лесби', 'бисексуал', 'трансгендер', 'por', 'porn', 'porno', 'sex', 'hot', 'xxx', 'lgbt', 'lesbian', 'bisexual', 'queer', 'transgender', 'same sex']; + + function Sources() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var scroll, + last, + active, + last_query = ''; + var html = document.createElement('div'), + results = []; + this.listener = Subscribe$2(); + + this.create = function () { + scroll = new Scroll({ + over: true, + mask: false, + horizontal: true + }); + var sources; + + if (permit.child) { + sources = [Api.sources.cub.discovery()]; + sources.forEach(this.build.bind(this)); + } else { + sources = params.sources || Api.availableDiscovery(); + sources.forEach(this.build.bind(this)); + + if (!params.sources) { + params.additional.forEach(this.build.bind(this)); + } + } + + this.enable(results[0]); + + if (results.length < 2) { + scroll.render(true).addClass('hide'); + html.addClass('search__results-offset'); + } // results.forEach(source=>{ + // source.recall(last_query) + // }) + + }; + + this.enable = function (result) { + active = result; + if (active.params.lazy && last_query) active.search(last_query, true);else { + active.recall(last_query); + } + html.empty().append(result.render(true)); + scroll.render().find('.search-source').removeClass('active').eq(results.indexOf(result)).addClass('active'); + Layer.visible(result.render(true)); + }; + + this.build = function (source) { + var _this = this; + + var tab = $('
    ' + source.title + '
    0
    '); + var result = new Results(source); + result.create(); + if (source.params.lazy) tab.find('.search-source__count').remove(); + result.listener.follow('start', function () { + tab.addClass('search-source--loading'); + tab.find('.search-source__count').html(' '); + }); + result.listener.follow('clear', function () { + tab.find('.search-source__count').text(0); + }); + result.listener.follow('finded', function (e) { + tab.removeClass('search-source--loading'); + tab.find('.search-source__count').text(e.count); + if (active == result) Layer.visible(result.render(true)); + + _this.listener.send('finded', { + source: source, + result: result, + count: e.count, + data: e.data + }); + }); + result.listener.follow('up', function (e) { + if (results.length < 2) _this.listener.send('up');else _this.toggle(); + }); + result.listener.follow('select', this.listener.send.bind(this.listener, 'select')); + result.listener.follow('back', this.listener.send.bind(this.listener, 'back')); + result.listener.follow('toggle', function (e) { + _this.listener.send('toggle', { + source: source, + result: e.result, + element: e.element + }); + }); + tab.on('hover:enter', function () { + _this.enable(result); + }).on('hover:focus', function (e) { + last = e.target; + scroll.update($(e.target)); + }); + scroll.append(tab); + results.push(result); + this.listener.send('create', { + source: source, + result: result + }); + }; + + this.toggle = function (from_search) { + var _this2 = this; + + Controller.add('search_sources', { + toggle: function toggle() { + Controller.collectionSet(scroll.render(true)); + Controller.collectionFocus(last, scroll.render(true)); + if (from_search && results.length < 2 && active.any()) active.toggle(); + }, + update: function update() {}, + up: function up() { + _this2.listener.send('up'); + }, + down: function down() { + if (active.any()) active.toggle(); + }, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + Navigator.move('left'); + }, + back: function back() { + _this2.listener.send('back'); + } + }); + Controller.toggle('search_sources'); + }; + + this.search = function (query, immediately) { + results.forEach(function (result) { + return result.cancel(); + }); + + if (!stop_keys.find(function (k) { + return k == query.toLowerCase().trim(); + })) { + last_query = query; + this.listener.send('search', { + query: query, + immediately: immediately + }); + results.forEach(function (result) { + if (!result.params.lazy || active === result) result.search(query, immediately); + }); + } + }; + + this.cancel = function () { + results.forEach(function (result) { + return result.cancel(); + }); + }; + + this.tabs = function () { + return scroll.render(true); + }; + + this.render = function (js) { + return js ? html : $(html); + }; + + this.destroy = function () { + scroll.destroy(); + results.forEach(function (result) { + return result.cancel(); + }); + this.listener.destroy(); + }; + } + + function History() { + var scroll, + last, + keys = []; + this.listener = Subscribe$2(); + + this.create = function () { + var _this = this; + + scroll = new Scroll({ + over: true, + mask: false, + horizontal: true + }); + + scroll.onWheel = function (step) { + _this.toggle(); + + Controller.enabled().controller[step > 0 ? 'right' : 'left'](); + }; + + scroll.onScroll = function (step) {}; + + keys = Storage.get('search_history', '[]'); + keys.map(function (v) { + return v; + }).reverse().slice(0, 15).forEach(function (key) { + _this.append(key); + }); + if (!keys.length) scroll.append($('
    ' + Lang.translate('search_empty') + '
    ')); + }; + + this.append = function (value) { + var _this2 = this; + + var key = $('
    ' + value + '
    '); + key.on('hover:enter', function () { + _this2.listener.send('enter', { + value: value + }); + }).on('hover:focus', function (e) { + last = e.target; + scroll.update($(e.target), true); + }).on('hover:long', function () { + var selc = scroll.render().find('.selector'); + Arrays.remove(keys, value); + Storage.set('search_history', keys); + Storage.remove('search_history', value); + var index = selc.index(key); + if (index > 0) last = selc.eq(index - 1)[0];else if (selc[index + 1]) last = selc.eq(index + 1)[0]; + key.remove(); + if (selc.length - 1 <= 0) last = false; + Controller.collectionFocus(last, scroll.render()); + }); + scroll.append(key); + }; + + this.add = function (value) { + var inx = keys.indexOf(value); + + if (inx == -1) { + keys.push(value); + } else { + Arrays.remove(keys, value); + keys.push(value); + } + + Storage.set('search_history', keys); + }; + + this.toggle = function () { + var _this3 = this; + + Controller.add('search_history', { + toggle: function toggle() { + Controller.collectionSet(scroll.render()); + Controller.collectionFocus(last, scroll.render()); + }, + update: function update() {}, + up: function up() { + _this3.listener.send('up'); + }, + down: function down() { + _this3.listener.send('down'); + }, + right: function right() { + Navigator.move('right'); + }, + back: function back() { + _this3.listener.send('back'); + }, + left: function left() { + Navigator.move('left'); + } + }); + Controller.toggle('search_history'); + }; + + this.any = function () { + return keys.length; + }; + + this.render = function () { + return scroll.render(); + }; + + this.destroy = function () { + scroll.destroy(); + this.listener.destroy(); + keys = null; + last = null; + }; + } + + var html$9 = Template.elem('div', { + "class": 'main-search' + }), + search$1, + history, + sources, + keyboard$1, + scroll, + input$1 = '', + params$1 = {}, + additional = [], + listener$4 = Subscribe$2(); + + function init$y() { + Head.addIcon(Template.string('icon_search'), open$3).addClass('open--search'); + } + + function open$3() { + var use_params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + params$1 = use_params; + input$1 = use_params.input || ''; + $('body').toggleClass('ambience--enable', true); + $('body').toggleClass('search--open', true); + create$6(); + toggle$3(); + Layer.update(html$9); + listener$4.send('open'); + } + + function toggle$3() { + Controller.add('search', { + invisible: true, + toggle: function toggle() { + keyboard$1.toggle(); + }, + update: function update() {}, + back: destroy$2 + }); + Controller.toggle('search'); + } + + function scrollTo(element) { + scroll.update(element ? element : search$1.find('.search__input'), true); + } + + function create$6() { + search$1 = Template.get('search'); + scroll = new Scroll({ + step: 300 + }); + scroll.height(); + scroll.render().addClass('search'); + scroll.append(HeadBackward(Lang.translate('search'))); + scroll.append(search$1); + html$9.append(scroll.render(true)); + + scroll.onScroll = function (step) { + Layer.visible(scroll.render(true)); + }; + + if (Storage.field('keyboard_type') !== 'lampa') search$1.find('.search__input').hide(); + createKeyboard(); + createHistory(); + createSources(); + keyboard$1.value(input$1); + } + + function createSources() { + sources = new Sources({ + sources: params$1.sources, + additional: additional + }); + listener$4.send('sources', { + sources: sources + }); + sources.create(); + sources.listener.follow('back', destroy$2); + sources.listener.follow('up', function () { + if (history.any()) history.toggle();else keyboard$1.toggle(); + scrollTo(); + }); + sources.listener.follow('toggle', function (e) { + scrollTo(e.element); + }); + sources.listener.follow('select', function (e) { + if (input$1) history.add(input$1); + destroy$2(); + }); + search$1.find('.search__sources').append(sources.tabs()); + search$1.find('.search__results').append(sources.render()); + } + + function createHistory() { + history = new History(); + history.create(); + history.listener.follow('down', function () { + sources.toggle(true); + }); + history.listener.follow('up', function () { + keyboard$1.toggle(); + }); + history.listener.follow('enter', function (event) { + keyboard$1.value(event.value); + sources.search(event.value, true); + }); + history.listener.follow('back', destroy$2); + search$1.find('.search__history').append(history.render()); + } + + function createKeyboard() { + keyboard$1 = new Keyboard({ + layout: 'search' + }); + keyboard$1.create(); + keyboard$1.listener.follow('change', function (event) { + input$1 = event.value; + + if (input$1) { + search$1.find('.search__input').toggleClass('filled', true).html(input$1.replace(/\s/g, ' ')); + sources.search(input$1); + } else { + search$1.find('.search__input').toggleClass('filled', false).text(Lang.translate('search_input') + '...'); + sources.search(''); + } + }); + keyboard$1.listener.follow('down', function () { + if (history.any()) history.toggle();else sources.toggle(); + }); + keyboard$1.listener.follow('hover', function () { + input$1.length <= 2 ? sources.cancel() : sources.search(input$1); + }); + keyboard$1.listener.follow('back', destroy$2); + } + + function addSource(source) { + additional.push(source); + } + + function removeSource(source) { + Arrays.remove(additional, source); + } + + function render$3(js) { + return js ? html$9 : $(html$9); + } + + function destroy$2() { + keyboard$1.destroy(); + history.destroy(); + sources.destroy(); + search$1.remove(); + html$9.empty(); + $('body').toggleClass('ambience--enable', false); + $('body').toggleClass('search--open', false); + if (params$1.onBack) params$1.onBack();else Controller.toggle('content'); + params$1 = {}; + input$1 = ''; + listener$4.send('close'); + } + + function close$4() { + destroy$2(); + } + + var Search = { + init: init$y, + listener: listener$4, + open: open$3, + render: render$3, + addSource: addSource, + removeSource: removeSource, + close: close$4 + }; + + var CardParser = /*#__PURE__*/function (_Constructor) { + _inherits(CardParser, _Constructor); + + var _super = _createSuper(CardParser); + + function CardParser(data) { + var _this; + + _classCallCheck(this, CardParser); + + _this = _super.call(this, data); + + _this.use(Callback$1); + + return _this; + } + + _createClass(CardParser, [{ + key: "create", + value: function create() { + this.html = Template.js('card_parser', this.data); + this.html.on('visible', this.emit.bind(this, 'visible')); + this.emit('create'); + } + }]); + + return CardParser; + }(Constructor({})); + + var network$2 = new Request(); + var TMDB_GENRE_ANIMATION = 16; + var ANIME_LANGUAGES = ['ja', 'zh']; + + function isAnimeMovie(movie) { + return ANIME_LANGUAGES.includes(movie.original_language) && (movie.genres || []).some(function (g) { + return g.id == TMDB_GENRE_ANIMATION; + }); + } + + function init$x() { + Storage.set('parser_torrent_type', Storage.get('parser_torrent_type') || 'jackett'); + var source = { + title: Lang.translate('title_parser'), + search: function search(params, oncomplite) { + get$5({ + search: decodeURIComponent(params.query), + other: true, + from_search: true + }, function (json) { + json.Results.sort(function (a, b) { + return (b.Seeders || 0) - (a.Seeders || 0); + }); + json.title = Lang.translate('title_parser'); + json.results = json.Results.slice(0, 20); + json.total = json.Results.length; + json.total_pages = Math.ceil(json.total / 20); + json.Results = null; + json.results.forEach(function (element) { + element.Title = Utils$1.shortText(element.Title, 110); + element.params = { + createInstance: function createInstance(item) { + return new CardParser(item); + } + }; + }); + oncomplite(json.results.length ? [json] : []); + }, function () { + oncomplite([]); + }); + }, + onRecall: function onRecall(data, last_query) { + data[0].results.forEach(function (element) { + element.params = { + createInstance: function createInstance(item) { + return new CardParser(item); + } + }; + }); + }, + onCancel: network$2.clear.bind(network$2), + params: { + lazy: true + }, + onMore: function onMore(params, close) { + close(); + Activity.push({ + url: '', + title: Lang.translate('title_torrents'), + component: 'torrents', + search: params.query, + from_search: true, + page: 1 + }); + }, + onSelect: function onSelect(params, close) { + Torrent.start(params.element, { + title: params.element.Title + }); + Torrent.back(params.line.toggle.bind(params.line)); + } + }; + + function addSource() { + var reg = Platform.is('android') ? true : Torserver.url(); + if (Storage.field('parse_in_search') && reg) Search.addSource(source); + } + + Storage.listener.follow('change', function (e) { + if (e.name == 'parse_in_search' || e.name == 'torrserver_url' || e.name == 'torrserver_url_two' || e.name == 'torrserver_use_link') { + Search.removeSource(source); + addSource(); + } + }); + addSource(); + } + + function parserLinks(type) { + if (type == 'jackett') { + return [{ + url: Storage.field('jackett_url').replace('jacred.xyz', 'jac.red'), + key: Storage.field('jackett_key'), + rank: 0 + }, { + url: Storage.field('jackett_url_two').replace('jacred.xyz', 'jac.red'), + key: Storage.field('jackett_key_two'), + rank: 1 + }]; + } else if (type == 'prowlarr') { + return [{ + url: Storage.field('prowlarr_url'), + key: Storage.field('prowlarr_key'), + rank: 0 + }, { + url: Storage.field('prowlarr_url_two'), + key: Storage.field('prowlarr_key_two'), + rank: 1 + }]; + } else return []; + } + + function selectParserLinks(type) { + var use = Storage.field('parser_use_link') || 'one'; + var links = parserLinks(type); + if (use == 'one') return links[0] && links[0].url ? [links[0]] : []; + if (use == 'two') return links[1] && links[1].url ? [links[1]] : []; + return links.filter(function (l) { + return l && l.url; + }); + } + + function resultKey(item) { + if (item.MagnetUri) return 'm:' + item.MagnetUri; + if (item.downloadUrl) return 'm:' + item.downloadUrl; + var size = item.Size || item.size || ''; + var tracker = item.Tracker || ''; + var hash = item.hash || Utils$1.hash((item.Title || '') + size + tracker); + return 'h:' + hash + '|' + size + '|' + tracker; + } + + function mergeResults(items) { + var map = new Map(); + items.forEach(function (item) { + var key = resultKey(item); + var prev = map.get(key); + if (!prev) map.set(key, item);else { + var prev_rank = typeof prev.source_rank == 'number' ? prev.source_rank : 0; + var next_rank = typeof item.source_rank == 'number' ? item.source_rank : 0; + + if (next_rank < prev_rank) { + map.set(key, item); + } else if (next_rank == prev_rank) { + var prev_time = prev.checked_at || 0; + var next_time = item.checked_at || 0; + if (next_time > prev_time) map.set(key, item); + } + } + }); + return Array.from(map.values()); + } + + function get$5() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var oncomplite = arguments.length > 1 ? arguments[1] : undefined; + var onerror = arguments.length > 2 ? arguments[2] : undefined; + + function complite(data) { + oncomplite(data); + } + + function error(e) { + onerror(e); + } + + if (Storage.field('parser_torrent_type') == 'jackett') { + var links = selectParserLinks('jackett'); + + if (links.length) { + var calls = links.map(function (link) { + return function (done, fail) { + var base = Utils$1.checkEmptyUrl(link.url); + + jackett(params, base, link.key, link.rank, done, fail); + }; + }); + if (calls.length == 1) calls[0](complite, error);else { + var results = []; + var pending = calls.length; + var success = false; + var first_error; + calls.forEach(function (call, index) { + call(function (json) { + results[index] = json; + success = true; + + if (--pending == 0) { + var _ref; + + var merged = mergeResults((_ref = []).concat.apply(_ref, _toConsumableArray(results.map(function (r) { + return r && r.Results ? r.Results : []; + })))); + complite({ + Results: merged + }); + } + }, function (e) { + results[index] = null; + first_error = first_error || e; + + if (--pending == 0) { + if (success) { + var _ref2; + + var merged = mergeResults((_ref2 = []).concat.apply(_ref2, _toConsumableArray(results.map(function (r) { + return r && r.Results ? r.Results : []; + })))); + complite({ + Results: merged + }); + } else error(first_error || ''); + } + }); + }); + } + } else { + error(Lang.translate('torrent_parser_set_link') + ': Jackett'); + } + } else if (Storage.field('parser_torrent_type') == 'prowlarr') { + var _links = selectParserLinks('prowlarr'); + + if (_links.length) { + var _calls = _links.map(function (link) { + return function (done, fail) { + var base = Utils$1.checkEmptyUrl(link.url); + prowlarr(params, base, link.key, link.rank, done, fail); + }; + }); + + if (_calls.length == 1) _calls[0](complite, error);else { + var _results = []; + var _pending = _calls.length; + var _success = false; + + var _first_error; + + _calls.forEach(function (call, index) { + call(function (json) { + _results[index] = json; + _success = true; + + if (--_pending == 0) { + var _ref3; + + var merged = mergeResults((_ref3 = []).concat.apply(_ref3, _toConsumableArray(_results.map(function (r) { + return r && r.Results ? r.Results : []; + })))); + complite({ + Results: merged + }); + } + }, function (e) { + _results[index] = null; + _first_error = _first_error || e; + + if (--_pending == 0) { + if (_success) { + var _ref4; + + var merged = mergeResults((_ref4 = []).concat.apply(_ref4, _toConsumableArray(_results.map(function (r) { + return r && r.Results ? r.Results : []; + })))); + complite({ + Results: merged + }); + } else error(_first_error || ''); + } + }); + }); + } + } else { + error(Lang.translate('torrent_parser_set_link') + ': Prowlarr'); + } + } else if (Storage.field('parser_torrent_type') == 'torrserver') { + var torr_link = Storage.field(Storage.field('torrserver_use_link') == 'two' ? 'torrserver_url_two' : 'torrserver_url'); + + if (torr_link) { + torrserver(params, Utils$1.checkEmptyUrl(torr_link), complite, error); + } else { + error(Lang.translate('torrent_parser_set_link') + ': TorrServer'); + } + } + } + + function viewed(hash) { + var view = Storage.cache('torrents_view', 5000, []); + return view.indexOf(hash) > -1; + } + + function jackett() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var base_url = arguments.length > 1 ? arguments[1] : undefined; + var api_key = arguments.length > 2 ? arguments[2] : undefined; + var source_rank = arguments.length > 3 ? arguments[3] : undefined; + var oncomplite = arguments.length > 4 ? arguments[4] : undefined; + var onerror = arguments.length > 5 ? arguments[5] : undefined; + network$2.timeout(1000 * Storage.field('parse_timeout')); + var u = base_url + '/api/v2.0/indexers/' + (Storage.field('jackett_interview') == 'healthy' ? 'status:healthy' : 'all') + '/results?apikey=' + (api_key || '') + '&Query=' + encodeURIComponent(params.search); + + if (!params.from_search) { + var genres = params.movie.genres.map(function (a) { + return a.name; + }); + + if (!params.clarification) { + u = Utils$1.addUrlComponent(u, 'title=' + encodeURIComponent(params.movie.title)); + u = Utils$1.addUrlComponent(u, 'title_original=' + encodeURIComponent(params.movie.original_title)); + } + + u = Utils$1.addUrlComponent(u, 'year=' + encodeURIComponent(((params.movie.first_air_date || params.movie.release_date || '0000') + '').slice(0, 4))); + u = Utils$1.addUrlComponent(u, 'is_serial=' + (params.movie.original_name ? '2' : params.other ? '0' : '1')); + u = Utils$1.addUrlComponent(u, 'genres=' + encodeURIComponent(genres.join(','))); + if (!params.global) u = Utils$1.addUrlComponent(u, 'Category[]=' + (params.movie.number_of_seasons > 0 ? 5000 : 2000) + (isAnimeMovie(params.movie) ? ',5070' : '')); + } + + network$2["native"](u, function (json) { + if (json.Results) { + var checked_at = Date.now(); + json.Results.forEach(function (element) { + element.PublisTime = Utils$1.strToTime(element.PublishDate); + element.hash = Utils$1.hash(element.Title); + element.viewed = viewed(element.hash); + element.size = Utils$1.bytesToSize(element.Size); + element.checked_at = checked_at; + element.source_rank = source_rank; + }); + oncomplite(json); + } else onerror(Lang.translate('torrent_parser_no_responce') + ' (' + base_url + ')'); + }, function (a, c) { + onerror(Lang.translate('torrent_parser_no_responce') + ' (' + base_url + ')'); + }); + } // доки https://wiki.servarr.com/en/prowlarr/search#search-feed + + + function prowlarr() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var base_url = arguments.length > 1 ? arguments[1] : undefined; + var api_key = arguments.length > 2 ? arguments[2] : undefined; + var source_rank = arguments.length > 3 ? arguments[3] : undefined; + var oncomplite = arguments.length > 4 ? arguments[4] : undefined; + var onerror = arguments.length > 5 ? arguments[5] : undefined; + var q = []; + q.push({ + name: 'apikey', + value: api_key || '' + }); + q.push({ + name: 'query', + value: params.search + }); + + if (!params.from_search) { + var isSerial = !!params.movie.original_name; + + if (!params.global) { + var baseCategory = params.movie.number_of_seasons > 0 ? '5000' : '2000'; + q.push({ + name: 'categories', + value: baseCategory + }); + if (isAnimeMovie(params.movie)) q.push({ + name: 'categories', + value: '5070' + }); + } + + q.push({ + name: 'type', + value: isSerial ? 'tvsearch' : 'search' + }); + } + + var u = Utils$1.buildUrl(base_url, '/api/v1/search', q); + network$2.timeout(1000 * Storage.field('parse_timeout')); + network$2["native"](u, function (json) { + if (Array.isArray(json)) { + var checked_at = Date.now(); + oncomplite({ + Results: json.filter(function (e) { + return e.protocol === 'torrent'; + }).map(function (e) { + var hash = Utils$1.hash(e.title); + var timeValue = Utils$1.strToTime(e.publishDate); + return { + Title: e.title, + Tracker: e.indexer, + Size: e.size, + PublishDate: Utils$1.strToTime(e.publishDate), + PublisTime: timeValue, + Seeders: parseInt(e.seeders), + Peers: parseInt(e.leechers), + MagnetUri: e.downloadUrl, + viewed: viewed(hash), + checked_at: checked_at, + source_rank: source_rank, + hash: hash + }; + }) + }); + } else { + onerror(Lang.translate('torrent_parser_request_error') + ' (' + JSON.stringify(json) + ')'); + } + }, function () { + onerror(Lang.translate('torrent_parser_no_responce') + ' (' + base_url + ')'); + }); + } // TorrServer exposes two search backends: + // /search/?query=... — built-in rutor scraper (no setup). + // /torznab/search/?query=... — Torznab indexer(s) configured inside TorrServer + // (EnableTorznabSearch + TorznabUrls). Same JSON + // shape (models.TorrentDetails) as /search/. + // `torrserver_search_type`: 'rutor' | 'torznab' | 'both' (default 'both'). + + + function normalizeTorrServerSize(size) { + if (!size) return ''; + return String(size).replace(/\s*GCiB\b/gi, ' GB').replace(/\s*MCiB\b/gi, ' MB').replace(/\s*KCiB\b/gi, ' KB'); + } + + function torrserver() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var base_url = arguments.length > 1 ? arguments[1] : undefined; + var oncomplite = arguments.length > 2 ? arguments[2] : undefined; + var onerror = arguments.length > 3 ? arguments[3] : undefined; + network$2.timeout(1000 * Storage.field('parse_timeout')); + var mode = Storage.field('torrserver_search_type') || 'both'; + + function mapResult(e, source_rank) { + var hash = Utils$1.hash(e.Title); + var timeValue = Utils$1.strToTime(e.CreateDate); // Some torznab indexers expose only a .torrent download URL via `Link` + // and no magnet. If the link itself is a magnet URI, fall back to it. + + var magnet = e.Magnet || (/^magnet:/i.test(e.Link || '') ? e.Link : ''); + return { + Title: e.Title, + Tracker: e.Tracker, + size: normalizeTorrServerSize(e.Size), + Size: Utils$1.sizeToBytes(normalizeTorrServerSize(e.Size)), + PublishDate: Utils$1.strToTime(e.CreateDate), + PublisTime: timeValue, + Seeders: parseInt(e.Seed), + Peers: parseInt(e.Peer), + MagnetUri: magnet, + Link: e.Link, + viewed: viewed(hash), + CategoryDesc: e.Categories, + checked_at: Date.now(), + source_rank: source_rank, + hash: hash + }; + } + + function callSearch(path, done, fail) { + var u = Utils$1.buildUrl(base_url, path, [{ + name: 'query', + value: params.search + }]); + network$2["native"](u, function (json) { + if (Array.isArray(json)) done(json);else fail(Lang.translate('torrent_parser_request_error') + ' (' + path + ')'); + }, function () { + fail(Lang.translate('torrent_parser_no_responce') + ' (' + base_url + path + ')'); + }); + } + + var calls = []; + if (mode == 'rutor' || mode == 'both') calls.push({ + path: '/search/', + rank: 0 + }); + if (mode == 'torznab' || mode == 'both') calls.push({ + path: '/torznab/search/', + rank: 1 + }); + + function runCall(spec, ondone, onfail) { + callSearch(spec.path, function (json) { + ondone(json.map(function (e) { + return mapResult(e, spec.rank); + })); + }, onfail); + } + + if (calls.length == 1) { + runCall(calls[0], function (items) { + return oncomplite({ + Results: items + }); + }, onerror); + return; + } + + var results = []; + var pending = calls.length; + var success = false; + var first_error; + calls.forEach(function (spec, index) { + runCall(spec, function (items) { + results[index] = items; + success = true; + + if (--pending == 0) { + var _ref5; + + var merged = mergeResults((_ref5 = []).concat.apply(_ref5, _toConsumableArray(results.filter(Boolean)))); + oncomplite({ + Results: merged + }); + } + }, function (err) { + results[index] = null; + first_error = first_error || err; + + if (--pending == 0) { + if (success) { + var _ref6; + + var merged = mergeResults((_ref6 = []).concat.apply(_ref6, _toConsumableArray(results.filter(Boolean)))); + oncomplite({ + Results: merged + }); + } else onerror(first_error || ''); + } + }); + }); + } + + function clear$3() { + network$2.clear(); + } + + var Parser = { + init: init$x, + get: get$5, + jackett: jackett, + clear: clear$3 + }; + + var WatchedHistory = /*#__PURE__*/function () { + function WatchedHistory(movie) { + _classCallCheck(this, WatchedHistory); + + this.file_id = Utils$1.hash(movie.number_of_seasons ? movie.original_name : movie.original_title); + this.html = Template.js('watched_history'); + this.update(); + } + + _createClass(WatchedHistory, [{ + key: "set", + value: function set(_set) { + var watched = Storage.cache('online_watched_last', 5000, {}); + if (!watched[this.file_id]) watched[this.file_id] = {}; + Arrays.extend(watched[this.file_id], _set, true); + Storage.set('online_watched_last', watched); + this.update(); + } + }, { + key: "get", + value: function get() { + var watched = Storage.cache('online_watched_last', 5000, {}); + return watched[this.file_id]; + } + }, { + key: "update", + value: function update() { + var watched = this.get(); + var body = this.html.find('.watched-history__body').empty(); + + if (watched) { + var line = []; + if (watched.balanser_name) line.push(watched.balanser_name); + if (watched.voice_name) line.push(watched.voice_name); + if (watched.season) line.push(Lang.translate('torrent_serial_season') + ' ' + watched.season); + if (watched.episode) line.push(Lang.translate('torrent_serial_episode') + ' ' + watched.episode); + line.forEach(function (n) { + body.append(Template.elem('span', { + text: Utils$1.clearHtmlTags(n).trim() + })); + }); + } else body.append(Template.elem('span', { + text: Lang.translate('no_watch_history') + })); + } + }, { + key: "render", + value: function render(js) { + return js ? this.html : $(this.html); + } + }]); + + return WatchedHistory; + }(); + + function Listener(movie) { + var _self = this; + + function start(e) { + if (e.type == 'list_open') { + Lampa.Listener.follow('torrent_file', open); + } + + if (e.type == 'list_close') { + Lampa.Listener.remove('torrent_file', open); + } + } + + function open(e) { + if (e.type == 'onenter') { + var open_movie = e.params.movie || {}; + if (open_movie.id == movie.id) _self.listener.send('open', e); + } + } + + this.listener = Subscribe$2(); + + this.destroy = function () { + Lampa.Listener.remove('torrent_file', start); + Lampa.Listener.remove('torrent_file', open); + }; + + Lampa.Listener.follow('torrent_file', start); + } + + var voices$1 = ["Анастасия Гайдаржи + Андрей Юрченко", "Студии Суверенного Лепрозория", "Студия Пиратского Дубляжа", "IgVin & Solncekleshka", "Gremlin Creative Studio", "Alternative Production", "HelloMickey Production", "Bubble Dubbing Company", "Н.Севастьянов seva1988", "XDUB Dorama + Колобок", "Мобильное телевидение", "СПД - Сладкая парочка", "Selena International", "Black Street Records", "Intra Communications", "BBC Saint-Petersburg", "Melodic Voice Studio", "Voice Project Studio", "Несмертельное оружие", "Петербургский дубляж", "Studio Victory Аsia", "Asian Miracle Group", "True Dubbing Studio", "Lizard Cinema Trade", "National Geographic", "Позитив-Мультимедиа", "Премьер Мультимедиа", "Уолт Дисней Компани", "Parovoz Production", "Shadow Dub Project", "Zone Vision Studio", "Анастасия Гайдаржи", "The Kitchen Russia", "Малиновский Сергей", "Family Fan Edition", "Paramount Pictures", "Иванова и П. Пашут", "Так Треба Продакшн", "Хихикающий доктор", "Четыре в квадрате", "Project Web Mania", "Paramount Channel", "Back Board Cinema", "Zoomvision Studio", "Universal Channel", "RedDiamond Studio", "НеЗупиняйПродакшн", "Селена Интернешнл", "Студия «Стартрек»", "Колодій Трейлерів", "Universal Russia", "Paramount Comedy", "Андрей Питерский", "Реальный перевод", "MC Entertainment", "Екатеринбург Арт", "Lucky Production", "Cowabunga Studio", "Анатолий Ашмарин", "Васька Куролесов", "Brain Production", "Квадрат Малевича", "Первый канал ОРТ", "Русский Репортаж", "Сolumbia Service", "Sunshine Studio", "GreenРай Studio", "New Dream Media", "DeadLine Studio", "Воробьев Сергей", "DeeAFilm Studio", "Николай Дроздов", "Денис Шадинский", "Cartoon Network", "Amazing Dubbing", "Volume-6 Studio", "Антонов Николай", "Ульпаней Эльром", "Cinema Prestige", "AnimeSpace Team", "CinemaSET GROUP", "XvidClub Studio", "З Ранку До Ночі", "Максим Логинофф", "Студия Горького", "Ушастая озвучка", "Hamster Studio", "Agatha Studdio", "SunshineStudio", "Kulzvuk Studio", "Вартан Дохалов", "Viasat History", "DIVA Universal", "KosharaSerials", "Julia Prosenuk", "SovetRomantica", "Mallorn Studio", "TUMBLER Studio", "CrazyCatStudio", "Syfy Universal", "Horizon Studio", "Анатолий Гусев", "Максим Жолобов", "RedRussian1337", "Creative Sound", "Garsu Pasaulis", "visanti-vasaer", "GoodTime Media", "Кирдин | Stalk", "Anything-group", "Goodtime Media", "Jakob Bellmann", "Витя «говорун»", "Л. Володарский", "Леша Прапорщик", "Медиа-Комплекс", "Прайд Продакшн", "Русский дубляж", "Союзмультфильм", "Студия Колобок", "Red Head Sound", "LE-Production", "ViruseProject", "Victory-Films", "Jetvis Studio", "Greb&Creative", "5-й канал СПб", "Dream Records", "Filiza Studio", "SHIZA Project", "Bars MacAdams", "Nazel & Freya", "Vulpes Vulpes", "Храм Дорам ТВ", "АРК-ТВ Studio", "Film Prestige", "Rainbow World", "Banyan Studio", "Bonsai Studio", "Мадлен Дюваль", "VO-Production", "Voice Project", "Flarrow Films", "Видеопродакшн", "Хоррор Мэйкер", "Lizard Cinema", "Фортуна-Фильм", "VIP Serial HD", "Старый Бильбо", "Семыкина Юлия", "Штамп Дмитрий", "Arasi project", "ARRU Workshop", "Byako Records", "FiliZa Studio", "Gezell Studio", "HamsterStudio", "PCB Translate", "Renegade Team", "Sci-Fi Russia", "The Mike Rec.", "VO-production", "Мика Бондарик", "Наталья Гурзо", "Премьер Видео", "Трамвай-фильм", "Кубик в Кубе", "Кураж-Бамбей", "Первый канал", "Trdlo.studio", "Студия Райдо", "AniLibria.TV", "RG.Paravozik", "Profix Media", "AlphaProject", "AnimeReactor", "Кармен Видео", "Korean Craze", "Sony Channel", "Train Studio", "Фильмэкспорт", "Кирилл Сагач", "ViP Premiere", "Деваль Видео", "RussianGuy27", "HaseRiLLoPaW", "Сергей Дидок", "Mystery Film", "Psychotronic", "КонтентикOFF", "Говинда Рага", "Horror Maker", "Альтера Парс", "Видеоимпульс", "Мьюзик-трейд", "Тоникс Медиа", "Элегия фильм", "Oneinchnales", "Кинопремьера", "A. Lazarchuk", "Animereactor", "BadCatStudio", "DreamRecords", "General Film", "Ivnet Cinema", "RG Paravozik", "sweet couple", "VictoryFilms", "VulpesVulpes", "Wayland team", "Гей Кино Гид", "Нурмухаметов", "Е. Хрусталёв", "К. Поздняков", "Н. Золотухин", "Новый Дубляж", "Р. Янкелевич", "С. Кузьмичёв", "С. Щегольков", "Синема Трейд", "Синта Рурони", "Точка Zрения", "КОМНАТА ДИДИ", "FocusStudio", "Gears Media", "GladiolusTV", "RecentFilms", "NEON Studio", "Володарский", "Мастер Тэйп", "XDUB Dorama", "Sound-Group", "Sony Sci-Fi", "Good People", "JWA Project", "Nika Lenina", "RiZZ_fisher", "New Records", "КураСгречей", "Неоклассика", "CrezaStudio", "Видеосервис", "BTI Studios", "Eurochannel", "Варус-Видео", "HiWay Grope", "Эй Би Видео", "Nickelodeon", "StudioFilms", "Paul Bunyan", "Inter Video", "Franek Monk", "Другое кино", "Севастьянов", "Lazer Video", "Max Nabokov", "Завгородний", "SnowRecords", "Crunchyroll", "Gold Cinema", "Прямостанов", "Огородников", "Кенс Матвей", "1001 cinema", "Cactus Team", "Description", "DVD Classic", "Gala Voices", "hungry_inri", "Neoclassica", "Oghra-Brown", "Rebel Voice", "Saint Sound", "SakuraNight", "TF-AniGroup", "TrainStudio", "Zone Studio", "Zone Vision", "Варус Видео", "Г. Либергал", "Г. Румянцев", "Е. Гаевский", "И. Сафронов", "И. Степанов", "Лазер Видео", "Малиновский", "Новый Канал", "Петербуржец", "С. Визгунов", "С. Кузнецов", "Студия Трёх", "Цікава Ідея", "Я. Беллманн", "Studio Band", "ApofysTeam", "Карповский", "LevshaFilm", "1001cinema", "CP Digital", "Интерфильм", "Комедия ТВ", "Ох! Студия", "SilverSnow", "NewStation", "StudioBand", "Rain Death", "Первый ТВЧ", "HiWayGrope", "Animegroup", "Shachiburi", "CactusTeam", "Sony Turbo", "AXN Sci-Fi", "Т.О Друзей", "West Video", "East Dream", "Sound Film", "MaxMeister", "VoicePower", "CoralMedia", "VSI Moscow", "VGM Studio", "Студия NLS", "Хуан Рохас", "TatamiFilm", "диктор CDV", "Pazl Voice", "Саня Белый", "Мост-Видео", "AimaksaLTV", "Contentica", "Инфо-фильм", "Электричка", "Бусов Глеб", "AvePremier", "BraveSound", "CinemaTone", "DniproFilm", "ELEKTRI4KA", "eraserhead", "Fox Russia", "Mega-Anime", "MifSnaiper", "Nice-Media", "PiratVoice", "Postmodern", "Reanimedia", "Sky Voices", "SkyeFilmTV", "Костюкевич", "Толстобров", "Б. Федоров", "Ващенко С.", "Глуховский", "Держиморда", "Е. Гранкин", "И. Еремеев", "К. Филонов", "Мост Видео", "Н. Антонов", "Н. Дроздов", "Новый диск", "Переводман", "С. Казаков", "С. Лебедев", "С. Макашов", "Союз Видео", "ТВ XXI век", "Ю. Немахов", "Dream Cast", "Причудики", "NewStudio", "Red Media", "Синема УС", "SDI Media", "CasStudio", "turok1990", "HighHopes", "AniLibria", "FanStudio", "Sedorelli", "Flux-Team", "Kobayashi", "KinoGolos", "Fox Crime", "Discovery", "GREEN TEA", "Persona99", "3df voice", "ShinkaDan", "АрхиТеатр", "СВ-Студия", "FilmsClub", "fiendover", "Воротилин", "LakeFilms", "Кириллица", "AniPLague", "JoyStudio", "Формат AB", "AveBrasil", "Невафильм", "OnisFilms", "Neo-Sound", "Муравский", "BeniAffet", "Янкелевич", "AveDorama", "Киномания", "CBS Drama", "Novamedia", "NewComers", "Ghostface", "Sephiroth", "Andre1288", "DoubleRec", "Astana TV", "Останкино", "Видеобаза", "CLS Media", "Seoul Bay", "Хрусталев", "Золотухин", "Videogram", "AAA-Sound", "Epic Team", "GoodVideo", "Gramalant", "INTERFILM", "Kinomania", "No-Future", "RainDeath", "RATTLEBOX", "Sawyer888", "SmallFilm", "SOLDLUCK2", "SpaceDust", "Timecraft", "Total DVD", "Video-BIZ", "VIZ Media", "Васильцев", "Григорьев", "ААА-sound", "Амальгама", "Весельчак", "Деньщиков", "Шадинский", "ЕА Синема", "Зереницын", "И. Клушин", "Имидж-Арт", "Карапетян", "Машинский", "Мительман", "Рыжий пес", "С. Дьяков", "Самарский", "СВ Студия", "Советский", "Солодухин", "ТО Друзей", "Ю. Сербин", "Ю. Товбин", "AnimeVost", "Omskbird", "LostFilm", "AlexFilm", "IdeaFilm", "ColdFilm", "KinoView", "Jimmy J.", "Дольский", "Гаврилов", "Алексеев", "Визгунов", "Либергал", "Кузнецов", "Горчаков", "Gravi-TV", "Murzilka", "STEPonee", "NovaFilm", "Kerems13", "Fox Life", "AzOnFilm", "SorzTeam", "Гаевский", "СВ-Дубль", "GoldTeam", "DexterTV", "AniMedia", "ANIvoice", "JeFerSon", "RealFake", "AniMaunt", "TurkStar", "Медведев", "FilmGate", "Логинофф", "Loginoff", "Animedub", "GostFilm", "ClubFATE", "Hallmark", "Тимофеев", "Дьяконов", "Лексикон", "Superbit", "VideoBIZ", "WestFilm", "kubik&ko", "Марченко", "Журавлев", "Карусель", "Barin101", "Amalgama", "Кинолюкс", "AB-Video", "Пирамида", "Нарышкин", "Дубровин", "Махонько", "Хлопушка", "АрхиАзия", "Ultradox", "Мельница", "Бессонов", "Бахурани", "Индия ТВ", "AdiSound", "ALEKS KV", "AuraFilm", "DeadLine", "Extrabit", "Foxlight", "GetSmart", "ImageArt", "Marclail", "metalrus", "Milirina", "MiraiDub", "MOYGOLOS", "OMSKBIRD", "Radamant", "RoxMarty", "st.Elrom", "VashMax2", "VendettA", "XL Media", "Артемьев", "Васильев", "Савченко", "Воронцов", "Войсовер", "Домашний", "Е. Лурье", "Е. Рудой", "Ист-Вест", "ЛанселаП", "Ленфильм", "Заугаров", "Мосфильм", "Оверлорд", "С. Рябов", "Супербит", "Толмачев", "Ю. Живов", "Paradox", "BaibaKo", "Jaskier", "Колобок", "Михалев", "Дохалов", "SoftBox", "MUZOBOZ", "ZM-Show", "Levelin", "Немахов", "Яроцкий", "BadBajo", "СВ-Кадр", "Позитив", "RusFilm", "Назаров", "Сыендук", "Яковлев", "Lord32x", "Onibaku", "Trina_D", "Hamster", "AniFilm", "HDrezka", "ShowJet", "BukeDub", "SomeWax", "Anifilm", "TVShows", "РуФилмс", "Пифагор", "AniStar", "Netflix", "Octopus", "MixFilm", "Рутилов", "Elysium", "FireDub", "AveTurk", "Багичев", "Дасевич", "Twister", "Морозов", "Sam2007", "SesDizi", "AnyFilm", "Urasiko", "Wakanim", "Латышев", "Ващенко", "Сонотек", "Никитин", "Сонькин", "Кипарис", "Королёв", "RUSCICO", "Филонов", "Ошурков", "Герусов", "Пятница", "5 канал", "Amalgam", "Anistar", "AniWayt", "datynet", "DeadSno", "Eladiel", "ELYSIUM", "F-TRAIN", "FoxLife", "Janetta", "Kолобок", "LeDoyen", "Liga HQ", "lord666", "Macross", "McElroy", "NemFilm", "OpenDub", "PashaUp", "SOFTBOX", "To4kaTV", "TV 1000", "VicTeam", "ZM-SHOW", "Клюквин", "Матвеев", "Смирнов", "Бибиков", "Абдулов", "Данилов", "sf@irat", "Королев", "Люсьена", "Омикрон", "Парадиз", "Пепелац", "Синхрон", "Сокуров", "Хихидок", "AniBaza", "Ozz.tv", "Сербин", "Кравец", "SNK-TV", "Amedia", "Гоблин", "Kiitos", "Есарев", "Санаев", "Шварко", "Карцев", "Кашкин", "Мудров", "Иванов", "Котова", "Kansai", "ZEE TV", "AniDUB", "Ancord", "Berial", "Cuba77", "OSLIKt", "Tycoon", "Курдов", "Кошкин", "Stevie", "Лагута", "Кондор", "Киреев", "FocusX", "Пронин", "neko64", "Shaman", "GalVid", "D.I.M.", "Н-Кино", "Товбин", "binjak", "Акцент", "Козлов", "Нева-1", "Milvus", "Готлиб", "Zerzia", "Дьяков", "Вольга", "Строев", "Alezan", "ДиоНиК", "Стасюк", "TV1000", "NewDub", "Набиев", "Светла", "Nastia", "Emslie", "100 ТВ", "4u2ges", "Azazel", "BD CEE", "Boльгa", "den904", "Elegia", "Gemini", "Jetvis", "JimmyJ", "KANSAI", "kiitos", "L0cDoG", "LeXiKC", "Lisitz", "madrid", "Mikail", "MrRose", "Ozz TV", "Prolix", "RedDog", "Rumble", "Satkur", "Selena", "Suzaku", "WiaDUB", "WVoice", "Zendos", "Агапов", "Акопян", "Шуваев", "АБыГДе", "Акалит", "Альянс", "Анубис", "Anubis", "Арк-ТВ", "Бойков", "Вихров", "Векшин", "Гризли", "Гундос", "Пучков", "Живаго", "Жучков", "Зебуро", "Килька", "Лапшин", "Лизард", "Миняев", "НЕВА 1", "НЛО-TV", "Ракурс", "Россия", "С.Р.И.", "KOleso", "Гуртом", "ТВ СПб", "Швецов", "OnWave", "DZUSKI", "Kerob", "To4ka", "Чадов", "Живов", "ВГТРК", "Elrom", "Игмар", "Котов", "РенТВ", "Рыбин", "Ozeon", "Cmert", "Штейн", "zamez", "Гланц", "Белов", "Anika", "Lupin", "Ryc99", "ko136", "Рябов", "Amber", "Arisu", "DeMon", "Велес", "Акира", "Ворон", "Рудой", "С.Р.И", "Лайко", "D2Lab", "Jetix", "Попов", "Хабар", "Интер", "AniUA", "D2lab", "erogg", "IНТЕР", "JetiX", "PaDet", "RinGo", "seqw0", "SHIZA", "Solod", "ssvss", "Мишин", "АнВад", "Бигыч", "Рукин", "Штамп", "Новий", "Перец", "Райдо", "ТВЧ 1", "Laci", "ETV+", "Vano", "Jade", "RAIM", "Andy", "Нота", "Твин", "ИДДК", "Voiz", "CPIG", "Dice", "Gits", "ICTV", "jept", "KIHO", "Line", "SGEV", "Tori", "Troy", "Twix", "Чуев", "Инис", "Ирэн", "ТВ-3", "ТВИН", "ДТВ", "FOX", "НТВ", "СТС", "ICG", "ТВЦ", "2x2", "MTV", "Oni", "JAM", "AMS", "DDV", "AMC", "НСТ", "IVI", "КТК", "Че!", "MGM", "МИР", "ТНТ", "FDV", "ТВ3", "LDV", "1+1", "2+2", "2х2", "AOS", "CDV", "MCA", "QTV", "TB5", "VHS", "АМС", "ГКГ", "ИГМ", "НТН", "РТР", "ТВ6", "ТРК", "UKR", "D1", "R5", "К9"]; + + /** + * Torrent Title Decoder + * Разбирает название торрента и возвращает структурированные данные + * @param {string} title + * @returns {{ season: number|null, episodes: string|null, year: number|null, quality: string|null, resolution: string|null }} + */ + + function general(title) { + var result = { + season: null, + seasons: [], + episodes: null, + year: null, + quality: null, + resolution: null + }; + if (!title) return result; // ─── Season ─────────────────────────────────────────────────────────────── + // "4 сезон", "4 сезон:" → 4 + // "Season 3" → 3 + // "[S01-02]" → '1-2' (диапазон сезонов) + // "04x01" → 4 (NNxMM) + // "S03E01", "S03" → 3 + + var season_range = title.match(/\[S(\d{1,2})[-–](\d{1,2})\]/i) || title.match(/(?:сезон|season)\s*(\d{1,2})[-–](\d{1,2})/i) || title.match(/(\d{1,2})[-–](\d{1,2})\s*(?:сезон|season)/i); + + if (season_range) { + result.season = parseInt(season_range[1]) + '-' + parseInt(season_range[2]); + } else { + var season = title.match(/(\d+)\s*(?:сезон|season)/i) || title.match(/(?:сезон|season):?\s*(\d{1,2})/i) || title.match(/(\d{1,2})[nd|rd] season/i) || title.match(/(?:тв|tv)-(\d+)/i) || title.match(/\b(\d{1,2})x\d{1,2}/i) || title.match(/\bs(\d{1,2})e/i) || title.match(/\bs(\d{1,2})\b/i); + if (season) result.season = parseInt(season[1]); + } + + if (!result.season) result.season = 1; // Если сезон не указан, предполагаем что это 1-й сезон + + if (typeof result.season === 'string' && result.season.indexOf('-') !== -1) { + var parts = result.season.split('-'); + var from = parseInt(parts[0]); + var to = parseInt(parts[1]); + + for (var i = from; i <= to; i++) { + result.seasons.push(i); + } + } else { + result.seasons = [parseInt(result.season)]; + } // ─── Episodes ───────────────────────────────────────────────────────────── + // "04x01-07 из 10" → '1-7' + // "1-4 серия из 10" → '1-4' + // "[1- из 10]", "(1- из 10)" → '1-10' + // "(3-10 из 20)" → '3-10' + // "[12 из 12]", "(12 из 12)" → '12' + // "S01E05", "E05", "5 серия" → '5' + // NNxMM-KK format + + + var ep_nx = title.match(/\d{1,2}x(\d{1,2})[-–](\d{1,2})/i); + + if (ep_nx) { + result.episodes = parseInt(ep_nx[1]) + '-' + parseInt(ep_nx[2]); + } else { + // Range with optional "серия/из" + var ep_range = title.match(/(\d+)\s*[-–]\s*(\d+)\s*(?:серия|episode)/i) || title.match(/(\d{1,3})[-–](\d{1,3})\s*серии/i) || title.match(/[[(](\d{1,3})\s*[-–](\d{1,3})\s*(?:из|з|of)\s*(\d{1,3})/i) || title.match(/[[(](\d{1,3})\s*[-–]\s*(?:из|з|of)\s*(\d{1,3})/i) || title.match(/[[(](\d{1,3})\s*(?:из|з|of)\s*(\d{1,3})[\])]/i) || title.match(/[e](\d{1,3})\s*[-–]\s*(?:(?:из|з|of)\s+)?(\d{1,3})/i) || title.match(/(?:серии|серія|episodes)\s*(\d{1,3})\s*(?:(?:из|з|of)\s+)?(\d{1,3})/i) || title.match(/(?:серии|серія|episodes)\s*(\d{1,3})[-–](\d{1,3})\s*(?:(?:из|з|of)\s+)?(\d{1,3})/i) || title.match(/(?:серии|episodes):\s*(\d+)[-–](\d+)/i); + + if (ep_range) { + // Убеждаемся что это не диапазон годов (1990-2024) + var a = parseInt(ep_range[1]); + var b = parseInt(ep_range[2]); + var looks_like_years = a >= 1900 && b >= 1900; + + if (!looks_like_years) { + result.episodes = a == b ? '1-' + b : a > 1 ? '1-' + a : a + '-' + b; + } + } else { + // Single episode + var ep_single = title.match(/\bs\d{1,2}e(\d+)/i) || title.match(/\d{1,2}x(\d{1,2})\b/i) || title.match(/\be(\d{1,2})\b/i) || title.match(/[[(](\d{1,2})\s+(?:из|з|of)\s+\d{1,2}[\])]/) || title.match(/(\d{1,2})\s+(?:из|з|of)\s+\d{1,2}/) || title.match(/(\d+)\s*(?:серия|episode)/i); + if (ep_single) result.episodes = '1-' + String(parseInt(ep_single[1])); + } + } // ─── Year ───────────────────────────────────────────────────────────────── + // "(2022-2023)" → 2022 (диапазон лет — берём первый) + // "(2024)" → 2024 + // bare "2024" → 2024 + + + var year = title.match(/\(((?:19|20)\d{2})[-–](?:19|20)\d{2}\)/) || title.match(/\(((?:19|20)\d{2})\)/) || title.match(/\b((?:19|20)\d{2})\b/); + if (year) result.year = parseInt(year[1]); // ─── Quality ────────────────────────────────────────────────────────────── + // Порядок важен: более длинные/специфичные варианты идут первыми, + // чтобы "WEB-DLRip" не поглощалось "WEB-DL" и т.д. + + var qualities = ['WEB-DLRip', 'WEB-DL', 'WEBRip', 'WEB', 'Blu-Ray', 'BluRay', 'BDRip', 'HDRip', 'HDTV', 'DVDRip', 'DVD', 'CAM', 'TS']; + + for (var _i = 0, _qualities = qualities; _i < _qualities.length; _i++) { + var q = _qualities[_i]; + // Экранируем дефис, добавляем lookahead чтобы "WEB-DL" не совпадало с "WEB-DLRip" + var pattern = q.replace(/-/g, '[-]?') + '(?![a-zA-Z])'; + + if (new RegExp(pattern, 'i').test(title)) { + result.quality = q; + break; + } + } // ─── HDR ───────────────────────────────────────────────────────────────── + + + var hdr = title.match(/\b(HDR|Dolby Vision)\b/i); + if (hdr) result.hdr = hdr[1]; // ─── Resolution ─────────────────────────────────────────────────────────── + + var resolution_map = { + '4k': '4K', + 'uhd': '4K', + '2160p': '4K', + '1440p': '2K', + '1080p': 'FHD', + '720p': 'HD', + '480p': 'SD', + '360p': 'LD' + }; + var resolution = title.match(/\b(4K|UHD|2160p|1080p|720p|480p|360p)\b/i); + if (resolution) result.resolution = resolution_map[resolution[1].toLowerCase()] || resolution[1]; + return result; + } + + function voices(title) { + if (!title) return []; + var lower = title.toLowerCase(); + var found = []; + voices$1.forEach(function (voice) { + if (found.indexOf(voice) === -1 && lower.indexOf(voice.toLowerCase()) !== -1) { + found.push(voice); + } + }); + return found; + } + + var TitleParser = { + general: general, + voices: voices + }; + + var filter_langs = [{ + title: '#{filter_lang_ru}', + code: 'ru' + }, { + title: '#{filter_lang_uk}', + code: 'uk' + }, { + title: '#{filter_lang_en}', + code: 'en' + }, { + title: '#{filter_lang_be}', + code: 'be' + }, { + title: '#{filter_lang_zh}', + code: 'zh|cn' + }, { + title: '#{filter_lang_ja}', + code: 'ja' + }, { + title: '#{filter_lang_ko}', + code: 'ko' + }, { + title: '#{filter_lang_af}', + code: 'af' + }, { + title: '#{filter_lang_sq}', + code: 'sq' + }, { + title: '#{filter_lang_ar}', + code: 'ar' + }, { + title: '#{filter_lang_az}', + code: 'az' + }, { + title: '#{filter_lang_hy}', + code: 'hy' + }, { + title: '#{filter_lang_ba}', + code: 'ba' + }, { + title: '#{filter_lang_bg}', + code: 'bg' + }, { + title: '#{filter_lang_bn}', + code: 'bn' + }, { + title: '#{filter_lang_bs}', + code: 'bs' + }, { + title: '#{filter_lang_ca}', + code: 'ca' + }, { + title: '#{filter_lang_ce}', + code: 'ce' + }, { + title: '#{filter_lang_cs}', + code: 'cs' + }, { + title: '#{filter_lang_da}', + code: 'da' + }, { + title: '#{filter_lang_ka}', + code: 'ka' + }, { + title: '#{filter_lang_de}', + code: 'de' + }, { + title: '#{filter_lang_el}', + code: 'el' + }, { + title: '#{filter_lang_es}', + code: 'es' + }, { + title: '#{filter_lang_et}', + code: 'et' + }, { + title: '#{filter_lang_fa}', + code: 'fa' + }, { + title: '#{filter_lang_fi}', + code: 'fi' + }, { + title: '#{filter_lang_fr}', + code: 'fr' + }, { + title: '#{filter_lang_ga}', + code: 'ga' + }, { + title: '#{filter_lang_gl}', + code: 'gl' + }, { + title: '#{filter_lang_gn}', + code: 'gn' + }, { + title: '#{filter_lang_he}', + code: 'he' + }, { + title: '#{filter_lang_hi}', + code: 'hi' + }, { + title: '#{filter_lang_hr}', + code: 'hr' + }, { + title: '#{filter_lang_hu}', + code: 'hu' + }, { + title: '#{filter_lang_id}', + code: 'id' + }, { + title: '#{filter_lang_is}', + code: 'is' + }, { + title: '#{filter_lang_it}', + code: 'it' + }, { + title: '#{filter_lang_kk}', + code: 'kk' + }, { + title: '#{filter_lang_ks}', + code: 'ks' + }, { + title: '#{filter_lang_ku}', + code: 'ku' + }, { + title: '#{filter_lang_ky}', + code: 'ky' + }, { + title: '#{filter_lang_lt}', + code: 'lt' + }, { + title: '#{filter_lang_lv}', + code: 'lv' + }, { + title: '#{filter_lang_mi}', + code: 'mi' + }, { + title: '#{filter_lang_mk}', + code: 'mk' + }, { + title: '#{filter_lang_mn}', + code: 'mn' + }, { + title: '#{filter_lang_mt}', + code: 'mt' + }, { + title: '#{filter_lang_no}', + code: 'no|nb|nn' + }, { + title: '#{filter_lang_ne}', + code: 'ne' + }, { + title: '#{filter_lang_nl}', + code: 'nl' + }, { + title: '#{filter_lang_pa}', + code: 'pa' + }, { + title: '#{filter_lang_pl}', + code: 'pl' + }, { + title: '#{filter_lang_ps}', + code: 'ps' + }, { + title: '#{filter_lang_pt}', + code: 'pt' + }, { + title: '#{filter_lang_ro}', + code: 'ro' + }, { + title: '#{filter_lang_si}', + code: 'si' + }, { + title: '#{filter_lang_sk}', + code: 'sk' + }, { + title: '#{filter_lang_sl}', + code: 'sl' + }, { + title: '#{filter_lang_sm}', + code: 'sm' + }, { + title: '#{filter_lang_so}', + code: 'so' + }, { + title: '#{filter_lang_sr}', + code: 'sr' + }, { + title: '#{filter_lang_sv}', + code: 'sv' + }, { + title: '#{filter_lang_sw}', + code: 'sw' + }, { + title: '#{filter_lang_ta}', + code: 'ta' + }, { + title: '#{filter_lang_tg}', + code: 'tg' + }, { + title: '#{filter_lang_th}', + code: 'th' + }, { + title: '#{filter_lang_tk}', + code: 'tk' + }, { + title: '#{filter_lang_tr}', + code: 'tr' + }, { + title: '#{filter_lang_tt}', + code: 'tt' + }, { + title: '#{filter_lang_ur}', + code: 'ur' + }, { + title: '#{filter_lang_uz}', + code: 'uz' + }, { + title: '#{filter_lang_vi}', + code: 'vi' + }, { + title: '#{filter_lang_yi}', + code: 'yi' + }]; + + /** + * Компонент "Torrents" + * @param {*} object + */ + + function component$h(object) { + Arrays.extend(object, { + movie: { + title: object.search, + original_title: object.search + }, + params: { + noinfo: object.from_search ? true : false + } + }); + var network = new Request(); + var scroll = new Scroll({ + mask: true, + over: true + }); + var files = new Explorer$1(object); + var history = new WatchedHistory(object.movie); + var filter; + var results = []; + var filtred = []; + var listener; + var total_pages = 1; + var last; + var initialized; + var filter_items = { + quality: [Lang.translate('torrent_parser_any_one'), '4k', '1080p', '720p'], + hdr: [Lang.translate('torrent_parser_no_choice'), Lang.translate('torrent_parser_yes'), Lang.translate('torrent_parser_no')], + dv: [Lang.translate('torrent_parser_no_choice'), 'Dolby Vision', 'Dolby Vision TV', Lang.translate('torrent_parser_no')], + sub: [Lang.translate('torrent_parser_no_choice'), Lang.translate('torrent_parser_yes'), Lang.translate('torrent_parser_no')], + voice: [], + tracker: [Lang.translate('torrent_parser_any_two')], + year: [Lang.translate('torrent_parser_any_two')], + lang: [Lang.translate('torrent_parser_any_two')], + _3d: [Lang.translate('torrent_parser_no_choice'), Lang.translate('torrent_parser_yes'), Lang.translate('torrent_parser_no')] + }; + var filter_translate = { + quality: Lang.translate('torrent_parser_quality'), + hdr: 'HDR', + dv: 'Dolby Vision', + sub: Lang.translate('torrent_parser_subs'), + voice: Lang.translate('torrent_parser_voice'), + tracker: Lang.translate('torrent_parser_tracker'), + year: Lang.translate('torrent_parser_year'), + season: Lang.translate('torrent_parser_season'), + lang: Lang.translate('title_language_short'), + _3d: '3D' + }; + var filter_multiple = ['quality', 'voice', 'tracker', 'season', 'lang']; + var sort_translate = { + popular: Lang.translate('title_popular'), + Seeders: Lang.translate('torrent_parser_sort_by_seeders'), + Size: Lang.translate('torrent_parser_sort_by_size'), + Title: Lang.translate('torrent_parser_sort_by_name'), + Tracker: Lang.translate('torrent_parser_sort_by_tracker'), + PublisTime: Lang.translate('torrent_parser_sort_by_date'), + viewed: Lang.translate('torrent_parser_sort_by_viewed') + }; + var i = 20, + y = new Date().getFullYear(); + + while (i--) { + filter_items.year.push(y - (19 - i) + ''); + } + + var finded_seasons = []; + var finded_seasons_full = []; + filter_items.lang = filter_items.lang.concat(filter_langs.map(function (a) { + return Lang.translate(a.title); + })); + scroll.minus(files.render().find('.explorer__files-head')); + scroll.body().addClass('torrent-list'); + if (object.from_search) object.movie.original_title = ''; + + this.create = function () { + return this.render(); + }; + + this.initialize = function () { + var _this = this; + + this.activity.loader(true); + + if ((object.movie.original_language == 'ja' || object.movie.original_language == 'zh') && object.movie.genres.find(function (g) { + return g.id == 16; + }) && Storage.field('language') !== 'en') { + network.silent(TMDB$1.api((object.movie.name ? 'tv' : 'movie') + '/' + object.movie.id + '?api_key=' + TMDB$1.key() + '&language=en'), function (result) { + object.search_two = result.name || result.title; + + _this.parse(); + }, this.parse.bind(this)); + } else { + this.parse(); + } + + scroll.onEnd = this.next.bind(this); + listener = new Listener(object.movie); + listener.listener.follow('open', function (e) { + if (object.movie.original_name) { + history.set({ + balanser_name: 'Torrent', + season: e.element.season, + episode: e.element.episode + }); + } else { + history.set({ + balanser_name: 'Torrent' + }); + } + }); + return this.render(); + }; + + this.parse = function () { + var _this2 = this; + + filter = new Filter(object); + Parser.get(object, function (data) { + results = data; + results.Results.forEach(function (element) { + element.general = TitleParser.general(element.Title.toLowerCase()); + }); + + _this2.build(); + + Layer.update(scroll.render(true)); + + _this2.activity.loader(false); + + _this2.activity.toggle(); + }, function (text) { + _this2.empty(Lang.translate('torrent_error_connect') + ': ' + text); + }); + + filter.onSearch = function (value) { + var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Activity.replace({ + search: value, + clarification: true, + global: extra.global + }); + }; + + filter.onBack = function () { + _this2.start(); + }; + + filter.render().find('.selector').on('hover:focus', function (e) { + }); + filter.addButtonBack(); + files.appendHead(filter.render()); + }; + + this.empty = function (descr, add_button) { + var em_params = { + descr: descr + }; + + if (add_button) { + em_params.buttons = [{ + title: Lang.translate('filter_clarify'), + onEnter: function onEnter() { + filter.render().find('.filter--search').trigger('hover:enter'); + } + }]; + } + + var empty = new Empty(em_params); + files.render().find('.explorer__files-head').addClass('hide'); + files.appendFiles(empty.render(filter.empty())); + scroll.body().removeClass('torrent-list'); + this.start = empty.start.bind(empty); + this.activity.loader(false); + this.activity.toggle(); + }; + + this.listEmpty = function () { + var em = Template.get('empty_filter'); + var bn = $('
    ' + Lang.translate('filter_clarify') + '
    '); + bn.on('hover:enter', function () { + filter.render().find('.filter--filter').trigger('hover:enter'); + }); + em.find('.empty-filter__subtitle').text(Lang.translate('empty_text')); + em.find('.empty-filter__title').remove(); + em.find('.empty-filter__buttons').removeClass('hide').append(bn); + scroll.body().removeClass('torrent-list'); + scroll.append(em); + }; + + this.buildSorted = function () { + var need = Storage.get('torrents_sort', 'popular'); + var select = [{ + title: Lang.translate('title_popular'), + sort: 'popular' + }, { + title: Lang.translate('torrent_parser_sort_by_seeders'), + sort: 'Seeders' + }, { + title: Lang.translate('torrent_parser_sort_by_size'), + sort: 'Size' + }, { + title: Lang.translate('torrent_parser_sort_by_name'), + sort: 'Title' + }, { + title: Lang.translate('torrent_parser_sort_by_tracker'), + sort: 'Tracker' + }, { + title: Lang.translate('torrent_parser_sort_by_date'), + sort: 'PublisTime' + }, { + title: Lang.translate('torrent_parser_sort_by_viewed'), + sort: 'viewed' + }]; + select.forEach(function (element) { + if (element.sort == need) element.selected = true; + }); + this.sortResults(need); + filter.set('sort', select); + this.selectedSort(); + }; + + this.sortResults = function (need) { + if (object.movie.number_of_seasons && need == 'popular') { + results.Results.sort(function (a, b) { + var s_a = parseInt(String(a.general.season).split('-').pop()); + var s_b = parseInt(String(b.general.season).split('-').pop()); + var e_a = a.general.episodes ? parseInt(String(a.general.episodes).split('-').pop()) : 0; + var e_b = b.general.episodes ? parseInt(String(b.general.episodes).split('-').pop()) : 0; + return s_b - s_a || e_b - e_a || b.Seeders - a.Seeders; + }); + } else if (need == 'popular') filter.sort(results.Results, 'Seeders');else filter.sort(results.Results, need); + + this.sortWithViewed(); + }; + + this.sortWithViewed = function () { + var popular = []; + var other = []; + results.Results.forEach(function (a) { + if (a.viewed) popular.push(a);else other.push(a); + }); + popular.sort(function (a, b) { + return b.Seeders - a.Seeders; + }); + results.Results = popular.concat(other); + }; + + this.cardID = function () { + return object.movie.id + ':' + (object.movie.number_of_seasons ? 'tv' : 'movie'); + }; + + this.getFilterData = function () { + var all = Storage.cache('torrents_filter_data', 500, {}); + var cid = this.cardID(); + return all[cid] || Storage.get('torrents_filter', '{}'); + }; + + this.setFilterData = function (filter) { + var all = Storage.cache('torrents_filter_data', 500, {}); + var cid = this.cardID(); + all[cid] = filter; + Storage.set('torrents_filter_data', all); + Storage.set('torrents_filter', filter); + }; + + this.buildFilterd = function () { + var need = this.getFilterData(); + var select = []; + + var add = function add(type, title) { + var items = filter_items[type]; + var subitems = []; + var multiple = filter_multiple.indexOf(type) >= 0; + var value = need[type]; + if (multiple) value = Arrays.toArray(value); + items.forEach(function (name, i) { + subitems.push({ + title: name, + //selected: multiple ? i == 0 : value == i, + checked: multiple && value.indexOf(name) >= 0, + checkbox: multiple && i > 0, + noselect: true, + index: i + }); + }); + select.push({ + title: title, + subtitle: multiple ? value.length ? value.join(', ') : items[0] : typeof value == 'undefined' ? items[0] : items[value], + items: subitems, + noselect: true, + stype: type + }); + }; + + filter_items.voice = [Lang.translate('torrent_parser_any_two'), Lang.translate('torrent_parser_voice_dubbing'), Lang.translate('torrent_parser_voice_polyphonic'), Lang.translate('torrent_parser_voice_two'), Lang.translate('torrent_parser_voice_amateur')]; + filter_items.tracker = [Lang.translate('torrent_parser_any_two')]; + filter_items.season = [Lang.translate('torrent_parser_any_two')]; + results.Results.forEach(function (element) { + var title = element.Title.toLowerCase(), + tracker = element.Tracker; + + for (var _i = 0; _i < voices$1.length; _i++) { + var voice = voices$1[_i].toLowerCase(); + + if (title.indexOf(voice) >= 0) { + if (filter_items.voice.indexOf(voices$1[_i]) == -1) filter_items.voice.push(voices$1[_i]); + } + + if (!element.info) { + element.info = { + voices: TitleParser.voices(element.Title) + }; + } + + if (element.info && element.info.voices) { + if (element.info.voices.map(function (v) { + return v.toLowerCase(); + }).indexOf(voice) >= 0) { + if (filter_items.voice.indexOf(voices$1[_i]) == -1) filter_items.voice.push(voices$1[_i]); + } + } + } + + tracker.split(',').forEach(function (t) { + if (filter_items.tracker.indexOf(t.trim()) === -1) filter_items.tracker.push(t.trim()); + }); + element.general.seasons.forEach(function (season) { + var number = season + ''; + + if (finded_seasons.indexOf(number) == -1) { + finded_seasons.push(number); + finded_seasons_full.push(number); + } + }); + }); + finded_seasons_full.sort(function (a, b) { + var ac = parseInt(a); + var bc = parseInt(b); + if (ac > bc) return 1;else if (ac < bc) return -1;else return 0; + }); + finded_seasons.sort(function (a, b) { + var ac = parseInt(a); + var bc = parseInt(b); + if (ac > bc) return 1;else if (ac < bc) return -1;else return 0; + }); + if (finded_seasons.length) filter_items.season = filter_items.season.concat(finded_seasons); // Надо очистить от отсутствующих ключей + + need.voice = Arrays.removeNoIncludes(Arrays.toArray(need.voice), filter_items.voice); + need.tracker = Arrays.removeNoIncludes(Arrays.toArray(need.tracker), filter_items.tracker); + need.season = Arrays.removeNoIncludes(Arrays.toArray(need.season), filter_items.season); + this.setFilterData(need); + select.push({ + title: Lang.translate('torrent_parser_reset'), + reset: true + }); + add('quality', Lang.translate('torrent_parser_quality')); + add('hdr', 'HDR'); + add('dv', 'Dolby Vision'); + add('sub', Lang.translate('torrent_parser_subs')); + add('voice', Lang.translate('torrent_parser_voice')); + add('lang', Lang.translate('title_language_short')); + add('season', Lang.translate('torrent_parser_season')); + add('tracker', Lang.translate('torrent_parser_tracker')); + add('year', Lang.translate('torrent_parser_year')); + add('_3d', '3D'); + filter.set('filter', select); + this.selectedFilter(); + }; + + this.selectedFilter = function () { + var need = this.getFilterData(), + select = []; + + for (var _i2 in need) { + if (need[_i2]) { + if (Arrays.isArray(need[_i2])) { + if (need[_i2].length) select.push(filter_translate[_i2] + ':' + need[_i2].join(', ')); + } else { + select.push(filter_translate[_i2] + ': ' + filter_items[_i2][need[_i2]]); + } + } + } + + filter.chosen('filter', select); + }; + + this.selectedSort = function () { + var select = Storage.get('torrents_sort', 'popular'); + filter.chosen('sort', [sort_translate[select]]); + }; + + this.build = function () { + var _this3 = this; + + this.buildSorted(); + this.buildFilterd(); + this.filtred(); + + filter.onSelect = function (type, a, b) { + if (type == 'sort') { + Storage.set('torrents_sort', a.sort); + + _this3.sortResults(a.sort); + } else { + if (a.reset) { + _this3.setFilterData({}); + + _this3.buildFilterd(); + } else { + a.items.forEach(function (n) { + return n.checked = false; + }); + + var filter_data = _this3.getFilterData(); + + filter_data[a.stype] = filter_multiple.indexOf(a.stype) >= 0 ? [] : b.index; + a.subtitle = b.title; + + _this3.setFilterData(filter_data); + } + } + + _this3.applyFilter(); + + _this3.start(); + }; + + filter.onCheck = function (type, a, b) { + var data = _this3.getFilterData(), + need = Arrays.toArray(data[a.stype]); + + if (b.checked && need.indexOf(b.title)) need.push(b.title);else if (!b.checked) Arrays.remove(need, b.title); + data[a.stype] = need; + + _this3.setFilterData(data); + + a.subtitle = need.length ? need.join(', ') : a.items[0].title; + + _this3.applyFilter(); + }; + + this.showResults(); + }; + + this.applyFilter = function () { + this.filtred(); + this.selectedFilter(); + this.selectedSort(); + this.reset(); + this.showResults(); + last = scroll.render().find('.torrent-item:eq(0)')[0]; + if (last) scroll.update(last);else scroll.reset(); + }; + + this.filtred = function () { + var filter_data = this.getFilterData(); + var filter_any = false; + + for (var _i3 in filter_data) { + var filr = filter_data[_i3]; + + if (filr) { + if (Arrays.isArray(filr)) { + if (filr.length) filter_any = true; + } else filter_any = true; + } + } + + filtred = results.Results.filter(function (element) { + if (filter_any) { + var passed = false, + nopass = false, + title = element.Title.toLowerCase(), + tracker = element.Tracker; + var qua = Arrays.toArray(filter_data.quality), + hdr = filter_data.hdr, + dv = filter_data.dv, + sub = filter_data.sub, + voi = Arrays.toArray(filter_data.voice), + tra = Arrays.toArray(filter_data.tracker), + ses = Arrays.toArray(filter_data.season), + lng = Arrays.toArray(filter_data.lang), + yer = filter_data.year, + _3d = filter_data._3d; + + var test = function test(search, test_index) { + var regex = new RegExp(search); + return test_index ? title.indexOf(search) >= 0 : regex.test(title); + }; + + var check = function check(search, invert) { + if (test(search)) { + if (invert) nopass = true;else passed = true; + } else { + if (invert) passed = true;else nopass = true; + } + }; + + var includes = function includes(type, arr) { + if (!arr.length) return; + var any = false; + arr.forEach(function (a) { + if (type == 'quality') { + if (a == '4k' && test('(4k|uhd)[ |\\]|,|$]|2160[pр]|ultrahd')) any = true; + if (a == '1080p' && test('fullhd|1080[pр]')) any = true; + if (a == '720p' && test('720[pр]')) any = true; + } + + if (type == 'voice') { + var p = filter_items.voice.indexOf(a); + var n = element.info && element.info.voices ? element.info.voices.map(function (v) { + return v.toLowerCase(); + }) : []; + + if (p == 1) { + if (test('дублирован|дубляж| apple| dub| d[,| |$]|[,|\\s]дб[,|\\s|$]')) any = true; + } else if (p == 2) { + if (test('многоголос| p[,| |$]|[,|\\s](лм|пм)[,|\\s|$]')) any = true; + } else if (p == 3) { + if (test('двухголос|двуголос| l2[,| |$]|[,|\\s](лд|пд)[,|\\s|$]')) any = true; + } else if (p == 4) { + if (test('любитель|авторский| l1[,| |$]|[,|\\s](ло|ап)[,|\\s|$]')) any = true; + } else if (test(a.toLowerCase(), true)) any = true;else if (n.length && n.indexOf(a.toLowerCase()) >= 0) any = true; + } + + if (type == 'lang') { + var _p = filter_items.lang.indexOf(a); + + var c = filter_langs[_p - 1]; + + if (c) { + if (element.languages) { + if (element.languages.find(function (l) { + return l.toLowerCase().slice(0, 2) == c.code; + })) any = true; + } else if (title.indexOf(c.code) >= 0) any = true; + } else any = true; + } + + if (type == 'tracker') { + if (tracker.split(',').find(function (t) { + return t.trim().toLowerCase() == a.toLowerCase(); + })) any = true; + } + + if (type == 'season') { + var _i4 = finded_seasons.indexOf(a); + + var f = parseInt(finded_seasons_full[_i4]); + if (element.general.seasons.indexOf(f) >= 0) any = true; + } + }); + if (any) passed = true;else nopass = true; + }; + + includes('quality', qua); + includes('voice', voi); + includes('tracker', tra); + includes('season', ses); + includes('lang', lng); + if (hdr) check('[\\[| ]hdr[10| |\\]|,|$]', hdr !== 1); + + if (dv == 0) { + check(filter_items.dv[dv], dv !== 1); + } else if (dv == 1) { + check('dolby vision'); + } else if (dv == 2) { + check('dolby vision tv'); + } else if (dv == 3) { + check('dolby vision', dv !== 0); + } + + if (sub) check(' sub|[,|\\s]ст[,|\\s|$]', sub !== 1); + + if (yer) { + check(filter_items.year[yer]); + } + + if (_3d) check(' стереопара|interlace|anaglyph|анаглиф|bd3d|over\\-?under|side\\-?by\\-?side|[\\-\\[\\(| ]((half|h)?ou|(half|h)?sbs|lrq?|abq?|ba|rl|3d[\\- ]video)([ |\\]\\),]|$)', _3d !== 1); + return nopass ? false : passed; + } else return true; + }); + }; + + this.showResults = function () { + total_pages = Math.ceil(filtred.length / 20); + + if (filtred.length) { + scroll.body().addClass('torrent-list'); + scroll.append(history.render(true)); + this.append(filtred.slice(0, 20)); + } else { + if (results.Results.length) this.listEmpty();else this.empty(Lang.translate('search_nofound'), true); + } + + files.appendFiles(scroll.render()); + }; + + this.reset = function () { + last = false; + scroll.clear(); + }; + + this.next = function () { + if (object.page < 15 && object.page < total_pages) { + object.page++; + var offset = (object.page - 1) * 20; + this.append(filtred.slice(offset, offset + 20), true); + } + }; + + this.mark = function (element, item, add) { + var viewed = Storage.cache('torrents_view', 5000, []); + + if (add) { + if (viewed.indexOf(element.hash) == -1) { + viewed.push(element.hash); + item.append('
    ' + Template.get('icon_viewed', {}, true) + '
    '); + } + } else { + element.viewed = true; + Arrays.remove(viewed, element.hash); + item.find('.torrent-item__viewed').remove(); + } + + element.viewed = add; + Storage.set('torrents_view', viewed); + if (!add) Storage.remove('torrents_view', element.hash); + }; + + this.addToBase = function (element) { + Torserver.add({ + poster: object.movie.img, + title: object.movie.title + ' / ' + object.movie.original_title, + link: element.MagnetUri || element.Link, + data: { + lampa: true, + movie: object.movie + } + }, function () { + Noty.show(object.movie.title + ' - ' + Lang.translate('torrent_parser_added_to_mytorrents')); + }); + }; + + this.append = function (items, append) { + var _this4 = this; + + items.forEach(function (element) { + var date = Utils$1.parseTime(element.PublishDate); + var bitrate = object.movie.runtime ? Utils$1.calcBitrate(element.Size, object.movie.runtime) : 0; + Arrays.extend(element, { + title: element.Title, + date: date.full, + tracker: element.Tracker, + bitrate: bitrate, + size: !isNaN(parseInt(element.Size)) ? Utils$1.bytesToSize(element.Size) : element.size, + seeds: element.Seeders, + grabs: element.Peers + }); + var item = Template.get('torrent', element); + var need_remove_ffprobe = false; + + if (!element.ffprobe) { + element.ffprobe = []; + need_remove_ffprobe = true; + } + + if (element.ffprobe) { + var ffprobe_elem = item.find('.torrent-item__ffprobe'); + var ffprobe_tags = []; + var general = element.general || {}; + var quality = general.resolution || (element.info && element.info.quality ? Utils$1.qualityToText(element.info.quality + 'p') : ''); + + if (object.movie.number_of_seasons && general.season) { + ffprobe_elem.append('
    S' + general.season + '
    ' + (general.episodes ? '
    ' + general.episodes + '
    ' : '') + '
    '); + } + + if (quality) ffprobe_tags.push({ + media: 'resolution', + value: quality + }); + if (general.hdr) ffprobe_tags.push({ + media: 'resolution', + value: 'HDR' + }); + var video = element.ffprobe.find(function (a) { + return a.codec_type == 'video'; + }); + if (!quality && video) ffprobe_tags.push({ + media: 'resolution', + value: Utils$1.qualityToText(Utils$1.resolutionToQuality(video.width, video.height, 'p')) + }); + var audio = element.ffprobe.filter(function (a) { + return a.codec_type == 'audio' && a.tags; + }); + var subs = element.ffprobe.filter(function (a) { + return a.codec_type == 'subtitle' && a.tags; + }); + var voice = Arrays.clone(element.info && element.info.voices ? element.info.voices : []); + if (video) ffprobe_tags.push({ + media: 'video', + value: video.width + 'x' + video.height + }); + var is_71 = element.ffprobe.find(function (a) { + return a.codec_type == 'audio' && a.channels == 8; + }); + var is_51 = element.ffprobe.find(function (a) { + return a.codec_type == 'audio' && a.channels == 6; + }); + if (is_71) ffprobe_tags.push({ + media: 'channels', + value: '7.1' + }); + if (is_51) ffprobe_tags.push({ + media: 'channels', + value: '5.1' + }); + audio.forEach(function (a) { + var line = []; + var lang = (a.tags.language || '').toUpperCase(); + var name = a.tags.title || a.tags.handler_name || ''; + + var _short = voices$1.find(function (v) { + return name.toLowerCase().indexOf(v.toLowerCase()) >= 0; + }); + + if (_short) name = _short; + var find = voice.find(function (v) { + return name.toLowerCase().indexOf(v.toLowerCase()) >= 0; + }); + if (find) Arrays.remove(voice, find); + if (lang) line.push(lang); + + if (name && lang !== 'ENG') { + name = find || name; + if (name.toLowerCase().indexOf('dub') >= 0 || name.toLowerCase() == 'd') name = Lang.translate('torrent_parser_voice_dubbing'); + line.push(Utils$1.shortText(Utils$1.capitalizeFirstLetter(name), 20)); + } + + if (line.length) ffprobe_tags.push({ + media: 'audio', + value: line.join(' - ') + }); + }); + voice.forEach(function (v) { + ffprobe_tags.push({ + media: 'audio', + value: v + }); + }); + var find_subtitles = []; + subs.forEach(function (a) { + var lang = (a.tags.language || '').toUpperCase(); + if (lang) find_subtitles.push(lang); + }); + find_subtitles = find_subtitles.filter(function (el, pos) { + return find_subtitles.indexOf(el) == pos; + }); + find_subtitles.slice(0, 4).forEach(function (a) { + ffprobe_tags.push({ + media: 'subtitle', + value: a + }); + }); + if (find_subtitles.length > 4) ffprobe_tags.push({ + media: 'subtitle', + value: '+' + (find_subtitles.length - 4) + }); + ffprobe_tags = ffprobe_tags.filter(function (el, pos) { + return ffprobe_tags.map(function (a) { + return a.value + a.media; + }).indexOf(el.value + el.media) == pos; + }); + ffprobe_tags.forEach(function (tag) { + ffprobe_elem.append('
    ' + tag.value + '
    '); + }); + if ($('> div', ffprobe_elem).length) ffprobe_elem.removeClass('hide'); + if (need_remove_ffprobe) delete element.ffprobe; + } + + if (!bitrate) item.find('.bitrate').remove(); + if (element.viewed) item.append('
    ' + Template.get('icon_viewed', {}, true) + '
    '); + if (!element.size || parseInt(element.size) == 0) item.find('.torrent-item__size').remove(); + item.on('hover:focus', function (e) { + last = e.target; + scroll.update($(e.target), true); + }).on('hover:hover hover:touch', function (e) { + last = e.target; + Navigator.focused(last); + }).on('hover:enter', function (e) { + last = e.target; + Torrent.opened(function () { + _this4.mark(element, item, true); + }); + element.poster = object.movie.img; + + _this4.start(); + + Torrent.start(element, object.movie); + Lampa.Listener.send('torrent', { + type: 'onenter', + element: element, + item: item + }); + }).on('hover:long', function () { + var enabled = Controller.enabled().name; + var menu = [{ + title: Lang.translate('torrent_parser_add_to_mytorrents'), + tomy: true + }, { + title: Lang.translate('torrent_parser_label_title'), + subtitle: Lang.translate('torrent_parser_label_descr'), + mark: true + }, { + title: Lang.translate('torrent_parser_label_cancel_title'), + subtitle: Lang.translate('torrent_parser_label_cancel_descr'), + unmark: true + }]; + Lampa.Listener.send('torrent', { + type: 'onlong', + element: element, + item: item, + menu: menu + }); + Select.show({ + title: Lang.translate('title_action'), + items: menu, + onBack: function onBack() { + Controller.toggle(enabled); + }, + onSelect: function onSelect(a) { + if (a.tomy) { + _this4.addToBase(element); + } else if (a.mark) { + _this4.mark(element, item, true); + } else if (a.unmark) { + _this4.mark(element, item, false); + } + + Controller.toggle(enabled); + } + }); + }); + Lampa.Listener.send('torrent', { + type: 'render', + element: element, + item: item + }); + scroll.append(item); + if (append) Controller.collectionAppend(item); + }); + }; + + this.back = function () { + Activity.backward(); + }; + + this.start = function () { + if (!initialized) { + initialized = true; + this.initialize(); + } + + Background.immediately(Utils$1.cardImgBackgroundBlur(object.movie)); + Controller.add('content', { + toggle: function toggle() { + Controller.collectionSet(scroll.render(), files.render(true)); + Controller.collectionFocus(last || false, scroll.render(true)); + Navigator.remove(files.render().find('.explorer-card__head-img')[0]); + }, + update: function update() {}, + up: function up() { + if (Navigator.canmove('up')) { + Navigator.move('up'); + } else Controller.toggle('head'); + }, + down: function down() { + Navigator.move('down'); + }, + right: function right() { + if (Navigator.canmove('right')) Navigator.move('right');else filter.render().find('.filter--filter').trigger('hover:enter'); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else files.toggle(); + }, + back: this.back + }); + Controller.toggle('content'); + }; + + this.pause = function () { + listener && listener.destroy(); + }; + + this.stop = function () {}; + + this.render = function () { + return files.render(); + }; + + this.destroy = function () { + network.clear(); + Parser.clear(); + files.destroy(); + scroll.destroy(); + listener && listener.destroy(); + results = null; + network = null; + }; + } + + /** + * Компонент "Мои торренты" + * @param {*} object + * @returns + */ + + function component$g(object) { + var comp = Utils$1.createInstance(Full, object, { + empty: { + router: 'mytorrents' + } + }); + comp.use(Router, 0); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + Torserver.my(function (result) { + result.forEach(function (item) { + item.title = item.title.replace('[LAMPA] ', ''); + item.data = Arrays.decodeJson(item.data, {}); + + if (item.data.movie && item.data.movie.poster) { + item.poster = item.data.movie.poster; + } + + if (item.data.movie && item.data.movie.release_date) { + item.release_date = item.data.movie.release_date; + } + + if (item.data.movie && item.data.movie.first_air_date) { + item.first_air_date = item.data.movie.first_air_date; + } + + if (item.data.movie && item.data.movie.original_name) { + item.original_name = item.data.movie.original_name; + } + + item.params = { + module: Helper$9.only('Card', 'Release', 'Callback', 'Icons') + }; + }); + + _this.build({ + results: result + }); + }, this.empty.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onEnter: function onEnter() { + if (!this.disabled) Torrent.open(data.hash, data.data.lampa && data.data.movie ? data.data.movie : false); + }, + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + }, + onLong: function onLong() { + if (this.disabled) return; + var enabled = Controller.enabled().name; + var menu = []; + + if (data.data.movie) { + menu.push({ + title: Lang.translate('title_card'), + onSelect: router.call.bind(router, 'full', data.data.movie) + }); + } + + menu.push({ + title: Lang.translate('torrent_remove_title'), + subtitle: Lang.translate('torrent_remove_descr'), + onSelect: function onSelect() { + Torserver.remove(data.hash); + item.disable(); + Controller.toggle(enabled); + } + }); + Lampa.Listener.send('mytorrents', { + type: 'onlong', + object: data, + menu: menu + }); + Select.show({ + title: Lang.translate('title_action'), + items: menu, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + } + }); + } + }); + return comp; + } + + /** + * Компонент "Релизы" + * @param {*} object + * @returns + */ + + function component$f(object) { + var comp = Utils$1.createInstance(Full, object, { + module: Helper$4.toggle(Helper$4.MASK.base, 'Pagination') + }); + comp.use({ + onCreate: function onCreate() { + Api.relise(object, this.build.bind(this), this.empty.bind(this)); + }, + onNext: function onNext(resolve, reject) { + Api.relise(object, resolve.bind(this), reject.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + return comp; + } + + /** + * Компонент "Нет контента" + * @param {*} object + */ + + var Component$1 = /*#__PURE__*/function (_Emit) { + _inherits(Component, _Emit); + + var _super = _createSuper(Component); + + function Component(object) { + var _this; + + _classCallCheck(this, Component); + + _this = _super.call(this); + _this.object = object || {}; + + _this.emit('init'); + + return _this; + } + + _createClass(Component, [{ + key: "create", + value: function create() { + this.html = $('
    '); + this.empty = new Empty({}); + this.html.append(this.empty.render()); + this.start = this.empty.start.bind(this.empty); + this.emit('create'); + this.activity.loader(false); + this.activity.toggle(); + } + }, { + key: "render", + value: function render() { + return this.html; + } + }, { + key: "destroy", + value: function destroy() { + this.html.remove(); + this.emit('destroy'); + } + }]); + + return Component; + }(Emit); + + function component$e(object) { + var _this2 = this; + + var scroll = new Scroll({ + mask: true, + over: true, + step: 300 + }); + var html = $('
    '); + var body = $('
    '); + var cards = Favorite.full().card; + var table = TimeTable.all(); + var last; + var cards_map = {}; + + this.create = function () { + var _this = this; + + if (Account$1.Permit.sync) cards = Account$1.Bookmarks.all(); + cards.forEach(function (card) { + cards_map[card.id] = card; + }); + + if (table.length) { + var date_max = 0; + var date_now = new Date(); + var date_end = new Date(); + var date_one = 24 * 60 * 60 * 1000; + table.forEach(function (elem) { + var episodes = _this.episodes(elem.episodes, elem.next); + + episodes.forEach(function (ep) { + var air = Utils$1.parseToDate(ep.air_date); + var tim = air.getTime(); + + if (date_max < tim) { + date_max = tim; + date_end = air; + } + }); + }); + var date_dif = Math.max(30, Math.min(30, Math.round(Math.abs((date_now - date_end) / date_one)))); + + if (date_dif > 0) { + for (var i = 0; i < date_dif; i++) { + this.append(date_now); + date_now.setDate(date_now.getDate() + 1); + } + + scroll.minus(); + scroll.append(body); + html.append(scroll.render()); + } else this.empty(); + } else this.empty(); + + this.activity.loader(false); + this.activity.toggle(); + return this.render(); + }; + + this.episodes = function (episodes, next) { + var result = [].concat(episodes); + + if (next && !result.find(function (e) { + return e.air_date == next.air_date; + })) { + result.push(next); + } + + return result; + }; + + this.empty = function () { + var empty = new Empty({ + descr: Lang.translate('timetable_empty') + }); + html.append(empty.render()); + _this2.start = empty.start.bind(empty); + + _this2.activity.loader(false); + + _this2.activity.toggle(); + }; + + this.append = function (date) { + var _this3 = this; + + var item = $("\n
    \n
    \n
    \n
    \n
    \n
    \n "); + var air_date = date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + ('0' + date.getDate()).slice(-2); + var air_epis = []; + var day_week = Utils$1.parseTime(date.getTime()); + var weeks = [Lang.translate('week_7'), Lang.translate('week_1'), Lang.translate('week_2'), Lang.translate('week_3'), Lang.translate('week_4'), Lang.translate('week_5'), Lang.translate('week_6')]; + table.forEach(function (elem) { + var episodes = _this3.episodes(elem.episodes, elem.next); + + episodes.forEach(function (ep) { + var card = cards_map[elem.id]; + + if (ep.air_date == air_date && card) { + air_epis.push({ + episode: ep, + card: card + }); + } + }); + }); + + if (air_epis.length) { + air_epis.slice(0, 3).forEach(function (elem) { + item.find('.timetable__body').append('
    ' + elem.card.name + '
    '); + }); + + if (air_epis.length > 3) { + item.find('.timetable__body').append('
    +' + (air_epis.length - 3) + '
    '); + } + + if (air_epis.length == 1) { + var preview = $('
    ' + (air_epis[0].episode.name || Lang.translate('noname')) + '
    '); + Utils$1.imgLoad(preview.find('img'), TMDB$1.image('t/p/w200/' + air_epis[0].episode.still_path), false, function () { + preview.find('img').remove(); + }); + item.find('.timetable__body').prepend(preview); + } + + item.addClass('timetable__item--any'); + } + + item.find('.timetable__date').text(day_week["short"] + ' - ' + weeks[date.getDay()] + '.'); + item.on('hover:focus', function () { + last = $(this)[0]; + scroll.update($(this)); + }).on('hover:hover', function () { + last = $(this)[0]; + Navigator.focused(last); + }).on('hover:enter', function () { + last = $(this)[0]; + var modal = $('
    '); + air_epis.forEach(function (elem) { + var foot = $(''); + var noty = Template.get('notice_card', { + time: Utils$1.parseTime(air_date).full, + title: elem.card.name, + descr: Lang.translate('card_new_episode') + }); + foot.append('
    S - ' + elem.episode.season_number + '
    '); + foot.append('
    E - ' + elem.episode.episode_number + '
    '); + noty.find('.notice__descr').append(foot); + Utils$1.imgLoad(noty.find('img'), TMDB$1.image('t/p/w200/' + elem.card.poster_path), function () { + noty.addClass('image--loaded'); + }); + noty.on('hover:enter', function () { + Modal.close(); + Activity.push({ + url: '', + component: 'full', + id: elem.card.id, + method: 'tv', + card: elem.card, + source: elem.card.source + }); + }); + modal.append(noty); + }); + Modal.open({ + title: Lang.translate('menu_tv'), + size: 'medium', + html: modal, + onBack: function onBack() { + Modal.close(); + Controller.toggle('content'); + } + }); + }); + body.append(item); + }; + + this.back = function () { + Activity.backward(); + }; + + this.start = function () { + Controller.add('content', { + link: this, + toggle: function toggle() { + Controller.collectionSet(scroll.render()); + Controller.collectionFocus(last || false, scroll.render()); + Background.change(TMDB$1.image('t/p/w200/oXPYD4c3bLtfAS2FzwjZh7NWqo4.jpg')); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + right: function right() { + Navigator.move('right'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down'); + }, + back: this.back + }); + Controller.toggle('content'); + }; + + this.pause = function () {}; + + this.stop = function () {}; + + this.render = function () { + return html; + }; + + this.destroy = function () { + scroll.destroy(); + html.remove(); + }; + } + + /** + * Компонент "Подписки" + * @param {*} object + * @returns + */ + + function component$d(object) { + var comp = Utils$1.createInstance(Full, object, { + empty: { + account: true, + router: 'subscribe' + } + }); + comp.use(Router, 0); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + Account$1.Api.subscribes({ + to_card_subscribe: true + }, function (data) { + data.results.forEach(function (card) { + card.params = { + module: Helper$9.toggle(Helper$9.MASK.base, 'Subscribe') + }; + }); + + _this.build(data); + }, this.empty.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + return comp; + } + + var About = { + onCreate: function onCreate() { + this.html = Template.js('company', { + name: this.data.name, + place: (this.data.headquarters ? this.data.headquarters + (this.data.origin_country ? ', ' : '') : '') + (this.data.origin_country ? this.data.origin_country : '') + }); + Utils$1.imgLoad(this.html.find('img'), this.data.logo_path ? TMDB.img(this.data.logo_path, 'w500') : this.data.img || 'img/img_broken.svg', function (img) { + img.addClass('loaded'); + }); + } + }; + + var CompanyMap = { + About: About + }; + + var Company = /*#__PURE__*/function (_Constructor) { + _inherits(Company, _Constructor); + + var _super = _createSuper(Company); + + function Company() { + _classCallCheck(this, Company); + + return _super.apply(this, arguments); + } + + return Company; + }(Constructor(CompanyMap)); + + var Helper$3 = new Mask(Arrays.getKeys(CompanyMap)); + Helper$3.MASK.base = Helper$3.MASK.none; + + function component$c(object) { + var comp = Utils$1.createInstance(Full$1, object); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + Api.company(object, function (data) { + object.company = data.company; + Arrays.insert(data.lines, 0, { + results: [], + params: { + module: Helper$b.MASK.none, + emit: { + onCreate: function onCreate() { + this.company = Utils$1.createInstance(Company, object.company, { + module: Helper$3.only('About') + }); + this.company.create(); + this.scroll.append(this.company.render(true)); + }, + onDestroy: function onDestroy() { + var _this$company; + + (_this$company = this.company) === null || _this$company === void 0 ? void 0 : _this$company.destroy(); + } + } + } + }); + + _this.build(data.lines); + }, this.empty.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onMore: router.call.bind(router, 'category_full', { + url: data.url, + title: data.title, + companies: object.company.id, + sort_by: 'vote_count.desc', + source: 'tmdb' + }), + onInstance: function onInstance(card, data) { + card.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + } + }); + return comp; + } + + /** + * Компонент "Лента" + * @param {*} object + */ + + function Feed(object) { + var network = new Request(); + var scroll = new Scroll({ + mask: true, + over: true, + step: 250, + end_ratio: 2 + }); + var html = document.createElement('div'); + var feed = []; + var last; + + function enrichTmdbItem(element, oncomplite) { + var card = element.data || {}; + if (!card.imdb_id) return oncomplite(element); + var method = 'find/' + card.imdb_id + '?external_source=imdb_id'; + Api.sources.tmdb.get(method, {}, function (data) { + var movie = data.movie_results && data.movie_results[0]; + var tv = data.tv_results && data.tv_results[0]; + var tmdb = element.card_type == 'tv' ? tv || movie : movie || tv; + + if (tmdb) { + tmdb.source = 'tmdb'; + tmdb.imdb_id = card.imdb_id; + tmdb.imdb_rating = card.imdb_rating; + tmdb.kp_rating = card.kp_rating; + tmdb.release_quality = card.release_quality; + tmdb.countries = card.countries; + tmdb.episode = card.episode; + element.data = tmdb; + element.card_id = tmdb.id; + element.card_type = tmdb.name || tmdb.first_air_date ? 'tv' : 'movie'; + } + + oncomplite(element); + }, function () { + oncomplite(element); + }, { + life: 60 * 24 * 7 + }); + } + + function enrichTmdbFeed(items, oncomplite) { + var result = []; + var index = 0; + var active = 0; + var limit = 4; + + function next() { + if (index >= items.length && active == 0) return oncomplite(result); + + var _loop = function _loop() { + var position = index; + var element = items[index]; + index++; + active++; + enrichTmdbItem(element, function (updated) { + result[position] = updated; + active--; + next(); + }); + }; + + while (active < limit && index < items.length) { + _loop(); + } + } + + next(); + } + + this.create = function () { + var _this = this; + + this.activity.loader(true); + network.silent(Utils$1.protocol() + object$2.cub_domain + '/api/feed/all', this.build.bind(this), function () { + var empty = new Empty(); + html.append(empty.render(true)); + _this.start = empty.start.bind(empty); + + _this.activity.loader(false); + + _this.activity.toggle(); + }); + return this.render(); + }; + + this.next = function () { + if (object.page < 15) { + object.page++; + var offset = object.page - 1; + this.append(feed.slice(20 * offset, 20 * offset + 20), true); + } + }; + + this.loadImg = function (box, src) { + var img = box.find('img'); + + img.onload = function () { + box.addClass('loaded'); + }; + + img.onerror = function () { + img.src = './img/img_broken.svg'; + }; + + img.src = src; + }; + + this.append = function (data, append) { + var _this2 = this; + + data.forEach(function (element) { + var item = Template.js(element.type == 'episode' || element.type == 'trailer' ? 'feed_episode' : 'feed_item'); + item.addClass('feed-item--' + element.type); + var type = { + top: Lampa.Lang.translate('title_in_top'), + now_playing: Lampa.Lang.translate('title_now_watch'), + uhd: Lampa.Lang.translate('title_in_high_quality'), + popular: Lampa.Lang.translate('title_popular'), + trailer: Lampa.Lang.translate('title_trailers'), + episode: Lampa.Lang.translate('card_new_episode'), + now: Lampa.Lang.translate('title_new') + }; + var sity = element.data.countries || []; + var year = ((element.data.release_date || element.data.first_air_date) + '').slice(0, 4); + var info = []; + var tags = []; + info.push(year + (sity.length ? ' - ' + sity.slice(0, 2).join(', ') : '')); + + if (element.data.imdb_rating && parseFloat(element.data.imdb_rating) > 0) { + info.push('IMDB ' + element.data.imdb_rating); + } + + if (element.data.kp_rating && parseFloat(element.data.kp_rating) > 0) { + info.push('KP ' + element.data.kp_rating); + } + + if (element.type == 'episode') { + tags = element.hash.split(';').map(function (a) { + return Lang.translate(a.slice(0, 1) == 's' ? 'torrent_serial_season' : 'torrent_serial_episode') + ' - ' + a.slice(1); + }); + } else if (element.data.genres) tags.push(element.data.genres.join(', '));else if (element.data.genre_ids) { + tags.push(Api.sources.tmdb.getGenresNameFromIds(element.card_type, element.data.genre_ids).join(', ')); + } + + item.find('.feed-item__label').addClass('feed-item__label--' + element.type).text(type[element.type]); + item.find('.feed-item__title').text(element.data.title || element.data.name); + item.find('.feed-item__info').text(info.join(' / ')); + item.find('.feed-item__descr').text(element.data.overview || ''); + item.find('.feed-item__tags').text(tags.join(' / ')); + + _this2.loadImg(item.find('.feed-item__poster-box'), element.data.poster_path ? Api.img(element.data.poster_path, 'w500') : './img/img_broken.svg'); + + var image = item.find('.feed-item__image-box'); + + if (image) { + _this2.loadImg(image, Api.img(element.type == 'episode' ? element.data.episode.still_path : element.data.backdrop_path, 'w780')); + } + + scroll.append(item); + var btn_watch = document.createElement('div'); + btn_watch.addClass('simple-button selector'); + btn_watch.text(Lang.translate('title_watch')); + btn_watch.on('hover:focus', function () { + last = btn_watch; + scroll.update(item); + Background.change(Api.img(element.data.poster_path, 'w500')); + }); + btn_watch.on('hover:enter', function () { + Activity.push({ + url: '', + component: 'full', + id: element.card_id, + method: element.card_type, + card: element.data, + source: element.data.source || 'tmdb' + }); + }); + item.find('.feed-item__buttons').append(btn_watch); + if (append) Controller.collectionAppend(btn_watch); + }); + }; + + this.build = function (data) { + var _this3 = this; + + enrichTmdbFeed(data.result || [], function (result) { + feed = result; + html.addClass('feed'); + var head = Template.js('feed_head'); + head.find('.feed-head__title').text(Lang.translate('lampa_movie_title')); + head.find('.feed-head__info').html(Lang.translate('lampa_movie_descr')); + head.on('hover:focus', scroll.update.bind(scroll, head)); + scroll.minus(); + + scroll.onWheel = function (step) { + Navigator.move(step > 0 ? 'down' : 'up'); + }; + + scroll.onEnd = _this3.next.bind(_this3); + scroll.append(head); + + _this3.append(feed.slice(0, 20)); + + html.append(scroll.render(true)); + + _this3.activity.loader(false); + + _this3.activity.toggle(); + }); + }; + + this.start = function () { + Controller.add('content', { + toggle: function toggle() { + Controller.collectionSet(scroll.render(true)); + Controller.collectionFocus(last || false, scroll.render(true)); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + right: function right() { + Navigator.move('right'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down'); + }, + back: function back() { + Activity.backward(); + } + }); + Controller.toggle('content'); + }; + + this.render = function () { + return html; + }; + + this.destroy = function () { + network.clear(); + scroll.destroy(); + html.remove(); + }; + } + + /** + * Компонент "Избранное" + * @param {*} object + * @returns + */ + + function component$b(object) { + var all = Favorite.all(); + var comp = Utils$1.createInstance(Full$1, object, { + empty: { + router: 'bookmarks' + } + }); + comp.use(Router, 0); + comp.use({ + onCreate: function onCreate() { + var category = ['look', 'scheduled', 'book', 'like', 'wath', 'viewed', 'continued', 'thrown']; + var lines = []; + var folders = ['book', 'like', 'wath', 'viewed', 'scheduled', 'thrown']; + var media = ['movies', 'tv']; + var premium = Account$1.hasPremium(); + var sync = Account$1.Permit.sync; + lines.push({ + results: [], + params: { + module: Helper$b.toggle(Helper$b.MASK.base, 'More', 'Event'), + items: { + view: 20 + } + } + }); // Добавляем категории + + category.forEach(function (a) { + if (all[a].length) { + lines[0].results.push({ + title: Lang.translate('title_' + a), + count: all[a].length, + limit: sync ? premium ? 2000 : 500 : 0, + params: { + module: Helper$8.only('Line', 'Callback'), + createInstance: function createInstance(item) { + return new Register(item); + }, + emit: { + onEnter: router.call.bind(router, 'favorite', { + type: a + }) + } + } + }); + } + }); + if (lines[0].results.length == 0) lines = []; // Добавляем карточки + + category.forEach(function (a) { + if (all[a].length) { + var items = Arrays.clone(all[a].slice(0, 20)); + items.forEach(function (item) { + item.params = { + emit: { + onEnter: router.call.bind(router, 'full', item), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(item)); + } + } + }; + }); // Если есть папки, то добавляем их + + if (folders.indexOf(a) > -1) { + var i = 0; + media.forEach(function (m) { + var filter = Utils$1.filterCardsByType(all[a], m); + + if (filter.length) { + Arrays.insert(items, i, { + results: filter, + media: m, + params: { + module: Helper$9.only('Folder', 'Callback'), + emit: { + onEnter: router.call.bind(router, 'favorite', { + title: Lang.translate('title_' + a) + ' - ' + Lang.translate('menu_' + m), + type: a, + filter: m + }), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(filter[0])); + } + } + } + }); + i++; + } + }); + } + + lines.push({ + title: Lang.translate('title_' + a), + results: items, + type: a, + total_pages: all[a].length > 20 ? Math.ceil(all[a].length / 20) : 1, + params: { + module: Helper$b.toggle(Helper$b.MASK.base, 'Event'), + emit: { + onMore: router.call.bind(router, 'favorite', { + type: a, + page: 2 + }) + } + } + }); + } + }); + ContentRows.call('bookmarks', {}, lines); + + if (lines.length) { + comp.build(lines); + } else comp.empty(); + } + }); + return comp; + } + + var Line = { + onCreate: function onCreate() { + this.html = Template.js('season_info', this.data); + this.prefix = Template.prefix(this.html, 'season-info'); + var head = []; + if (this.data.vote_average) head.push(Lang.translate('title_rating') + ': ' + parseFloat(this.data.vote_average + '').toFixed(1)); + if (this.data.air_date) head.push(Lang.translate('full_date_of_release') + ': ' + Utils$1.parseTime(this.data.air_date).full); + if (this.data.episodes.length) head.push(Lang.translate('title_episodes') + ': ' + this.data.episodes.length); + if (head.length) this.prefix.head.append(Arrays.flatMap(head.map(function (s) { + return $('' + s + ''); + }), function () { + return $('  ●  '); + }));else this.prefix.head.remove(); + if (!this.html.overview) this.prefix.overview.remove(); + } + }; + + var SeasonMap = { + Line: Line, + Callback: Callback$1 + }; + + var Season = /*#__PURE__*/function (_Constructor) { + _inherits(Season, _Constructor); + + var _super = _createSuper(Season); + + function Season() { + _classCallCheck(this, Season); + + return _super.apply(this, arguments); + } + + return Season; + }(Constructor(SeasonMap)); + + var Helper$2 = new Mask(Arrays.getKeys(SeasonMap)); + Helper$2.MASK.base = Helper$2.MASK.none; + + function choiceSeason() { + var total = this.object.seasons_count || Utils$1.countSeasons(this.object.card); + var select = []; + + for (var i = total; i > 0; i--) { + select.push({ + title: Lang.translate('torrent_serial_season') + ' ' + i, + season: i, + selected: (this.object.season || Utils$1.countSeasons(this.object.card)) == i + }); + } + + Select.show({ + title: Lang.translate('torrent_serial_season'), + items: select, + onSelect: function onSelect(a) { + Controller.toggle('content'); + Activity.replace({ + season: a.season + }); + }, + onBack: function onBack() { + Controller.toggle('content'); + } + }); + } + /** + * Компонент "Сезоны сериала" + * @param {*} object + */ + + + function component$a(object) { + var comp = Utils$1.createInstance(Full, object, { + module: Helper$4.toggle(Helper$4.MASK.base, 'Explorer'), + items: { + mapping: 'list' + } + }); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + var season = object.season || Utils$1.countSeasons(object.card); + Api.seasons(object.card, [season], function (v) { + if (v[season] && v[season].episodes) { + object.seasons_count = v[season].seasons_count || Utils$1.countSeasons(object.card); + Arrays.extend(v[season], { + params: { + createInstance: function createInstance(item) { + return new Season(item); + }, + module: Helper$2.only('Line', 'Callback'), + emit: { + onEnter: choiceSeason.bind(_this) + } + } + }); + var results = [v[season]]; + v[season].episodes.forEach(function (episode) { + // Передаем название сериала для таймкода + episode.original_name = object.card.original_name; + episode.params = { + createInstance: function createInstance() { + return new Episode(episode); + }, + module: Helper$a.toggle(Helper$a.MASK.base, 'Line') + }; + results.push(episode); + }); + + if (!v[season].episodes.length) { + Arrays.insert(results, 1, { + episode_number: 1, + season_number: season, + air_date: '', + name: Lang.translate('title_anons'), + comeing: true, + params: { + createInstance: function createInstance(item) { + return new Episode(item); + }, + module: Helper$a.only('Line') + } + }); + } + + _this.build({ + results: results + }); + } else { + _this.empty(); + } + }); + }, + onController: function onController() { + Background.immediately(Utils$1.cardImgBackgroundBlur(object.card)); + } + }); + return comp; + } + + /** + * Компонент Персоны" + * @param {*} object + */ + + function component$9(object) { + var comp = new Full$1(object); + var next = null; + comp.use({ + onCreate: function onCreate() { + var _this = this; + + var parts = [function (call) { + Account$1.Api.persons(function (data) { + if (!data.length) return call(); + var persons = data.map(function (p) { + return p.person; + }); + persons.forEach(function (person) { + person.params = { + module: Helper$9.only('Card', 'Release', 'Callback'), + emit: { + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(person)); + }, + onEnter: router.call.bind(router, 'actor', person) + } + }; + }); + call({ + title: Lang.translate('title_persons'), + results: persons, + params: { + module: Helper$b.toggle(Helper$b.MASK.base, 'More', 'Event') + } + }); + }, call); + }]; + + function loadPart(partLoaded, partEmpty) { + Api.partNext(parts, 3, partLoaded, partEmpty); + } + + next = loadPart; + TMDB.get('person/popular', {}, function (json) { + if (!json.results) return loadPart(_this.build.bind(_this), _this.empty.bind(_this)); + json.results.sort(function (a, b) { + return a.popularity - b.popularity; + }); + var filtred = json.results.filter(function (p) { + return p.known_for_department && p.known_for; + }); + var persons = filtred.filter(function (p) { + return (p.known_for_department || '').toLowerCase() == 'acting' && p.known_for.length; + }).slice(0, 10); + persons.forEach(function (person_data, index) { + var event = function event(call_inner) { + TMDB.person({ + only_credits: 'movie', + id: person_data.id + }, function (result) { + if (!result.credits) return call_inner(); + var cards = (result.credits.movie || []).filter(function (m) { + return m.backdrop_path && m.vote_count > 20; + }); + cards.sort(function (a, b) { + var da = a.release_date || a.first_air_date; + var db = b.release_date || b.first_air_date; + if (db > da) return 1;else if (db < da) return -1;else return 0; + }); + var src = person_data.profile_path ? TMDB.img(person_data.profile_path, 'w90_and_h90_face') : person_data.img || './img/actor.svg'; + cards.forEach(function (item) { + item.params = { + emit: { + onEnter: router.call.bind(router, 'full', item), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(item)); + } + } + }; + }); + call_inner({ + title: person_data.name, + icon_img: src, + results: cards.length > 5 ? cards.slice(0, 20) : [], + params: { + module: Helper$b.toggle(Helper$b.MASK.base, 'Icon', 'More', 'MoreFirst', 'Event'), + text: Lang.translate('title_person_about'), + emit: { + onMore: router.call.bind(router, 'actor', person_data) + } + } + }); + }); + }; + + parts.push(event); + }); + loadPart(_this.build.bind(_this), _this.empty.bind(_this)); + }, function () { + loadPart(_this.build.bind(_this), _this.empty.bind(_this)); + }, { + life: 60 * 24 * 3 + }); + }, + onNext: function onNext(resolve, reject) { + if (next) { + next(resolve.bind(this), reject.bind(this)); + } else reject.call(this); + } + }); + return comp; + } + + function facts(card_id, card_type, callback, error) { + Api$1.load('ai/generate/facts/' + card_id + '/' + card_type, { + timeout: 60000 + }).then(callback)["catch"](error); + } + + function recommendations(card_id, card_type, callback, error) { + Api$1.load('ai/generate/recommend/' + card_id + '/' + card_type, { + timeout: 60000 + }).then(callback)["catch"](error); + } + + function _search(query, callback, error) { + Api$1.load('ai/search/' + encodeURIComponent(query), { + timeout: 60000 + }).then(callback)["catch"](error); + } + + function discovery() { + var source = { + title: Lang.translate('title_ai_assistant'), + search: function search(params, oncomplite) { + source.params.nofound = Lang.translate('search_nofound'); + + _search(decodeURIComponent(params.query), function (json) { + json.title = Lang.translate('title_ai_assistant'); + json.results.forEach(function (element) { + element.source = 'cub'; + }); + oncomplite(json.results.length ? [json] : []); + }, function (e) { + if (e.decode_code == 600) source.params.nofound = Lang.translate('ai_search_limit'); + oncomplite([]); + }); + }, + onCancel: function onCancel() { + Api$1.clear(); + }, + params: { + lazy: true, + save: true, + start_typing: Lang.translate('ai_search_start_typing') + } + }; + return source; + } + + var Ai$1 = { + facts: facts, + recommendations: recommendations, + discovery: discovery + }; + + var Ai = { + onEmpty: function onEmpty(e) { + var _this = this; + + var code = e.decode_code; + var data = { + title: Lang.translate('network_error'), + descr: Lang.translate('subscribe_noinfo') + }; + + if (code == 600) { + data.title = Lang.translate('ai_subscribe_title'); + data.descr = Lang.translate('ai_subscribe_descr'); + data.noicon = true; + data.width = 'medium'; + data.buttons = [{ + title: Lang.translate('account_premium_more'), + onEnter: Modal$1.premium.bind(Modal$1) + }]; + } + + if (code == 347) { + data.title = Lang.translate('empty_title_two'); + data.descr = Lang.translate('empty_text_two'); + } + + if (code == 345 || code == 403) { + data.title = Lang.translate('account_none_title'); + data.descr = Lang.translate('account_create'); + data.noicon = true; + data.buttons = [{ + title: Lang.translate('settings_cub_signin_button'), + onEnter: function onEnter() { + Device.login(_this.start.bind(_this)); + } + }]; + } + + this.empty_class = new Empty(data); + this.scroll.append(this.empty_class.render(true)); + this.start = this.empty_class.start.bind(this.empty_class); + } + }; + + /** + * Компонент "Факты о фильме" + * @param {*} object + */ + + function component$8(object) { + var comp = Utils$1.createInstance(Full, object, { + module: Helper$4.only('Explorer', 'Loading'), + loading: { + icon: 'text' + } + }); + comp.use(Ai, 2); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + var cache_name = ['facts', this.object.card.id, this.object.card.name ? 'tv' : 'movie'].join('_'); + var cache_text = ''; + Cache.getData('other', cache_name).then(function (text) { + cache_text = text; + })["finally"](function () { + if (cache_text) { + _this.build(cache_text); + } else { + Ai$1.facts(_this.object.card.id, _this.object.card.name ? 'tv' : 'movie', function (data) { + Cache.rewriteData('other', cache_name, data.text)["catch"](function () {}); + + _this.build(data.text); + }, _this.empty.bind(_this)); + } + }); + }, + onBuild: function onBuild(text) { + var _this2 = this; + + try { + this.body.html(Utils$1.simpleMarkdownParser(text)); + this.body.find('h1').remove(); + this.body.addClass('text-markdow explorer-list animate-up-content animate-opacity'); + + this.scroll.onWheel = function (step) { + if (!Controller.own(_this2)) _this2.start(); + if (step > 0) Controller.move('down');else Controller.move('up'); + }; + } catch (e) { + this.empty({ + status: 245, + message: e.message + }); + } + }, + onController: function onController(controller) { + var _this3 = this; + + controller.up = function () { + if (_this3.scroll.position() == 0) Controller.toggle('head');else _this3.scroll.wheel(-150); + }; + + controller.down = function () { + _this3.scroll.wheel(150); + }; + } + }); + return comp; + } + + /** + * Компонент "Рекомендации по фильму/сериалу" + * @param {*} object + */ + + function component$7(object) { + var comp = Utils$1.createInstance(Full, object, { + module: Helper$4.toggle(Helper$4.MASK.base, 'Explorer', 'Loading', 'Next', 'Empty'), + items: { + cols: 5 + } + }); + comp.use(Ai, 2); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + Ai$1.recommendations(object.card.id, object.card.name ? 'tv' : 'movie', function (data) { + if (data.results.length == 0) _this.empty({ + status: 347 + });else _this.build(data); + }, this.empty.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + return comp; + } + + /** + * Компонент "Рекомендации" + * @param {*} object + */ + + function component$6(object) { + var comp = Utils$1.createInstance(Full, object, { + module: Helper$4.only('Explorer', 'Next', 'Empty', 'Items'), + items: { + mapping: 'list' + } + }); + comp.use({ + onCreate: function onCreate() { + var _this = this; + + CUB.discussGet(object, function (data) { + _this.build(_objectSpread2(_objectSpread2({}, data), {}, { + results: data.result || [] + })); + }, this.empty.bind(this)); + }, + onNext: function onNext(resolve, reject) { + CUB.discussGet(object, function (data) { + resolve(_objectSpread2(_objectSpread2({}, data), {}, { + results: data.result || [] + })); + }, reject); + }, + onCreateAndAppend: function onCreateAndAppend(element) { + var item = Utils$1.createInstance(Discuss, element, { + module: Helper$5.only('Line', 'Read'), + line: { + full_text: true + } + }); + this.emit('instance', item, element); + item.create(); + this.emit('append', item, element); + } + }); + return comp; + } + + var data = []; + /** + * Запуск + */ + + function init$w() { + data = Storage.cache('recomends_scan', 300, []); + Timer.add(120 * 1000, function () { + var history = Favorite.get({ + type: 'history' + }); + var added = 0; + console.log('Recomendations', 'find history:', history.length); + history.forEach(function (elem) { + if (['cub', 'tmdb'].indexOf(elem.source) >= 0) { + var id = data.filter(function (a) { + return a.id == elem.id; + }); + + if (!id.length) { + data.push({ + id: elem.id, + tv: elem.number_of_seasons || elem.seasons + }); + added++; + } + } + }); + console.log('Recomendations', 'added to scan:', added, 'ready:', data.length); + Storage.set('recomends_scan', data); + search(); + }); + ContentRows.add({ + name: 'recomend_watch', + title: Lang.translate('title_recomend_watch'), + index: 1, + screen: ['main', 'category'], + call: function call(params, screen) { + if (params.url == 'anime') return; + var media = screen == 'main' ? 'movie' : params.url; + var all = get$4(media); + var results = Arrays.shuffle(all).slice(0, 20); + var total_pages = Math.ceil(all.length / 20); + if (!results.length) return; + return function (call) { + call({ + results: results, + title: Lang.translate('title_recomend_watch'), + total_pages: total_pages, + page: 1, + params: { + emit: { + onlyMore: function onlyMore() { + router.call('recomend', { + media: media, + total_pages: total_pages + }); + } + } + } + }); + }; + } + }); + } + + function search() { + var ids = data.filter(function (e) { + return !e.scan; + }); + + if (ids.length) { + var elem = ids[0]; + elem.scan = 1; + console.log('Recomendations', 'scan:', elem.id, elem.title || elem.name); + TMDB.get((elem.tv ? 'tv' : 'movie') + '/' + elem.id + '/recommendations', {}, function (json) { + console.log('Recomendations', 'result:', json.results && json.results.length ? json.results.length : 0); + + if (json.results && json.results.length) { + var recomend = Storage.cache('recomends_list', 100, []); + var favorite = Favorite.get({ + type: 'history' + }); + json.results.forEach(function (e) { + var year = (e.first_air_date || e.release_date || '0000').split('-'); + + if (!recomend.filter(function (r) { + return r.id == e.id; + }).length && !favorite.filter(function (h) { + return h.id == e.id; + }).length && year[0] > new Date().getFullYear() - 20) { + recomend.push(e); + } + }); + Storage.set('recomends_list', recomend); + } + }); + } else { + data.forEach(function (a) { + return a.scan = 0; + }); + } + + Storage.set('recomends_scan', data); + } + + function get$4(type) { + var all = Storage.get('recomends_list', '[]'); + var items = all.filter(function (e) { + return type == 'tv' ? e.number_of_seasons || e.first_air_date : !(e.number_of_seasons || e.first_air_date); + }).reverse(); + var history = Favorite.get({ + type: 'history' + }); + items = items.filter(function (e) { + return !history.find(function (h) { + return h.id == e.id; + }); + }); + return items; + } + + function page(object, call, empty) { + var all = get$4(object.media); + var page = object.page || 1; + var result = all.slice((page - 1) * 20, page * 20); + if (result.length == 0) return empty({ + status: 404 + }); + call({ + results: result, + title: Lang.translate('title_recomend_watch'), + total_pages: Math.ceil(all.length / 20), + page: page + }); + } + + var Recomends = { + init: init$w, + get: get$4, + page: page + }; + + /** + * Компонент "Рекомендации по фильму/сериалу" + * @param {*} object + */ + + function component$5(object) { + var comp = Utils$1.createInstance(Full, object); + comp.use({ + onCreate: function onCreate() { + Recomends.page(object, this.build.bind(this), this.empty.bind(this)); + }, + onNext: function onNext(resolve, reject) { + Recomends.page(object, resolve.bind(this), reject.bind(this)); + }, + onInstance: function onInstance(item, data) { + item.use({ + onEnter: router.call.bind(router, 'full', data), + onFocus: function onFocus() { + Background.change(Utils$1.cardImgBackground(data)); + } + }); + } + }); + return comp; + } + + var component$4 = { + main: component$n, + full: component$m, + category: component$k, + category_full: component$l, + actor: component$j, + favorite: component$i, + torrents: component$h, + mytorrents: component$g, + relise: component$f, + nocomponent: Component$1, + timetable: component$e, + subscribes: component$d, + company: component$c, + feed: Feed, + bookmarks: component$b, + episodes: component$a, + myperson: component$9, + ai_facts: component$8, + ai_recommendations: component$7, + discuss: component$6, + recomend: component$5 + }; + /** + * Создать компонент + * @param {{component:string}} object + * @returns + */ + + function create$5(object) { + if (component$4[object.component]) { + try { + return new component$4[object.component](object); + } catch (e) { + console.log('Component', 'create error', e.stack); + return new component$4.nocomponent(object); + } + } else { + return new component$4.nocomponent(object); + } + } + /** + * Добавить компонент + * @param {string} name + * @param {class} comp + */ + + + function add$5(name, comp) { + component$4[name] = comp; + } + /** + * Получить компонент + * @param {string} name + * @returns {class} + */ + + + function get$3(name) { + return component$4[name]; + } + + var Component = { + create: create$5, + add: add$5, + get: get$3 + }; + + function close$3() { + if (Platform.is('apple_tv')) window.location.assign('exit://exit'); + if (Platform.is('tizen')) tizen.application.getCurrentApplication().exit(); + if (Platform.is('webos') && typeof window.close == 'function') window.close(); + if (Platform.is('android')) Android.exit(); + if (Platform.is('orsay')) Orsay.exit(); + if (Platform.is('netcast')) window.NetCastBack(); + if (Platform.is('noname')) window.history.back(); + } + + function loadStyle() { + /** Start - для orsay одни стили, для других другие */ + var old_css = $('link[href="css/app.css"]'); + var urlStyle = 'http://lampa.mx/css/app.css?v'; + + if (Platform.is('orsay') && window.location.host.indexOf('localhost') == -1) { + //Для нового типа виджета берем сохраненный адрес загрузки + if (Orsay.isNewWidget()) { + //Для фрейм загрузчика запишем полный url + if (location.protocol != 'file:') { + var newloaderUrl = location.href.replace(/[^/]*$/, ''); + + if (newloaderUrl.slice(-1) == '/') { + newloaderUrl = newloaderUrl.substring(0, newloaderUrl.length - 1); + } + + if (Orsay.getLoaderUrl() != newloaderUrl) { + Orsay.setLoaderUrl(newloaderUrl); + } + } //console.log('Loader', 'start url: ', Orsay.getLoaderUrl()); + + + urlStyle = Orsay.getLoaderUrl() + '/css/app.css?v'; + } + + Utils$1.putStyle([urlStyle + object$2.css_version], function () { + old_css.remove(); + }); + } else if (window.lampa_settings.fix_widget || old_css.length) { + LoadingProgress.status('PutStyle ' + object$2.css_version); + Utils$1.putStyle([object$2.github_lampa + 'css/app.css?v' + object$2.css_version], function () { + old_css.remove(); + }, function () { + // Что-то не грузится, пробуем второй вариант + Utils$1.putStyle([urlStyle + object$2.css_version], function () { + old_css.remove(); + }); + }); + } + } + + function modalClose() { + var controller = Controller.enabled().name; + Modal.open({ + title: '', + align: 'center', + zIndex: 300, + html: $('
    ' + Lang.translate('close_app_modal') + '
    '), + buttons: [{ + name: Lang.translate('settings_param_no'), + onSelect: function onSelect() { + Modal.close(); + Controller.toggle(controller); + } + }, { + name: Lang.translate('settings_param_yes'), + onSelect: function onSelect() { + Modal.close(); + Controller.toggle(controller); + close$3(); + } + }] + }); + } + + var App = { + close: close$3, + loadStyle: loadStyle, + modalClose: modalClose + }; + + /** + * Универсальный провайдер пропсов + * @param data - начальные данные + * @example + let props = new Props({a:1, b:2}) + + props.set('c', 3) + props.set({a:10, d:4}) + + console.log(props.get('a')) // 10 + console.log(props.get('b')) // 2 + console.log(props.get('c')) // 3 + console.log(props.get('d')) // 4 + console.log(props.get('e', 5)) // 5 + + console.log(props.pick('a','b','e')) // {a:10, b:2, e:undefined} + + console.log(props.all()) // {a:10, b:2, c:3, d:4} + */ + + var Props = function Props(data) { + var _this = this; + + _classCallCheck(this, Props); + + _defineProperty(this, "set", function (key, value) { + if (Arrays.isObject(key)) { + for (var k in key) { + _this.data[k] = key[k]; + } + + return; + } + + _this.data[key] = value; + }); + + _defineProperty(this, "get", function (key, def) { + return _this.data[key] || def; + }); + + _defineProperty(this, "pick", function () { + for (var _len = arguments.length, keys = new Array(_len), _key = 0; _key < _len; _key++) { + keys[_key] = arguments[_key]; + } + + return Object.fromEntries(keys.map(function (k) { + return [k, _this.data[k]]; + })); + }); + + _defineProperty(this, "all", function () { + return _this.data; + }); + + this.data = data || {}; + }; + + /** + * Слайд активности + * @param {Object} component - Компонент активности + * @param {Object} object - Параметры активности + */ + + var ActivitySlide = /*#__PURE__*/function () { + function ActivitySlide(component, object) { + _classCallCheck(this, ActivitySlide); + + this.component = component; + this.object = object || {}; + this.slide = Template.js('activity'); + this.body = this.slide.find('.activity__body'); + this.is_stopped = false; + this.is_started = false; + } + /** + * Создание активности + * @returns {void} + */ + + + _createClass(ActivitySlide, [{ + key: "create", + value: function create() { + try { + this.component.create(this.body); + this.body.append(this.component.render(true)); + } catch (e) { + console.log('Activity', 'create error:', e.stack); + Noty.show('Activity create error:' + e.message + ' ' + e.stack); + this.component = Component.create({ + component: 'nocomponent' + }); + this.component.activity = this; + this.create(); + } + } + /** + * Показывает загрузку + * @param {boolean} status + */ + + }, { + key: "loader", + value: function loader(status) { + this.slide.toggleClass('activity--load', status); + } + /** + * Стартуем активную активность + * @return {void} + */ + + }, { + key: "start", + value: function start() { + this.is_started = true; + this.is_stopped = false; + Controller.add('content', { + invisible: true, + toggle: function toggle() { + Controller.clear(); + }, + left: function left() { + Controller.toggle('menu'); + }, + up: function up() { + Controller.toggle('head'); + }, + back: function back() { + Activity.backward(); + } + }); + Controller.toggle('content'); + if (this.waite_refresh) this.runRefresh();else { + try { + this.component.start(); + } catch (e) { + console.log('Activity', 'start error:', e.stack); + Noty.show('Activity start error:' + e.message + ' ' + e.stack); + } + } + } + /** + * Пауза активности + * @return {void} + */ + + }, { + key: "pause", + value: function pause() { + this.is_started = false; + this.component.pause && this.component.pause(); + } + /** + * Включаем активность если она активна + * @return {void} + */ + + }, { + key: "toggle", + value: function toggle() { + if (this.is_started) this.start(); + } + /** + * Событие изменения размеров окна + * @return {void} + */ + + }, { + key: "resize", + value: function resize() { + if (this.component.resize) this.component.resize(); + } + /** + * Обновить активность (если активна) или при следующем старте + * @return {void} + */ + + }, { + key: "refresh", + value: function refresh() { + if (this.waite_refresh) return; + this.waite_refresh = true; + if (Activity.own(this.component)) this.runRefresh(); + } + /** + * Запуск обновления активности + * @returns {void} + */ + + }, { + key: "runRefresh", + value: function runRefresh() { + var _this = this; + + // Если нет пометки на обновление, то не обновляем + if (!this.waite_refresh) return; + clearTimeout(this.timer_refresh); // При переходе назад текушая активность уничтожается через 200мс, поэтому ждем на удаление и запускаем обновление + + this.timer_refresh = setTimeout(function () { + if (_this.component.beforeRefresh) _this.component.beforeRefresh(); + Activity.replace(); + }, 400); + this.loader(true); + } + }, { + key: "canRefresh", + value: function canRefresh() { + console.warn('activity.canRefresh is deprecated'); + return false; + } + }, { + key: "needRefresh", + value: function needRefresh() { + console.warn('activity.needRefresh is deprecated, use activity.refresh()'); + } + /** + * Останавливает активность когда открывается другая + * @return {void} + */ + + }, { + key: "stop", + value: function stop() { + this.is_started = false; + if (this.is_stopped) return; + this.is_stopped = true; + this.component.stop && this.component.stop(); + this.slide.remove(); + } + /** + * Вернуть HTML слайд активности + * @param {boolean} js - вернуть js объект + * @returns {jQuery|HTMLElement} - HTML слайд активности + */ + + }, { + key: "render", + value: function render(js) { + return js ? this.slide : $(this.slide); + } + /** + * Уничтожение активности + * @returns {void} + */ + + }, { + key: "destroy", + value: function destroy() { + try { + this.component.destroy(); + } catch (e) { + console.log('Activity', 'destroy error:', e.stack); + } // После create работает долгий запрос и затем вызывается build, однако уже было вызвано destroy и возникают ошибки, поэтому заодно чистим функцию build и остальные функции компонента + + + for (var f in this.component) { + if (typeof this.component[f] == 'function') { + this.component[f] = function () {}; + } + } // Помечаем что компонент уничтожен, для внутренних функций компонента + + + this.component.destroyed = true; + this.slide.remove(); + clearTimeout(this.timer_refresh); + } + }]); + + return ActivitySlide; + }(); + + var listener$3 = Subscribe$2(); + var activites = []; + var callback = false; + var fullout = false; + var focustime = Date.now(); + var content; + var slides; + var maxsave; + var base; + var refresh_timer; + + function parseStart() { + if (window.start_deep_link) return; + var id = Utils$1.gup('card'); + + if (id) { + window.start_deep_link = { + id: id, + component: "full", + method: Utils$1.gup('media') || 'movie', + source: Utils$1.gup('source') || 'cub', + card: { + id: id, + source: Utils$1.gup('source') || 'cub' + } + }; + } else if (!(Platform.is('orsay') || Platform.is('netcast') || Platform.is('webos') || Platform.is('tizen'))) { + try { + var params = new URLSearchParams(window.location.search); + + if (params.has('component')) { + window.start_deep_link = {}; + params.forEach(function (v, n) { + window.start_deep_link[n] = v; + }); + } + } catch (e) { + console.log('Activity', 'url params start error:', e.message); + } + } + } + /** + * Запуск + */ + + + function init$v() { + content = Template.js('activitys'); + slides = content.querySelector('.activitys__slides'); + maxsave = Storage.get('pages_save_total', 5); + base = document.querySelector('head base'); + parseStart(); + empty(); + var wait = true; + var swip_status = 0; + var swip_timer; + var start_time = Date.now(); + setTimeout(function () { + wait = false; + }, 1500); + setTimeout(last, 500); + window.addEventListener('popstate', function () { + if (fullout || wait) return; + Screensaver$2.stop(); + if (swip_status == 0) empty(); //это чтоб не выходило с приложения, однако на айфонах это вызвает зависание на 2-3 сек + + listener$3.send('popstate', { + count: activites.length + }); + if (callback) callback();else { + backward(); + } + }); + Storage.listener.follow('change', function (event) { + if (event.name == 'pages_save_total') maxsave = Storage.get('pages_save_total', 5); + if (event.name == 'light_version' || event.name == 'account_use' || event.name == 'interface_size' || event.name == 'account' && !event.value) refresh(true); + }); // Обновляем активность при изменении профиля, протокола или прочитаных ссылок в закладках и истории + + Lampa.Listener.follow('state:changed', function (e) { + if (e.target == 'favorite' && (e.reason == 'profile' || e.reason == 'read')) refresh(true); + }); // После имземения размера окна возникает поломанный интерфейс, надо перезапустить активность или уведомить компонент о изменении + + Lampa.Listener.follow('resize_end', function (e) { + activites.forEach(function (activity) { + if (activity.activity) activity.activity.resize(); + }); + }); // Исключительно для огрызков пришлось мутить работу свайпа назад + + if (Platform.is('apple')) { + var body = document.querySelector('body'); + body.addEventListener('touchstart', function (e) { + var point = e.touches[0] || e.changedTouches[0]; + + if (point.clientX < window.innerWidth * 0.15 && point.clientX < window.innerHeight - 120) { + swip_status = 1; + clearTimeout(swip_timer); + swip_timer = setTimeout(function () { + swip_status = 0; + }, 2000); + } else { + swip_status = 0; + } + }); + } // Выход из приложения + + + listener$3.follow('backward', function (event) { + var noout = Platform.is('browser') || Platform.desktop(); + + if (event.count == 1 && Date.now() > start_time + 1000 * 2 && !noout) { + var enabled = Controller.enabled().name; + Select.show({ + title: Lang.translate('title_out'), + items: [{ + title: Lang.translate('title_out_confirm'), + out: true + }, { + title: Lang.translate('cancel') + }], + onSelect: function onSelect(a) { + if (a.out) { + out(); + Controller.toggle(enabled); + App.close(); + } else { + Controller.toggle(enabled); + } + }, + onBack: function onBack() { + Controller.toggle(enabled); + } + }); + } + }); // Обновляем активность при уходе и возвращении на страницу + + document.addEventListener('visibilitychange', resetFocusTime); // Дублирование для Android, где visibilitychange может не сработать + + Timer.add(1000, resetFocusTime, false, true); + PlayerVideo.listener.follow('timeupdate', resetFocusTime); + Keypad.listener.follow('keydown', resetFocusTime); + } + /** + * Сбросить время фокуса + */ + + + function resetFocusTime() { + if (Date.now() - focustime > 1000 * 60 * 60 * 6) refresh(true); + focustime = Date.now(); + } + /** + * Обновить активность или все активности + * @param {boolean} all - обновить все активности + * @return {void} + */ + + + function refresh() { + var all = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + clearTimeout(refresh_timer); // Обновляем активность через 1 секунду, чтобы не было сразу нескольких обновлений + + refresh_timer = setTimeout(function () { + if (all) { + activites.forEach(function (activity) { + if (activity.activity) activity.activity.refresh(); + }); + } else { + var curent = active$3(); + if (curent && curent.activity) curent.activity.refresh(); + } + }, 1000); + } + /** + * Лимит активностей, уничтожать если больше maxsave + * @return {void} + */ + + + function limit() { + var curent = active$3(); + if (curent && curent.activity) curent.activity.pause(); + var tree_stop = activites.slice(-2); + if (tree_stop.length > 1 && tree_stop[0].activity) tree_stop[0].activity.stop(); + var tree_destroy = activites.slice(-maxsave); + + if (tree_destroy.length > maxsave - 1) { + var first = tree_destroy[0]; + + if (first.activity) { + first.activity.destroy(); + Lampa.Listener.send('activity', { + component: first.component, + type: 'destroy', + object: first + }); + first.activity = null; + } + } + } + /** + * Обновить адрес в строке из активности + * @param {object} object - параметры активности + * @param {boolean} replace - заменить текущий адрес, по умолчанию false (добавить в историю) + * @param {string} mix - дополнительные параметры в строку + * @returns {void} + */ + + + function pushState(object, replace, mix) { + var path = window.location.protocol == 'file:' ? '' : base ? '/' : ''; + if (!window.lampa_settings.push_state) return window.history.pushState(null, null, path); + var data = Arrays.clone(extractObject(object)); + var comp = []; + + for (var n in data) { + if ((typeof data[n] == 'string' || typeof data[n] == 'number' || typeof data[n] == 'boolean') && data[n]) comp.push(n + '=' + encodeURIComponent(data[n])); + } + + var card = object.card || object.movie; + var meth = object.method || (card ? card.name ? 'tv' : 'movie' : ''); + var sour = object.source || (card ? card.source : 'tmdb'); + var durl = card && card.id ? '?card=' + card.id + (meth ? '&media=' + meth : '') + (sour ? '&source=' + sour : '') : '?' + comp.join('&'); + if (mix) durl += '&' + mix; + if (replace) window.history.replaceState(null, null, path + durl);else window.history.pushState(null, null, path + durl); + } + /** + * Обновить адрес в строке из активности с добавлением дополнительных параметров + * @param {string} mix - дополнительные параметры в строку + * @returns {void} + */ + + + function mixState(mix) { + var curent = active$3(); + if (curent && curent.activity) pushState(curent, true, mix); + } + /** + * Добавить новую активность + * @param {{component:string}} object - параметры активности + * @returns {void} + */ + + + function push$3(object) { + limit(); + create$4(object); + activites.push(object); + start$4(object); + pushState(object); + } + /** + * Создать новую активность + * @param {{component:string}} object - параметры активности + * @returns {void} + */ + + + function create$4(object) { + var comp = Component.create(object); + comp.props = new Props(Arrays.clone(extractObject(object))); + object.activity = new ActivitySlide(comp, object); + comp.activity = object.activity; + slides.append(object.activity.render(true)); + Lampa.Listener.send('activity', { + component: object.component, + type: 'init', + object: object + }); + object.activity.create(); + Lampa.Listener.send('activity', { + component: object.component, + type: 'create', + object: object + }); + } + /** + * Вызов (назад) пользователем + * @return {void} + */ + + + function back$3() { + listener$3.send('popstate', { + count: activites.length + }); + if (callback) callback();else { + backward(); + } + } + /** + * Получить активную активность + * @returns {object} + * @return {{component:string, activity:class}} - параметры активности + */ + + + function active$3() { + return activites[activites.length - 1]; + } + + function inActivity() { + return $('body').hasClass('settings--open') || $('body').hasClass('menu--open') ? false : true; + } + /** + * Создать пустую историю + * @return {void} + */ + + + function empty() { + var curent = active$3(); + if (curent && curent.activity) pushState(curent, false, 'r=' + Math.random()); + } + /** + * Получить все активности + * @returns {[{component:string, activity:class}]} + */ + + + function all() { + return activites; + } + /** + * Получить рендеры всех активностей + * @param {boolean} js - вернуть js объекты + * @returns {array} + */ + + + function renderLayers(js) { + var result = []; + all().forEach(function (item) { + if (item.activity) result.push(item.activity.render(js)); + }); + return result; + } + /** + * Обработать событие назад + * @return {void} + */ + + + function backward() { + callback = false; + listener$3.send('backward', { + count: activites.length + }); + if (activites.length == 1) return; + Array.from(slides.children).forEach(function (slide) { + return slide.classList.remove('activity--active'); + }); + var curent = activites.pop(); + + if (curent) { + setTimeout(function () { + curent.activity.destroy(); + Lampa.Listener.send('activity', { + component: curent.component, + type: 'destroy', + object: curent + }); + }, 200); + } + + var previous_tree = activites.slice(-maxsave); + + if (previous_tree.length > maxsave - 1) { + create$4(previous_tree[0]); + } + + previous_tree = activites.slice(-1)[0]; + + if (previous_tree) { + if (previous_tree.activity) { + start$4(previous_tree); + Lampa.Listener.send('activity', { + component: previous_tree.component, + type: 'archive', + object: previous_tree + }); + pushState(previous_tree, true); + } else { + create$4(previous_tree); + start$4(previous_tree); + pushState(previous_tree); + } + } + } + /** + * Сохранить активность в память + * @param {{component:string, activity:class}} object + * @return {void} + */ + + + function save(object) { + Storage.set('activity', extractObject(object)); + } + /** + * Получить данные активности + * @param {{component:string, activity:class}} object - параметры активности + * @returns {{component:string}} + */ + + + function extractObject(object) { + var saved = {}; + + for (var i in object) { + if (!(i == 'activity' || i == 'props' || i == 'params')) saved[i] = object[i]; + } + + return saved; + } + /** + * Активируем следующию активность + * @param {{component:string, activity:class}} object - параметры активности + * @return {void} + */ + + + function start$4(object) { + Head.title(object.title); + + if (object.activity.is_stopped) { + slides.append(object.activity.render(true)); + } + + object.activity.start(); + save(object); + Array.from(slides.children).forEach(function (slide) { + slide.hasClass('activity--active') && slide.removeClass('activity--active'); + }); + object.activity.render().addClass('activity--active'); + Lampa.Listener.send('activity', { + component: object.component, + type: 'start', + object: object + }); + } + /** + * С какой активности начать запуск лампы + * @return {void} + */ + + + function last() { + var active = Storage.get('activity', 'false'); + var start_from = Storage.field("start_page"); + + if (window.lampa_settings.iptv) { + active = { + component: 'iptv', + page: 1 + }; + push$3(active); + } else if (window.start_deep_link) { + window.start_deep_link.page = 1; + push$3(window.start_deep_link); + } else if (active && start_from === "last") { + if (active.page) active.page = 1; + push$3(active); + } else { + var _start_from$split = start_from.split('@'), + _start_from$split2 = _slicedToArray(_start_from$split, 2), + action = _start_from$split2[0], + type = _start_from$split2[1]; + + if (action == 'favorite') { + push$3({ + url: '', + title: Lang.translate(type == 'bookmarks' ? 'settings_input_links' : 'title_history'), + component: type == 'bookmarks' ? 'bookmarks' : 'favorite', + type: type, + page: 1 + }); + } else if (action == 'mytorrents') { + push$3({ + url: '', + title: Lang.translate('title_mytorrents'), + component: 'mytorrents', + page: 1 + }); + } else { + push$3({ + url: '', + title: Lang.translate('title_main') + ' - ' + Storage.field('source').toUpperCase(), + component: 'main', + source: Storage.field('source'), + page: 1 + }); + } + } + } + /** + * Рендер + * @returns {HTMLElement} + */ + + + function render$2() { + return content; + } + /** + * Подключить обратный вызов при изменени истории + * @param {function} call - функция обратного вызова + * @return {void} + */ + + + function call(call) { + callback = call; + } + /** + * Выход из лампы + * @return {void} + */ + + + function out() { + fullout = true; + back$3(); + + for (var i = 0; i < window.history.length; i++) { + back$3(); + } + + setTimeout(function () { + fullout = false; + empty(); + }, 100); + } + /** + * Заменить активную активность + * @param {object} replace - заменить на новые параметры + * @param {boolean} clear - использовать только новые параметры, по умолчанию false + * @return {void} + */ + + + function replace() { + var replace = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var clear = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var object = extractObject(active$3()); + + for (var i in replace) { + object[i] = replace[i]; + } + + var made = active$3(); + made.activity.destroy(); + Lampa.Listener.send('activity', { + component: made.component, + type: 'destroy', + object: made + }); + activites.pop(); + push$3(clear ? replace : object); + } + /** + * Проверить что активность принадлежит компоненту + * @param {object} component - компонент + * @returns {boolean} + */ + + + function own$1(component) { + var curent = active$3(); + return curent && curent.activity && curent.activity === component.activity; + } + + var Activity = { + init: init$v, + listener: listener$3, + push: push$3, + back: back$3, + render: render$2, + backward: backward, + call: call, + last: last, + out: out, + replace: replace, + active: active$3, + all: all, + extractObject: extractObject, + renderLayers: renderLayers, + inActivity: inActivity, + pushState: pushState, + mixState: mixState, + own: own$1, + refresh: refresh + }; + + var listener$2 = Subscribe$2(); + var active$2; + var active_name = ''; + var controlls = {}; + var select_active; + var try_close = false; + + function observe() { + if (typeof MutationObserver == 'undefined') return; + var observer = new MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { + var mutation = mutations[i]; + + if (mutation.type == 'childList' && !mutation.removedNodes.length) { + var selectors = Array.from(mutation.target.querySelectorAll('.selector')); + selectors.forEach(function (elem) { + if (!elem.classList.contains('hg-button')) bindEvents(elem); + }); + } + } + }); + observer.observe(document, { + childList: true, + subtree: true + }); + } + + function animateTriggerEnter(elem) { + if (Storage.field('advanced_animation')) { + elem.addClass('animate-trigger-enter'); + setTimeout(function () { + elem.removeClass('animate-trigger-enter'); + }, 500); + } + } + /** + * Добавить контроллер + * @param {String} name + * @param {Object} calls + */ + + + function add$4(name, calls) { + controlls[name] = calls; + } + /** + * Запустить функцию + * @param {String} name + * @param {Object} params + */ + + + function run(name, params) { + if (active$2) { + if (active$2[name]) { + if (typeof active$2[name] == 'function') active$2[name](params);else if (typeof active$2[name] == 'string') { + run(active$2[name], params); + } + } + } + } + /** + * Двигать + * @param {String} direction + */ + + + function move(direction) { + run(direction); + } + /** + * Вызов enter + */ + + + function enter() { + if (active$2 && active$2.enter) run('enter');else if (select_active) { + animateTriggerEnter(select_active); + Utils$1.trigger(select_active, 'hover:enter'); + } + } + /** + * Вызов long + */ + + + function _long() { + if (active$2 && active$2["long"]) run('long');else if (select_active) Utils$1.trigger(select_active, 'hover:long'); + } + /** + * Завершить + */ + + + function finish() { + run('finish'); + } + /** + * Нажали назад + */ + + + function back$2() { + run('back'); + } + /** + * Переключить контроллер + * @param {String} name + */ + + + function toggle$2(name) { + if (active$2 && active$2.gone) active$2.gone(name); + + if (controlls[name]) { + if (name == 'content') toContent(); + active$2 = controlls[name]; + active_name = name; + Activity.call(function () { + run('back'); + }); + if (active$2.toggle) active$2.toggle(); + if (active$2.update) active$2.update();else { + Layer.update(); + } + listener$2.send('toggle', { + name: name + }); + } + } + + function bindEvents(elem) { + if (elem.classList.contains('selector') && !elem.bind_events) { + elem.bind_events = true; + var long_position = 0; + var long_timer; + + var longStart = function longStart() { + clearTimeout(long_timer); + var offset = elem.getBoundingClientRect(); + long_timer = setTimeout(function () { + var time = elem.long_time || 0; + offset = elem.getBoundingClientRect(); + + if (time + 100 < Date.now()) { + var mutation = Math.abs(long_position - (offset.top + offset.left)); + if (mutation < 30) Utils$1.trigger(elem, 'hover:long'); + } + + elem.long_time = Date.now(); + }, 800); + long_position = offset.top + offset.left; + }; + + var longClear = function longClear() { + clearTimeout(long_timer); + }; + + var touchStart = function touchStart() { + longStart(); + Utils$1.trigger(elem, 'hover:touch'); + }; + + var rightClick = function rightClick(e) { + Utils$1.trigger(elem, 'hover:long'); + }; + + elem.trigger_click = function (e) { + if (DeviceInput.canClick(e) && DeviceInput.noDubleClick(e)) { + animateTriggerEnter(elem); + Utils$1.trigger(elem, 'hover:enter'); + } + }; + + elem.trigger_mouseenter = function () { + clearAllFocus(); + elem.toggleClass('focus', true); + Utils$1.trigger(elem, 'hover:hover'); + }; + + elem.trigger_mouseleave = function () { + elem.toggleClass('focus', false); + }; + + elem.addEventListener('click', function (e) { + setTimeout(elem.trigger_click.bind(null, e), 20); + }); + + if (!Utils$1.isTouchDevice() && Storage.field('navigation_type') == 'mouse') { + elem.addEventListener('mouseenter', elem.trigger_mouseenter); + elem.addEventListener('mouseleave', elem.trigger_mouseleave); + elem.addEventListener('mouseout', longClear); + elem.addEventListener('mouseup', longClear); + elem.addEventListener('mousedown', longStart); + elem.addEventListener('contextmenu', rightClick); + } + + if (Utils$1.isTouchDevice()) { + elem.addEventListener('touchstart', touchStart); + elem.addEventListener('touchend', longClear); + elem.addEventListener('touchmove', longClear); + } + } + } + + function enable(name) { + if (active_name == name) toggle$2(name); + } + + function clearSelects() { + select_active = false; + removeClass(['focus']); + } + + function clearAllFocus() { + var collection = Array.from(document.body.querySelectorAll('.selector')); + collection.forEach(function (item) { + return item.toggleClass('focus', false); + }); + } + /** + * Вызвать событие + * @param {String} name + * @param {Object} params + */ + + + function trigger$1(name, params) { + run(name, params); + } + /** + * Очистить классы + * @param {Array} classes + */ + + + function removeClass(classes) { + if (Navigator._collection) { + Navigator._collection.forEach(function (element) { + classes.forEach(function (class_name) { + element.toggleClass(class_name, false); + }); + }); + } + } + /** + * Фокус на элементе + * @param {Object} target + */ + + + function focus(target) { + Utils$1.trigger(target, 'hover:focus'); + + if (Platform.screen('tv')) { + removeClass(['focus']); + target.toggleClass('focus', true); + } + + select_active = target; + } + + function collectionSet(html) { + var append = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var visible_only = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + html = html instanceof jQuery ? html[0] : html; + append = append instanceof jQuery ? append[0] : append; + var colection = Array.from(html.querySelectorAll('.selector')); + if (visible_only) colection = colection.filter(function (e) { + return e.offsetParent !== null; + }); + + if (append) { + colection = colection.concat(Array.from(append.querySelectorAll('.selector'))); + } + + if (colection.length || active$2.invisible) { + clearSelects(); + Navigator.setCollection(colection); + } + } + + function collectionAppend(append) { + append = append instanceof jQuery ? append.toArray() : append; + if (!append.length) append = Array.from([append]); + Navigator.multiAdd(append); + } + + function collectionFocus(target, html) { + var visible_only = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + html = html instanceof jQuery ? html[0] : html; + target = target instanceof jQuery ? target[0] : target; + if (target && target.offsetParent === null) target = false; + + if (target) { + Navigator.focus(target); + } else { + var colection = Array.from(html.querySelectorAll('.selector')).filter(function (elem) { + return !elem.classList.contains('hide'); + }); + if (visible_only) colection = colection.filter(function (e) { + return e.offsetParent !== null; + }); + if (colection.length) Navigator.focus(colection[0]); + } + } + + function own(link) { + return active$2 && active$2.link == link; + } + + function enabled() { + return { + name: active_name, + controller: active$2 + }; + } + + function toContent() { + if (try_close) return; + try_close = true; + var trys = 0; + Screensaver$2.stopSlideshow(); + + var any = function any() { + return parseInt([$('body').hasClass('settings--open') ? 1 : 0, $('body').hasClass('selectbox--open') ? 1 : 0, $('.modal,.youtube-player,.player,.search-box,.search').length ? 1 : 0].join('')); + }; + + var close = function close() { + var contrl = enabled(); + trys++; + + if (any()) { + try { + if (contrl.controller.back) contrl.controller.back(); + } catch (e) {} + + if (trys < 10) close(); + } + }; + + var remove = function remove() { + try { + if ($('body').hasClass('settings--open')) $('body').removeClass('settings--open'); + if ($('body').hasClass('selectbox--open')) Select.close(); + if ($('.modal').length) Modal.close(); + if ($('.player').length) Player.close(); + if ($('.search-box').length) $('.search-box').remove(); + if ($('body').hasClass('search--open')) Search.close(); + $('body').removeClass('ambience--enable'); + } catch (e) {} + }; + + close(); + remove(); + try_close = false; + } + + function clear$2() { + clearSelects(); + Navigator.setCollection([]); + } + + var Controller = { + listener: listener$2, + observe: observe, + add: add$4, + move: move, + enter: enter, + finish: finish, + toggle: toggle$2, + trigger: trigger$1, + back: back$2, + focus: focus, + collectionSet: collectionSet, + collectionFocus: collectionFocus, + collectionAppend: collectionAppend, + enable: enable, + enabled: enabled, + "long": _long, + toContent: toContent, + updateSelects: function updateSelects() {}, + own: own, + clear: clear$2 + }; + + var http = window.location.protocol == 'https:' ? 'https://' : 'http://'; + var layers = { + search: { + 'sim': ['{MIC} {ABC} 1 2 3 4 5 6 7 8 9 0 {BKSP}', '{LANG} - + _ : ( ) [ ] . / {SPACE}'], + 'en': ['{MIC} q w e r t y u i o p {BKSP}', '{LANG} a s d f g h j k l', '{SIM} z x c v b n m . {SPACE}'], + 'uk': ['{MIC} й ц у к е н г ш щ з х ї {BKSP}', '{LANG} ф і в а п р о л д ж є', '{SIM} я ч с м и т ь б ю . {SPACE}'], + 'he': ['{MIC} ק ר א ט ו ן ם פ {BKSP}', '{LANG} ש ד ג כ ע י ח ל ך ף', '{SIM} ז ס ב ה נ מ צ ת ץ . {SPACE}'], + 'default': ['{MIC} й ц у к е н г ш щ з х ъ {BKSP}', '{LANG} ё ф ы в а п р о л д ж э', '{SIM} я ч с м и т ь б ю . {SPACE}'] + }, + clarify: { + 'en': ['1 2 3 4 5 6 7 8 9 0 - {BKSP}', 'q w e r t y u i o p', 'a s d f g h j k l', 'z x c v b n m .', '{MIC} {LANG} {SPACE} {SEARCH}'], + 'uk': ['1 2 3 4 5 6 7 8 9 0 - {BKSP}', 'й ц у к е н г ш щ з х ї', 'ф і в а п р о л д ж є', 'я ч с м и т ь б ю .', '{MIC} {LANG} {SPACE} {SEARCH}'], + 'he': ['1 2 3 4 5 6 7 8 9 0 - {BKSP}', 'ק ר א ט ו ן ם פ', 'ש ד ג כ ע י ח ל ך ף', 'ז ס ב ה נ מ צ ת ץ .', '{MIC} {LANG} {SPACE} {SEARCH}'], + 'default': ['1 2 3 4 5 6 7 8 9 0 - {BKSP}', 'й ц у к е н г ш щ з х ъ', 'ф ы в а п р о л д ж э', 'я ч с м и т ь б ю .', '{MIC} {LANG} {SPACE} {SEARCH}'] + }, + "default": { + 'en': ['{SIM} 1 2 3 4 5 6 7 8 9 0 - + = {BKSP}', '{LANG} q w e r t y u i o p', 'a s d f g h j k l / {ENTER}', '{SHIFT} z x c v b n m , . : ' + http, '{SPACE}'], + 'uk': ['{SIM} 1 2 3 4 5 6 7 8 9 0 - + = {BKSP}', '{LANG} й ц у к е н г ш щ з х ї', 'ф і в а п р о л д ж є {ENTER}', '{SHIFT} я ч с м и т ь б ю . : ' + http, '{SPACE}'], + 'he': ['{SIM} ק ר א ט ו ן ם פ {BKSP}', '{LANG} ש ד ג כ ע י ח ל ך ף', 'ז ס ב ה נ מ צ ת ץ . /', '{SHIFT} ! @ # $ % ^ & * ( ) {SPACE}'], + 'sim': ['{ABC} 1 2 3 4 5 6 7 8 9 0 - + = {BKSP}', '{LANG} ! @ # $ % ^ & * ( ) [ ]', '- _ = + \\ | [ ] { }', '; : \' " , . < > / ?', '{SPACE}'], + 'default': ['{SIM} 1 2 3 4 5 6 7 8 9 0 - + = {BKSP}', '{LANG} й ц у к е н г ш щ з х ъ', 'ф ы в а п р о л д ж э {ENTER}', '{SHIFT} я ч с м и т ь б ю , . : ' + http, '{SPACE}'] + }, + nums: { + 'default': ['0 1 2 3 4 {BKSP}', '5 6 7 8 9 {ENTER}'] + } + }; + + function add$3(name, layout) { + layers[name] = layout; + } + + function addLang(name, code, layout) { + layers[name][code] = layout; + } + + function get$2(name) { + return layers[name]; + } + + var Layers = { + add: add$3, + addLang: addLang, + get: get$2 + }; + + /** + * Виртуальная клавиатура + * @param {object} [params] - параметры клавиатуры + * @param {string} [params.layout] - имя слоя клавиатуры из Layers (default, extended, full, ru, en и т.д.) или сам слой + * @param {boolean} [params.textarea=false] - использовать textarea вместо input (для мобильных устройств) + * @param {boolean} [params.nomic=false] - отключить микрофон + * @param {string} [params.keyboard] - тип клавиатуры (lampa или simple) + * @return {Keyboard} + */ + + function Keyboard() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var _keyClass = window.SimpleKeyboard["default"], + _keyBord; + + var _lang_codes = { + 'ru': 'ru-RU', + 'en': 'en-US', + 'be': 'be-BY', + 'uk': 'uk-UA', + 'zh': 'zh-CN', + 'bg': 'bg-BG', + 'pt': 'pt-PT', + 'cs': 'cs-CZ' + }; + var last; + var ime; + var recognition; + var simple = Storage.field('keyboard_type') !== 'lampa'; + var input; + var last_value; + var height = window.innerHeight; + var mobile = Platform.screen('mobile') && params.textarea; + var is_electron = Platform.is('electron'); + + if (params.keyboard) { + simple = params.keyboard !== 'lampa'; + } + + if (Platform.screen('mobile')) simple = true; + this.listener = Subscribe$2(); + + this.create = function () { + var _this = this; + + if (simple) { + input = $(''); + + if (mobile) { + input = $(''); + input.on('input', function () { + input[0].style.height = 'auto'; + input[0].style.height = input[0].scrollHeight + 'px'; + }); + } + + var time_blur = 0; + var time_focus = 0; + var stated, ended; + + if (Platform.is('orsay')) { + ime = new IMEShell_Common(); + + if ($('.settings-input--free').length > 0) { + ime.setUseNumberMode(true); + } + + ime.inputboxID = 'orsay-keyboard'; + ime.setUseIMEDim(false); + ime.setMaxlength(256); + ime.inputTitle = Lang.translate('search_input') + "..."; + + ime.onKeyPressFunc = function (key, str, id) { + switch (key) { + case 29443: // Enter Key + + case 88: //return + + case 45: + //exit + _this.listener.send('enter'); + + ime.onClose(); + input.blur(); + break; + } + }; + + ime.setOnTextChangeFunc = function (e) { + input.val(e); + var now_value = input.val(); + + if (last_value !== now_value) { + last_value = now_value; + stated = ended = false; + + _this.listener.send('change', { + value: now_value + }); + } + }; + } + + input.on('keyup change input keypress', function (e) { + var now_value = input.val(); + + if (last_value !== now_value) { + last_value = now_value; + stated = ended = false; + + _this.listener.send('change', { + value: now_value + }); + } + }); + input.on('blur', function () { + Keypad.enable(); + time_blur = Date.now(); + if (Platform.is('android') && Platform.screen('tv')) input.attr('disabled', 'true'); + + _this.listener.send('blur'); + }); + input.on('focus', function () { + if (!Platform.is('apple_tv')) Keypad.disable(); + time_focus = Date.now(); + if (!(Platform.is('browser') || Platform.desktop())) _this.listener.send('focus'); + }); + input.on('keyup', function (e) { + if (time_focus + 1000 > Date.now()) return; + var keys = [13, 65376, 29443, 117, 65385, 461, 27]; + var valu = input.val(); + var cart = e.target.selectionStart; + + if (keys.indexOf(e.keyCode) >= 0 && !(Utils$1.isTouchDevice() && params.textarea && Platform.screen('mobile'))) { + e.preventDefault(); + console.log('Keyboard', 'blur key:', e.keyCode, 'value:', valu); + input.blur(); + } + + if ((e.keyCode == 13 || e.keyCode == 65376) && !(Utils$1.isTouchDevice() && params.textarea && Platform.screen('mobile'))) _this.listener.send('enter'); + + if (e.keyCode == 37 && cart == 0 && height == window.innerHeight) { + if (stated) input.blur(), _this.listener.send('left'); + stated = true; + ended = false; + } + + if (e.keyCode == 39 && cart >= valu.length && height == window.innerHeight) { + if (ended) input.blur(), _this.listener.send('right'); + ended = true; + stated = false; + } + + if (e.keyCode == 40) { + if (height == window.innerHeight) input.blur(), _this.listener.send('down'); + } + + if (e.keyCode == 38) { + if (height == window.innerHeight) input.blur(), _this.listener.send('up'); + } + }); + input.on('hover:focus', function () { + if (Platform.is('orsay')) ime.onShow(); + input.removeAttr('disabled'); + input.focus(); + }); + input.on('hover:enter', function () { + if (time_blur + 1000 < Date.now()) { + if (Platform.is('orsay')) ime.onShow(); + input.focus(); + if (Platform.is('apple_tv')) window.location.assign('lampa://openkeyboard'); + } + }); + var keyboard = $('.simple-keyboard'); + + if (!is_electron && !Platform.is('orsay') && !Platform.is('apple_tv') && (window.SpeechRecognition || window.webkitSpeechRecognition) && !params.nomic && Platform.screen('tv')) { + var mic = $("
    \n \n \n \n \n \n
    "); + mic.on('hover:enter', function () { + if (Platform.is('android')) { + Android.voiceStart(); + window.voiceResult = _this.value.bind(_this); + } else if (recognition) { + try { + if (recognition.record) recognition.stop();else recognition.start(); + } catch (e) { + recognition.stop(); + } + } + }); + keyboard.addClass('simple-keyboard--with-mic').append(mic); + } + + keyboard.append(input); + if (mobile) keyboard.addClass('simple-keyboard--with-textarea'); + + if (Platform.screen('mobile') || Platform.mouse()) { + var buttons = $('
    ' + Lang.translate('ready') + '
    ' + Lang.translate('cancel') + '
    '); + buttons.find('.simple-keyboard-buttons__enter').on('click', function () { + input.blur(); + + _this.listener.send('enter'); + }); + buttons.find('.simple-keyboard-buttons__cancel').on('click', function () { + _this.value(''); + + Controller.back(); + }); + $('.simple-keyboard').append(buttons); + } + } else { + var layout = typeof params.layout == 'string' ? Layers.get(params.layout) : params.layout || Layers.get('default'); + var press = Date.now(); + + if (is_electron) { + Arrays.getKeys(layout).forEach(function (code) { + layout[code] = layout[code].map(function (row) { + return row.replace('{MIC}', '').replace(/\s{2,}/g, ' ').trim(); + }); + }); + } + + _keyBord = new _keyClass({ + display: { + '{BKSP}': ' ', + '{ENTER}': ' ', + '{SHIFT}': ' ', + '{SPACE}': ' ', + '{LANG}': ' ', + '{ABC}': 'Aa', + '{SIM}': '#+', + '{SEARCH}': Lang.translate('search'), + '{MIC}': "\n \n \n \n " + }, + layout: layout, + onChange: function onChange(value) { + _this.listener.send('change', { + value: value + }); + }, + onKeyPress: function onKeyPress(button) { + if (Date.now() - press < 100) return; + press = Date.now(); + if (button === "{SHIFT}" || button === "{SIM}" || button === "{ABC}") _this._handle(button);else if (button === '{MIC}') { + if (is_electron) return; + + if (Platform.is('android')) { + Android.voiceStart(); + window.voiceResult = _this.value.bind(_this); + } else if (recognition) { + try { + if (recognition.record) recognition.stop();else recognition.start(); + } catch (e) { + recognition.stop(); + } + } + } else if (button === '{LANG}') { + var codes = Lang.codes(); + var items = []; + + var select_code = _keyBord.options.layoutName.split('-')[0]; + + items.push({ + title: codes.ru, + value: 'default', + selected: select_code == 'default' + }); + Arrays.getKeys(codes).forEach(function (code) { + if (layout[code]) { + items.push({ + title: codes[code], + value: code, + selected: select_code == code + }); + } + }); + setTimeout(function () { + Select.show({ + title: Lang.translate('title_choice_language'), + items: items, + onSelect: function onSelect(item) { + Select.hide(); + Storage.set('keyboard_default_lang', item.value); + var shifted = _keyBord.options.layoutName.split('-')[1] == 'shift'; + var new_layout = item.value + (shifted ? '-shift' : ''); + + _this.shifted(!shifted, new_layout, item.value); + + _keyBord.setOptions({ + layoutName: new_layout + }); + + last = false; + _keyBord.options.lastLayerSelect = _keyBord.options.layoutName; + Controller.toggle('keybord'); + $('.simple-keyboard').attr('shifted', Boolean(shifted)); + Controller.collectionFocus($('.simple-keyboard [data-skbtn="{LANG}"]')[0], $('.simple-keyboard')); + }, + onBack: function onBack() { + Select.hide(); + Controller.toggle('keybord'); + } + }); + }, 300); + } else if (button === '{SPACE}') { + _this.value(_keyBord.getInput() + ' '); + } else if (button === '{BKSP}') { + _this.value(_keyBord.getInput().slice(0, -1)); + } else if (button === '{ENTER}' || button === '{SEARCH}') { + _this.listener.send('enter'); + } + } + }); + var lang = Storage.get('keyboard_default_lang', Storage.get('language', 'ru')); + + _keyBord.setOptions({ + layoutName: lang == 'ru' ? 'default' : Arrays.getKeys(layout).indexOf(lang) >= 0 ? lang : layout.en ? 'en' : 'default' + }); + + $('.simple-keyboard').addClass('hg-style-' + (params.layout || 'default')); + } + + this.speechRecognition(); + }; + + this.speechRecognition = function () { + var _this2 = this; + + var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; + console.log('Speech', 'status:', SpeechRecognition ? true : false); + + if (SpeechRecognition) { + recognition = new SpeechRecognition(); + recognition.continuous = false; + recognition.lang = _lang_codes[Storage.get('language', 'ru')] || 'en-US'; + console.log('Speech', 'lang:', recognition.lang); + recognition.addEventListener("start", function () { + console.log('Speech', 'start'); + $('.simple-keyboard [data-skbtn="{mic}"]').css('color', 'red'); + $('.simple-keyboard-mic').addClass('record'); + recognition.record = true; + Noty.show(Lang.translate('keyboard_listen')); + }); + recognition.addEventListener("end", function () { + console.log('Speech', 'end'); + $('.simple-keyboard [data-skbtn="{mic}"]').css('color', 'white'); + $('.simple-keyboard-mic').removeClass('record'); + recognition.record = false; + }); + recognition.addEventListener("result", function (event) { + console.log('Speech', 'result:', event.resultIndex, event.results[event.resultIndex]); + var current = event.resultIndex; + var transcript = event.results[current][0].transcript; + console.log('Speech', 'transcript:', transcript); + + if (transcript.toLowerCase().trim() === "stop recording") { + recognition.stop(); + } else { + if (transcript.toLowerCase().trim() === "reset input") { + _this2.value(''); + } else { + _this2.value(transcript); + } + } + }); + recognition.addEventListener("error", function (event) { + console.log('Speech', 'error:', event); + + if (event.error == 'not-allowed') { + Noty.show(Lang.translate('keyboard_nomic')); + } + + recognition.stop(); + }); + } else { + $('.simple-keyboard [data-skbtn="{mic}"]').css('opacity', '0.3'); + } + }; + + this.value = function (value) { + if (simple) { + input.val(value); + + if (mobile) { + input[0].style.height = 'auto'; + input[0].style.height = input[0].scrollHeight + 'px'; + } + } else _keyBord.setInput(value); + + last_value = value; + this.listener.send('change', { + value: value + }); + }; + + this._layout = function () { + var _this3 = this; + + var keys = $('.simple-keyboard .hg-button').addClass('selector'); + Controller.collectionSet($('.simple-keyboard')); + Controller.collectionFocus(last || keys[0], $('.simple-keyboard')); + $('.simple-keyboard .hg-button:not(.binded)').on('hover:enter', function (e) { + Controller.collectionFocus($(this)[0]); + + _keyBord.handleButtonClicked($(this).attr('data-skbtn'), e); + }).on('hover:focus', function (e) { + last = e.target; + + _this3.listener.send('hover', { + button: e.target + }); + }); + keys.addClass('binded'); + $('.simple-keyboard').addClass('hg-style-' + (params.layout || 'default')); + }; + + this.shifted = function (shifted, layout, code) { + if (!(shifted && _keyBord.options.layout[layout])) { + var shift_layer = Arrays.clone(_keyBord.options.layout[code]); + shift_layer = shift_layer.map(function (button) { + return button.toUpperCase(); + }); + _keyBord.options.layout[layout] = shift_layer; + } + }; + + this._handle = function (button) { + var current_layout = _keyBord.options.layoutName, + layout = 'default', + focus; + var shifted = current_layout.split('-')[1] == 'shift'; + var code = current_layout.split('-')[0]; + $('.simple-keyboard').attr('shifted', Boolean(!shifted)); + + if (button == '{SHIFT}') { + if (shifted) layout = code;else layout = code + '-shift'; + this.shifted(shifted, layout, code); + } else if (button == '{SIM}') { + layout = 'sim'; + focus = '{ABC}'; + _keyBord.options.lastLayerSelect = current_layout; + } else if (button == '{ABC}') { + layout = _keyBord.options.lastLayerSelect || 'default'; + focus = '{SIM}'; + } + + _keyBord.setOptions({ + layoutName: layout + }); + + last = false; + Controller.toggle('keybord'); + Controller.collectionFocus($('.simple-keyboard [data-skbtn="' + (focus || button) + '"]')[0], $('.simple-keyboard')); + }; + + this.toggle = function () { + var _this4 = this; + + Controller.add('keybord', { + toggle: function toggle() { + if (simple) { + Controller.collectionSet($('.simple-keyboard')); + Controller.collectionFocus(mobile ? $('.simple-keyboard-input') : false, $('.simple-keyboard')); + } else _this4._layout(); + }, + update: function update() {}, + up: function up() { + if (!Navigator.canmove('up')) { + _this4.listener.send('up'); + } else Navigator.move('up'); + }, + down: function down() { + if (!Navigator.canmove('down')) { + _this4.listener.send('down'); + } else Navigator.move('down'); + }, + left: function left() { + if (!Navigator.canmove('left')) { + _this4.listener.send('left'); + } else Navigator.move('left'); + }, + right: function right() { + if (!Navigator.canmove('right')) { + _this4.listener.send('right'); + } else Navigator.move('right'); + }, + back: function back() { + _this4.listener.send('back'); + } + }); + Controller.toggle('keybord'); + }; + + this.destroy = function () { + try { + if (simple) { + input.remove(); + } else _keyBord.destroy(); + + if (recognition) recognition.stop(); + } catch (e) {} + + this.listener.destroy(); + Keypad.enable(); + }; + } + + var html$8, + keyboard, + input, + input_value = ''; + /** + * Заустить редактор + * @param {{title:string, value:string, free:boolean, nosave:boolean}} params + * @param {function} call + */ + + function edit(params, call) { + html$8 = Template.get('settings_input'); + input = html$8.find('.settings-input__input'); + if ((params.keyboard || Storage.field('keyboard_type')) !== 'lampa') input.hide(); + $('body').addClass('keyboard-input--visible').append(html$8); + html$8.addClass('settings-input--align-' + (params.align || 'center')); + + var pass = function pass(v) { + return params.password ? v.replace(/./g, '*') : v; + }; + + keyboard = new Keyboard(params); + keyboard.listener.follow('change', function (event) { + input_value = event.value.trim(); + input.toggleClass('filled', Boolean(event.value)); + input.html(pass(Utils$1.inputDisplay(event.value))); + }); + keyboard.listener.follow('enter', function (event) { + back$1(); + call(input_value); + }); + keyboard.listener.follow('focus', function (event) { + html$8.toggleClass('settings-input--focus', true); + }); + keyboard.listener.follow('blur', function (event) { + html$8.toggleClass('settings-input--focus', false); + }); + html$8.toggleClass('settings-input--free', params.free ? true : false); + $('.settings-input__links', html$8).toggleClass('hide', params.nosave ? true : false); + if (params.title) html$8.find('.settings-input__content').prepend('
    ' + params.title + '
    '); + keyboard.listener.follow('down', function (event) { + if (params.nosave) return; + var members = Storage.get('setting_member', []); + var links = []; + links.push({ + title: (members.indexOf(input_value) == -1 ? Lang.translate('settings_add') : Lang.translate('settings_remove')) + ' ' + Lang.translate('settings_this_value'), + subtitle: input_value, + add: true + }); + members.forEach(function (link) { + links.push({ + title: link, + subtitle: Lang.translate('settings_user_links'), + url: link, + member: true + }); + }); + links = links.concat([{ + title: '127.0.0.1:8090', + subtitle: Lang.translate('settings_for_local'), + url: '127.0.0.1:8090' + }]); + Select.show({ + title: Lang.translate('title_links'), + items: links, + onSelect: function onSelect(a) { + if (a.add) { + if (members.indexOf(a.subtitle) == -1) { + Arrays.insert(members, 0, a.subtitle); + Noty.show(Lang.translate('settings_added') + ' (' + a.subtitle + ')'); + } else { + Arrays.remove(members, a.subtitle); + Noty.show(Lang.translate('settings_removed') + ' (' + a.subtitle + ')'); + } + + Storage.set('setting_member', members); + } else { + keyboard.value(a.url); + } + + keyboard.toggle(); + }, + onLong: function onLong(a, elem) { + if (a.member) { + Arrays.remove(members, a.url); + Noty.show(Lang.translate('settings_removed') + ' (' + a.url + ')'); + Storage.set('setting_member', members); + $(elem).css({ + opacity: 0.4 + }); + } + }, + onBack: function onBack() { + keyboard.toggle(); + } + }); + }); + keyboard.listener.follow('back', function () { + back$1(); + call(input_value); + }); + keyboard.create(); + keyboard.value(params.value); + keyboard.toggle(); + input_value = params.value; + return keyboard; + } + /** + * Назад + */ + + + function back$1() { + destroy$1(); + Controller.toggle('settings_component'); + } + /** + * Уничтожить + */ + + + function destroy$1() { + keyboard.destroy(); + html$8.remove(); + $('body').removeClass('keyboard-input--visible'); + html$8 = null; + keyboard = null; + input = null; + } + + var Input = { + edit: edit + }; + + var values = {}; + var defaults = {}; + var listener$1 = Subscribe$2(); + /** + * Запуск + */ + + function init$u() { + if (Platform.is('tizen')) { + select('player', { + 'inner': '#{settings_param_player_inner}', + 'tizen': 'Tizen' + }, 'tizen'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}', + 'tizen': 'Tizen' + }, 'tizen'); + select('player_torrent', { + 'inner': '#{settings_param_player_inner}', + 'tizen': 'Tizen' + }, 'tizen'); + } + + if (Platform.is('orsay')) { + select('player', { + 'inner': '#{settings_param_player_inner}', + 'orsay': 'Orsay' + }, 'orsay'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}', + 'orsay': 'Orsay' + }, 'orsay'); + select('player_torrent', { + 'inner': '#{settings_param_player_inner}', + 'orsay': 'Orsay' + }, 'orsay'); + } else if (Platform.is('webos')) { + select('player', { + 'inner': '#{settings_param_player_inner}', + 'webos': 'WebOS' + }, 'inner'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}', + 'webos': 'WebOS' + }, 'inner'); + select('player_torrent', { + 'inner': '#{settings_param_player_inner}', + 'webos': 'WebOS' + }, 'inner'); + } else if (Platform.is('android')) { + select('player', { + 'inner': '#{settings_param_player_inner}', + 'android': 'Android' + }, 'android'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}', + 'android': 'Android' + }, 'android'); + select('player_torrent', { + 'android': 'Android' + }, 'android'); + trigger('internal_torrclient', false); + } else if (Platform.desktop() && !Platform.macOS()) { + select('player', { + 'inner': '#{settings_param_player_inner}', + 'other': '#{settings_param_player_outside}' + }, 'inner'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}', + 'other': '#{settings_param_player_outside}' + }, 'inner'); + select('player_torrent', { + 'inner': '#{settings_param_player_inner}', + 'other': '#{settings_param_player_outside}' + }, 'inner'); + } else if (Platform.macOS()) { + select('player', { + 'inner': '#{settings_param_player_inner}', + 'iina': 'IINA', + 'infuse': 'Infuse', + 'mpv': 'MPV', + 'nplayer': 'nPlayer', + 'senplayer': 'SenPlayer', + 'tracyplayer': 'TracyPlayer' + }, 'inner'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}', + 'iina': 'IINA', + 'infuse': 'Infuse', + 'mpv': 'MPV', + 'nplayer': 'nPlayer', + 'senplayer': 'SenPlayer', + 'tracyplayer': 'TracyPlayer' + }, 'inner'); + select('player_torrent', { + 'inner': '#{settings_param_player_inner}', + 'iina': 'IINA', + 'infuse': 'Infuse', + 'mpv': 'MPV', + 'nplayer': 'nPlayer', + 'senplayer': 'SenPlayer', + 'tracyplayer': 'TracyPlayer' + }, 'inner'); + } else if (Platform.is('apple')) { + select('player', { + 'inner': '#{settings_param_player_inner}', + 'ios': 'iOS', + 'vlc': 'VLC', + 'nplayer': 'nPlayer', + 'infuse': 'Infuse', + 'vidhub': 'Vidhub', + 'svplayer': 'SVPlayer', + 'tracyplayer': 'TracyPlayer', + 'senplayer': 'SenPlayer' + }, 'inner'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}', + 'ios': 'iOS', + 'vlc': 'VLC', + 'nplayer': 'nPlayer', + 'infuse': 'Infuse', + 'svplayer': 'SVPlayer', + 'tracyplayer': 'TracyPlayer', + 'senplayer': 'SenPlayer' + }, 'inner'); + select('player_torrent', { + 'inner': '#{settings_param_player_inner}', + 'ios': 'iOS', + 'vlc': 'VLC', + 'nplayer': 'nPlayer', + 'infuse': 'Infuse', + 'vidhub': 'Vidhub', + 'svplayer': 'SVPlayer', + 'tracyplayer': 'TracyPlayer', + 'senplayer': 'SenPlayer' + }, 'inner'); + } else if (Platform.is('apple_tv')) { + select('player', { + 'tvospro': '#{settings_param_player_inner_tvos} tvOS Pro', + 'tvos': '#{settings_param_player_inner_tvos} tvOS Universal', + 'tvosl': '#{settings_param_player_inner_tvos} tvOS Online', + 'tvosSelect': '#{settings_param_player_outside}', + 'vlc': 'VLC', + 'infuse': 'Infuse', + 'senplayer': 'SenPlayer', + 'vidhub': 'Vidhub', + 'inner': '#{settings_param_player_inner}', + 'svplayer': 'SVPlayer' + }, 'tvos'); + select('player_iptv', { + 'tvospro': '#{settings_param_player_inner_tvos} tvOS Pro', + 'tvos': '#{settings_param_player_inner_tvos} tvOS Universal', + 'tvosl': '#{settings_param_player_inner_tvos} tvOS Online', + 'tvosSelect': '#{settings_param_player_outside}', + 'vlc': 'VLC', + 'infuse': 'Infuse', + 'senplayer': 'SenPlayer', + 'vidhub': 'Vidhub', + 'inner': '#{settings_param_player_inner}', + 'svplayer': 'SVPlayer' + }, 'inner'); + select('player_torrent', { + 'tvospro': '#{settings_param_player_inner_tvos} tvOS Pro', + 'tvos': '#{settings_param_player_inner_tvos} tvOS Universal', + 'tvosSelect': '#{settings_param_player_outside}', + 'infuse': 'Infuse', + 'senplayer': 'SenPlayer', + 'vidhub': 'Vidhub', + 'vlc': 'VLC', + 'inner': '#{settings_param_player_inner}', + 'svplayer': 'SVPlayer' + }, 'tvos'); + } + + trigger('glass_style', Platform.screen('mobile')); + trigger('advanced_animation', Platform.is('apple_tv') || Platform.is('browser') || Platform.desktop() || navigator.userAgent.toLowerCase().indexOf('shield') >= 0); + var screensaver_types = { + 'nature': '#{settings_param_screensaver_nature}', + 'chrome': 'ChromeCast', + 'cub': 'CUB', + 'aerial': 'Aerial' + }; + select('screensaver_type', screensaver_types, 'aerial'); + select('keyboard_type', { + 'lampa': '#{settings_param_keyboard_lampa}', + 'integrate': '#{settings_param_keyboard_system}' + }, Platform.screen('mobile') || Platform.is('apple_tv') || Platform.macOS() || Platform.desktop() || Platform.is('browser') ? 'integrate' : 'lampa'); + select('navigation_type', { + 'controll': '#{settings_param_navigation_remote}', + 'mouse': '#{settings_param_navigation_mouse}', + 'touch': '#{settings_param_navigation_touch}' + }, Platform.is('browser') || Platform.desktop() ? 'mouse' : Platform.screen('mobile') ? 'touch' : 'controll'); //язык и комбинации для поиска + + var langcode = Storage.get('language', 'ru'); + var langname = Lang.codes()[langcode]; + var selector = { + 'df': '#{settings_param_torrent_lang_orig}', + 'df_year': '#{settings_param_torrent_lang_orig} + #{torrent_parser_year}', + 'df_lg': '#{settings_param_torrent_lang_orig} + ' + langname, + 'df_lg_year': '#{settings_param_torrent_lang_orig} + ' + langname + ' + #{torrent_parser_year}', + 'lg': langname, + 'lg_year': langname + ' + #{torrent_parser_year}', + 'lg_df': langname + ' + #{settings_param_torrent_lang_orig}', + 'lg_df_year': langname + ' + #{settings_param_torrent_lang_orig} + #{torrent_parser_year}' + }; + if (Arrays.getKeys(selector).indexOf(Storage.get('parse_lang', 'df')) == -1) Storage.set('parse_lang', 'df'); + select('parse_lang', selector, 'df'); + select('tmdb_lang', Lang.codes(), 'ru'); // баг со старыми телеками, неправильно работает Utils.protocol() + // let agent = navigator.userAgent.toLowerCase() + // let versi = agent.match(/chrome\/(\d+)/) + // versi = versi ? parseInt(versi[1]) : 60 + // versi = isNaN(versi) ? 60 : versi + + select('protocol', { + 'http': '#{settings_param_no}', + 'https': '#{settings_param_yes}' + }, 'https'); + trigger('request_caching', Platform.is('orsay') || Platform.is('netcast') ? false : true); + } + /** + * Переключатель + * @param {string} name - название + * @param {boolean} value_default - значение по дефолту + */ + + + function trigger(name, value_default) { + values[name] = { + 'true': '#{settings_param_yes}', + 'false': '#{settings_param_no}' + }; + defaults[name] = value_default; + } + /** + * Выбрать + * @param {string} name - название + * @param {{key:string}} select_data - значение + * @param {string} select_default_value - значение по дефолту + */ + + + function select(name, select_data, select_default_value) { + values[name] = select_data; + defaults[name] = select_default_value; + } + /** + * Биндит события на элемент + * @param {object} elems + */ + + + function bind(elems, elems_html) { + elems.on('hover:enter', function (event) { + var elem = $(event.target); + var type = elem.data('type'); + var name = elem.data('name'); + var onChange = elem.data('onChange'); + + if (type == 'toggle') { + var params = values[name]; + var keys = Arrays.isArray(params) ? params : Arrays.getKeys(params), + value = Storage.get(name, defaults[name]) + '', + position = keys.indexOf(value); + position++; + if (position >= keys.length) position = 0; + position = Math.max(0, Math.min(keys.length - 1, position)); + value = keys[position]; + Storage.set(name, value); + update$3(elem, elems, elems_html); + if (onChange) onChange(value); + } + + if (type == 'input') { + Input.edit({ + elem: elem, + name: name, + nomic: true, + value: elem.data('string') ? window.localStorage.getItem(name) || defaults[name] : Storage.get(name, defaults[name]) + '' + }, function (new_value) { + Storage.set(name, new_value); + update$3(elem, elems, elems_html); + if (onChange) onChange(new_value); + }); + } + + if (type == 'button') { + listener$1.send('button', { + name: name + }); + if (onChange) onChange(); + } + + if (type == 'add') { + Input.edit({ + value: '' + }, function (new_value) { + if (new_value && Storage.add(name, new_value)) { + displayAddItem(elem, new_value); + listener$1.send('update_scroll'); + } + }); + } + + if (type == 'select') { + var _params = values[name]; + + var _value = Storage.get(name, defaults[name]) + ''; + + var items = []; + + for (var i in _params) { + items.push({ + title: Lang.translate(_params[i]), + value: i, + selected: i == _value + }); + } + + var enabled = Controller.enabled().name; + Select.show({ + title: Lang.translate('title_choice'), + items: items, + onBack: function onBack() { + Controller.toggle(enabled); + }, + onSelect: function onSelect(a) { + Storage.set(name, a.value); + update$3(elem, elems, elems_html); + Controller.toggle(enabled); + if (onChange) onChange(a.value); + } + }); + } + }).on('hover:hover hover:touch', function (e) { + Navigator.focused(e.target); + }).each(function () { + if (!$(this).data('static')) update$3($(this), elems, elems_html); + }); + + if (elems.eq(0).data('type') == 'add') { + displayAddList(elems.eq(0)); + } + } + /** + * Добавить дополнительное полу + * @param {object} elem + * @param {object} element + */ + + + function displayAddItem(elem, element) { + var name = elem.data('name'); + var item = $('
    ' + element + '
    ' + '
    '); + item.on('hover:long', function () { + var list = Storage.get(name, '[]'); + Arrays.remove(list, element); + Storage.set(name, list); + item.css({ + opacity: 0.5 + }); + }); + elem.after(item); + } + /** + * Вывести дополнительные поля + * @param {object} elem + */ + + + function displayAddList(elem) { + var list = Storage.get(elem.data('name'), '[]'); + list.forEach(function (element) { + displayAddItem(elem, element); + }); + listener$1.send('update_scroll'); + } + /** + * Обновляет значения на элементе + * @param {object} elem + */ + + + function update$3(elem, elems, elems_html) { + var name = elem.data('name'); + var key = elem.data('string') ? window.localStorage.getItem(name) || defaults[name] : Storage.get(name, defaults[name] + ''); + var val = typeof values[name] == 'string' ? key : values[name][key] || values[name][defaults[name]]; + var plr = elem.attr('placeholder'); + if (!val && plr) val = plr; + elem.find('.settings-param__value').text(Lang.translate(val)); + var children = elem.data('children'); + + if (children) { + var parent = elems_html ? elems_html.find('[data-parent="' + children + '"]') : elems.filter('[data-parent="' + children + '"]'); + var value = elem.data('children-value'); + var visibl = value ? Storage.field(name) !== value : !Storage.field(name); + if (elem.data('children-reverse')) visibl = !visibl; + parent.toggleClass('hide', visibl); + parent.filter('[data-visible-value]').each(function () { + $(this).toggleClass('hide', $(this).data('visible-value') !== key); + }); + parent.filter('[data-visible-value-in]').each(function () { + var valueStr = this.getAttribute('data-visible-value-in'); + var valueList = valueStr.split(',').map(function (item) { + return item.trim().toLowerCase(); + }); + var isVisible = false; + + for (var i = 0; i < valueList.length; i++) { + if (key.toLowerCase().indexOf(valueList[i]) !== -1) { + isVisible = true; + break; + } + } + + $(this).toggleClass('hide', !isVisible); + }); + listener$1.send('update_scroll_position'); + } + + updateInfuseLaunchVisibility(elems_html); + } + + function isInfusePlayerSelected() { + return ['player', 'player_iptv', 'player_torrent'].some(function (name) { + return Storage.field(name) === 'infuse'; + }); + } + + function updateInfuseLaunchVisibility(elems_html) { + if (!elems_html || !elems_html.length) return; + elems_html.find('[data-infuse-launch]').toggleClass('hide', !isInfusePlayerSelected()); + } + /** + * Получить значение параметра + * @param {string} name + * @returns * + */ + + + function field$1(name) { + return Storage.get(name, defaults[name] + ''); + } + /** + * Добовляем селекторы + */ + + + select('interface_size', { + 'small': '#{settings_param_interface_size_small}', + 'normal': '#{settings_param_interface_size_normal}', + 'bigger': '#{settings_param_interface_size_bigger}' + }, 'normal'); + select('navigation_type', { + 'controll': '#{settings_param_navigation_remote}', + 'mouse': '#{settings_param_navigation_mouse}', + 'touch': '#{settings_param_navigation_touch}' + }, 'controll'); + select('poster_size', { + 'w200': '#{settings_param_poster_quality_low}', + 'w300': '#{settings_param_poster_quality_average}', + 'w500': '#{settings_param_poster_quality_high}' + }, 'w300'); + select('parser_torrent_type', { + 'jackett': 'Jackett', + 'prowlarr': 'Prowlarr', + 'torrserver': 'TorrServer' + }, 'jackett'); + select('parser_use_link', { + 'one': '#{settings_param_link_use_one}', + 'two': '#{settings_param_link_use_two}', + 'both': '#{settings_param_link_use_both}' + }, 'one'); + select('jackett_interview', { + 'all': '#{settings_param_jackett_interview_all}', + 'healthy': '#{settings_param_jackett_interview_healthy}' + }, 'all'); + select('background_type', { + 'complex': '#{settings_param_background_complex}', + 'simple': '#{settings_param_background_simple}', + 'poster': '#{settings_param_background_image}' + }, 'simple'); + select('pages_save_total', { + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '10': '10', + '20': '20' + }, '5'); + select('player', { + 'inner': '#{settings_param_player_inner}' + }, 'inner'); + select('player_iptv', { + 'inner': '#{settings_param_player_inner}' + }, 'inner'); + select('player_torrent', { + 'inner': '#{settings_param_player_inner}' + }, 'inner'); + select('torrserver_use_link', { + 'one': '#{settings_param_link_use_one}', + 'two': '#{settings_param_link_use_two}' + }, 'one'); + select('torrserver_search_type', { + 'rutor': '#{settings_param_torrserver_search_rutor}', + 'torznab': '#{settings_param_torrserver_search_torznab}', + 'both': '#{settings_param_torrserver_search_both}' + }, 'both'); + select('subtitles_size', { + 'small': '#{settings_param_subtitles_size_small}', + 'normal': '#{settings_param_subtitles_size_normal}', + 'large': '#{settings_param_subtitles_size_bigger}' + }, 'normal'); + select('subtitles_lang', filter_langs.reduce(function (result, lang) { + result[lang.code] = lang.title; + return result; + }, { + 'auto': '#{settings_param_subtitles_lang_auto}' + }), 'auto'); + select('screensaver_time', { + '1': '1', + '2': '2', + '5': '5', + '10': '10' + }, '5'); + select('parse_lang', { + 'df': '#{settings_param_torrent_lang_orig}' + }, 'df'); + select('parse_timeout', { + '15': '15', + '30': '30', + '60': '60', + '90': '90', + '120': '120' + }, '15'); + select('player_rewind', { + '5': '5', + '10': '10', + '15': '15', + '20': '20', + '30': '30', + '50': '50', + '100': '100' + }, '20'); + select('player_timecode', { + 'again': '#{settings_param_player_timecode_again}', + 'continue': '#{settings_param_player_timecode_continue}', + 'ask': '#{settings_param_player_timecode_ask}' + }, 'continue'); + select('infuse_launch_mode', { + 'ask': '#{settings_infuse_launch_ask}', + 'play': '#{settings_infuse_launch_play}', + 'save_and_play': '#{settings_infuse_launch_save_and_play}' + }, 'play'); + select('player_scale_method', { + 'transform': 'Transform', + 'calculate': '#{settings_param_player_scale_method}' + }, 'transform'); + select('player_hls_method', { + 'application': '#{settings_param_player_hls_app}', + 'hlsjs': '#{settings_param_player_hls_js}' + }, 'application'); + select('source', { + 'tmdb': 'TMDB', + 'cub': 'CUB' + }, 'tmdb'); + select('start_page', { + 'main': '#{title_main}', + 'favorite@bookmarks': '#{settings_input_links}', + 'favorite@history': '#{title_history}', + 'mytorrents': '#{title_mytorrents}', + 'last': '#{title_last}' + }, 'main'); + select('scroll_type', { + 'css': 'CSS', + 'js': 'Javascript' + }, 'css'); + select('card_views_type', { + 'preload': '#{settings_param_card_view_load}', + 'view': '#{settings_param_card_view_all}' + }, 'preload'); + select('keyboard_type', { + 'lampa': '#{settings_param_keyboard_lampa}', + 'integrate': '#{settings_param_keyboard_system}' + }, 'lampa'); + select('card_interfice_type', { + 'old': '#{settings_param_card_interface_old}', + 'new': '#{settings_param_card_interface_new}' + }, 'new'); + select('glass_opacity', { + 'easy': '#{settings_param_glass_easy}', + 'medium': '#{settings_param_glass_medium}', + 'blacked': '#{settings_param_glass_blacked}' + }, 'easy'); + select('interface_sound_level', { + '100': '100', + '80': '80', + '60': '60', + '40': '40', + '20': '20' + }, '60'); + select('time_offset', { + 'n-10': '-10', + 'n-9': '-9', + 'n-8': '-8', + 'n-7': '-7', + 'n-6': '-6', + 'n-5': '-5', + 'n-4': '-4', + 'n-3': '-3', + 'n-2': '-2', + 'n-1': '-1', + 'n0': '0', + 'n1': '1', + 'n2': '2', + 'n3': '3', + 'n4': '4', + 'n5': '5', + 'n6': '6', + 'n7': '7', + 'n8': '8', + 'n9': '9', + 'n10': '10' + }, 'n0'); + select('video_quality_default', { + '480': '480p', + '720': '720p', + '1080': '1080p', + '1440': '1440p', + '2160': '2160p' + }, '1080'); + select('player_launch_trailers', { + 'inner': '#{settings_param_player_inner}', + 'youtube': 'YouTube' + }, 'inner'); + var mirrors_select = {}; + object$2.cub_mirrors.forEach(function (mirror) { + mirrors_select[mirror] = mirror; + }); + select('cub_domain', mirrors_select, object$2.cub_domain); + /** + * Добовляем триггеры + */ + + trigger('animation', true); + trigger('background', true); + trigger('torrserver_savedb', false); + trigger('torrserver_preload', true); + trigger('parser_use', false); + trigger('cloud_use', false); + trigger('account_use', false); + trigger('torrserver_auth', false); + trigger('torrserver_gts', false); + trigger('torrserver_tracktimecode', false); + trigger('mask', true); + trigger('playlist_next', true); + trigger('internal_torrclient', true); + trigger('subtitles_stroke', true); + trigger('subtitles_backdrop', false); + trigger('screensaver', true); + trigger('proxy_tmdb', true); + trigger('proxy_tmdb_auto', true); + trigger('proxy_other', true); + trigger('parse_in_search', false); + trigger('subtitles_start', false); + trigger('helper', true); + trigger('light_version', false); + trigger('player_normalization', false); + trigger('card_quality', true); + trigger('card_episodes', true); + trigger('card_interfice_poster', true); + trigger('glass_style', false); + trigger('black_style', false); + trigger('hide_outside_the_screen', true); + trigger('card_interfice_cover', true); + trigger('card_interfice_reactions', true); + trigger('cache_images', false); + trigger('interface_sound_play', false); + trigger('menu_always', false); + trigger('player_external_fullscreen', true); + trigger('adult_content_view', false); + /** + * Добовляем поля + */ + + select('jackett_url', '', ''); + select('jackett_key', '', ''); + select('jackett_url_two', '', ''); + select('jackett_key_two', '', ''); + select('prowlarr_url', '', ''); + select('prowlarr_key', '', ''); + select('prowlarr_url_two', '', ''); + select('prowlarr_key_two', '', ''); + select('torrserver_url', '', ''); + select('torrserver_url_two', '', ''); + select('torrserver_login', '', ''); + select('torrserver_password', '', ''); + select('parser_website_url', '', ''); + select('cloud_token', '', ''); + select('account_email', '', ''); + select('account_password', '', ''); + select('device_name', '', 'Lampa'); + select('player_nw_path', '', 'C:/Program Files/VideoLAN/VLC/vlc.exe'); + select('tmdb_proxy_api', '', ''); + select('tmdb_proxy_image', '', ''); + var Params = { + listener: listener$1, + init: init$u, + bind: bind, + update: update$3, + field: field$1, + select: select, + trigger: trigger, + values: values, + defaults: defaults + }; + + var network$1 = new Request(); + + function api$1() { + return Utils$1.protocol() + object$2.cub_domain + '/api/'; + } + + var WorkerArray = /*#__PURE__*/function () { + function WorkerArray(field) { + _classCallCheck(this, WorkerArray); + + this.field = field; + this.empty = []; + this.data = []; + this.limit = 3000; + this.loaded = false; + this.update_time = 0; + this.send_timers = {}; + this.send_rate = { + count: 0, + reset: 0 + }; + } + + _createClass(WorkerArray, [{ + key: "init", + value: function init(class_type) { + var _this = this; + + var timer_update; + var start_time = Date.now(); + this.class_type = class_type; + console.log('StorageWorker', this.field, 'start follow'); + Storage.listener.follow('change', function (e) { + if (_this.field == e.name && _this.loaded && Account$1.Permit.sync && Account$1.hasPremium()) { + try { + _this.save(e.value); + } catch (e) { + console.log('StorageWorker', _this.field, e.message); + } + } + + if (e.name == 'account') { + clearTimeout(timer_update); + timer_update = setTimeout(_this.update.bind(_this, true), 5 * 1000); + } + }); + Socket.listener.follow('message', function (e) { + if (e.method == 'storage' && e.data.name == _this.field) { + try { + if (e.data.remove) _this.removeFromSocket(e.data);else _this.updateFromSocket(e.data); + } catch (e) { + console.log('StorageWorker', _this.field, e.message); + } + } + }); + Socket.listener.follow('open', function (e) { + if (Date.now() - start_time > 1000 * 60 * 5) { + clearTimeout(timer_update); + timer_update = setTimeout(_this.update.bind(_this, false, true), 10 * 1000); + } + }); + this.update(); + } + }, { + key: "restrict", + value: function restrict(result) { + if (Arrays.isObject(result)) { + var keys = Arrays.getKeys(result); + + if (keys.length > this.limit) { + var remv = keys.slice(0, keys.length - this.limit); + remv.forEach(function (k) { + delete result[k]; + }); + } + } else if (result.length > this.limit) { + result = result.slice(result.length - this.limit); + } + + return result; + } + }, { + key: "parse", + value: function parse(from, nolisten) { + var to = Storage.cache(this.field, this.limit, Arrays.clone(this.empty)); + this.filter(from, to); + Storage.set(this.field, to, nolisten); + this.data = this.restrict(Arrays.decodeJson(localStorage.getItem(this.field), Arrays.clone(this.empty))); + Lampa.Listener.send('worker_storage', { + type: 'insert', + name: this.field, + from: from, + to: to + }); + } + }, { + key: "filter", + value: function filter(from, to) { + from.forEach(function (a) { + if (to.indexOf(a) == -1) to.push(a); + }); + } + }, { + key: "update", + value: function update(full, nolisten) { + var _this2 = this; + + if (Account$1.Permit.sync && Account$1.hasPremium() && Date.now() - this.update_time > 1000 * 60 * 9) { + var account = Account$1.Permit.account; + this.update_time = Date.now(); + var url = api$1() + 'storage/data/' + encodeURIComponent(this.field) + '/' + this.class_type; + var all = full; + if (Storage.get('storage_' + this.field + '_update_time', '0') + 1000 * 60 * 60 * 24 < Date.now()) all = true; + if (all) url = url + '?full=true'; + network$1.silent(url, function (result) { + try { + _this2.parse(result.data, nolisten); + } catch (e) { + console.log('StorageWorker', _this2.field, e.message); + } + + Storage.set('storage_' + _this2.field + '_update_time', Date.now()); + _this2.loaded = true; + }, function (e) { + console.log('StorageWorker', _this2.field, e.decode_error); + }, false, { + headers: { + token: account.token, + profile: account.profile.id + } + }); + } + } + }, { + key: "removeFromSocket", + value: function removeFromSocket(data) { + Arrays.remove(this.data, data.value); + var store = Storage.cache(this.field, this.limit, Arrays.clone(this.empty)); + Arrays.remove(store, data.value); + Storage.set(this.field, store, true); + } + }, { + key: "updateFromSocket", + value: function updateFromSocket(data) { + var from = [data.value]; + this.parse(from, true); + } + }, { + key: "send", + value: function send(id, value) { + var _this3 = this; + + if (!Account$1.hasPremium()) return; + clearTimeout(this.send_timers[id]); + this.send_timers[id] = setTimeout(function () { + delete _this3.send_timers[id]; + var now = Date.now(); + + if (now > _this3.send_rate.reset) { + _this3.send_rate.count = 0; + _this3.send_rate.reset = now + 2000; + } + + if (_this3.send_rate.count >= 5) { + console.log('StorageWorker', 'rate limit:', _this3.field, id); + return; + } + + _this3.send_rate.count++; + console.log('StorageWorker', 'save:', _this3.field, id, value); + var str = JSON.stringify(value); + + if (str.length < 10000) { + Socket.send('storage', { + params: { + id: id, + name: _this3.field, + value: value + } + }); + } + }, 2000); + } + }, { + key: "sendRemove", + value: function sendRemove(id, value) { + var str = JSON.stringify(value); + console.log('StorageWorker', 'remove:', this.field, id, value); + + if (str.length < 10000) { + Socket.send('storage', { + params: { + id: id, + name: this.field, + value: value, + remove: true + } + }); + } + } + }, { + key: "sendClean", + value: function sendClean() { + Socket.send('storage', { + params: { + id: null, + name: this.field, + value: '', + clean: true + } + }); + } + }, { + key: "save", + value: function save(value) { + var _this4 = this; + + var uniq = value.filter(function (a) { + return _this4.data.indexOf(a) == -1; + }); + uniq.forEach(function (val) { + _this4.data.push(val); + + _this4.send(null, val); + }); + } + }, { + key: "remove", + value: function remove(value) { + Arrays.remove(this.data, value); + this.sendRemove(null, value); + } + }, { + key: "clean", + value: function clean() { + this.data = []; + this.sendClean(); + } + }]); + + return WorkerArray; + }(); + + var WorkerFilterID = /*#__PURE__*/function (_WorkerArray) { + _inherits(WorkerFilterID, _WorkerArray); + + var _super = _createSuper(WorkerFilterID); + + function WorkerFilterID() { + _classCallCheck(this, WorkerFilterID); + + return _super.apply(this, arguments); + } + + _createClass(WorkerFilterID, [{ + key: "filter", + value: function filter(from, to) { + from.forEach(function (a) { + var find = to.find(function (b) { + return b.id == a.id; + }); + if (!find) to.push(a);else { + to[to.indexOf(find)] = a; + } + }); + } + }, { + key: "removeFromSocket", + value: function removeFromSocket(data) { + var find = this.data.find(function (a) { + return a.id == data.id; + }); + if (find) Arrays.remove(this.data, find); + var store = Storage.cache(this.field, this.limit, Arrays.clone(this.empty)); + find = store.find(function (a) { + return a.id == data.id; + }); + if (find) Arrays.remove(store, find); + Storage.set(this.field, store, true); + } + }, { + key: "updateFromSocket", + value: function updateFromSocket(data) { + var from = [data.value]; + this.parse(from, true); + } + }, { + key: "save", + value: function save(value) { + var _this5 = this; + + var uniq = []; + value.forEach(function (val) { + var find = _this5.data.find(function (a) { + return a.id == val.id; + }); + + if (!find) { + _this5.data.push(_typeof(val) == 'object' ? Arrays.clone(val) : val); + + uniq.push(val); + } else if (JSON.stringify(val) !== JSON.stringify(find)) { + _this5.data[_this5.data.indexOf(find)] = _typeof(val) == 'object' ? Arrays.clone(val) : val; + uniq.push(val); + } + }); + uniq.forEach(function (val) { + _this5.send(val.id, val); + }); + } + }, { + key: "remove", + value: function remove(id) { + var find = this.data.find(function (a) { + return a.id == id; + }); + if (find) Arrays.remove(this.data, find); + this.sendRemove(id, null); + } + }]); + + return WorkerFilterID; + }(WorkerArray); + + var WorkerObject = /*#__PURE__*/function (_WorkerArray2) { + _inherits(WorkerObject, _WorkerArray2); + + var _super2 = _createSuper(WorkerObject); + + function WorkerObject(params) { + var _this6; + + _classCallCheck(this, WorkerObject); + + _this6 = _super2.call(this, params); + _this6.data = {}; + _this6.empty = {}; + return _this6; + } + + _createClass(WorkerObject, [{ + key: "filter", + value: function filter(from, to) { + for (var _id in from) { + to[_id] = from[_id]; + } + } + }, { + key: "removeFromSocket", + value: function removeFromSocket(data) { + delete this.data[id]; + var store = Storage.cache(this.field, this.limit, Arrays.clone(this.empty)); + delete store[id]; + Storage.set(this.field, store, true); + } + }, { + key: "updateFromSocket", + value: function updateFromSocket(data) { + var object = {}; + object[data.id] = data.value; + this.parse(object, true); + } + }, { + key: "save", + value: function save(value) { + var _this7 = this; + + var uniq = []; + + for (var _id2 in value) { + var a = value[_id2]; + var b = this.data[_id2]; + + if (!this.data[_id2]) { + this.data[_id2] = _typeof(a) == 'object' ? Arrays.clone(a) : a; + uniq.push(_id2); + } else { + a = JSON.stringify(a); + b = JSON.stringify(b); + + if (a !== b) { + this.data[_id2] = _typeof(value[_id2]) == 'object' ? Arrays.clone(value[_id2]) : value[_id2]; + uniq.push(_id2); + } + } + } + + uniq.forEach(function (id) { + _this7.send(id, value[id]); + }); + } + }, { + key: "remove", + value: function remove(id) { + delete this.data[id]; + this.sendRemove(id, null); + } + }, { + key: "clean", + value: function clean() { + this.data = {}; + this.sendClean(); + } + }]); + + return WorkerObject; + }(WorkerArray); + + var Workers = { + //['string',0499383] + array_string: WorkerArray, + //[{'id':'049994',...}] + array_object_id: WorkerFilterID, + //{'id048994':{...}, ...} + object_object: WorkerObject, + //{'id399884':'string', ...} + object_string: WorkerObject + }; + + var listener = Subscribe$2(); + var readed = {}; + var workers = {}; + var reserve = {}; + + function init$t() { + sync('online_view', 'array_string'); + sync('torrents_view', 'array_string'); + sync('search_history', 'array_string'); + sync('online_last_balanser', 'object_string'); + sync('user_clarifys', 'object_object'); + sync('torrents_filter_data', 'object_object'); + Socket.listener.follow('send', function (e) { + if (e.method == 'storage') { + Api$1.load('storage/update', {}, { + json: JSON.stringify(e.data.params) + })["catch"](function (e) {}); + } + }); + } + /** + * Загрузка кеша из IndexedDB + * @doc + * @name task + * @alias Storage + * @param {function} next функция обратного вызова + */ + + + function task(next) { + Cache.getData('storage').then(function (result) { + if (result) { + console.log('Storage', 'load cache:', result.length); + result.forEach(function (data) { + reserve[data.key] = data.value; + }); + } + + next(); + })["catch"](function (e) { + console.log('Storage', 'cache error:', e.message, e.stack, e); + next(); + }); + } + /** + * Получить значение переменной из оператвной памяти localStorage + * @doc + * @name get + * @alias Storage + * @param {string} name название + * @param {string} empty значение по умолчанию + * @returns {any} + */ + + + function get$1(name, empty) { + var item; + var value = readed[name]; + + if (typeof value == 'undefined') { + item = window.localStorage.getItem(name); + value = item; + + if (item == null && reserve[name]) { + value = reserve[name]; + } + } + + value = value || empty || ''; + if (value == 'true' || value == 'false') return value == 'true' ? true : false; + if (readed[name] && (Arrays.isObject(value) || Arrays.isArray(value))) return readed[name]; + var convert = parseInt(value); + if (!isNaN(convert) && /^\d+$/.test(value)) return convert; + var i = typeof value == 'string' ? value[0] : ''; + + if (i == '[' || i == '{') { + try { + value = JSON.parse(value); + } catch (error) {} + } + + readed[name] = value; + return value; + } + /** + * Получить значение переменной напрямую из localStorage + * @doc + * @name value + * @alias Storage + * @param {string} name название + * @param {string} empty значение по умолчанию + * @returns {string} + */ + + + function value(name, empty) { + return window.localStorage.getItem(name) || empty || ''; + } + /** + * Установить значение переменной в оператвную память и localStorage + * @doc + * @name set + * @alias Storage + * @param {string} name название + * @param {any} value значение + * @param {boolean} nolisten по умолчанию `false`, если `true`, то не отправлять событие об изменении + * @returns {string} + */ + + + function set(name, value, nolisten, callerror) { + readed[name] = value; + var write = ''; + + try { + write = Arrays.isObject(value) || Arrays.isArray(value) ? JSON.stringify(value) : value; + } catch (e) { + console.log('Storage', name, 'JSON.stringify error:', e, value); + } + + try { + window.localStorage.setItem(name, write); + } catch (e) { + if (e.name == 'QuotaExceededError') { + console.log('Storage', 'QuotaExceededError:', name, value); + window.localStorage.removeItem(name); + Cache.rewriteData('storage', name, { + key: name, + value: write + }).then(function () { + reserve[name] = write; + })["catch"](function (e) { + console.log('Storage', 'Cache error:', e.message, e.stack, e); + }); + if (callerror) callerror(e); + } + } + + if (!nolisten) listener.send('change', { + name: name, + value: value + }); + } + /** + * Добавить значение в массив к уже существующим + * @doc + * @name add + * @alias Storage + * @param {string} name название + * @param {any} new_value значение + * @param {boolean} nolisten по умолчанию `false`, если `true`, то не отправлять событие об изменении + * @returns {boolean} true если значение добавлено, false если значение уже существует + */ + + + function add$2(name, new_value, nolisten) { + var list = get$1(name, '[]'); + + if (list.indexOf(new_value) == -1) { + list.push(new_value); + set(name, list, nolisten); + if (!nolisten) listener.send('add', { + name: name, + value: new_value + }); + return true; + } + } + /** + * Значение по умолчанию из параметров лампы + * @doc + * @name field + * @alias Storage + * @param {string} name название + * @returns {any} значение + */ + + + function field(name) { + return Params.field(name); + } + /** + * Записать значение в кэш с ограничением по количеству данных + * @doc + * @name cache + * @alias Storage + * @param {string} name название + * @param {integer} max максимальное количество данных + * @param {string} empty значение по умолчанию + * @returns {any} значение + */ + + + function cache(name, max, empty) { + var result = get$1(name, JSON.stringify(empty)); + + if (Arrays.isObject(empty)) { + var keys = Arrays.getKeys(result); + + if (keys.length > max) { + var remv = keys.slice(0, keys.length - max); + remv.forEach(function (k) { + delete result[k]; + }); + set(name, result); + } + } else if (result.length > max) { + result = result.slice(result.length - max); + set(name, result); + } + + return result; + } + /** + * Добавить переменную в синхронизацию с сервером + * @doc + * @name sync + * @alias Storage + * @param {string} field_name название + * @param {string} class_type тип данных, доступно (array_string | array_object_id | object_string | object_object) \n\n `array_string` - ['a','b','c'] \n\n `array_object_id` - [{id:1,..},{id:2,..}] \n\n `object_string` - {a:'a',b:'b'} \n\n `object_object` - {a:{a:'a'},b:{b:'b'}} + */ + + + function sync(field_name, class_type) { + if (Workers[class_type] && !workers[field_name]) { + workers[field_name] = new Workers[class_type](field_name); + workers[field_name].init(class_type); + } + } + /** + * Удалить значение из синхронизации + * @doc + * @name remove + * @alias Storage + * @param {string} field_name название + * @param {any} value значение + */ + + + function remove(field_name, value) { + if (workers[field_name]) workers[field_name].remove(value); + } + /** + * Очистить полностью значение из синхронизации + * @doc + * @name clean + * @alias Storage + * @param {string} field_name название + */ + + + function clean(field_name) { + if (workers[field_name]) workers[field_name].clean(); + } + /** + * Очистить кэш + * @doc + * @name clear + * @alias Storage + * @param {function} full `true` - полностью очистить, `false` - очистить только кеш + */ + + + function clear$1(full) { + listener.send('clear', { + full: full + }); + + if (full) { + Noty.show(Lang.translate('settings_clear_cache')); + localStorage.clear(); + } else { + Noty.show(Lang.translate('settings_clear_cache_only')); + var need = ['online_view', 'ser_clarifys', 'torrents_view', 'account_bookmarks', 'recomends_list', 'file_view', 'timetable', 'search_history', 'recomends_scan']; + var more = ['online_', 'file_view_', 'storage_']; + + for (var key in localStorage) { + if (more.find(function (w) { + return key.indexOf(w) >= 0; + })) need.push(key); + } + + need.forEach(function (a) { + localStorage.setItem(a, ''); + }); + } + + setTimeout(function () { + window.location.reload(); + }, 3000); + } + /** + * Получить размер данных в localStorage + * @doc + * @name getsize + * @alias Storage + * @param {function} call функция обратного вызова + */ + + + function getsize(call) { + if (localStorage) { + var i = 0; + var t = setInterval(function () { + i += 250; + + try { + localStorage.setItem('testsize', new Array(i * 1024 + 1).join('a')); + } catch (e) { + localStorage.removeItem('testsize'); + clearInterval(t); + } + + call((i - 250) * 1024); + }, 100); + } else { + call(5000 * 1024); + } + } + + var Storage = { + listener: listener, + init: init$t, + get: get$1, + set: set, + field: field, + cache: cache, + add: add$2, + value: value, + sync: sync, + remove: remove, + clear: clear$1, + clean: clean, + getsize: getsize, + task: task + }; + + var meta = { + languages: { + ru: { + code: 'ru', + name: 'Русский', + lang_choice_title: 'Добро пожаловать', + lang_choice_subtitle: 'Выберите свой язык' + }, + en: { + code: 'en', + name: 'English', + lang_choice_title: 'Welcome', + lang_choice_subtitle: 'Choose your language' + }, + uk: { + code: 'uk', + name: 'Українська', + lang_choice_title: 'Ласкаво просимо', + lang_choice_subtitle: 'Виберіть мову' + }, + be: { + code: 'be', + name: 'Беларуская', + lang_choice_title: 'Сардэчна запрашаем', + lang_choice_subtitle: 'Выберыце сваю мову' + }, + zh: { + code: 'zh', + name: '简体中文', + lang_choice_title: '欢迎', + lang_choice_subtitle: '选择你的语言' + }, + pt: { + code: 'pt', + name: 'Português', + lang_choice_title: 'Bem-vindo', + lang_choice_subtitle: 'Escolhe o teu idioma' + }, + bg: { + code: 'bg', + name: 'Български', + lang_choice_title: 'Здравейте', + lang_choice_subtitle: 'Изберете вашият език' + }, + he: { + code: 'he', + name: 'עִברִית', + lang_choice_title: 'ברוך הבא', + lang_choice_subtitle: 'בחר את השפה שלך' + }, + cs: { + code: "cs", + name: "Čeština", + lang_choice_title: "Vítejte", + lang_choice_subtitle: "Vyberte svůj jazyk" + }, + ro: { + code: "ro", + name: "Română", + lang_choice_title: "Bun venit", + lang_choice_subtitle: "Alegeți limba" + }, + fr: { + code: 'fr', + name: 'Français', + lang_choice_title: 'Bienvenue', + lang_choice_subtitle: 'Choisissez votre langue' + }, + pl: { + code: "pl", + name: "Polski", + lang_choice_title: "Witamy", + lang_choice_subtitle: "Wybierz język" + }, + es: { + code: 'es', + name: 'Español', + lang_choice_title: 'Bienvenido', + lang_choice_subtitle: 'Elige tu idioma' + } + } + }; + + var ru = { + lang_choice_title: 'Добро пожаловать', + lang_choice_subtitle: 'Выберите свой язык', + more: 'Еще', + show_more: 'Показать ещё', + more_results: 'Показать больше результатов', + loading: 'Загрузка', + nofind_movie: 'Не удалось найти фильм.', + noname: 'Без названия', + nochoice: 'Не выбрано', + cancel: 'Отменить', + confirm: 'Подтверждаю', + sure: 'Вы уверены?', + nodata: 'Нет данных', + back: 'Назад', + ready: 'Готово', + close_app_modal: 'Вы уверены, что хотите покинуть приложение?', + connected_seeds: 'подкл.', + search: 'Поиск', + search_input: 'Введите текст', + search_empty: 'История поиска пуста.', + search_delete: 'Влево - удалить', + search_start_typing: 'Начните вводить текст для поиска.', + search_searching: 'Идет поиск...', + search_start: 'Начать поиск', + search_nofound: 'По вашему запросу ничего не найдено.', + global_search: 'Глобальный поиск', + full_genre: 'Жанр', + full_production: 'Производство', + full_date_of_release: 'Дата релиза', + full_budget: 'Бюджет', + full_countries: 'Страны', + full_like: 'Нравится', + full_torrents: 'Торренты', + full_trailers: 'Трейлеры', + full_detail: 'Подробно', + full_notext: 'Без описания.', + full_series_release: 'Выход серий', + full_next_episode: 'Следующая', + full_episode_days_left: 'Осталось дней', + full_trailer_official: 'Официальный', + full_trailer_no_official: 'Неофициальный', + full_season: 'Сезон', + full_episode: 'Эпизод', + full_directing: 'Режиссура', + full_writing: 'Сценарий', + full_keywords: 'Теги', + full_crew: 'Еще', + full_editing: 'Монтаж', + full_creator: 'Создатель', + settings_cub_sync: 'Синхронизация', + settings_cub_sync_descr: 'Синхронизация с сервисом CUB: синхронизация ваших закладок, истории просмотров, меток и тайм-кодов.', + settings_cub_account: 'Аккаунт', + settings_cub_logged_in_as: 'Вошли как', + settings_cub_profile: 'Профиль', + settings_cub_sync_btn: 'Синхронизировать', + settings_cub_sync_btn_descr: 'Сохранить локальные закладки в аккаунт CUB', + settings_cub_backup: 'Бэкап', + settings_cub_backup_descr: 'Сохранить или загрузить бэкап данных', + settings_cub_logout: 'Выйти из аккаунта', + settings_cub_signin: 'Авторизация', + settings_cub_not_specified: 'Не указан', + settings_cub_password: 'Пароль', + settings_cub_status: 'Статус', + settings_cub_backup_import: 'Импорт', + settings_cub_backup_export: 'Экспорт', + settings_cub_backup_export_descr: 'Сохранить настройки в облако', + settings_cub_backup_import_descr: 'Восстановить настройки из облака', + settings_cub_sync_filters: 'Синхронизация фильтров', + settings_cub_sync_calendar: 'Синхронизация календаря', + settings_cub_sync_quality: 'Синхронизация отметок (качество)', + settings_cub_sync_search: 'Синхронизация истории поиска', + settings_cub_sync_recomends: 'Синхронизация рекомендаций', + settings_cub_sync_timecodes: 'Синхронизация тайм-кодов', + settings_cub_signin_button: 'Выполнить вход', + settings_cub_domain: 'Основной домен', + settings_input_links: 'Избранное', + settings_interface_type: 'Облегчённая версия', + settings_interface_size: 'Размер интерфейса', + settings_interface_menu_always: 'Всегда показывать левое меню', + settings_interface_background: 'Фон', + settings_interface_background_use: 'Показывать фон', + settings_interface_background_type: 'Тип фона', + settings_interface_performance: 'Быстродействие', + settings_interface_animation: 'Анимация', + settings_interface_advanced_animation: 'Продвинутая анимация', + settings_interface_animation_descr: 'Анимация карточек и контента', + settings_interface_attenuation: 'Затухание', + settings_interface_attenuation_descr: 'Плавное затухание карточек снизу и сверху', + settings_interface_scroll: 'Тип скроллинга', + settings_interface_view_card: 'Тип просмотра карточек', + settings_interface_view_card_descr: 'По мере скроллинга ленты карточки будут подгружаться постепенно или загружаться все', + settings_interface_lang: 'Язык интерфейса', + settings_interface_lang_reload: 'Необходимо перезапустить приложение, нажмите «OK» для перезагрузки', + settings_interface_card_interfice: 'Интерфейс карточек', + settings_interface_card_poster: 'Показать постер', + settings_interface_card_cover: 'Показать обложку', + settings_interface_card_reactions: 'Показать реакции', + settings_interface_glass: 'Стекло', + settings_interface_glass_descr: 'Показывать интерфейс в стекловидном стиле', + settings_interface_glass_opacity: 'Прозрачность стекла', + settings_interface_black_style: 'Чёрный стиль', + settings_interface_hide_outside_the_screen: 'Скрывать карточки за пределами экрана', + settings_interface_hide_outside_the_screen_descr: 'Это ускорит рендер интерфейса и улучшит производительность', + settings_interface_sound: 'Системные звуки', + settings_interface_sound_play: 'Переходы', + settings_interface_sound_level: 'Уровень громкости', + settings_main_account: 'Аккаунт', + settings_main_interface: 'Интерфейс', + settings_main_player: 'Плеер', + settings_main_parser: 'Парсер', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Расширения', + settings_main_rest: 'Остальное', + settings_rest_start: 'Стартовая страница', + settings_rest_start_descr: 'С какой страницы начинать при запуске', + settings_rest_source: 'Источник', + settings_rest_source_use: 'Основной источник', + settings_rest_source_descr: 'Откуда брать информацию о фильмах', + settings_rest_tmdb_lang: 'На каком языке отображать данные с TMDB', + settings_rest_tmdb_prox: 'Проксировать TMDB', + settings_rest_tmdb_prox_auto: 'Включить прокси автоматически', + settings_rest_tmdb_posters: 'Разрешение постеров TMDB', + settings_rest_screensaver: 'Скринсейвер', + settings_rest_screensaver_use: 'Показывать заставку при бездействии', + settings_rest_screensaver_type: 'Тип заставки', + settings_rest_screensaver_time: 'Через сколько минут запустить скринсейвер', + settings_rest_helper: 'Подсказки', + settings_rest_helper_use: 'Показывать подсказки', + settings_rest_helper_reset: 'Показать подсказки снова', + settings_rest_pages: 'Сколько страниц хранить в памяти', + settings_rest_pages_descr: 'Хранит страницы в том состоянии, в котором вы их покинули.', + settings_rest_time: 'Сместить время', + settings_rest_navigation: 'Тип навигации', + settings_rest_keyboard: 'Тип клавиатуры', + settings_rest_device: 'Название устройства', + settings_rest_device_placeholder: 'Например: Моя Лампа', + settings_rest_cache: 'Очистить кэш', + settings_rest_tmdb_example: 'Например:', + settings_rest_tmdb_api_descr: 'Для получения данных', + settings_rest_tmdb_image_descr: 'Для получения изображений', + settings_rest_card_quality: 'Отметки качества', + settings_rest_card_quality_descr: 'Отображать отметки качества на карточках', + settings_rest_card_episodes: 'Отметки эпизодов', + settings_rest_card_episodes_descr: 'Отображать отметки эпизодов на карточках', + settings_rest_cache_images: 'Кэш изображений', + settings_rest_cache_images_descr: 'Кэшировать постеры и фоны в локальное хранилище', + settings_rest_protocol_use: 'Безопасное соединение', + settings_rest_protocol_descr: 'Использовать протокол HTTPS', + settings_rest_cache_only: 'Только кеш', + settings_rest_cache_only_descr: 'Основные настройки сохранятся', + settings_rest_cache_all: 'Кеш и данные', + settings_rest_cache_all_descr: 'Будут очищены все настройки и данные', + settings_rest_cache_calculate: 'Сколько осталось памяти', + settings_request_caching_use: 'Кэширование запросов', + settings_request_caching_descr: 'Сохранять ответы от серверов в кэш для ускорения работы приложения', + settings_parser_use: 'Использовать парсер', + settings_parser_use_descr: 'Тем самым, вы соглашаетесь принять на себя всю ответственность за использование публичных ссылок для просмотра торрент и онлайн контента.', + settings_parser_type: 'Тип парсера для торрентов', + settings_parser_jackett_placeholder: 'Например: 192.168.х', + settings_parser_jackett_link: 'Ссылка', + settings_parser_jackett_link_descr: 'Укажите ссылку на скрипт Jackett', + settings_parser_prowlarr_link_descr: 'Укажите ссылку на сервер Prowlarr', + settings_parser_jackett_key_placeholder: 'Например: sa0sk83d..', + settings_parser_jackett_key: 'Api-ключ', + settings_parser_jackett_key_descr: 'Находится в Jackett', + settings_parser_prowlarr_key_descr: 'Находится во вкладке настроек Prowlarr в категории основное', + settings_parser_torlook_type: 'Метод парсинга сайта TorLook', + settings_parser_scraperapi_placeholder: 'Например: scraperapi.com', + settings_parser_scraperapi_link: 'Ссылка на парсер сайтов', + settings_parser_scraperapi_descr: 'Зарегистрируйтесь на сайте scraperapi.com, введите ссылку api.scraperapi.com?api_key=...&url={q}
    В {q} будет поставляться сайт w41.torlook.info', + settings_parser_search: 'Поиск', + settings_parser_search_descr: 'На каком языке производить поиск?', + settings_parser_in_search: 'Парсер в поиске', + settings_parser_in_search_descr: 'Показывать результаты в поиске?', + settings_parser_timeout_title: 'Таймаут парсера', + settings_parser_timeout_descr: 'Время (в секундах) ожидания ответа от сервера', + settings_player_type: 'Тип плеера', + settings_player_type_descr: 'Каким плеером воспроизводить видео', + settings_infuse_launch_mode: 'Запуск в Infuse', + settings_infuse_launch_mode_descr: 'Что делать при открытии видео в Infuse. Для торрентов всегда сразу воспроизведение', + settings_infuse_launch_ask: 'Спрашивать при запуске', + settings_infuse_launch_play: 'Играть', + settings_infuse_launch_save_and_play: 'Сохранить и играть', + settings_player_iptv_type: 'Тип плеера для IPTV', + settings_player_iptv_type_descr: 'Каким плеером воспроизводить IPTV-каналы', + settings_player_torrent_type: 'Тип плеера для торрентов', + settings_player_torrent_type_descr: 'Каким плеером воспроизводить торренты', + settings_player_reset: 'Сбросить плеер по умолчанию', + settings_player_reset_descr: 'Сбрасывает выбранный Android-плеер в приложении', + settings_player_path: 'Путь к плееру', + settings_player_path_descr: 'Укажите путь к исполняемому файлу плеера', + settings_player_external_header: 'Внешний плеер', + settings_player_external_fullscreen: 'Запускать в полноэкранном режиме', + settings_player_normalization: 'Нормализация звука', + settings_player_normalization_descr: 'Нормализирует звук в один уровень, понижает громкие звуки и повышает тихие.', + settings_player_next_episode: 'Следующая серия', + settings_player_next_episode_descr: 'Автоматически переключать на следующую серию по окончании текущей', + settings_player_timecode: 'Тайм-код', + settings_player_timecode_descr: 'Продолжить с последнего места просмотра', + settings_player_scale: 'Метод масштабирования', + settings_player_scale_descr: 'Каким образом производить вычисления для масштабирования видео', + settings_player_subs: 'Субтитры', + settings_player_subs_use: 'Включить', + settings_player_subs_use_descr: 'Всегда включать субтитры после запуска видео', + settings_player_subs_lang: 'Язык субтитров', + settings_player_subs_lang_descr: 'Какие субтитры включать автоматически, если доступно несколько языков', + settings_param_subtitles_lang_auto: 'Язык интерфейса', + settings_player_subs_size: 'Размер', + settings_player_subs_size_descr: 'Размер субтитров на экране', + settings_player_subs_stroke_use: 'Использовать окантовку', + settings_player_subs_stroke_use_descr: 'Субтитры будут обведены черным цветом для улучшения читаемости', + settings_player_subs_backdrop_use: 'Использовать подложку', + settings_player_subs_backdrop_use_descr: 'Субтитры будут отображаться на полупрозрачной подложке для улучшения читаемости', + settings_player_quality: 'Качество видео по умолчанию', + settings_player_quality_descr: 'Предпочтительное качество видео для просмотра', + settings_player_hls_title: 'Обработка потока .m3u8', + settings_player_hls_descr: 'Не трогайте этот параметр, если не знаете, зачем он.', + settings_player_rewind_title: 'Перемотка', + settings_player_rewind_descr: 'Интервал перемотки в секундах', + settings_player_launch_trailers: 'Плеер для трейлеров', + settings_plugins_notice: 'Для применения плагина необходимо перезагрузить приложение', + settings_plugins_add: 'Добавить плагин', + settings_plugins_add_descr: 'Для удаления добавленного плагина удерживайте или нажмите дважды клавишу (OK) на нем', + settings_plugins_install: 'Установить плагин', + settings_plugins_install_descr: 'Установить плагин из списка доступных', + settings_server_link: 'Использовать ссылку', + settings_server_links: 'Ссылки', + settings_server_placeholder: 'Например: 192.168.х', + settings_server_link_one: 'Основная ссылка', + settings_server_link_one_descr: 'Укажите основную ссылку на TorrServer', + settings_server_link_two: 'Дополнительная ссылка', + settings_server_link_two_descr: 'Укажите дополнительную ссылку на TorrServer', + settings_server_additionally: 'Дополнительно', + settings_server_client: 'Встроенный клиент', + settings_server_client_descr: 'Использовать встроенный JS-клиент TorrServer, иначе запускается системный.', + settings_server_base: 'Сохранять в базу', + settings_server_base_descr: 'Торрент будет добавлен в базу TorrServer', + settings_server_preload: 'Использовать буфер пред.загрузки', + settings_server_preload_descr: 'Дожидаться заполнения буфера предварительной загрузки TorrServer перед проигрыванием', + settings_server_auth: 'Авторизация', + settings_server_password_use: 'Вход по паролю', + settings_server_login: 'Логин', + settings_server_password: 'Пароль', + settings_server_not_specified: 'Не указан', + settings_server_search_type: 'Тип поиска', + settings_server_search_type_descr: 'Где искать торренты: встроенный rutor, Torznab-индексеры в TorrServer, или оба источника.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + settings_server_gts: 'Транскодирование', + settings_server_gts_descr: 'Автоматически преобразовывать видео в совместимый формат при необходимости.', + settings_server_tracktimecode: 'Включить TrackTimecode', + settings_server_tracktimecode_descr: 'Сохраняет прогресс просмотра фильмов и сериалов на сервере TorrServer. Для работы эту опцию также необходимо включить в TorrServer.', + settings_webos_launcher: 'Запуск приложения', + settings_webos_launcher_add_device: 'Установить как стартовое', + settings_webos_launcher_remove_device: 'Убрать из стартовых приложений', + settings_parental_control_param_time_always: 'Всегда', + settings_parental_control_param_time_once: 'Один раз', + settings_parental_control_param_time_10: 'Через 10 минут', + settings_parental_control_param_time_20: 'Через 20 минут', + settings_parental_control_param_time_30: 'Через 30 минут', + settings_parental_control_param_time_60: 'Через 1 час', + settings_parental_control_param_time_120: 'Через 2 часа', + settings_parental_control_change_pin: 'Изменить PIN-код', + settings_parental_control_demand_title: 'Когда запрашивать', + settings_parental_control_demand_descr: 'Через какое время запрашивать PIN-код', + settings_parental_control_enabled: 'Включено', + settings_parental_control_disabled: 'Отключено', + settings_parental_control_where: 'Где запрашивать PIN-код', + settings_lgbt_content_block: 'Блокировать ЛГБТ контент', + parental_control_input_new_code: 'Введите новый PIN-код', + parental_control_confirm_new_code: 'Повторите PIN-код', + parental_control_no_match_code: 'PIN-код не совпадает с прошлым кодом', + parental_control_input_code: 'Введите PIN-код', + parental_control_input_error: 'Вы ввели неправильный PIN-код', + torent_nohash_reasons: 'Причины', + torent_nohash_reason_one: 'TorServer не смог скачать торрент файл', + torent_nohash_reason_two: 'Ответ от TorServer', + torent_nohash_reason_three: 'Ссылка', + torent_nohash_do: 'Что делать?', + torent_nohash_do_one: 'Проверьте правильно ли вы настроили Jackett', + torent_nohash_do_two: 'Приватные источники могут не выдавать ссылку на файл', + torent_nohash_do_three: 'Убедитесь что Jackett тоже может скачать файл', + torent_nohash_do_four: 'Написать в нашу Telegram-группу: @lampa_group', + torent_nohash_do_five: 'Укажите какой фильм, какая раздача и по возможности фото этой раздачи', + torrent_error_text: 'Не удалось подключиться к TorrServer. Давайте быстро пройдёмся по списку возможных проблем и всё проверим.', + torrent_error_step_1: 'Запущен ли TorrServer', + torrent_error_step_2: 'Динамический IP-адрес', + torrent_error_step_3: 'Протокол и порт', + torrent_error_step_4: 'Блокировка антивирусами', + torrent_error_step_5: 'Проверьте на доступность', + torrent_error_step_6: 'Все равно не работает', + torrent_error_info_1: 'Убедитесь, что вы запустили TorrServer на устройстве, где он установлен.', + torrent_error_info_2: 'Частая ошибка, изменился IP-адрес устройства с TorrServer. Убедитесь, что IP-адрес, который вы ввели - {ip}, совпадает с адресом устройства, на котором установлен TorrServer.', + torrent_error_info_3: 'Для подключения к TorrServer, необходимо указать протокол http:// в начале и порт :8090 в конце адреса. Убедитесь, что после IP-адреса указан порт, ваш текущий адрес - {ip}', + torrent_error_info_4: 'Частое явление, антивирус или брандмауэр может блокировать доступ по IP-адресу, попробуйте отключить антивирус и брандмауэр.', + torrent_error_info_5: 'На любом другом устройстве в этой же сети, откройте в браузере адрес {ip} и проверьте, доступен ли веб-интерфейс TorrServer.', + torrent_error_info_6: 'Если после всех проверок всё равно возникает ошибка подключения, попробуйте перезагрузить TorrServer и интернет-адаптер.', + torrent_error_info_7: 'Если проблема не устранена, пишите в Telegram-группу @lampa_group с текстом (Lampa не подключается к TorrServer после всех проверок, текущий адрес {ip})', + torrent_error_start: 'Начать проверку', + torrent_error_nomatrix: 'Не удалось подтвердить версию Matrix', + torrent_error_made: 'Выполнено', + torrent_error_from: 'из', + torrent_error_next: 'Далее', + torrent_error_complite: 'Завершить', + torrent_error_connect: 'Ошибка подключения', + torrent_error_check_no_auth: 'Сервер ответил на запрос, но не удалось пройти авторизацию', + torrent_install_need: 'Необходим TorrServer', + torrent_install_text: 'TorrServer – приложение, которое позволяет просматривать контент из торрент-файлов в онлайн режиме.

    Более детальную информацию по установке вы найдете в Telegram-группах, указанных ниже.', + torrent_install_contact: 'Telegram-группы', + torrent_item_bitrate: 'Битрейт', + torrent_item_seeds: 'Раздают', + torrent_item_grabs: 'Качают', + torrent_item_mb: 'Мбит/с', + torrent_serial_episode: 'Серия', + torrent_serial_season: 'Сезон', + torrent_serial_date: 'Выход', + torrent_get_magnet: 'Запрашиваю magnet ссылку', + torrent_remove_title: 'Удалить', + torrent_remove_descr: 'Торрент будет удален из вашего списка', + torrent_parser_any_one: 'Любое', + torrent_parser_any_two: 'Любой', + torrent_parser_no_choice: 'Не выбрано', + torrent_parser_yes: 'Да', + torrent_parser_no: 'Нет', + torrent_parser_quality: 'Качество', + torrent_parser_subs: 'Субтитры', + torrent_parser_voice: 'Перевод', + torrent_parser_tracker: 'Трекер', + torrent_parser_year: 'Год', + torrent_parser_season: 'Сезон', + torrent_parser_sort_by_seeders: 'По раздающим', + torrent_parser_sort_by_size: 'По размеру', + torrent_parser_sort_by_name: 'По названию', + torrent_parser_sort_by_tracker: 'По источнику', + torrent_parser_sort_by_date: 'По дате', + torrent_parser_sort_by_viewed: 'По просмотренным', + torrent_parser_voice_dubbing: 'Дубляж', + torrent_parser_voice_polyphonic: 'Многоголосый', + torrent_parser_voice_two: 'Двухголосый', + torrent_parser_voice_amateur: 'Любительский', + torrent_parser_reset: 'Сбросить фильтр', + torrent_parser_empty: 'Не удалось получить результатов', + torrent_parser_no_hash: 'Не удалось получить HASH, попробуйте перезагрузить TorrServer', + torrent_parser_added_to_mytorrents: 'добавлено в «Мои торренты»', + torrent_parser_add_to_mytorrents: 'Добавить в «Мои торренты»', + torrent_parser_label_title: 'Пометить', + torrent_parser_label_descr: 'Пометить раздачу с флагом (просмотрено)', + torrent_parser_label_cancel_title: 'Снять отметку', + torrent_parser_label_cancel_descr: 'Снять отметку с раздачи (просмотрено)', + torrent_parser_timeout: 'Время ожидания истекло', + torrent_parser_nofiles: 'Не удалось извлечь подходящие файлы', + torrent_parser_set_link: 'Укажите ссылку для парсинга', + torrent_parser_request_error: 'Ошибка в запросе', + torrent_parser_magnet_error: 'Не удалось получить magnet ссылку', + torrent_parser_no_responce: 'Парсер не отвечает на запрос', + torrent_parser_torlook_fallback_search_notification: 'Парсер Jackett не доступен или настройки подключения не верны. Осуществляется поиск в Torlook...', + about_text: 'Приложение полностью бесплатное и использует публичные ссылки для получения информации о видео, новинках, популярных фильмах и т.д. Вся доступная информация используется исключительно в познавательных целях, приложение не использует свои собственные серверы для распространения информации.', + about_channel: 'Наш канал', + about_group: 'Группа', + about_version: 'Версия', + about_donate: 'Донат', + title_watched: 'Вы смотрели', + title_settings: 'Настройки', + title_collections: 'Подборки', + title_company: 'Компания', + title_actors: 'Актеры', + title_actor: 'Актер', + title_actress: 'Актриса', + title_person: 'Персона', + title_persons: 'Персоны', + title_person_about: 'О персоне', + title_comments: 'Комментарии', + title_torrents: 'Торренты', + title_trailers: 'Трейлеры', + title_watch: 'Смотреть', + title_error: 'Ошибка', + title_links: 'Ссылки', + title_choice: 'Выбрать', + title_main: 'Главная', + title_book: 'Закладки', + title_like: 'Нравится', + title_wath: 'Позже', + title_look: 'Смотрю', + title_scheduled: 'Запланировано', + title_viewed: 'Просмотрено', + title_thrown: 'Брошено', + title_continued: 'Продолжение следует', + title_history: 'История просмотров', + title_mytorrents: 'Мои торренты', + title_last: 'Последняя', + title_action: 'Действие', + title_action_infuse: 'Действие Infuse', + title_producer: 'Режиссер', + title_collection: 'Коллекция', + title_recomendations: 'Рекомендации', + title_similar: 'Похожие', + title_about: 'О приложении', + title_timetable: 'Расписание', + title_relises: 'Цифровые релизы', + title_catalog: 'Каталог', + title_category: 'Категория', + title_parser: 'Парсер', + title_type: 'Тип', + title_rating: 'Рейтинг', + title_country: 'Страна', + title_year: 'Год', + title_genre: 'Жанр', + title_filter: 'Фильтр', + title_notice: 'Уведомления', + title_files: 'Файлы', + title_now_watch: 'Сейчас смотрят', + title_latest: 'Последнее добавление', + title_continue: 'Продолжить просмотр', + title_recomend_watch: 'Рекомендуем посмотреть', + title_new_episodes: 'Новые серии', + title_popular: 'Популярное', + title_popular_movie: 'Популярные фильмы', + title_popular_tv: 'Популярные сериалы', + title_new_this_year: 'Новинки этого года', + title_hight_voite: 'С высоким рейтингом', + title_new: 'Новинки', + title_trend_day: 'Сегодня в тренде', + title_trend_week: 'В тренде за неделю', + title_upcoming: 'Смотрите в кинозалах', + title_top_movie: 'Топ фильмы', + title_top_tv: 'Топ сериалы', + title_tv_today: 'Сегодня в эфире', + title_this_week: 'На этой неделе', + title_in_top: 'В топе', + title_out: 'Выход', + title_out_confirm: 'Да, выйти', + title_continue_two: 'Продолжить', + title_choice_language: 'Выбрать язык', + title_subscribe: 'Подписаться', + title_subscribes: 'Подписки', + title_unsubscribe: 'Отписаться', + title_language: 'Язык оригинала', + title_language_short: 'Язык', + title_ongoing: 'Онгоинги', + title_pgrating: 'Возрастное ограничение', + title_card: 'Карточка', + title_seasons: 'Сезоны', + title_episodes: 'Серии', + title_rewiews: 'Отзывы', + title_channel: 'Канал', + title_in_high_quality: 'В высоком качестве', + title_author: 'Автор', + title_buffer: 'Буфер', + title_upcoming_episodes: 'Ближайшие выходы эпизодов', + title_recent_episodes: 'Недавние выходы эпизодов', + title_reactions: 'Реакции', + title_last_year: 'Прошлый год', + title_reset: 'Перезагрузить', + title_left: 'Осталось', + title_parental_control: 'Родительский контроль', + title_worth_rewatch: 'Стоит пересмотреть', + title_fire: 'Огонь!', + title_top_100: 'Топ 100', + title_ai_assistant: 'AI-ассистент', + title_facts: 'Интересные факты', + title_anons: 'Анонс', + title_developer: 'Разработчик', + title_navigation: 'Навигация', + title_page: 'Страница', + title_channels: 'Каналы', + title_best_of_2000: 'Золотые 2000-е', + title_best_of_2010: 'Хиты 2010-х', + title_best_of_2015: 'Современная классика', + title_comedy_of_2000: 'Смех 2000-х', + title_comedy_of_2010: 'Юмор 2010-х', + title_comedy_of_2015: 'Современные комедии', + title_metadata: 'Метаданные', + title_moods: 'Настроения', + title_meta_violence: 'Насилие', + title_meta_fear: 'Страх', + title_meta_profanity: 'Лексика', + title_meta_sadness: 'Грусть', + title_meta_sex: 'Сексуальность', + title_meta_humor: 'Юмор', + title_meta_tension: 'Напряжение', + title_meta_romance: 'Романтика', + title_meta_pace: 'Темп', + title_meta_importance: 'Важные сцены', + title_meta_action: 'Экшн', + reactions_none: 'Нет реакций', + reactions_fire: 'Супер', + reactions_nice: 'Неплохо', + reactions_think: 'Смотрибельно', + reactions_bore: 'Скука', + reactions_shit: 'Плохо', + reactions_ready: 'Вы уже оставили реакцию', + subscribe_success: 'Вы успешно подписались', + subscribe_error: 'Возникла ошибка при подписке, попробуйте позже', + subscribe_noinfo: 'Не удалось получить информацию, попробуйте позже', + subscribe_info: 'В разделе (Подписки) у вас будут отображаться все ваши подписки на переводы. Когда выйдет новая серия с выбранным переводом, вы получите уведомление.', + company_headquarters: 'Штаб', + company_homepage: 'Сайт', + company_country: 'Страна', + country_ad: 'Андорра', + country_ae: 'ОАЭ', + country_af: 'Афганистан', + country_al: 'Албания', + country_am: 'Армения', + country_ao: 'Ангола', + country_ar: 'Аргентина', + country_at: 'Австрия', + country_au: 'Австралия', + country_aw: 'Аруба', + country_az: 'Азербайджан', + country_bа: 'Босния и Герцеговина', + country_bd: 'Бангладеш', + country_be: 'Бельгия', + country_bg: 'Болгария', + country_bh: 'Бахрейн', + country_bi: 'Бурунди', + country_bj: 'Бенин', + country_bo: 'Боливия', + country_br: 'Бразилия', + country_bs: 'Багамские о-ва', + country_bt: 'Бутан', + country_bw: 'Ботсвана', + country_by: 'Беларусь', + country_ca: 'Канада', + country_ch: 'Швейцария', + country_cl: 'Чили', + country_cm: 'Камерун', + country_cn: 'Китай', + country_co: 'Колумбия', + country_cr: 'Коста-Рика', + country_cu: 'Куба', + country_cv: 'Кабо-Верде', + country_cy: 'Кипр', + country_cz: 'Чехия', + country_de: 'Германия', + country_dj: 'Джибути', + country_dk: 'Дания', + country_do: 'Доминикана', + country_dz: 'Алжир', + country_ec: 'Эквадор', + country_ee: 'Эстония', + country_eg: 'Египет', + country_es: 'Испания', + country_et: 'Эфиопия', + country_fi: 'Финляндия', + country_fo: 'Фарерские о-ва', + country_fr: 'Франция', + country_ga: 'Габон', + country_gb: 'Великобритания', + country_ge: 'Грузия', + country_gh: 'Гана', + country_gl: 'Гренландия', + country_gp: 'Гваделупа', + country_gr: 'Греция', + country_gt: 'Гватемала', + country_hk: 'Гонконг', + country_hr: 'Хорватия', + country_ht: 'Гаити', + country_hu: 'Венгрия', + country_id: 'Индонезия', + country_ie: 'Ирландия', + country_il: 'Израиль', + country_in: 'Индия', + country_iq: 'Ирак', + country_ir: 'Иран', + country_is: 'Исландия', + country_it: 'Италия', + country_jm: 'Ямайка', + country_jo: 'Иордания', + country_jp: 'Япония', + country_ke: 'Кения', + country_kg: 'Киргизия', + country_kh: 'Камбоджа', + country_kp: 'Северная Корея', + country_kr: 'Южная Корея', + country_kz: 'Казахстан', + country_kw: 'Кувейт', + country_la: 'Лаос', + country_lb: 'Ливан', + country_li: 'Лихтенштейн', + country_lk: 'Шри-Ланка', + country_lr: 'Либерия', + country_lt: 'Литва', + country_lu: 'Люксембург', + country_lv: 'Латвия', + country_ly: 'Ливия', + country_ma: 'Марокко', + country_mc: 'Монако', + country_md: 'Молдова', + country_me: 'Черногория', + country_mk: 'Македония', + country_mm: 'Мьянма', + country_mn: 'Монголия', + country_mo: 'Макао', + country_mt: 'Мальта', + country_mu: 'Маврикий', + country_mv: 'Мальдивы', + country_mw: 'Малави', + country_mx: 'Мексика', + country_my: 'Малайзия', + country_mz: 'Мозамбик', + country_na: 'Намибия', + country_ne: 'Нигер', + country_ng: 'Нигерия', + country_ni: 'Никарагуа', + country_nl: 'Нидерланды', + country_no: 'Норвегия', + country_np: 'Непал', + country_nz: 'Новая Зеландия', + country_om: 'Оман', + country_pa: 'Панама', + country_pe: 'Перу', + country_pg: 'Папуа - Новая Гвинея', + country_ph: 'Филиппины', + country_pk: 'Пакистан', + country_pl: 'Польша', + country_pr: 'Пуэрто-Рико', + country_ps: 'Палестина', + country_pt: 'Португалия', + country_py: 'Парагвай', + country_qa: 'Катар', + country_ro: 'Румыния', + country_rs: 'Сербия', + country_ru: 'Россия', + country_rw: 'Руанда', + country_sa: 'Саудовская Аравия', + country_sd: 'Судан', + country_se: 'Швеция', + country_sg: 'Сингапур', + country_si: 'Словения', + country_sk: 'Словакия', + country_sn: 'Сенегал', + country_su: 'СССР', + country_sv: 'Сальвадор', + country_sy: 'Сирия', + country_th: 'Таиланд', + country_tj: 'Таджикистан', + country_tm: 'Туркменистан', + country_tn: 'Тунис', + country_tr: 'Турция', + country_tw: 'Тайвань', + country_tz: 'Танзания', + country_ua: 'Украина', + country_ug: 'Уганда', + country_us: 'США', + country_uy: 'Уругвай', + country_uz: 'Узбекистан', + country_ve: 'Венесуэла', + country_vn: 'Вьетнам', + country_ws: 'Самоа', + country_xk: 'Косово', + country_ye: 'Йемен', + country_yu: 'Югославия', + country_za: 'ЮАР', + country_zm: 'Замбия', + country_zw: 'Зимбабве', + filter_clarify: 'Уточнить', + filter_clarify_two: 'Уточнить поиск', + filter_set_name: 'Указать название', + filter_sorted: 'Сортировать', + filter_filtred: 'Фильтр', + filter_any: 'Любой', + filter_combinations: 'Комбинации', + filter_alt_names: 'Другие названия', + filter_rating_from: 'от', + filter_rating_to: 'до', + filter_lang_af: 'Африкаанс', + filter_lang_ar: 'Арабский', + filter_lang_az: 'Азербайджанский', + filter_lang_ba: 'Башкирский', + filter_lang_be: 'Белорусский', + filter_lang_bg: 'Болгарский', + filter_lang_bn: 'Бенгальский', + filter_lang_bs: 'Боснийский', + filter_lang_ca: 'Каталанский', + filter_lang_ce: 'Чеченский', + filter_lang_cs: 'Чешский', + filter_lang_da: 'Датский', + filter_lang_de: 'Немецкий', + filter_lang_el: 'Греческий', + filter_lang_en: 'Английский', + filter_lang_es: 'Испанский', + filter_lang_et: 'Эстонский', + filter_lang_fa: 'Персидский', + filter_lang_fi: 'Финский', + filter_lang_fr: 'Французский', + filter_lang_ga: 'Ирландский', + filter_lang_gl: 'Галисийский', + filter_lang_gn: 'Гуарани', + filter_lang_he: 'Иврит', + filter_lang_hi: 'Хинди', + filter_lang_hr: 'Хорватский', + filter_lang_hu: 'Венгерский', + filter_lang_hy: 'Армянский', + filter_lang_id: 'Индонезийский', + filter_lang_is: 'Исландский', + filter_lang_it: 'Итальянский', + filter_lang_ja: 'Японский', + filter_lang_ka: 'Грузинский', + filter_lang_kk: 'Казахский', + filter_lang_ko: 'Корейский', + filter_lang_ks: 'Кашмири', + filter_lang_ku: 'Курдский', + filter_lang_ky: 'Киргизский', + filter_lang_lt: 'Литовский', + filter_lang_lv: 'Латышский', + filter_lang_mi: 'Маори', + filter_lang_mk: 'Македонский', + filter_lang_mn: 'Монгольский', + filter_lang_mt: 'Мальтийский', + filter_lang_ne: 'Непальский', + filter_lang_nl: 'Нидерландский', + filter_lang_no: 'Норвежский', + filter_lang_pa: 'Панджаби', + filter_lang_pl: 'Польский', + filter_lang_ps: 'Пушту', + filter_lang_pt: 'Португальский', + filter_lang_ro: 'Румынский', + filter_lang_ru: 'Русский', + filter_lang_si: 'Сингальский', + filter_lang_sk: 'Словацкий', + filter_lang_sl: 'Словенский', + filter_lang_sm: 'Самоанский', + filter_lang_so: 'Сомалийский', + filter_lang_sq: 'Албанский', + filter_lang_sr: 'Сербский', + filter_lang_sv: 'Шведский', + filter_lang_sw: 'Суахили', + filter_lang_ta: 'Тамильский', + filter_lang_tg: 'Таджикский', + filter_lang_th: 'Тайский', + filter_lang_tk: 'Туркменский', + filter_lang_tr: 'Турецкий', + filter_lang_tt: 'Татарский', + filter_lang_ur: 'Урду', + filter_lang_uk: 'Украинский', + filter_lang_uz: 'Узбекский', + filter_lang_vi: 'Вьетнамский', + filter_lang_yi: 'Идиш', + filter_lang_zh: 'Китайский', + filter_genre_ac: 'Боевик', + filter_genre_ad: 'Приключения', + filter_genre_mv: 'Мультфильм', + filter_genre_cm: 'Комедия', + filter_genre_cr: 'Криминал', + filter_genre_dc: 'Документальный', + filter_genre_dr: 'Драма', + filter_genre_fm: 'Семейный', + filter_genre_fe: 'Фэнтези', + filter_genre_hi: 'История', + filter_genre_ho: 'Ужасы', + filter_genre_mu: 'Музыка', + filter_genre_de: 'Детектив', + filter_genre_md: 'Мелодрама', + filter_genre_fa: 'Фантастика', + filter_genre_tv: 'Телевизионный фильм', + filter_genre_tr: 'Триллер', + filter_genre_mi: 'Военный', + filter_genre_ve: 'Вестерн', + filter_genre_aa: 'Боевик и Приключения', + filter_genre_ch: 'Детский', + filter_genre_nw: 'Новости', + filter_genre_rs: 'Реалити-шоу', + filter_genre_hf: 'НФ и Фэнтези', + filter_genre_op: 'Мыльная опера', + filter_genre_tc: 'Ток-шоу', + filter_genre_mp: 'Война и Политика', + filter_keyword_sequel: 'Сиквел', + filter_keyword_based_comic: 'По комиксам', + filter_keyword_space: 'Космос', + filter_keyword_survival: 'Выживание', + filter_keyword_zombie: 'Зомби', + filter_keyword_school: 'Школа', + filter_keyword_revenge: 'Месть', + filter_keyword_detective: 'Детектив', + filter_keyword_robots: 'Роботы', + filter_keyword_vampires: 'Вампиры', + filter_keyword_aliens: 'Инопланетяне', + filter_keyword_police: 'Полиция', + filter_keyword_reincarnation: 'Перерождение', + filter_keyword_spy: 'Шпион', + filter_keyword_disaster: 'Катастрофа', + filter_keyword_christmas: 'Рождество', + empty_title: 'Пусто', + empty_text: 'По вашему фильтру ничего не нашлось, уточните фильтр.', + empty_title_two: 'Здесь пусто', + empty_text_two: 'На данный момент список пустой', + empty_subscribes_title: 'Ваши подписки на переводы', + empty_subscribes_text: 'Просто подпишитесь на любимый перевод и мы будем уведомлять вас о выходе новой серии.', + empty_history_title: 'Ваша история просмотров', + empty_history_text: 'Здесь будет отображаться ваша история просмотров.', + empty_bookmark_title: 'Ваше избранное', + empty_bookmark_text: 'Добавляйте в избранное понравившиеся фильмы и сериалы, чтобы быстро находить их в этом разделе.', + empty_mytorrents_title: 'Ваши торренты', + empty_mytorrents_text: 'Здесь будут отображаться загруженные вами торренты через TorServer.', + back_to_card: 'Вернуться в карточку', + menu_main: 'Главная', + menu_movies: 'Фильмы', + menu_tv: 'Сериалы', + menu_catalog: 'Каталог', + menu_filter: 'Фильтр', + menu_collections: 'Подборки', + menu_relises: 'Релизы', + menu_anime: 'Аниме', + menu_bookmark: 'Закладки', + menu_like: 'Нравится', + menu_time: 'Позже', + menu_history: 'История', + menu_timeline: 'Расписание', + menu_torrents: 'Торренты', + menu_settings: 'Настройки', + menu_about: 'Информация', + menu_console: 'Консоль', + menu_multmovie: 'Мультфильмы', + menu_multtv: 'Мультсериалы', + menu_feed: 'Лента', + lampa_movie_title: 'Ламповое кино', + lampa_movie_descr: 'Следите за новинками на своем смартфоне.
    Телеграм: @lampa_movie', + plugins_catalog_work: 'Рабочие плагины', + plugins_catalog_work_descr: 'Плагины, которые точно работают в лампе.', + plugins_catalog_popular: 'Популярные плагины среди пользователей', + plugins_catalog_popular_descr: 'Установка из неизвестных источников может привести к некорректной работе приложения.', + plugins_online: 'Просмотр онлайн', + plugins_check_fail: 'Не удалось проверить работоспособность плагина. Однако это не означает, что плагин не работает. Перезагрузите приложение для выяснения, загружается ли плагин.', + plugins_need_reload: 'Для применения плагина необходимо перезагрузить приложение', + plugins_install: 'Установить', + plugins_install_ready: 'Этот плагин уже установлен.', + plugins_installed: 'Установок', + plugins_load_from: 'Загружено из CUB', + plugins_ok_for_check: 'Нажмите (OK) для проверки плагина', + plugins_no_loaded: 'При загрузке приложения, часть плагинов не удалось загрузить', + plugins_remove: 'Удалить плагины', + plugins_add_success: 'Плагин успешно подключен', + time_viewed: 'Просмотрено', + time_from: 'из', + time_reset: 'Сбросить тайм-код', + settings_clear_cache: 'Кеш и данные очищены', + settings_clear_cache_only: 'Кеш очищен', + settings_user_links: 'Пользовательская ссылка', + settings_for_local: 'Для локального TorrServer', + settings_add: 'Добавить', + settings_remove: 'Удалить', + settings_this_value: 'текущее значение', + settings_added: 'Добавлено', + settings_removed: 'Удалено', + settings_reset: 'Сброс настроек', + settings_param_player_inner: 'Встроенный', + settings_param_player_outside: 'Внешний', + settings_param_player_inner_tvos: 'Встроенный', + settings_param_yes: 'Да', + settings_param_no: 'Нет', + settings_param_interface_size_small: 'Меньше', + settings_param_interface_size_normal: 'Нормальный', + settings_param_interface_size_bigger: 'Больше', + settings_param_poster_quality_low: 'Низкое', + settings_param_poster_quality_average: 'Среднее', + settings_param_poster_quality_high: 'Высокое', + settings_param_parse_directly: 'Напрямую', + settings_param_parse_api: 'Через API сайта', + settings_param_background_complex: 'Сложный', + settings_param_background_simple: 'Простой', + settings_param_background_image: 'Картинка', + settings_param_link_use_one: 'Основную', + settings_param_link_use_two: 'Дополнительную', + settings_param_link_use_both: 'Обе', + settings_param_subtitles_size_small: 'Маленькие', + settings_param_subtitles_size_normal: 'Обычные', + settings_param_subtitles_size_bigger: 'Большие', + settings_param_screensaver_nature: 'Природа', + settings_param_torrent_lang_orig: 'Оригинал', + settings_param_player_timecode_again: 'Начать с начала', + settings_param_player_timecode_continue: 'Продолжить', + settings_param_player_timecode_ask: 'Спрашивать', + settings_param_player_scale_method: 'Рассчитать', + settings_param_player_hls_app: 'Системный', + settings_param_player_hls_js: 'Программный', + settings_param_card_view_load: 'Подгружать', + settings_param_card_view_all: 'Показать все', + settings_param_navigation_remote: 'Пульт', + settings_param_navigation_mouse: 'Пульт с мышкой', + settings_param_navigation_touch: 'Сенсор', + settings_param_keyboard_lampa: 'Встроенная', + settings_param_keyboard_system: 'Системная', + settings_param_card_interface_old: 'Старый', + settings_param_card_interface_new: 'Новый', + settings_param_glass_easy: 'Прозрачная', + settings_param_glass_medium: 'Полупрозрачная', + settings_param_glass_blacked: 'Затемнённая', + settings_param_jackett_interview_all: 'Все', + settings_param_jackett_interview_healthy: 'Только доступные', + settings_parser_jackett_interview: 'Опрашивать трекеры', + helper_keyboard: 'После ввода значения нажмите кнопку «Назад» для сохранения', + helper_torrents: 'Удерживайте клавишу (ОК) для вызова контекстного меню', + helper_cleared: 'Успешно, подсказки будут показаны заново.', + helper_torrents_view: 'Для сброса тайм-кода и вызова меню удерживайте клавишу (ОК)', + fav_sync_title: 'Синхронизация закладок', + fav_sync_text: 'Ваши любимые закладки вместе с Вами. Подключите синхронизацию и просматривайте на любом устройстве.

    Для этого зарегистрируйтесь на сайте {site}, создайте профиль и авторизуйтесь в приложение.', + fav_sync_site: 'Сайт', + fav_remove_title: 'Удалить из истории', + fav_remove_descr: 'Удалить выделенную карточку', + fav_clear_title: 'Очистить историю', + fav_clear_descr: 'Удалить все карточки из истории', + fav_clear_label_title: 'Очистить метки', + fav_clear_label_descr: 'Очистить метки о просмотрах', + fav_clear_time_title: 'Очистить тайм-коды', + fav_clear_time_descr: 'Очистить все тайм-коды', + fav_label_cleared: 'Отметки очищены', + fav_time_cleared: 'Тайм-коды очищены', + timetable_empty: 'В этом разделе будут отображаться даты выхода новых серий', + player_quality: 'Качество', + player_flow: 'Поток', + player_tracks: 'Аудиодорожки', + player_disabled: 'Отключено', + player_unknown: 'Неизвестно', + player_subs: 'Субтитры', + player_size_default_title: 'По умолчанию', + player_size_default_descr: 'Размер видео по умолчанию', + player_size_cover_title: 'Расширить', + player_size_cover_descr: 'Расширяет видео на весь экран', + player_size_fill_title: 'Заполнить', + player_size_fill_descr: 'Вместить видео на весь экран', + player_size_s115_title: 'Увеличить 115%', + player_size_s115_descr: 'Увеличить видео на 115%', + player_size_s130_title: 'Увеличить 130%', + player_size_s130_descr: 'Увеличить видео на 130%', + player_size_v115_title: 'По вертикали 115%', + player_size_v115_descr: 'Увеличить видео на 115%', + player_size_v130_title: 'По вертикали 130%', + player_size_v130_descr: 'Увеличить видео на 130%', + player_video_size: 'Размер видео', + player_playlist: 'Плейлист', + player_error_one: 'Не удалось декодировать видео', + player_error_two: 'Видео не найдено или повреждено', + player_start_from: 'Продолжить просмотр с', + player_not_found: 'Плеер не найден', + player_lauch: 'Запустить плеер', + player_speed_default_title: 'Обычная', + player_speed_two_descr: 'Воспроизводиться без звука', + player_video_speed: 'Скорость воспроизведения', + player_share_title: 'Поделиться', + player_share_descr: 'Запустить это видео на другом устройстве', + player_normalization_power_title: 'Сила нормализации', + player_normalization_smooth_title: 'Скорость нормализации', + player_normalization_step_none: 'Нулевая', + player_normalization_step_low: 'Низкое', + player_normalization_step_medium: 'Среднее', + player_normalization_step_hight: 'Высокое', + player_normalization: 'Нормализация', + player_normalization_type_title: 'Тип нормализации', + player_normalization_type_all: 'Все', + player_normalization_type_up: 'Только повышение', + player_normalization_type_down: 'Только понижение', + player_youtube_no_played: 'К сожалению, это видео не доступно в вашем регионе, возможно, оно было заблокировано или удалено.', + player_youtube_start_play: 'Для начала проигрывания видео, нажмите кнопку "Плей"', + player_youtube_no_support: 'Ваше устройство не поддерживает воспроизведение YouTube видео, проверьте интернет соединение.', + player_segments_title: 'Сегменты', + player_segments_descr: 'Пропуск интро и другие части видео', + player_segments_ad_title: 'Рекламные вставки', + player_segments_skip_title: 'Интро и другое', + player_segments_value_none: 'Не пропускать', + player_segments_value_auto: 'Автопропуск', + player_segments_value_user: 'Пользовательский', + player_segments_skiped: 'Сегмент пропущен', + player_segments_skip_now: 'Пропустить', + player_segments_skip_in: 'Пропуск через', + player_segments_skip_intro: 'Пропустить заставку', + player_segments_next: 'Следующая серия', + player_segments_next_in: 'Следующая серия через', + player_pip: 'Уменьшить', + player_volume: 'Громкость', + player_time_end: 'Конец в', + broadcast_open: 'Открыть карточку на другом устройстве', + broadcast_play: 'Выберите устройство для просмотра', + card_new_episode: 'Новая серия', + card_book_remove: 'Убрать из закладок', + card_book_add: 'В закладки', + card_book_descr: 'Смотрите в меню (Закладки)', + card_like_remove: 'Убрать из понравившихся', + card_like_add: 'Нравится', + card_like_descr: 'Смотрите в меню (Нравится)', + card_wath_remove: 'Убрать из ожидаемых', + card_wath_add: 'Смотреть позже', + card_wath_descr: 'Смотрите в меню (Позже)', + card_history_remove: 'Убрать из истории', + card_history_add: 'В историю', + card_history_descr: 'Смотрите в меню (История)', + keyboard_listen: 'Говорите, я слушаю...', + keyboard_nomic: 'Нет доступа к микрофону', + notice_new_quality: 'Доступно новое качество', + notice_quality: 'Качество', + notice_new_episode: 'Новая серия', + notice_none: 'У вас еще нет никаких уведомлений, зарегистрируйтесь на сайте {site}, чтобы следить за новыми сериями и релизами.', + notice_in_quality: 'В качестве', + notice_none_account: 'У вас еще нет никаких уведомлений, добавьте сериалы в закладки и ожидайте уведомления о новых сериях.', + notice_none_system: 'На данный момент у вас отсутствуют уведомления. Мы обязательно оповестим вас, когда появятся новые уведомления.', + copy_link: 'Копировать ссылку на видео', + copy_secuses: 'Ссылка скопирована в буфер обмена', + copy_error: 'Ошибка при копирование ссылки', + copy_link_buffer: 'Скопировать ссылку', + account_sync_to_profile: 'Все закладки будут перенесены в профиль', + account_sync_secuses: 'Все закладки успешно перенесены', + account_profiles: 'Профили', + account_profiles_empty: 'Не удалось получить список профилей', + account_authorized: 'Авторизованы', + account_logged_in: 'Вы вошли под аккаунтом', + account_login_failed: 'Вход не выполнен', + account_login_wait: 'Ожидаем входа в аккаунт', + account_profile_main: 'Общий', + account_profile_child: 'Детский', + account_profile_add: 'Добавить профиль', + account_profile_name: 'Имя профиля', + account_profile_created: 'Профиль успешно создан', + account_profile_limited: 'Достигнут максимальный лимит профилей: {count}', + account_profile_info: 'Вы можете управлять профилями в настройках аккаунта, для этого перейдите на сайт ', + account_export_secuses: 'Экспорт успешно завершён', + account_export_fail: 'Ошибка при экспорте', + account_export_fail_500: 'Неизвестная ошибка', + account_export_fail_610: 'Вы исчерпали лимит на сегодня', + account_export_fail_200: 'Ошибка базы данных, попробуйте позже', + account_export_fail_600: 'Ошибка, не удалось загрузить файл', + account_export_fail_620: 'Ошибка, файл не передан', + account_import_secuses: 'Импорт успешно завершён', + account_import_fail: 'Ошибка при импорте', + account_imported: 'импортировано', + account_reload_after: 'перезагрузка через 5 сек.', + account_create: 'Откройте больше возможностей с аккаунтом CUB. Зарегистрируйтесь на сайте и получите доступ к синхронизации ваших закладок, тайм-кодов и других возможностей аккаунта CUB.', + account_premium: 'Раскройте новые горизонты с аккаунтом CUB Premium! Наслаждайтесь увеличенными лимитами и обогащенным функционалом сервиса. Перейдите на сайт и узнайте больше о преимуществах премиум аккаунта.', + account_premium_more: 'Подробнее о CUB Premium', + account_limited: 'Вы достигли максимального лимита. Увеличьте лимит с аккаунтом CUB Premium. Подробнее на сайте ', + account_premium_include_1: 'Увеличение количества закладок', + account_premium_include_2: 'Увеличение истории просмотров', + account_premium_include_3: 'Увеличение количества тайм-кодов', + account_premium_include_4: 'Количество профилей на аккаунт', + account_premium_include_5: 'Уведомления', + account_premium_include_6: 'Синхронизация данных', + account_premium_include_text_1: 'Больше закладок - больше возможностей! Сохраняйте свои любимые фильмы и сериалы, создавайте списки просмотра и наслаждайтесь просмотром в любое удобное время.', + account_premium_include_text_2: 'Увеличьте историю просмотров в приложении и следите за тем, что уже посмотрели. Легко находите и пересматривайте свои любимые фильмы и сериалы.', + account_premium_include_text_3: 'Не бойтесь пропустить ни одной важной сцены! Увеличьте количество тайм-кодов в приложении и легко отслеживайте, где остановились в просмотре любимых фильмов и сериалов.', + account_premium_include_text_4: 'Получите больше свободы с нашим премиум доступом! Увеличьте количество профилей на аккаунте и позвольте своим друзьям и близким наслаждаться фильмами и сериалами вместе с вами. Никаких ограничений - наслаждайтесь просмотром с любимыми людьми.', + account_premium_include_text_5: 'Не пропустите ни одной новой серии или перевода! Получайте уведомления вовремя и будьте в курсе всех обновлений. Увеличьте свой кинопоток вместе с нами и получайте уведомления о выходе новых серий и переводов прямо на свой смартфон.', + account_premium_include_text_6: 'Синхронизуйте свои данные между устройствами с премиум доступом! Больше не нужно тратить время на поиск последнего эпизода, на котором вы остановились. С нашим премиум доступом вы можете синхронизировать свои данные между устройствами, чтобы продолжать просмотр с места, где вы остановились, на любом устройстве, где установлено приложение.', + account_code_enter: 'Введите шестизначный код', + account_code_error: 'Возможно, вы ввели неверный или устаревший код', + account_code_wrong: 'Возможно, вы указали неверный формат', + account_code_where: 'Перейдите на сайт и введите указанный там код.', + account_code_input: 'Ввести код', + account_qr_premium: 'Отсканируйте QR-код, чтобы узнать больше о CUB Premium', + account_qr_code: 'Отсканируйте QR-код для получения кода добавления устройства', + account_qr_create: 'Отсканируйте QR-код, чтобы создать аккаунт', + account_add_device_title: 'Добавить устройство', + account_add_device_text: 'Перейдите на сайт по ссылки чтобы получить код для добавления устройства.', + account_none_title: 'Еще нет аккаунта?', + account_none_include_1: 'Закладки и история просмотров сохраняются в облаке', + account_none_include_2: 'Синхронизация между устройствами', + account_none_include_3: 'Уведомления о новых сериях и релизах', + account_none_include_4: 'Создание нескольких профилей на одном аккаунте', + account_discuss_add_qr: 'Отсканируйте QR-код', + account_discuss_add_title: 'Хотите оставить комментарий?', + account_discuss_add_text: 'Отсканируйте QR-код, чтобы перейти в приложение и добавить комментарий к этому фильму или сериалу.

    - Возьмите телефон или планшет
    - Откройте камеру
    - Наведите на QR-код
    - Перейдите по ссылки, которая появится на экране', + account_discuss_added: 'Спасибо за ваш комментарий!', + account_discuss_added_ready: 'Вы уже оставили комментарий к этому фильму или сериалу.', + network_noconnect: 'Нет подключения к сети', + network_404: 'Запрошенная страница не найдена. [404]', + network_401: 'Авторизация не удалась', + network_500: 'Внутренняя ошибка сервера. [500]', + network_parsererror: 'Запрошенный синтаксический анализ JSON завершился неудачно.', + network_timeout: 'Время запроса истекло.', + network_abort: 'Запрос был прерван.', + network_error: 'Неизвестная ошибка', + size_zero: '0 Байт', + size_byte: 'Байт', + size_kb: 'КБ', + size_mb: 'МБ', + size_gb: 'ГБ', + size_tb: 'ТБ', + size_pp: 'ПБ', + speed_bit: 'бит/c', + speed_kb: 'Кбит/c', + speed_mb: 'Мбит/c', + speed_gb: 'Гбит/c', + speed_tb: 'Тбит/c', + speed_pp: 'Пбит/c', + month_1: 'Январь', + month_2: 'Февраль', + month_3: 'Март', + month_4: 'Апрель', + month_5: 'Ма', + month_6: 'Июнь', + month_7: 'Июль', + month_8: 'Август', + month_9: 'Сентябрь', + month_10: 'Октябрь', + month_11: 'Ноябрь', + month_12: 'Декабрь', + day_1: 'Понедельник', + day_2: 'Вторник', + day_3: 'Среда', + day_4: 'Четверг', + day_5: 'Пятница', + day_6: 'Суббота', + day_7: 'Воскресенье', + month_1_e: 'Января', + month_2_e: 'Февраля', + month_3_e: 'Марта', + month_4_e: 'Апреля', + month_5_e: 'Мая', + month_6_e: 'Июня', + month_7_e: 'Июля', + month_8_e: 'Августа', + month_9_e: 'Сентября', + month_10_e: 'Октября', + month_11_e: 'Ноября', + month_12_e: 'Декабря', + week_1: 'Пн', + week_2: 'Вт', + week_3: 'Ср', + week_4: 'Чт', + week_5: 'Пт', + week_6: 'Сб', + week_7: 'Вс', + time_h: 'ч.', + time_m: 'м.', + time_s: 'с.', + extensions_enable: 'Включить', + extensions_disable: 'Отключить', + extensions_check: 'Проверить статус', + extensions_install: 'Установить', + extensions_info: 'Информация', + extensions_edit: 'Редактировать', + extensions_change_name: 'Изменить название', + extensions_change_link: 'Изменить ссылку', + extensions_remove: 'Удалить', + extensions_set_name: 'Введите название плагина', + extensions_set_url: 'Введите адрес плагина', + extensions_ready: 'Этот плагин уже установлен', + extensions_no_info: 'Без информации', + extensions_no_name: 'Без названия', + extensions_worked: 'Рабочий', + extensions_no_plugin: 'Плагин не подтверждён ', + extensions_add: 'Добавить плагин', + extensions_from_memory: 'Установленные в память ', + extensions_from_cub: 'Установленные из CUB', + extensions_from_popular: 'Популярные плагины', + extensions_from_lib: 'Библиотека плагинов', + extensions_from_connected: 'Подключенные плагины', + extensions_hpu_best: 'Популярные', + extensions_hpu_recomend: 'Рекомендуем', + extensions_hpu_theme: 'Темы', + extensions_hpu_screensaver: 'Скринсейвер', + extensions_hpu_video: 'Видео', + extensions_hpu_control: 'Управление', + extensions_hpu_other: 'Разное', + extensions_hpu_: 'Остальное', + speedtest_connect: 'подключение', + speedtest_test: 'тестирование', + speedtest_ready: 'готово', + speedtest_button: 'Тестировать скорость', + change_source_on_cub: 'Сменить источник на CUB', + tv_status_returning_series: 'Онгоинг', + tv_status_planned: 'Запланировано', + tv_status_in_production: 'В производстве', + tv_status_ended: 'Завершено', + tv_status_canceled: 'Отменено', + tv_status_pilot: 'Пилотный', + tv_status_released: 'Выпущенный', + tv_status_rumored: 'По слухам', + tv_status_post_production: 'Скоро', + input_detection_touch: 'Хотите переключить на сенсорное управление?', + input_detection_mouse: 'Хотите переключить на управление мышью?', + input_detection_remote: 'Хотите переключить на управление пультом?', + https_text: 'Вы используете протокол HTTPS, с которым Lampa работает некорректно. Для корректной работы приложения используйте адрес с протоколом HTTP', + premiere_author_recomend_1: 'Закажите пиццу и готовьтесь к драйву.', + premiere_author_recomend_2: 'Вечеринка только начинается.', + premiere_author_recomend_3: 'Подготовьтесь к адреналину.', + premiere_author_recomend_4: 'Готовы к незабываемому вечеру?', + premiere_author_recomend_5: 'Рекомендую к просмотру.', + premiere_title: 'Премьера', + termsofuse_t_01: 'Правила использования', + termsofuse_t_02: 'Lampa - это удобный инструмент для ознакомления с новинками киноиндустрии, включая фильмы, сериалы, мультфильмы и другую информацию. Для получения информации о фильмах используется открытый источник - сайт themoviedb.org', + termsofuse_t_03: 'Контент', + termsofuse_t_04: 'Lampa использует API (Application Programming Interface) от каталога themoviedb.org для получения информации о фильмах и телесериалах, а также для просмотра связанных с ними медиафайлов, таких как постеры, трейлеры и другое.', + termsofuse_t_05: 'API от themoviedb.org позволяет приложению Lampa получать доступ к базе данных фильмов и телесериалов, предоставляя возможность поиска медиафайлов и просмотра информации о них.', + termsofuse_t_06: 'Взаимодействие между приложением Lampa и themoviedb.org происходит через запросы к API, которые отправляются из приложения Lampa на серверы themoviedb.org для получения информации и медиафайлов. Themoviedb.org обрабатывает запросы и отправляет обратно в приложение Lampa запрошенные данные.', + termsofuse_t_07: 'Таким образом, благодаря использованию API от themoviedb.org, приложение Lampa предоставляет пользователям доступ к обширной базе данных фильмов и телесериалов, соблюдая при этом условия использования и ограничения, установленные правообладателем.', + termsofuse_t_08: 'Расширения', + termsofuse_t_09: 'Расширения - это мощный инструмент, предоставляемый для приложения Lampa, который позволяет пользователям расширить его возможности, добавить дополнительный функционал и изменить контент в соответствии с их потребностями.', + termsofuse_t_10: 'Однако, следует отметить, что пользователи устанавливают расширения на свой страх и риск. Все последствия, возникающие в результате использования расширений, ложатся на пользователя. Пользователям рекомендуется быть осторожными при установке и использовании расширений, тщательно оценивая их надежность и безопасность.', + termsofuse_t_11: 'Нарушения авторских прав', + termsofuse_t_12: 'Если вы обнаружили нарушение авторских прав в приложении Lampa - свяжитесь с разработчиками, используя раздел Контакты приложения. Однако, важно учесть, что приложение Lampa использует API от каталога themoviedb.org, который предоставляет открытый доступ к информации о фильмах и сериалах. Это означает, что информация, которая отображается в приложении Lampa, является общедоступной и не нарушает авторских прав.', + termsofuse_t_13: 'Если вы считаете, что в приложении Lampa все же есть контент, нарушающий авторские права - обратитесь к правообладателю этого контента с просьбой удалить его со страниц сайта themoviedb.org. В свою очередь, приложение Lampa может удалить контент при получении соответствующего уведомления о нарушении авторских прав.', + install_app_apk_title: 'Как установить Lampa на Android', + install_app_apk_text: 'Мы заметили, что для запуска Lampa на Android вы используете MediaStationX. Мы рекомендуем вам установить Lampa в виде APK-приложения. Это обеспечит более стабильную работу и доступ ко всем функциям приложения.

    Перейдите в группу в Телеграме, чтобы скачать последнюю версию APK и инструкции по установке.', + install_app_apk_qr: 'Отсканируйте QR-код, чтобы скачать Lampa APK', + ad: 'Реклама', + ad_disable: 'Подписавшись на CUB Premium, вы забудете о рекламе.', + ad_plugin: 'Реклама от плагина', + ad_after: 'Реклама через', + ad_skip: 'Пропустить', + ad_continue_after: 'Просмотр начнется через', + discuss_rules_title: 'Следуйте правилам и уважайте других — создаём комфорт вместе!', + discuss_rules_rule_1: 'Не используйте слова, состоящие только из цифр.', + discuss_rules_rule_2: 'Пишите на одном языке, используйте слова из 5 и более букв.', + discuss_rules_rule_3: 'Используйте знаки препинания и завершайте предложения точками.', + discuss_rules_rule_4: 'Избегайте непонятных символов !?#%', + discuss_rules_rule_5: 'Пишите полные предложения, используйте предложение из 5 и более слов.', + discuss_rules_rule_6: 'Не используйте слишком длинные слова.', + discuss_rules_rule_7: 'Постарайтесь уместиться в 300 символов.', + discuss_voited: 'Спасибо за вашу оценку! Ваш голос помогает улучшать контент.', + confirm_open_player: 'Другое устройство запрашивает доступ к плееру. Хотите воспроизвести видео?', + pincode_use_remote: 'Используйте пульт для ввода кода, нажимая стрелки для выбора нужной цифры.', + pincode_use_toggle: 'Нажмите и удерживайте кнопку OK, чтобы сменить раскладку.', + storage_quota_exceeded: 'Превышен лимит хранилища. Удалите кеш и повторите попытку.', + ai_search_start_typing: 'Спросите у AI-ассистента, какие фильмы вы хотите найти. Например: "Фильмы про космос"', + ai_search_limit: 'Лимит запросов превышен. Попробуйте повторить запрос позже. С подпиской CUB Premium лимиты будут увеличены, и вам не придется ждать!', + ai_subscribe_title: 'Откройте больше возможностей с AI', + ai_subscribe_descr: 'Оформите подписку CUB Premium и увеличьте количество запросов к AI. Вместе с AI мы подберем вам лучшие фильмы которые только сможем.', + dmca_title: 'Контент заблокирован', + dmca_descr: 'Данный материал недоступен для просмотра. Он был заблокирован по просьбе правообладателя в соответствии с законодательством об авторских правах.', + dmca_title_lgbt: 'Контент ограничен', + dmca_descr_lgbt: 'Просмотр недоступен в вашем регионе, так как возможно содержит ЛГБТ-контент. В некоторых странах такие материалы могут быть запрещены или ограничены.', + loading_progress_step_0: 'Подготовка', + loading_progress_step_1: 'Загрузка языков', + loading_progress_step_2: 'Поиск зеркал', + loading_progress_step_3: 'Подготовка расширений', + loading_progress_step_4: 'Осталось немного', + loading_progress_step_5: 'Уже скоро', + install_extension_rule_1: 'Установка стороннего плагина', + install_extension_rule_2: 'Плагины создаются независимыми разработчиками, и LAMPA не проверяет их содержимое. Устанавливая их, вы соглашаетесь с тем, что:', + install_extension_rule_3: '- Некоторые плагины могут запрашивать доступ к вашим данным или работать с непроверенными источниками.', + install_extension_rule_4: '- Если устанавливаемый вами плагин нарушает авторские права или другие законы, вся ответственность за его использование лежит на вас.', + install_extension_rule_5: '- Устанавливайте только плагины из доверенных источников. Если вы сомневаетесь в безопасности или законности плагина, лучше откажитесь от его установки.', + install_extension_rule_6: 'LAMPA не поддерживает и не одобряет плагины, связанные с пиратским контентом.', + install_extension_rule_7: 'Продолжая, вы подтверждаете, что понимаете эти риски.', + terminal_title: 'Терминал', + terminal_no_access: 'Без доступа', + terminal_confirm: 'Разрешить', + terminal_deny: 'Запретить', + terminal_update: 'Обновить', + terminal_code: 'Код доступа', + terminal_text: 'Вы запрашиваете доступ к терминалу. Разработчики могут получить доступ к вашему устройству и управлять им. Это может быть полезно для диагностики и устранения проблем, но также может представлять риск безопасности. Пожалуйста, убедитесь, что вы доверяете разработчикам, прежде чем предоставлять доступ.

    Вы можете в любой момент отключить эту функцию нажав на кнопку "Запретить".', + developer_param_enabled: 'Режим разработчика', + developer_param_nopremium: 'Отключить CUB Premium', + developer_param_nodemo: 'Отключить демонстрационный режим', + developer_param_ads: 'Показывать рекламу', + developer_param_fps: 'Показывать FPS', + developer_trigger_help_1: 'Почти догадались :)', + developer_trigger_help_2: 'Еще немного :)', + developer_trigger_help_3: 'Точно хочешь войти в режим разработчика?', + developer_trigger_help_4: 'Режим разработчика активирован', + remote_helper_long: 'Удерживайте кнопку (ОК) для вызова меню', + no_watch_history: 'Нет истории просмотра', + adult_content_title: 'Взрослый контент', + adult_content_text_warning: 'Контент может содержать материалы для взрослых, которые могут быть неуместны для некоторых зрителей.', + adult_content_text_modal: 'Этот фильм или сериал помечен как содержащий взрослый контент. Для просмотра этого материала вам должно быть 18 лет или больше. Пожалуйста, подтвердите, что вы достигли совершеннолетия, чтобы продолжить просмотр.', + adult_content_confirm: 'Мне 18 лет или больше', + adult_content_deny: 'Мне меньше 18 лет', + inner_player_disclaimer_title: 'Дисклеймер плеера', + inner_player_disclaimer_text: 'Я понимаю, что запускаю плеер с неполной поддержкой, и понимаю, что это может приводить к нетипичному поведению устройства. Оптимально перейти на плееры семейства tvOS или другие альтернативы.', + inner_player_disclaimer_change_player: 'Сменить плеер', + remote_configuration_settings_title: 'Удалённая конфигурация', + remote_configuration_registration_text: 'Удалённая конфигурация предоставляет временный доступ к вашему приложению, другое приложение сможет установить расширения и настроить параметры.', + remote_configuration_waite_text: 'Теперь вы можете передать этот код в другое приложение, чтобы предоставить доступ к настройкам.', + remote_configuration_open_button: 'Открыть доступ', + remote_configuration_code_life: 'Код действителен', + remote_configuration_notice_nocode: 'Не удалось открыть доступ', + player_ai_agent_info: 'Хотите узнать больше о видео? Спросите у AI-ассистента, и он предоставит вам график настроений, краткий сюжет и интересные моменты.', + player_ai_agent_ask_plot: 'Кратко о сюжете', + player_ai_agent_ask_moods: 'Показать график', + player_ai_agent_ask_highlights: 'Интересные моменты', + player_ai_agent_ask: 'Спросить', + player_ai_agent_processing: 'Анализирую...', + player_ai_agent_no_data: 'Нет данных для показа.', + player_ai_agent_no_analysis: 'Не удалось провести анализ видео.', + player_ai_agent_quota: 'Лимит запросов превышен. Попробуйте повторить запрос позже.', + player_ai_agent_working: 'Я еще работаю над этим...' + }; + + var en = { + lang_choice_title: 'Welcome', + lang_choice_subtitle: 'Choose your language', + more: 'More', + show_more: 'Show more', + more_results: 'Show more results', + loading: 'Loading', + nofind_movie: 'The movie could not be found.', + noname: 'Untitled', + nochoice: 'Not chosen', + cancel: 'Cancel', + confirm: 'I confirm', + sure: 'Are you sure?', + nodata: 'No data', + back: 'Back', + ready: 'Ready', + close_app_modal: 'Are you sure you want to leave the app?', + connected_seeds: 'connected', + search: 'Search', + search_input: 'Enter text', + search_empty: 'Search history is empty.', + search_delete: 'Left - delete', + search_start_typing: 'Start typing search text.', + search_searching: 'Search in progress...', + search_start: 'To start searching', + search_nofound: 'Nothing was found according to your request.', + global_search: 'Global search', + full_genre: 'Genre', + full_production: 'Production', + full_date_of_release: 'date of release', + full_budget: 'Budget', + full_countries: 'Countries', + full_like: 'Like', + full_torrents: 'Torrents', + full_trailers: 'Trailers', + full_detail: 'In detail', + full_notext: 'No description.', + full_series_release: 'Series release', + full_next_episode: 'Next', + full_episode_days_left: 'Days left', + full_trailer_official: 'Official', + full_trailer_no_official: 'Informal', + full_season: 'Season', + full_episode: 'Episode', + full_directing: 'Directing', + full_writing: 'Writing', + full_keywords: 'Tags', + settings_cub_sync: 'Synchronization', + settings_cub_sync_descr: 'Synchronization with the CUB service: Synchronization of your bookmarks, browsing history, tags and timecodes.', + settings_cub_account: 'Account', + settings_cub_logged_in_as: 'Logged in as', + settings_cub_profile: 'Profile', + settings_cub_sync_btn: 'Synchronize', + settings_cub_sync_btn_descr: 'Save local bookmarks to CUB account', + settings_cub_backup: 'Backup', + settings_cub_backup_descr: 'Save or load backup data', + settings_cub_logout: 'Sign out', + settings_cub_signin: 'Authorization', + settings_cub_not_specified: 'Not specified', + settings_cub_password: 'Password', + settings_cub_status: 'Status', + settings_cub_backup_import: 'Import', + settings_cub_backup_export: 'Export', + settings_cub_sync_filters: 'Filters sync', + settings_cub_sync_calendar: 'Calendar sync', + settings_cub_sync_quality: 'Quality sync', + settings_cub_sync_search: 'Search history sync', + settings_cub_sync_recomends: 'Recommendations sync', + settings_cub_sync_timecodes: 'Timecode Synchronization', + settings_input_links: 'Favorites', + settings_interface_type: 'Lite version', + settings_interface_size: 'Interface size', + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: 'Background', + settings_interface_background_use: 'Show background', + settings_interface_background_type: 'Background type', + settings_interface_performance: 'Performance', + settings_interface_animation: 'Animation', + settings_interface_animation_descr: 'Animation of cards and content', + settings_interface_attenuation: 'Attenuation', + settings_interface_attenuation_descr: 'Smooth fading of cards from below and from above', + settings_interface_scroll: 'Scroll Type', + settings_interface_view_card: 'Card view type', + settings_interface_view_card_descr: 'As you scroll the feed, the cards will load gradually or load all', + settings_interface_lang: 'Interface language', + settings_interface_lang_reload: 'You need to restart the application, click "OK" to restart.', + settings_main_account: 'Account', + settings_main_interface: 'Interface', + settings_main_player: 'Player', + settings_main_parser: 'Parser', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Extensions', + settings_main_rest: 'Other', + settings_rest_start: 'Start page', + settings_rest_start_descr: 'Which page to start at startup', + settings_rest_source: 'Source', + settings_rest_source_use: 'Main source', + settings_rest_source_descr: 'Where to get information about films', + settings_rest_tmdb_lang: 'What language to display data from TMDB', + settings_rest_tmdb_prox: 'Proxy TMDB', + settings_rest_tmdb_prox_auto: 'Enable proxy automatically', + settings_rest_tmdb_posters: 'Resolution of TMDB posters', + settings_rest_screensaver: 'Screensaver', + settings_rest_screensaver_use: 'Show splash screen when idle', + settings_rest_screensaver_type: 'Screen saver type', + settings_rest_helper: 'Hints', + settings_rest_helper_use: 'Show hints', + settings_rest_helper_reset: 'Show hints again', + settings_rest_pages: 'How many pages to keep in memory', + settings_rest_pages_descr: 'Keeps pages in the state you left them in', + settings_rest_time: 'Shift time', + settings_rest_navigation: 'Navigation type', + settings_rest_keyboard: 'Keyboard type', + settings_rest_device: 'Device name', + settings_rest_device_placeholder: 'For example: My Lamp', + settings_rest_cache: 'Clear cache', + settings_rest_cache_descr: 'All settings and data will be cleared', + settings_rest_tmdb_example: 'For example:', + settings_rest_tmdb_api_descr: 'To get data', + settings_rest_tmdb_image_descr: 'To get images', + settings_rest_card_quality: 'Quality marks', + settings_rest_card_quality_descr: 'Display quality marks on cards', + settings_rest_card_episodes: 'Episode marks', + settings_rest_card_episodes_descr: 'Display episode markers on cards', + settings_parser_use: 'Use parser', + settings_parser_use_descr: 'Hereby, you agree to accept all responsibility for the use of public links to view torrent and online content.', + settings_parser_type: 'Parser type for torrents', + settings_parser_jackett_placeholder: 'For example: 192.168.x', + settings_parser_jackett_link: 'Link', + settings_parser_jackett_link_descr: 'Provide a link to the Jackett script', + settings_parser_jackett_key_placeholder: 'For example: sa0sk83d..', + settings_parser_jackett_key: 'Api key', + settings_parser_jackett_key_descr: 'Located in Jackett', + settings_parser_torlook_type: 'TorLook site parsing method', + settings_parser_scraperapi_placeholder: 'For example: scraperapi.com', + settings_parser_scraperapi_link: 'Link to site parser', + settings_parser_scraperapi_descr: 'Register on the site scraperapi.com, enter the link api.scraperapi.com?api_key=...&url={q}
    W41.torlook.info will be delivered to {q}', + settings_parser_search: 'Search', + settings_parser_search_descr: 'What language to search in?', + settings_parser_in_search: 'Parser in search', + settings_parser_in_search_descr: 'Show search results?', + settings_parser_timeout_title: 'Parser timeout', + settings_parser_timeout_descr: 'Time in seconds to wait for a response from the server', + settings_player_type: 'Player type', + settings_player_type_descr: 'Which player to play', + settings_infuse_launch_mode: 'Launch in Infuse', + settings_infuse_launch_mode_descr: 'What to do when opening video in Infuse. Torrents always play immediately', + settings_infuse_launch_ask: 'Ask on launch', + settings_infuse_launch_play: 'Play', + settings_infuse_launch_save_and_play: 'Save and play', + settings_player_iptv_type: 'Player type for IPTV', + settings_player_iptv_type_descr: 'Which player to play IPTV channels', + settings_player_reset: 'Reset default player', + settings_player_reset_descr: 'Resets the selected Android player in the application', + settings_player_path: 'Path to the player', + settings_player_path_descr: 'Specify the path to the player .exe', + settings_player_external_header: 'External player', + settings_player_external_fullscreen: 'Launch in fullscreen mode', + settings_player_normalization: 'Sound normalization', + settings_player_normalization_descr: 'Normalizes sound to one level, lowers loud sounds and boosts quiet ones.', + settings_player_next_episode: 'Next episode', + settings_player_next_episode_descr: 'Automatically switch to the next series after the end of the current one', + settings_player_timecode: 'Timecode', + settings_player_timecode_descr: 'Continue from last viewed location', + settings_player_scale: 'Scaling Method', + settings_player_scale_descr: 'How to calculate video scaling', + settings_player_subs: 'Subtitles', + settings_player_subs_use: 'Turn on', + settings_player_subs_use_descr: 'Always turn on subtitles after starting a video', + settings_player_subs_lang: 'Subtitle language', + settings_player_subs_lang_descr: 'Which subtitles to turn on automatically when several languages are available', + settings_param_subtitles_lang_auto: 'Interface language', + settings_player_subs_size: 'The size', + settings_player_subs_size_descr: 'Screen size of subtitles', + settings_player_subs_stroke_use: 'Use edging', + settings_player_subs_stroke_use_descr: 'Subtitles will be outlined in black for better readability', + settings_player_subs_backdrop_use: 'Use an underlay', + settings_player_subs_backdrop_use_descr: 'Subtitles will be displayed on a translucent backing to improve readability', + settings_player_quality: 'Default video quality', + settings_player_quality_descr: 'Preferred video quality for viewing', + settings_player_hls_title: 'Processing the .m3u8 stream', + settings_player_hls_descr: 'Do not touch this parameter if you do not know why it is.', + settings_plugins_notice: 'To apply the plugin, you need to restart the application', + settings_plugins_add: 'Add Plugin', + settings_plugins_add_descr: 'To delete an added plugin, hold or double-click the (OK) key on it', + settings_plugins_install: 'Install Plugin', + settings_plugins_install_descr: 'Install a plugin from the list of available', + settings_server_link: 'Use link', + settings_server_links: 'Links', + settings_server_placeholder: 'For example: 192.168.X', + settings_server_link_one: 'Main Link', + settings_server_link_one_descr: 'Specify the main link to the TorrServer script', + settings_server_link_two: 'Additional link', + settings_server_link_two_descr: 'Provide an additional link to the TorrServer script', + settings_server_additionally: 'Additionally', + settings_server_client: 'Embedded client', + settings_server_client_descr: 'Use the built-in TorrServer JS client, otherwise the system one starts.', + settings_server_base: 'Save to database', + settings_server_base_descr: 'The torrent will be added to the TorrServer database', + settings_server_preload: 'Use prefetch buffer', + settings_server_preload_descr: 'Wait for TorrServer\'s preload buffer to fill before playing', + settings_server_auth: 'Authorization', + settings_server_password_use: 'Password login', + settings_server_login: 'Login', + settings_server_password: 'Password', + settings_server_not_specified: 'Not specified', + settings_server_search_type: 'Search type', + settings_server_search_type_descr: 'Where to look for torrents: built-in rutor, Torznab indexers in TorrServer, or both sources.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + torent_nohash_reasons: 'The reasons', + torent_nohash_reason_one: 'TorServer was unable to download the torrent file', + torent_nohash_reason_two: 'Reply from TorServer', + torent_nohash_reason_three: 'Link', + torent_nohash_do: 'What to do?', + torent_nohash_do_one: 'Check if you configured Jackett correctly', + torent_nohash_do_two: 'Private sources may not provide a link to the file', + torent_nohash_do_three: 'Make sure Jackett can download the file too', + torent_nohash_do_four: 'Write to our telegram group: @lampa_group', + torent_nohash_do_five: 'Specify which movie, which distribution and, if possible, a photo of this distribution', + torrent_error_text: 'Failed to connect to TorrServer. Let\'s quickly go through the list of possible problems and check everything.', + torrent_error_step_1: 'Is TorrServer running', + torrent_error_step_2: 'Dynamic IP', + torrent_error_step_3: 'Protocol and Port', + torrent_error_step_4: 'Antivirus blocking', + torrent_error_step_5: 'Check for availability', + torrent_error_step_6: 'Still doesn\'t work', + torrent_error_info_1: 'Make sure you have launched TorrServer on the device where it is installed.', + torrent_error_info_2: 'A common mistake, the IP address of the device with TorrServer has changed. Make sure that the IP address you entered - {ip} - matches the address of the device on which TorrServer is installed.', + torrent_error_info_3: 'To connect to TorrServer, you must specify the protocol http:// at the beginning and port :8090 at the end of the address. Make sure there is a port after the IP address, your current address is {ip}', + torrent_error_info_4: 'Frequent occurrence, antivirus or firewall can block access by IP address, try disabling antivirus and firewall.', + torrent_error_info_5: 'On any other device on the same network, open the {ip} address in a browser and check if the TorrServer web interface is available.', + torrent_error_info_6: 'If, after all the checks, a connection error still occurs, try restarting TorrServer and the Internet adapter.', + torrent_error_info_7: 'If the problem persists, write to the Telegram group @lampa_group with the text (Lampa does not connect to TorrServer after all checks, the current address is {ip})', + torrent_error_start: 'Start verification', + torrent_error_nomatrix: 'Failed to verify Matrix version', + torrent_error_made: 'Performed', + torrent_error_from: 'from', + torrent_error_next: 'Further', + torrent_error_complite: 'To complete', + torrent_error_connect: 'Connection error', + torrent_install_need: 'Requires TorrServer', + torrent_install_text: 'TorrServer is an application that allows you to view content from torrent files online.

    More detailed information on installation can be found in the Telegram groups below.', + torrent_install_contact: 'Telegram groups', + torrent_item_bitrate: 'Bitrate', + torrent_item_seeds: 'Seeds', + torrent_item_grabs: 'Leechers', + torrent_item_mb: 'Mbps', + torrent_serial_episode: 'Series', + torrent_serial_season: 'Season', + torrent_serial_date: 'Exit', + torrent_get_magnet: 'Requesting a magnet link', + torrent_remove_title: 'Delete', + torrent_remove_descr: 'The torrent will be removed from your list', + torrent_parser_any_one: 'Any', + torrent_parser_any_two: 'Any', + torrent_parser_no_choice: 'Not chosen', + torrent_parser_yes: 'Yes', + torrent_parser_no: 'No', + torrent_parser_quality: 'Quality', + torrent_parser_subs: 'Subtitles', + torrent_parser_voice: 'Translation', + torrent_parser_tracker: 'tracker', + torrent_parser_year: 'Year', + torrent_parser_season: 'Season', + torrent_parser_sort_by_seeders: 'By distributors', + torrent_parser_sort_by_size: 'To size', + torrent_parser_sort_by_name: 'by name', + torrent_parser_sort_by_tracker: 'By source', + torrent_parser_sort_by_date: 'By date', + torrent_parser_sort_by_viewed: 'Viewed', + torrent_parser_voice_dubbing: 'Dubbing', + torrent_parser_voice_polyphonic: 'Polyphonic', + torrent_parser_voice_two: 'Two-voiced', + torrent_parser_voice_amateur: 'Amateur', + torrent_parser_reset: 'Reset filter', + torrent_parser_empty: 'Failed to get results', + torrent_parser_no_hash: 'Failed to get HASH, try reloading TorrServer', + torrent_parser_added_to_mytorrents: 'added to "My torrents"', + torrent_parser_add_to_mytorrents: 'Add to "My torrents"', + torrent_parser_label_title: 'Flag', + torrent_parser_label_descr: 'Flag a hand with a flag (viewed)', + torrent_parser_label_cancel_title: 'Uncheck', + torrent_parser_label_cancel_descr: 'Remove the mark from the distribution (viewed)', + torrent_parser_timeout: 'Timeout expired', + torrent_parser_nofiles: 'Failed to extract suitable files', + torrent_parser_set_link: 'Specify a link for parsing', + torrent_parser_request_error: 'Request error', + torrent_parser_magnet_error: 'Failed to get magnet link', + torrent_parser_no_responce: 'The parser is not responding to the request', + torrent_parser_torlook_fallback_search_notification: 'Jackett parser is not available or the connection settings are incorrect. Searching Torlook...', + about_text: 'The application is completely free and uses public links to get information about videos, new releases, popular movies, etc. All available information is used solely for educational purposes, the application does not use its own servers to distribute information.', + about_channel: 'Our channel', + about_group: 'Group', + about_version: 'Version', + about_donate: 'Donat', + title_watched: 'You watched', + title_settings: 'Settings', + title_collections: 'Collections', + title_company: 'Company', + title_actors: 'Actors', + title_actor: 'Actor', + title_actress: 'Actress', + title_person: 'Person', + title_persons: 'Persons', + title_comments: 'Comments', + title_torrents: 'Torrents', + title_trailers: 'Trailers', + title_watch: 'Watch', + title_error: 'Error', + title_links: 'Links', + title_choice: 'Choose', + title_main: 'Home', + title_book: 'Bookmarks', + title_like: 'Like', + title_wath: 'Later', + title_history: 'Browsing history', + title_mytorrents: 'My torrents', + title_last: 'Last', + title_action: 'Action', + title_action_infuse: 'Infuse action', + title_producer: 'Producer', + title_collection: 'Collection', + title_recomendations: 'Recommendations', + title_similar: 'Similar', + title_about: 'About the application', + title_timetable: 'Schedule', + title_relises: 'Digital releases', + title_catalog: 'Catalog', + title_category: 'Category', + title_parser: 'Parser', + title_type: 'Type of', + title_rating: 'Rating', + title_country: 'Country', + title_year: 'Year', + title_genre: 'Genre', + title_filter: 'Filter', + title_notice: 'Notifications', + title_files: 'Files', + title_now_watch: 'Watching now', + title_latest: 'Last addition', + title_continue: 'Continue browsing', + title_recomend_watch: 'We recommend to see', + title_new_episodes: 'New episodes', + title_popular: 'Popular', + title_popular_movie: 'Popular films', + title_popular_tv: 'Popular TV shows', + title_new_this_year: 'New this year', + title_hight_voite: 'Highly rated', + title_new: 'New', + title_trend_day: 'Today in trend', + title_trend_week: 'Trending for the week', + title_upcoming: 'Watch in cinemas', + title_top_movie: 'Top movies', + title_top_tv: 'Top series', + title_tv_today: 'On air today', + title_this_week: 'This week', + title_in_top: 'Top', + title_out: 'Exit', + title_out_confirm: 'Yes, get out', + title_continue_two: 'Proceed', + title_choice_language: 'Choose a language', + title_subscribe: 'Subscribe', + title_subscribes: 'Subscriptions', + title_unsubscribe: 'Unsubscribe', + title_language: 'Original language', + subscribe_success: 'You have successfully subscribed', + subscribe_error: 'An error occurred while subscribing, please try again later', + subscribe_noinfo: 'Failed to retrieve information, please try again later', + company_headquarters: 'Headquarters', + company_homepage: 'Website', + company_country: 'Country', + country_ad: 'Andorra', + country_ae: 'UAE', + country_af: 'Afghanistan', + country_al: 'Albania', + country_am: 'Armenia', + country_ao: 'Angola', + country_ar: 'Argentina', + country_at: 'Austria', + country_au: 'Australia', + country_aw: 'Aruba', + country_az: 'Azerbaijan', + country_bа: 'Bosnia & Herzegovina', + country_bd: 'Bangladesh', + country_be: 'Belgium', + country_bg: 'Bulgaria', + country_bh: 'Bahrain', + country_bi: 'Burundi', + country_bj: 'Benin', + country_bo: 'Bolivia', + country_br: 'Brazil', + country_bs: 'Bahamas', + country_bt: 'Bhutan', + country_bw: 'Botswana', + country_by: 'Belarus', + country_ca: 'Canada', + country_ch: 'Switzerland', + country_cl: 'Chile', + country_cm: 'Cameroon', + country_cn: 'China', + country_co: 'Colombia', + country_cr: 'Costa Rica', + country_cu: 'Cuba', + country_cv: 'Cape Verde', + country_cy: 'Cyprus', + country_cz: 'Czech Republic', + country_de: 'Germany', + country_dj: 'Djibouti', + country_dk: 'Denmark', + country_do: 'Dominican Republic', + country_dz: 'Algeria', + country_ec: 'Ecuador', + country_ee: 'Estonia', + country_eg: 'Egypt', + country_es: 'Spain', + country_et: 'Ethiopia', + country_fi: 'Finland', + country_fo: 'Faroe Islands', + country_fr: 'France', + country_ga: 'Gabon', + country_gb: 'United Kingdom', + country_ge: 'Georgia', + country_gh: 'Ghana', + country_gl: 'Greenland', + country_gp: 'Guadeloupe', + country_gr: 'Greece', + country_gt: 'Guatemala', + country_hk: 'Hong Kong', + country_hr: 'Croatia', + country_ht: 'Haiti', + country_hu: 'Hungary', + country_id: 'Indonesia', + country_ie: 'Ireland', + country_il: 'Israel', + country_in: 'India', + country_iq: 'Iraq', + country_ir: 'Iran', + country_is: 'Iceland', + country_it: 'Italy', + country_jm: 'Jamaica', + country_jo: 'Jordan', + country_jp: 'Japan', + country_ke: 'Kenya', + country_kg: 'Kyrgyzstan', + country_kh: 'Cambodia', + country_kp: 'North Korea', + country_kr: 'South Korea', + country_kz: 'Kazakhstan', + country_kw: 'Kuwait', + country_la: 'Laos', + country_lb: 'Lebanon', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Liberia', + country_lt: 'Lithuania', + country_lu: 'Luxembourg', + country_lv: 'Latvia', + country_ly: 'Libya', + country_ma: 'Morocco', + country_mc: 'Monaco', + country_md: 'Moldova', + country_me: 'Montenegro', + country_mk: 'Macedonia', + country_mm: 'Myanmar', + country_mn: 'Mongolia', + country_mo: 'Macau', + country_mt: 'Malta', + country_mu: 'Mauritius', + country_mv: 'Maldives', + country_mw: 'Malawi', + country_mx: 'Mexico', + country_my: 'Malaysia', + country_mz: 'Mozambique', + country_na: 'Namibia', + country_ne: 'Niger', + country_ng: 'Nigeria', + country_ni: 'Nicaragua', + country_nl: 'Netherlands', + country_no: 'Norway', + country_np: 'Nepal', + country_nz: 'New Zealand', + country_om: 'Oman', + country_pa: 'Panama', + country_pe: 'Peru', + country_pg: 'Papua New Guinea', + country_ph: 'Philippines', + country_pk: 'Pakistan', + country_pl: 'Poland', + country_pr: 'Puerto Rico', + country_ps: 'Palestinian Territory', + country_pt: 'Portugal', + country_py: 'Paraguay', + country_qa: 'Qatar', + country_ro: 'Romania', + country_rs: 'Serbia', + country_ru: 'Russia', + country_rw: 'Rwanda', + country_sa: 'Saudi Arabia', + country_sd: 'Sudan', + country_se: 'Sweden', + country_sg: 'Singapore', + country_si: 'Slovenia', + country_sk: 'Slovakia', + country_sn: 'Senegal', + country_su: 'USSR', + country_sv: 'El Salvador', + country_sy: 'Syria', + country_th: 'Thailand', + country_tj: 'Tajikistan', + country_tm: 'Turkmenistan', + country_tn: 'Tunisia', + country_tr: 'Turkey', + country_tw: 'Taiwan', + country_tz: 'Tanzania', + country_ua: 'Ukraine', + country_ug: 'Uganda', + country_us: 'USA', + country_uy: 'Uruguay', + country_uz: 'Uzbekistan', + country_ve: 'Venezuela', + country_vn: 'Viet Nam', + country_xk: 'Kosovo', + country_ws: 'Samoa', + country_ye: 'Yemen', + country_yu: 'Yugoslavia', + country_za: 'South Africa', + country_zm: 'Zambia', + country_zw: 'Zimbabwe', + filter_clarify: 'Clarify', + filter_clarify_two: 'Refine Search', + filter_set_name: 'Specify title', + filter_sorted: 'Sort', + filter_filtred: 'Filter', + filter_any: 'Any', + filter_combinations: 'Combinations', + filter_alt_names: 'Other names', + filter_rating_from: 'from', + filter_rating_to: 'to', + filter_lang_af: 'Afrikaans', + filter_lang_ar: 'Arabic', + filter_lang_az: 'Azerbaijani', + filter_lang_ba: 'Bashkir', + filter_lang_be: 'Belarusian', + filter_lang_bg: 'Bulgarian', + filter_lang_bn: 'Bengali', + filter_lang_bs: 'Bosnian', + filter_lang_ca: 'Catalan', + filter_lang_ce: 'Chechen', + filter_lang_cs: 'Czech', + filter_lang_da: 'Danish', + filter_lang_de: 'German', + filter_lang_el: 'Greek', + filter_lang_en: 'English', + filter_lang_es: 'Spanish', + filter_lang_et: 'Estonian', + filter_lang_fa: 'Persian', + filter_lang_fi: 'Finnish', + filter_lang_fr: 'French', + filter_lang_ga: 'Irish', + filter_lang_gl: 'Galician', + filter_lang_gn: 'Guarani', + filter_lang_he: 'Hebrew', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Croatian', + filter_lang_hu: 'Hungarian', + filter_lang_hy: 'Armenian', + filter_lang_id: 'Indonesian', + filter_lang_is: 'Icelandic', + filter_lang_it: 'Italian', + filter_lang_ja: 'Japanese', + filter_lang_ka: 'Georgian', + filter_lang_kk: 'Kazakh', + filter_lang_ko: 'Korean', + filter_lang_ks: 'Kashmiri', + filter_lang_ku: 'Kurdish', + filter_lang_ky: 'Kirghiz', + filter_lang_lt: 'Lithuanian', + filter_lang_lv: 'Latvian', + filter_lang_mi: 'Maori', + filter_lang_mk: 'Macedonian', + filter_lang_mn: 'Mongolian', + filter_lang_mt: 'Maltese', + filter_lang_ne: 'Nepali', + filter_lang_nl: 'Dutch (Nederlands)', + filter_lang_no: 'Norwegian', + filter_lang_pa: 'Punjabi', + filter_lang_pl: 'Polish', + filter_lang_ps: 'Pushto', + filter_lang_pt: 'Portuguese', + filter_lang_ro: 'Romanian', + filter_lang_ru: 'Russian', + filter_lang_si: 'Sinhalese', + filter_lang_sk: 'Slovak', + filter_lang_sl: 'Slovenian', + filter_lang_sm: 'Samoan', + filter_lang_so: 'Somali', + filter_lang_sq: 'Albanian', + filter_lang_sr: 'Serbian', + filter_lang_sv: 'Swedish', + filter_lang_sw: 'Swahili', + filter_lang_ta: 'Tamil', + filter_lang_tg: 'Tajik', + filter_lang_th: 'Thai', + filter_lang_tk: 'Turkmen', + filter_lang_tr: 'Turkish', + filter_lang_tt: 'Tatar', + filter_lang_ur: 'Urdu', + filter_lang_uk: 'Ukrainian', + filter_lang_uz: 'Uzbek', + filter_lang_vi: 'Vietnamese', + filter_lang_yi: 'Yiddish', + filter_lang_zh: 'Chinese', + filter_genre_ac: 'Action', + filter_genre_ad: 'Adventures', + filter_genre_mv: 'Cartoon', + filter_genre_cm: 'Comedy', + filter_genre_cr: 'Crime', + filter_genre_dc: 'Documentary', + filter_genre_dr: 'Drama', + filter_genre_fm: 'Family', + filter_genre_fe: 'Fantasy', + filter_genre_hi: 'Story', + filter_genre_ho: 'Horror', + filter_genre_mu: 'Music', + filter_genre_de: 'Detective', + filter_genre_md: 'Melodrama', + filter_genre_fa: 'Fiction', + filter_genre_tv: 'TV film', + filter_genre_tr: 'Thriller', + filter_genre_mi: 'Military', + filter_genre_ve: 'Western', + filter_genre_aa: 'Action & Adventure', + filter_genre_ch: 'Children\'s', + filter_genre_nw: 'News', + filter_genre_rs: 'Reality show', + filter_genre_hf: 'Sci-Fi and Fantasy', + filter_genre_op: 'Soap opera', + filter_genre_tc: 'Talk show', + filter_genre_mp: 'War and Politics', + empty_title: 'Empty', + empty_text: 'Nothing found for your filter, please refine your filter.', + empty_title_two: 'It\'s empty here', + empty_text_two: 'The list is currently empty.', + menu_main: 'Home', + menu_movies: 'Movies', + menu_tv: 'Series', + menu_catalog: 'Catalog', + menu_filter: 'Filter', + menu_collections: 'Collections', + menu_relises: 'Releases', + menu_anime: 'Anime', + menu_bookmark: 'Bookmarks', + menu_like: 'Like', + menu_time: 'Later', + menu_history: 'History', + menu_timeline: 'Schedule', + menu_torrents: 'Torrents', + menu_settings: 'Settings', + menu_about: 'Information', + menu_console: 'Console', + menu_multmovie: 'Cartoons', + menu_multtv: 'Animated series', + plugins_catalog_work: 'Working plugins', + plugins_catalog_work_descr: 'Plugins that work exactly in the lamp.', + plugins_catalog_popular: 'Popular plugins among users', + plugins_catalog_popular_descr: 'Installation from unknown sources may cause the application to work incorrectly.', + plugins_online: 'View online', + plugins_check_fail: 'Failed to test the functionality of the plugin. However, this does not mean that the plugin does not work. Reload the application to see if the plugin is loading.', + plugins_need_reload: 'To apply the plugin, you need to restart the application', + plugins_install: 'Install', + plugins_install_ready: 'This plugin is already installed.', + plugins_installed: 'Installations', + plugins_load_from: 'Loaded from CUB', + plugins_ok_for_check: 'Click (OK) to test the plugin', + plugins_no_loaded: 'When loading the application, some plugins could not be loaded', + time_viewed: 'Viewed', + time_from: 'from', + time_reset: 'Reset timecode', + settings_clear_cache: 'Cache and data cleared', + settings_user_links: 'Custom Link', + settings_for_local: 'For local TorrServer', + settings_add: 'Add', + settings_remove: 'Delete', + settings_this_value: 'present value', + settings_added: 'Added', + settings_removed: 'Removed', + settings_param_player_inner: 'Lampa', + settings_param_player_outside: 'External', + settings_param_player_inner_tvos: 'Internal', + settings_param_yes: 'Yes', + settings_param_no: 'No', + settings_param_interface_size_small: 'Smaller', + settings_param_interface_size_normal: 'Normal', + settings_param_interface_size_bigger: 'More', + settings_param_poster_quality_low: 'Low', + settings_param_poster_quality_average: 'Average', + settings_param_poster_quality_high: 'High', + settings_param_parse_directly: 'Directly', + settings_param_parse_api: 'Through the website API', + settings_param_background_complex: 'Complex', + settings_param_background_simple: 'Simple', + settings_param_background_image: 'Picture', + settings_param_link_use_one: 'Main', + settings_param_link_use_two: 'Additional', + settings_param_link_use_both: 'Both', + settings_param_subtitles_size_small: 'small', + settings_param_subtitles_size_normal: 'Ordinary', + settings_param_subtitles_size_bigger: 'Large', + settings_param_screensaver_nature: 'Nature', + settings_param_torrent_lang_orig: 'Original', + settings_param_torrent_lang_ru: 'Russian', + settings_param_player_timecode_again: 'Start over', + settings_param_player_timecode_continue: 'Proceed', + settings_param_player_timecode_ask: 'To ask', + settings_param_player_scale_method: 'Calculate', + settings_param_player_hls_app: 'Systemic', + settings_param_player_hls_js: 'Program', + settings_param_card_view_load: 'Upload', + settings_param_card_view_all: 'Show all', + settings_param_navigation_remote: 'Remote controller', + settings_param_navigation_mouse: 'Remote control with mouse', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: 'Systemic', + helper_keyboard: 'After entering the value, press the "Back" button to save', + helper_torrents: 'Hold down the (OK) key to bring up the context menu', + helper_cleared: 'Success, tooltips will be shown again.', + helper_torrents_view: 'Hold down the (OK) key to reset the timecode and display the menu', + fav_sync_title: 'Bookmark sync', + fav_sync_text: 'Your favorite bookmarks with you. Connect synchronization and view on any device.

    To do this, register on the site {site}, create a profile and log in to the application.', + fav_sync_site: 'Website', + fav_remove_title: 'Remove from history', + fav_remove_descr: 'Delete selected card', + fav_clear_title: 'Clear the history', + fav_clear_descr: 'Delete all cards from history', + fav_clear_label_title: 'Clear labels', + fav_clear_label_descr: 'Clear View Tags', + fav_clear_time_title: 'Clear Timecodes', + fav_clear_time_descr: 'Clear all timecodes', + fav_label_cleared: 'Marks cleared', + fav_time_cleared: 'Timecodes cleared', + timetable_empty: 'This section will display the release dates of new episodes.', + player_quality: 'Quality', + player_flow: 'Flow', + player_tracks: 'Audio tracks', + player_disabled: 'Disabled', + player_unknown: 'Unknown', + player_subs: 'Subtitles', + player_size_default_title: 'Default', + player_size_default_descr: 'Default video size', + player_size_cover_title: 'Expand', + player_size_cover_descr: 'Expands video to full screen', + player_size_fill_title: 'Fill', + player_size_fill_descr: 'Fit video to full screen', + player_size_s115_title: 'Zoom 115%', + player_size_s115_descr: 'Enlarge video by 115%', + player_size_s130_title: 'Zoom 130%', + player_size_s130_descr: 'Enlarge video by 130%', + player_size_v115_title: 'Vertical 115%', + player_size_v115_descr: 'Enlarge video by 115%', + player_size_v130_title: 'Vertical 130%', + player_size_v130_descr: 'Enlarge video by 130%', + player_video_size: 'Video size', + player_playlist: 'Playlist', + player_error_one: 'Failed to decode video', + player_error_two: 'Video not found or corrupted', + player_start_from: 'Continue browsing from', + player_not_found: 'Player not found', + player_lauch: 'Launch player', + player_speed_default_title: 'Plain', + player_speed_two_descr: 'Play without sound', + player_video_speed: 'Playback speed', + player_share_title: 'Share', + player_share_descr: 'Play this video on another device', + player_normalization_power_title: 'Normalization power', + player_normalization_smooth_title: 'Normalization speed', + player_normalization_step_low: 'Low', + player_normalization_step_medium: 'Average', + player_normalization_step_hight: 'High', + player_youtube_no_played: 'Sorry, this video is not available in your region and may have been blocked or removed.', + player_youtube_start_play: 'To start playing the video, click the "Play" button.', + broadcast_open: 'Open card on another device', + broadcast_play: 'Choose the device to watch on', + card_new_episode: 'New series', + card_book_remove: 'Remove from bookmarks', + card_book_add: 'To bookmarks', + card_book_descr: 'Look in the menu (Bookmarks)', + card_like_remove: 'Remove from favorites', + card_like_add: 'Like', + card_like_descr: 'Look at the menu (Like)', + card_wath_remove: 'Remove from expected', + card_wath_add: 'Watch Later', + card_wath_descr: 'See the menu (Later)', + card_history_remove: 'Remove from history', + card_history_add: 'Into history', + card_history_descr: 'Look in the menu (History)', + keyboard_listen: 'Speak, I\'m listening...', + keyboard_nomic: 'No microphone access', + notice_new_quality: 'New quality available', + notice_quality: 'Quality', + notice_new_episode: 'New series', + notice_none: 'You don\'t have any notifications yet, register at {site} to follow new episodes and releases.', + notice_in_quality: 'As', + notice_none_account: 'You don\'t have any notifications yet, bookmark the series and wait for notifications of new episodes.', + notice_none_system: 'You currently have no notifications. We will be sure to notify you when new notifications become available.', + copy_link: 'Copy video link', + copy_secuses: 'Link copied to clipboard', + copy_error: 'Error copying link', + account_sync_to_profile: 'All bookmarks will be moved to the profile', + account_sync_secuses: 'All bookmarks have been successfully transferred', + account_profiles: 'Profiles', + account_profiles_empty: 'Failed to get list of profiles', + account_authorized: 'Authorized', + account_logged_in: 'You are logged in', + account_login_failed: 'Login failed', + account_login_wait: 'Waiting for login', + account_profile_main: 'General', + account_export_secuses: 'Export completed successfully', + account_export_fail: 'Export error', + account_import_secuses: 'Import completed successfully', + account_import_fail: 'Import error', + account_imported: 'imported', + account_reload_after: 'reboot after 5 sec.', + account_create: 'Discover more opportunities with a CUB account. Register at and get access to sync your bookmarks, timecodes and other CUB account features.', + account_premium_more: 'Learn more about CUB Premium', + account_limited: 'You have reached the maximum limit. Increase the limit with a CUB Premium account. Learn more at ', + account_code_enter: 'Enter a six-digit code', + account_code_error: 'Perhaps you entered an incorrect or outdated code', + account_code_wrong: 'Perhaps you entered an incorrect format', + account_code_where: 'Go to the website and enter the code provided there.', + account_code_input: 'Enter code', + settings_cub_signin_button: 'Sign in', + network_noconnect: 'No network connection', + network_404: 'The requested page was not found. [404]', + network_401: 'Authorization failed', + network_500: 'Internal Server Error. [500]', + network_parsererror: 'The requested JSON parsing failed.', + network_timeout: 'Request timed out.', + network_abort: 'The request has been aborted.', + network_error: 'Unknown error', + size_zero: '0 Byte', + size_byte: 'Byte', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'TB', + size_pp: 'PB', + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + month_1: 'January', + month_2: 'February', + month_3: 'March', + month_4: 'April', + month_5: 'May', + month_6: 'June', + month_7: 'July', + month_8: 'August', + month_9: 'September', + month_10: 'October', + month_11: 'November', + month_12: 'December', + day_1: 'Monday', + day_2: 'Tuesday', + day_3: 'Wednesday', + day_4: 'Thursday', + day_5: 'Friday', + day_6: 'Saturday', + day_7: 'Sunday', + month_1_e: 'January', + month_2_e: 'February', + month_3_e: 'March', + month_4_e: 'April', + month_5_e: 'May', + month_6_e: 'June', + month_7_e: 'July', + month_8_e: 'August', + month_9_e: 'September', + month_10_e: 'October', + month_11_e: 'November', + month_12_e: 'December', + week_1: 'Mon', + week_2: 'Tue', + week_3: 'Wed', + week_4: 'Thu', + week_5: 'Fri', + week_6: 'Sat', + week_7: 'Sun', + extensions_enable: 'Turn on', + extensions_disable: 'Disable', + extensions_check: 'Check status', + extensions_install: 'Install', + extensions_info: 'Information', + extensions_edit: 'Edit', + extensions_change_name: 'Change name', + extensions_change_link: 'Change link', + extensions_remove: 'Delete', + extensions_set_name: 'Enter plugin name', + extensions_set_url: 'Enter plugin url', + extensions_ready: 'This plugin is already installed', + extensions_no_info: 'Without information', + extensions_no_name: 'Untitled', + extensions_worked: 'Worker', + extensions_no_plugin: 'Plugin not verified', + extensions_add: 'Add Plugin', + extensions_from_memory: 'Installed in memory', + extensions_from_cub: 'Installed from CUB', + extensions_from_popular: 'Popular plugins', + extensions_from_lib: 'Plugin Library', + extensions_from_connected: 'Connected plugins', + settings_webos_launcher: 'Application launch', + settings_webos_launcher_add_device: 'Install as starter app', + settings_webos_launcher_remove_device: 'Remove from starter spplications', + player_normalization: 'Normalization', + change_source_on_cub: 'Change source to CUB', + settings_param_jackett_interview_all: 'All', + settings_param_jackett_interview_healthy: 'Available only', + settings_parser_jackett_interview: 'Poll trackers', + title_ongoing: 'Ongoings', + title_pgrating: 'Age limit', + settings_interface_card_interfice: 'Card interface', + settings_interface_card_poster: 'Show poster', + title_card: 'Card', + settings_param_card_interface_old: 'Old', + settings_param_card_interface_new: 'New', + title_seasons: 'Seasons', + title_episodes: 'Episodes', + title_rewiews: 'Reviews', + settings_interface_glass: 'Glass', + settings_interface_glass_descr: 'Show interface in glassy style', + settings_interface_black_style: 'Black style', + plugins_remove: 'Remove plugins', + plugins_add_success: 'Plugin connected successfully', + settings_reset: 'Reset', + title_channel: 'Channel', + input_detection_touch: 'Want to switch to touch control?', + input_detection_mouse: 'Want to switch to mouse control?', + input_detection_remote: 'Want to switch to remote control?', + settings_interface_hide_outside_the_screen: 'Hide cards off screen', + settings_interface_hide_outside_the_screen_descr: 'This will speed up UI rendering and improve performance', + https_text: 'You are using the HTTPS protocol, in this protocol the lamp does not work correctly. For the correct operation of the lamp, use the address with the HTTP protocol', + extensions_hpu_best: 'Popular', + extensions_hpu_recomend: 'Recommended', + extensions_hpu_theme: 'Themes', + extensions_hpu_screensaver: 'Screensaver', + extensions_hpu_video: 'Video', + extensions_hpu_control: 'Control', + extensions_hpu_other: 'Miscellaneous', + extensions_hpu_: 'Other', + title_author: 'Author', + title_buffer: 'Buffer', + settings_rest_screensaver_time: 'After how many minutes to start the screensaver', + time_h: 'h.', + time_m: 'm.', + time_s: 's.', + settings_param_glass_easy: 'Transparent', + settings_param_glass_medium: 'Semitransparent', + settings_param_glass_blacked: 'Blacked out', + settings_interface_glass_opacity: 'Glass transparency', + torrent_error_check_no_auth: 'The server responded to the request, but the authorization failed', + settings_interface_card_cover: 'Show cover', + title_upcoming_episodes: 'Upcoming episode releases', + title_recent_episodes: 'Recent episode releases', + settings_rest_cache_images: 'Image cache', + settings_rest_cache_images_descr: 'Cache posters and backgrounds to local storage', + settings_player_rewind_title: 'Rewind', + settings_player_rewind_descr: 'Rewind interval in seconds', + settings_interface_card_reactions: 'Show reactions', + title_look: 'Looking', + title_scheduled: 'Scheduled', + title_viewed: 'Viewed', + title_thrown: 'Thrown', + title_reactions: 'Reactions', + reactions_none: 'No reactions', + reactions_fire: 'Great', + reactions_nice: 'Nice', + reactions_think: 'Interesting', + reactions_bore: 'Boring', + reactions_shit: 'Bad', + reactions_ready: 'You have already left a reaction', + settings_player_launch_trailers: 'Trailer Player', + title_continued: 'To be continued', + title_language_short: 'Language', + speedtest_connect: 'connection', + speedtest_test: 'testing', + speedtest_ready: 'ready', + speedtest_button: 'Test Speed', + termsofuse_t_01: 'Terms of Use', + termsofuse_t_02: 'Lampa is a convenient tool for exploring the latest news in the film industry, including movies, TV shows, cartoons, and other information. To obtain information about movies, an open-source website, themoviedb.org, is used.', + termsofuse_t_03: 'Content', + termsofuse_t_04: 'Lampa utilizes the API (application programming interface) from the themoviedb.org catalog to retrieve information about movies and TV shows, as well as to view associated media files such as posters, trailers, and more.', + termsofuse_t_05: 'The themoviedb.org API allows the Lampa application to access a database of movies and TV shows, providing the ability to search and view media file information.', + termsofuse_t_06: 'The interaction between the Lampa application and themoviedb.org occurs through API requests that are sent from the Lampa application to the themoviedb.org servers to obtain information and media files. Themoviedb.org processes the requests and sends the requested data back to the Lampa application.', + termsofuse_t_07: 'Thus, thanks to the use of the themoviedb.org API, the Lampa application provides users with access to an extensive database of movies and TV shows, while complying with the terms of use and restrictions set by the rights holder.', + termsofuse_t_08: 'Extensions', + termsofuse_t_09: 'Extensions are a powerful tool provided for the Lampa application, allowing users to enhance its capabilities, add additional functionality, and modify content according to their needs.', + termsofuse_t_10: 'However, it should be noted that users install extensions at their own risk. All consequences arising from the use of extensions are the responsibility of the user. Users are advised to exercise caution when installing and using extensions, carefully evaluating their reliability and security.', + termsofuse_t_11: 'Copyright Infringements', + termsofuse_t_12: 'If you discover any copyright infringement in the Lampa application, you should contact the developers of the Lampa application. You can use the contacts provided in the Lampa application to do so. However, it is important to note that the Lampa application uses the API from the themoviedb.org catalog, which provides open access to information about movies and TV shows. This means that the information displayed in the Lampa application is publicly available and does not infringe on copyright.', + termsofuse_t_13: 'If you believe that the Lampa application still contains content that violates your copyright, you can contact the rights holder of that content and request its removal from the themoviedb.org website. In turn, the Lampa application can remove content upon receiving a proper copyright infringement notification.', + settings_rest_protocol_use: 'Secure connection', + settings_rest_protocol_descr: 'Use HTTPS protocol', + install_app_apk_title: 'How to install Lampa on Android', + install_app_apk_text: 'We noticed that you use MediaStationX to run Lampa on Android. We recommend installing Lampa as an APK app. This will ensure more stable operation and access to all the app\'s features.

    Go to the Telegram group to download the latest APK and installation instructions.', + install_app_apk_qr: 'Scan the QR code to download the Lampa APK', + copy_link_buffer: 'Copy link', + tv_status_returning_series: 'Returning series', + tv_status_planned: 'Planned', + tv_status_in_production: 'In Production', + tv_status_ended: 'Ended', + tv_status_canceled: 'Canceled', + tv_status_pilot: 'Pilot', + tv_status_released: 'Released', + tv_status_rumored: 'Rumored', + tv_status_post_production: 'Post Production', + title_last_year: 'Last year', + title_reset: 'Reboot', + back_to_card: 'Return to card', + premiere_author_recomend_1: 'Order pizza and get ready for some excitement.', + premiere_author_recomend_2: 'The party is just getting started.', + premiere_author_recomend_3: 'Get ready for some adrenaline.', + premiere_author_recomend_4: 'Ready for an unforgettable evening?', + premiere_author_recomend_5: 'I recommend watching it.', + premiere_title: 'Premiere', + settings_clear_cache_only: 'Cache Cleared', + settings_rest_cache_only: 'Only Cache', + settings_rest_cache_only_descr: 'Basic settings will be preserved', + settings_rest_cache_all: 'Cache and Data', + settings_rest_cache_all_descr: 'All settings and data will be cleared', + settings_rest_cache_calculate: 'How much memory is left', + title_left: 'Left', + account_export_fail_500: 'Unknown error', + account_export_fail_610: 'You have exceeded the limit for today', + account_export_fail_200: 'Database error, please try again later', + account_export_fail_600: 'Error, failed to upload the file', + account_export_fail_620: 'Error, file not transmitted', + title_parental_control: 'Parental Control', + settings_parental_control_param_time_always: 'Always', + settings_parental_control_param_time_once: 'Once', + settings_parental_control_param_time_10: 'In 10 minutes', + settings_parental_control_param_time_20: 'In 20 minutes', + settings_parental_control_param_time_30: 'In 30 minutes', + settings_parental_control_param_time_60: 'In 1 hour', + settings_parental_control_param_time_120: 'In 2 hours', + settings_parental_control_change_pin: 'Change PIN', + settings_parental_control_demand_title: 'When to Prompt', + settings_parental_control_demand_descr: 'After how much time to prompt for the PIN', + settings_parental_control_enabled: 'Enabled', + settings_parental_control_disabled: 'Disabled', + parental_control_input_new_code: 'Enter new PIN code', + parental_control_confirm_new_code: 'Confirm PIN code', + parental_control_no_match_code: 'PIN code does not match the previous code', + parental_control_input_code: 'Enter PIN code', + parental_control_input_error: 'You entered an incorrect PIN code', + title_worth_rewatch: 'Worth a rewatch', + ad_disable: 'By subscribing to CUB Premium, you will forget about advertising.', + ad_after: 'Advertising via', + ad: 'Advertising', + ad_skip: 'Skip', + ad_continue_after: 'Viewing will start in', + settings_parser_prowlarr_link_descr: 'Provide a link to the Prowlarr server', + settings_parser_prowlarr_key_descr: 'Located in the Prowlarr settings tab in the general category', + settings_player_torrent_type: 'Player type for torrents', + settings_player_torrent_type_descr: 'Which player to play torrents', + full_crew: 'More', + full_editing: 'Editing', + full_creator: 'Creator', + player_normalization_step_none: 'Zero', + settings_cub_backup_export_descr: 'Save settings to the cloud', + settings_cub_backup_import_descr: 'Restore settings from the cloud', + settings_interface_sound: 'System sounds', + settings_interface_sound_play: 'Transitions', + settings_interface_sound_level: 'Volume level', + settings_interface_advanced_animation: 'Advanced animation', + confirm_open_player: 'Another device is requesting access to the player. Do you want to play the video?', + pincode_use_remote: 'Use the remote control to enter the code by pressing the arrows to select the desired number.', + pincode_use_toggle: 'Press and hold the OK button to change the layout.', + settings_parental_control_where: 'Where to request a PIN code', + title_fire: 'Fire!', + title_top_100: 'Top 100', + player_normalization_type_title: 'Normalization Type', + player_normalization_type_all: 'All', + player_normalization_type_up: 'Only Increase', + player_normalization_type_down: 'Only Decrease', + storage_quota_exceeded: 'Storage quota exceeded. Clear cache and try again.', + settings_cub_domain: 'Primary domain', + title_ai_assistant: 'AI Assistant', + title_facts: 'Interesting Facts', + ai_search_start_typing: 'Ask the AI Assistant what movies you want to find. For example: "Movies about space"', + ai_search_limit: 'Request limit exceeded. Please try again later. With a CUB Premium subscription, limits will be increased, and you won’t have to wait!', + ai_subscribe_title: 'Unlock More Opportunities with AI', + ai_subscribe_descr: 'Subscribe to CUB Premium and increase the number of requests to AI. Together with AI, we’ll find the best movies for you.', + dmca_title: 'Content blocked', + dmca_descr: 'This material is not available for viewing. It has been blocked at the request of the copyright holder in accordance with copyright law.', + loading_progress_step_0: 'Preparation', + loading_progress_step_1: 'Loading languages', + loading_progress_step_2: 'Searching for mirrors', + loading_progress_step_3: 'Preparing extensions', + loading_progress_step_4: 'Almost there', + loading_progress_step_5: 'Coming soon', + install_extension_rule_1: 'Installing a third-party plugin', + install_extension_rule_2: 'Plugins are created by independent developers, and LAMPA does not verify their content. By installing them, you agree that:', + install_extension_rule_3: '- Some plugins may request access to your data or work with unverified sources.', + install_extension_rule_4: '- If the plugin you install violates copyright or other laws, you are fully responsible for its use.', + install_extension_rule_5: '- Install only plugins from trusted sources. If you have any doubts about the security or legality of a plugin, it is better to refrain from installing it.', + install_extension_rule_6: 'LAMPA does not support or endorse plugins related to pirated content.', + install_extension_rule_7: 'By proceeding, you confirm that you understand these risks.', + ad_plugin: 'Advertisement from the plugin', + terminal_title: 'Terminal', + terminal_no_access: 'No access', + terminal_confirm: 'Allow', + terminal_deny: 'Deny', + terminal_update: 'Update', + terminal_code: 'Access code', + terminal_text: 'You are requesting access to the terminal. Developers may gain access to your device and control it. This can be useful for diagnostics and troubleshooting, but may also pose a security risk. Please make sure you trust the developers before granting access.

    You can disable this feature at any time by clicking the "Deny" button.', + title_anons: 'Announcement', + title_developer: 'Developer', + title_navigation: 'Navigation', + title_page: 'Page', + title_person_about: 'About', + account_qr_premium: 'Scan the QR code to learn more about CUB Premium', + account_qr_code: 'Scan the QR code to receive a device linking code', + account_qr_create: 'Scan the QR code to create an account', + account_add_device_title: 'Add Device', + account_add_device_text: 'Go to to get a code for adding a device.', + account_none_title: 'Don’t have an account yet?', + account_none_include_1: 'Bookmarks and watch history are stored in the cloud', + account_none_include_2: 'Sync between devices', + account_none_include_3: 'Notifications about new episodes and releases', + account_none_include_4: 'Create multiple profiles under one account', + account_premium_include_1: 'Increased number of bookmarks', + account_premium_include_2: 'Extended watch history', + account_premium_include_3: 'More timecodes available', + account_premium_include_4: 'Number of profiles per account', + empty_subscribes_title: 'Your translation subscriptions', + empty_subscribes_text: 'Just subscribe to your favorite translation and we’ll notify you when a new episode is released.', + empty_history_title: 'Your watch history', + empty_history_text: 'Your watch history will appear here.', + empty_bookmark_title: 'Your favorites', + empty_bookmark_text: 'Add movies and TV shows you like to favorites to quickly find them in this section.', + empty_mytorrents_title: 'Your torrents', + empty_mytorrents_text: 'Torrents you’ve downloaded via TorServer will appear here.', + developer_param_enabled: 'Developer Mode', + developer_param_nopremium: 'Disable CUB Premium', + developer_param_nodemo: 'Disable Demo Mode', + developer_param_ads: 'Show Ads', + developer_param_fps: 'Show FPS', + developer_trigger_help_1: 'Almost guessed it :)', + developer_trigger_help_2: 'Just a little more :)', + developer_trigger_help_3: 'Are you sure you want to enter Developer Mode?', + developer_trigger_help_4: 'Developer Mode activated', + settings_param_navigation_touch: 'Sensor', + account_discuss_add_qr: 'Scan the QR code', + account_discuss_add_title: 'Want to leave a comment?', + account_discuss_add_text: 'Scan the QR code to go to the app and add a comment on this movie or TV series.

    - Take your phone or tablet
    - Open the camera
    - Point to the QR code
    - Follow the link that appears on the screen', + account_discuss_added: 'Thank you for your comment!', + account_discuss_added_ready: 'You have already left a comment on this movie or TV series.', + remote_helper_long: 'Hold the (OK) button to open the menu', + account_premium: 'Unlock new horizons with a CUB Premium account! Enjoy increased limits and enhanced service functionality. Visit and learn more about the benefits of a premium account.', + player_segments_title: 'Segments', + player_segments_descr: 'Skip intro and other parts of the video', + player_segments_ad_title: 'Ads', + player_segments_skip_title: 'Intro and other', + player_segments_value_none: 'Do not skip', + player_segments_value_auto: 'Auto skip', + player_segments_value_user: 'Custom', + player_segments_skiped: 'Segment skipped', + player_segments_skip_now: 'Skip', + player_segments_skip_in: 'Skip in', + player_segments_skip_intro: 'Skip intro', + player_segments_next: 'Next episode', + player_segments_next_in: 'Next episode in', + subscribe_info: 'In the Subscriptions section, you\'ll see all your translation subscriptions. You\'ll receive a notification when a new episode with your selected translation is released.', + no_watch_history: 'No browsing history', + settings_request_caching_use: 'Request Caching', + settings_request_caching_descr: 'Cache API requests to speed up the interface and reduce data usage.', + account_profile_child: 'Child', + account_profile_add: 'Add profile', + account_profile_name: 'Profile name', + account_profile_created: 'Profile successfully created', + account_profile_limited: 'The maximum profile limit has been reached: {count}', + account_profile_info: 'You can manage profiles in your account settings. To do this, go to ', + player_youtube_no_support: 'Your device does not support YouTube video playback, please check your internet connection.', + title_channels: 'Channels', + title_best_of_2000: 'Golden 2000s', + title_best_of_2010: 'Hits of the 2010s', + title_best_of_2015: 'Modern Classics', + title_comedy_of_2000: 'Laughter of the 2000s', + title_comedy_of_2010: 'Humor of the 2010s', + title_comedy_of_2015: 'Modern Comedies', + filter_keyword_sequel: 'Sequel', + filter_keyword_based_comic: 'Based on Comics', + filter_keyword_space: 'Space', + filter_keyword_survival: 'Survival', + filter_keyword_zombie: 'Zombie', + filter_keyword_school: 'School', + filter_keyword_revenge: 'Revenge', + filter_keyword_detective: 'Detective', + filter_keyword_robots: 'Robots', + filter_keyword_vampires: 'Vampires', + filter_keyword_aliens: 'Aliens', + filter_keyword_police: 'Police', + filter_keyword_reincarnation: 'Reincarnation', + filter_keyword_spy: 'Spy', + filter_keyword_disaster: 'Catastrophe', + filter_keyword_christmas: 'Christmas', + dmca_title_lgbt: 'Content Restricted', + dmca_descr_lgbt: 'Viewing is unavailable in your region as it may contain LGBT content. Such material may be prohibited or restricted in some countries.', + settings_lgbt_content_block: 'Block LGBT content', + // todo: + adult_content_title: 'Adult Content', + adult_content_text_warning: 'Content may contain adult material that may be inappropriate for some viewers.', + adult_content_text_modal: 'This film or series is marked as containing adult content. You must be 18 years of age or older to view this material. Please confirm that you are of legal age to continue viewing.', + adult_content_confirm: 'I am 18 or older', + adult_content_deny: 'I am under 18', + inner_player_disclaimer_title: 'Player Disclaimer', + inner_player_disclaimer_text: 'I understand that I am launching a player with incomplete support, and I understand that this may cause atypical behavior on the device. It is recommended to switch to tvOS family players or other alternatives.', + inner_player_disclaimer_change_player: 'Change player', + remote_configuration_settings_title: 'Remote Configuration', + remote_configuration_registration_text: 'Remote configuration provides temporary access to your application, another application will be able to install extensions and configure parameters.', + remote_configuration_waite_text: 'You can now pass this code to another application to grant access to settings.', + remote_configuration_open_button: 'Open Access', + remote_configuration_code_life: 'Code is valid', + remote_configuration_notice_nocode: 'Failed to open access', + settings_server_gts: 'Transcoding', + settings_server_gts_descr: 'Automatically convert video to a compatible format when needed.', + settings_server_tracktimecode: 'Enable TrackTimecode', + settings_server_tracktimecode_descr: 'Saves the playback progress of movies and TV shows on the TorrServer. This option must also be enabled in TorrServer for it to work.', + title_metadata: 'Metadata', + title_moods: 'Moods', + title_meta_violence: 'Violence', + title_meta_fear: 'Fear', + title_meta_profanity: 'Profanity', + title_meta_sadness: 'Sadness', + title_meta_sex: 'Sexuality', + player_pip: 'Minimize', + player_volume: 'Volume', + player_time_end: 'Ends at', + player_ai_agent_info: 'Want to know more about the video? Ask the AI assistant and it will provide you with a mood chart, brief plot summary, and highlights.', + player_ai_agent_ask_plot: 'Brief plot', + player_ai_agent_ask_moods: 'Show chart', + player_ai_agent_ask_highlights: 'Highlights', + player_ai_agent_ask: 'Ask', + player_ai_agent_processing: 'Analyzing...', + player_ai_agent_no_data: 'No data to show.', + player_ai_agent_no_analysis: 'Could not analyze the video.', + player_ai_agent_quota: 'Request limit exceeded. Please try again later.', + player_ai_agent_working: 'Still working on it...', + title_meta_humor: 'Humor', + title_meta_tension: 'Tension', + title_meta_romance: 'Romance', + title_meta_pace: 'Pace', + title_meta_importance: 'Key scenes', + title_meta_action: 'Action' + }; + + var langs = {}; + var keys = {}; + var startup = { + uk: ['Підготовка', 'Завантаження мов'], + be: ['Падрыхтоўка', 'Загрузка моў'], + zh: ['准备', '加载语言'], + pt: ['Preparação', 'Carregando idiomas'], + bg: ['Подготовка', 'Зареждане на езици'], + he: ['הכנה', 'טעינת שפות'], + cs: ['Příprava', 'Načítání jazyků'], + ro: ['Inițializare', 'Încărcare limbi'], + fr: ['Préparation', 'Chargement des langues'], + pl: ['Przygotowanie', 'Ładowanie języków'], + es: ['Preparación', 'Cargando idiomas'] + }; + var lang_default = 'ru'; + Object.defineProperty(langs, 'ru', { + get: function get() { + return ru; + } + }); + Object.defineProperty(langs, 'en', { + get: function get() { + return en; + } + }); + + for (var code in meta.languages) { + keys[code] = meta.languages[code].name; + if (!langs[code]) langs[code] = {}; + langs[code].lang_choice_title = meta.languages[code].lang_choice_title; + langs[code].lang_choice_subtitle = meta.languages[code].lang_choice_subtitle; + } + /** + * Перевести + * @param {string} name + * @param {string} custom_code - ru/en/uk... + * @returns + */ + + + function translate(name, custom_code) { + name = name + ''; + var code = custom_code || Storage.get('language', 'ru'); + var result = ''; + if (!langs[code]) code = lang_default; + + if (name.indexOf('#{') >= 0) { + result = name.replace(/#{([a-z_0-9-]+)}/g, function (e, s) { + return langs[code][s] || langs[lang_default][s] || s; + }); + } else { + var _startup$code; + + var step = name === 'loading_progress_step_0' ? 0 : name === 'loading_progress_step_1' ? 1 : null; + result = langs[code][name] || (step !== null ? (_startup$code = startup[code]) === null || _startup$code === void 0 ? void 0 : _startup$code[step] : null) || langs[lang_default][name] || name; + } + + result = result.replace(/{site}/g, object$2.cub_site); + result = result.replace(/{mirror}/g, Utils$1.protocol() + object$2.cub_domain); + return result; + } + /** + * Добавить переводы + * @param {{key_name:{en:string,ru:string}}} data + */ + + + function add$1(data) { + for (var name in data) { + for (var _code in data[name]) { + if (langs[_code]) { + langs[_code][name] = data[name][_code]; + } + } + } + } + /** + * Добавить перевод для кода + * @param {string} code + * @param {{key1:string,key2:string}} data + */ + + + function AddTranslation(code, data) { + if (!langs[code]) langs[code] = {}; + + for (var name in data) { + langs[code][name] = data[name]; + } + } + /** + * Добавить коды + * @param {{code_name:string}} new_codes + */ + + + function addCodes(new_codes) { + for (var i in new_codes) { + keys[i] = new_codes[i]; + langs[i] = {}; + } + } + /** + * Получить список кодов + * @returns {{ru:string,en:string}} + */ + + + function codes() { + return Arrays.clone(keys); + } + + function selected(check_codes) { + return check_codes.indexOf(Storage.get('language', 'ru')) >= 0 ? true : false; + } + + var Lang = { + translate: translate, + add: add$1, + codes: codes, + addCodes: addCodes, + AddTranslation: AddTranslation, + selected: selected + }; + + /** + * Инициализирует основное приложение + * @returns {void} + */ + + function app() { + var app = $('#app').empty(); + var wrap = Template.get('wrap'); + app.append(Template.get('icons_sprite')); + wrap.find('.wrap__left').append(Menu$1.render()); + wrap.find('.wrap__content').append(Activity.render()); + app.append(Background.render()); + app.append(Head.render()); + app.append(wrap); + app.append(Settings.render()); + app.append(Search.render()); + } + + var Render = { + app: app + }; + + var html$7; + var object; + + function init$s() { + html$7 = Template.get('iframe'); + } + + function show$2() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + object = params; + + html$7.find('iframe').attr('src', params.url)[0].onload = function () { + html$7.addClass('iframe--loaded'); + }; + + $('body').append(html$7); + toggle$1(); + } + + function toggle$1() { + Controller.add('iframe', { + toggle: function toggle() {}, + back: close$2 + }); + Controller.toggle('iframe'); + } + + function close$2() { + html$7.removeClass('iframe--loaded'); + html$7.detach(); + html$7.find('iframe').attr('src', ''); + if (object.onBack) object.onBack(); + } + + function render$1() { + return html$7; + } + + var Iframe = { + init: init$s, + show: show$2, + close: close$2, + render: render$1 + }; + + var items = { + App: [], + Errors: [], + Warnings: [] + }; + var original = { + App: [], + Errors: [], + Warnings: [] + }; + var times = 0; + var html$6; + var scroll_tabs; + var scroll_body; + var last_tab; + var console_orig = { + log: console.log, + error: console.error, + warn: console.warn + }; + + function init$r() { + Keypad.listener.follow('keydown', function (e) { + if (e.code == 38 || e.code == 29460) { + var enable = Controller.enabled(); + + if (enable.name == 'head') { + times++; + + if (times > 10) { + Controller.toggle('console'); + } + } else { + times = 0; + } + } + }); + Controller.add('console', { + toggle: function toggle() { + build(); + Controller.toggle('console-tabs'); + }, + back: back + }); + Controller.add('console-tabs', { + toggle: function toggle() { + Controller.collectionSet(scroll_tabs.render()); + Controller.collectionFocus(scroll_tabs.render().find('.console__tab[data-name="' + Utils$1.hash(last_tab) + '"]')[0], scroll_tabs.render()); + }, + down: function down() { + Controller.toggle('console-body'); + }, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + Navigator.move('left'); + }, + back: back + }); + follow(); + } + + function back() { + times = 0; + scroll_tabs.destroy(); + scroll_body.destroy(); + html$6.remove(); + Controller.toggle('head'); + } + + function show$1(name) { + scroll_body.clear(); + scroll_body.reset(); + + if (items[name]) { + items[name].forEach(function (element) { + var item = $(element); + item.on('hover:focus', function (e) { + scroll_body.update($(e.target)); + }); + + if (name == 'Request') { + item.on('hover:enter', function (e) { + var str = item.text(); + var mth = str.match(/error of (.*?) :/); + + if (mth && mth[1]) { + Iframe.show({ + url: mth[1], + onBack: function onBack() { + Controller.toggle('console-body'); + } + }); + } + }); + } + + scroll_body.append(item); + }); + } + + Controller.add('console-body', { + toggle: function toggle() { + Controller.collectionSet(scroll_body.render()); + Controller.collectionFocus(false, scroll_body.render()); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('console-tabs'); + }, + down: function down() { + Navigator.move('down'); + }, + back: back + }); + Controller.toggle('console-body'); + } + + function tab(name, lines) { + var elem = $('
    ' + Utils$1.shortText(name, 10) + ' - ' + lines.length + '
    '); + elem.on('hover:enter', function () { + show$1(name); + last_tab = name; + }).on('hover:focus', function (e) { + scroll_tabs.update($(e.target)); + }); + scroll_tabs.append(elem); + if (!last_tab) last_tab = name; + if (last_tab == name) show$1(name); + } + + function build() { + html$6 = Template.get('console'); + scroll_body = new Scroll({ + over: true, + mask: true + }); + scroll_tabs = new Scroll({ + horizontal: true + }); + + for (var i in items) { + tab(i, items[i]); + } + + html$6.find('.console__tabs').append(HeadBackward(Lang.translate('menu_console'))).append(scroll_tabs.render()); + html$6.find('.console__body').append(scroll_body.render()); + scroll_body.height(html$6.find('.console__tabs')); + $('body').append(html$6); + } + + function add(name, message, message_original) { + if (!items[name]) { + items[name] = []; + original[name] = []; + } + + var where_items = items[name]; + var where_original = original[name]; + var time = Utils$1.parseTime(Date.now()).time_full; + + try { + Arrays.insert(where_items, 0, '
    ' + time + ' - ' + message + '
    '); + Arrays.insert(where_original, 0, { + time: Date.now(), + message: message_original + }); + + if (Storage.get('terminal_access', '') && Socket.terminalAccess()) { + Socket.send('terminal_console', { + name: name, + time: Date.now(), + message: message_original + }); + } + } catch (e) { + Arrays.insert(where_items, 0, '
    ' + time + ' - Failed to print line
    '); + Arrays.insert(where_original, 0, { + time: Date.now(), + message: 'Failed to print line' + }); + } + + if (where_items.length > 50) where_items.pop(); + if (where_original.length > 200) where_original.pop(); + } + + function escapeHtml(text) { + return text.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + } + + function decode(arr) { + if (Arrays.isObject(arr) || Arrays.isArray(arr)) { + try { + arr = JSON.stringify(arr); + } catch (e) { + arr = '[noview]'; + } + } else if (typeof arr === 'string' || typeof arr === 'number' || typeof arr === 'boolean') { + arr = escapeHtml(arr + ''); + } else { + var a = []; + + for (var i in arr) { + a.push(i + ': ' + arr[i]); + } + + arr = JSON.stringify(a); + } + + return arr; + } + + function follow() { + var _get_logger_function = function _get_logger_function(func, color) { + var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; + return function () { + var msgs = []; + var mcon = []; + var orgn = []; + + while (arguments.length) { + var arr = [].shift.call(arguments); + msgs.push(Utils$1.shortText(decode(arr), 600)); + mcon.push(arr); + orgn.push(decode(arr)); + } + + var name = msgs[0]; + + if (msgs.length < 2) { + name = 'Other'; + } else { + // Add color and prefix to lampa console + var spanColor = color || Utils$1.stringToHslColor(msgs[0], 50, 65); + msgs[0] = '' + msgs[0] + ''; // Add brackets to real log + + if (mcon.length > 0) { + mcon[0] = '[' + mcon[0] + ']'; + } + } + + if (prefix == 'ERROR' || prefix == 'WARNING') { + add(prefix == 'ERROR' ? 'Errors' : 'Warnings', msgs.join(' '), orgn); + } + + add(name, msgs.join(' '), orgn); + func.apply(console, mcon); + }; + }; + + var called = { + log: _get_logger_function(console_orig.log, null), + error: _get_logger_function(console_orig.error, 'red', 'ERROR'), + warn: _get_logger_function(console_orig.warn, 'yellow', 'WARNING') + }; + Timer.add(1000, function () { + // Заменяем консоль на свою + console.log = called.log; + console.error = called.error; + console.warn = called.warn; + }); + console.log = called.log; + console.error = called.error; + console.warn = called.warn; + window.addEventListener("error", function (e) { + var stack = (e.error && e.error.stack ? e.error.stack : e.stack || '').split("\n").join('
    '); + var message = typeof e.error == 'string' ? e.error : (e.error || e).message; + var filename = e.filename || (e.error && e.error.fileName ? e.error.fileName : ''); + var noty = []; + message && noty.push('Message: ' + message); + filename && noty.push('In: ' + filename); + stack && noty.push('Stack: ' + stack); + noty = noty.join('

    '); + var welcome = $('.welcome'); + + if (welcome.length) { + welcome.fadeOut(500, function () { + Noty.show(noty, { + time: 8000 + }); + }); + } + + add('Errors', noty, noty.replace(/
    /g, '\n')); + if (!(stack.indexOf('resetTopStyle') >= 0 || stack.indexOf('Blocked a frame') >= 0 || stack.indexOf('global code@http') >= 0)) Noty.show(noty, { + time: 8000 + }); + }); + } + + var Console = { + init: init$r, + "export": function _export() { + return original; + } + }; + + function create$3() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var html = Template.get('files', params.movie); + html.addClass('layer--width'); + + if (params.movie.id) { + html.find('.selector').on('hover:enter', function () { + if (Activity.all().length > 1) { + Activity.back(); + } else { + Activity.push({ + url: params.movie.url, + component: 'full', + id: params.movie.id, + method: params.movie.name ? 'tv' : 'movie', + card: params.movie, + source: params.movie.source + }); + } + }); + } else { + html.find('.selector').removeClass('selector'); + } + + this.render = function () { + return html; + }; + + this.append = function (add) { + html.find('.files__body').append(add); + }; + + this.destroy = function () { + html.remove(); + html = null; + }; + + this.clear = function () { + html.find('.files__body').empty(); + }; + } + + function create$2() { + var html; + + this.create = function () { + html = Template.get('info'); + }; + + this.update = function (data) { + var nofavorite = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var create = ((data.release_date || data.first_air_date || '0000') + '').slice(0, 4); + var vote = parseFloat((data.vote_average || 0) + '').toFixed(1); + html.find('.info__title').text(data.title); + html.find('.info__title-original').text((create == '0000' ? '' : create + ' - ') + (data.original_title || '')); + html.find('.info__vote span').text(vote); + html.find('.info__vote').toggleClass('hide', !(vote > 0)); + html.find('.info__icon').removeClass('active'); + + if (!nofavorite) { + var status = Favorite.check(data); + $('.icon--book', html).toggleClass('active', status.book); + $('.icon--like', html).toggleClass('active', status.like); + $('.icon--wath', html).toggleClass('active', status.wath); + } + + html.find('.info__right').toggleClass('hide', nofavorite); + }; + + this.render = function () { + return html; + }; + + this.empty = function () { + this.update({ + title: Lang.translate('more'), + original_title: Lang.translate('more_results'), + vote_average: 0 + }, true); + }; + + this.destroy = function () { + html.remove(); + html = null; + }; + } + + /** + * Карточка + * @param {object} data + * @param {{isparser:boolean, card_small:boolean, card_category:boolean, card_collection:boolean, card_wide:true}} params + */ + + function Card(data) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + console.warn('Card is deprecated'); + this.data = data; + this.params = params; + Arrays.extend(data, { + title: data.name, + original_title: data.original_name, + release_date: data.first_air_date + }); + data.release_year = ((data.release_date || data.birthday || '0000') + '').slice(0, 4); + + function remove(elem) { + if (elem) elem.remove(); + } + /** + * Загрузить шаблон + */ + + + this.build = function () { + this.card = Template.js(params.isparser ? 'card_parser' : 'card', data); + this.img = this.card.querySelector('.card__img') || {}; + this.card.card_data = data; + + if (params.isparser) { + var elem_title = this.card.querySelector('.card-parser__title'); + var elem_size = this.card.querySelector('.card-parser__size'); + var elem_details = this.card.querySelector('.card-parser__details'); + if (elem_title) elem_title.innerText = data.Title; + if (elem_size) elem_size.innerText = data.size; + var seeds = document.createElement('div'); + var grabs = document.createElement('div'); + elem_details.innerHTML = ''; + seeds.innerHTML = Lang.translate('torrent_item_seeds') + ': ' + data.Seeders + ''; + grabs.innerHTML = Lang.translate('torrent_item_grabs') + ': ' + data.Peers + ''; + elem_details.appendChild(seeds); + elem_details.appendChild(grabs); + } else { + var _elem_title = this.card.querySelector('.card__title'); + + if (_elem_title) _elem_title.innerText = data.title; + + if (data.original_name) { + var type_elem = document.createElement('div'); + type_elem.classList.add('card__type'); + type_elem.innerText = data.original_name ? 'TV' : 'MOV'; + this.card.querySelector('.card__view').appendChild(type_elem); + this.card.classList.add(data.original_name ? 'card--tv' : 'card--movie'); + } + + if (params.card_small) { + this.card.classList.add('card--small'); + remove(this.card.querySelector('.card__title')); + remove(this.card.querySelector('.card__age')); + } + + if (params.card_category) { + this.card.classList.add('card--category'); + } + + if (params.card_explorer) { + this.card.classList.add('card--explorer'); + } + + if (params.card_collection) { + this.card.classList.add('card--collection'); + remove(this.card.querySelector('.card__age')); + } + + if (params.card_wide) { + this.card.classList.add('card--wide'); + data.poster = data.cover; + + if (data.promo || data.promo_title) { + var promo_wrap = document.createElement('div'); + promo_wrap.classList.add('card__promo'); + + if (data.promo_title) { + var promo_title = document.createElement('div'); + promo_title.classList.add('card__promo-title'); + promo_title.innerText = data.promo_title; + promo_wrap.appendChild(promo_title); + } + + if (data.promo) { + var promo_text = document.createElement('div'); + promo_text.classList.add('card__promo-text'); + promo_text.innerText = data.promo.slice(0, 110) + (data.promo.length > 110 ? '...' : ''); + promo_wrap.appendChild(promo_text); + } + + this.card.querySelector('.card__view').appendChild(promo_wrap); + } + + if (Storage.field('light_version')) remove(this.card.querySelector('.card__title')); + remove(this.card.querySelector('.card__age')); + } + + if (data.release_year == '0000') { + remove(this.card.querySelector('.card__age')); + } else { + var year = this.card.querySelector('.card__age'); + if (year) year.innerText = data.release_year; + } + + var vote = parseFloat((data.cub_hundred_rating || data.vote_average || 0) + '').toFixed(1); + + if (vote > 0) { + var vote_elem = document.createElement('div'); + vote_elem.classList.add('card__vote'); + vote_elem.innerText = data.cub_hundred_fire ? Utils$1.bigNumberToShort(data.cub_hundred_fire) : vote >= 10 ? 10 : vote; + this.card.querySelector('.card__view').appendChild(vote_elem); + } + + var qu = data.quality || data.release_quality; + + if (qu && Storage.field('card_quality') && !data.original_name) { + var quality = document.createElement('div'); + quality.classList.add('card__quality'); + var quality_inner = document.createElement('div'); + quality_inner.innerText = qu; + quality.appendChild(quality_inner); + this.card.querySelector('.card__view').appendChild(quality); + } + } + + this.card.addEventListener('visible', this.visible.bind(this)); + this.card.addEventListener('update', this.update.bind(this)); + }; + /** + * Загрузить картинку + */ + + + this.image = function () { + var _this = this; + + if (params.isparser) return; + + this.img.onload = function () { + _this.card.classList.add('card--loaded'); + }; + + this.img.onerror = function () { + TMDB$1.broken(); + console.log('Img', 'noload', _this.img.src); + _this.img.src = './img/img_broken.svg'; + }; + }; + /** + * Добавить иконку + * @param {string} name + */ + + + this.addicon = function (name) { + var icon = document.createElement('div'); + icon.classList.add('card__icon'); + icon.classList.add('icon--' + name); + this.card.querySelector('.card__icons-inner').appendChild(icon); + }; + /** + * Обносить состояние карточки + */ + + + this.update = function () { + if (params.isparser) return; + this.watched_checked = false; + if (this.watched_wrap) remove(this.watched_wrap); + this.favorite(); + if (this.card.classList.contains('focus')) this.watched(); + }; + /** + * Какие серии просмотрено + */ + + + this.watched = function () { + var _this2 = this; + + if (!Storage.field('card_episodes')) return; + + if (!this.watched_checked) { + var get = function get(callback) { + if (data.original_name) TimeTable.get(data, callback);else callback([]); + }; + + get(function (episodes) { + var viewed; + episodes.forEach(function (ep) { + var hash = Utils$1.hash([ep.season_number, ep.season_number > 10 ? ':' : '', ep.episode_number, data.original_title].join('')); + var view = Timeline$1.view(hash); + if (view.percent) viewed = { + ep: ep, + view: view + }; + }); + + if (!viewed && data.original_name) { + var last = Storage.get('online_watched_last', '{}'); + var filed = last[Utils$1.hash(data.original_title)]; + + if (filed && filed.episode) { + viewed = { + ep: { + episode_number: filed.episode, + name: Lang.translate('full_episode') + ' ' + filed.episode + }, + view: Timeline$1.view(Utils$1.hash([filed.season, filed.season > 10 ? ':' : '', filed.episode, data.original_title].join(''))) + }; + } + } + + if (!viewed && !data.original_name) { + var time = Timeline$1.view(Utils$1.hash([data.original_title].join(''))); + + if (time.percent) { + viewed = { + ep: { + name: Lang.translate('title_viewed') + ' ' + (time.time ? Utils$1.secondsToTimeHuman(time.time) : time.percent + '%') + }, + view: time + }; + } + } + + if (viewed) { + var soon = []; + var next = episodes.slice(episodes.indexOf(viewed.ep)).filter(function (ep) { + return ep.air_date; + }).filter(function (ep) { + var date = Utils$1.parseToDate(ep.air_date).getTime(); + if (date > Date.now()) soon.push(ep); + return date < Date.now(); + }).slice(0, 5); + if (next.length == 0) next = [viewed.ep]; + if (soon.length && next.length < 5 && !next.find(function (n) { + return n.episode_number == soon[0].episode_number; + })) next.push(soon[0]); + var wrap = Template.js('card_watched', {}); + next.forEach(function (ep) { + var div = document.createElement('div'); + var span = document.createElement('span'); + var date = Utils$1.parseToDate(ep.air_date); + var now = Date.now(); + var days = Math.ceil((date.getTime() - now) / (24 * 60 * 60 * 1000)); + div.classList.add('card-watched__item'); + div.appendChild(span); + span.innerText = (ep.episode_number ? ep.episode_number + ' - ' : '') + (days > 0 ? Lang.translate('full_episode_days_left') + ': ' + days : ep.name || Lang.translate('noname')); + if (ep == viewed.ep) div.appendChild(Timeline$1.render(viewed.view)[0]); + wrap.querySelector('.card-watched__body').appendChild(div); + }); + _this2.watched_wrap = wrap; + + var view = _this2.card.querySelector('.card__view'); + + view.insertBefore(wrap, view.firstChild); + } + }); + this.watched_checked = true; + } + }; + /** + * Обновить иконки на закладки + */ + + + this.favorite = function () { + var status = Favorite.check(data); + var marker = this.card.querySelector('.card__marker'); + var marks = ['look', 'viewed', 'scheduled', 'continued', 'thrown']; + this.card.querySelector('.card__icons-inner').innerHTML = ''; + if (status.book) this.addicon('book'); + if (status.like) this.addicon('like'); + if (status.wath) this.addicon('wath'); + if (status.history || Timeline$1.watched(data)) this.addicon('history'); + var any_marker = marks.find(function (m) { + return status[m]; + }); + + if (any_marker) { + if (!marker) { + marker = document.createElement('div'); + marker.addClass('card__marker'); + marker.append(document.createElement('span')); + this.card.querySelector('.card__view').append(marker); + } + + marker.find('span').text(Lang.translate('title_' + any_marker)); + marker.removeClass(marks.map(function (m) { + return 'card__marker--' + m; + }).join(' ')).addClass('card__marker--' + any_marker); + } else if (marker) marker.remove(); + }; + /** + * Вызвали меню + * @param {object} target + * @param {object} data + */ + + + this.onMenu = function (target, data) { + var _this3 = this; + + var enabled = Controller.enabled().name; + var status = Favorite.check(data); + var menu_plugins = []; + var menu_favorite = [{ + title: Lang.translate('title_book'), + where: 'book', + checkbox: true, + checked: status.book + }, { + title: Lang.translate('title_like'), + where: 'like', + checkbox: true, + checked: status.like + }, { + title: Lang.translate('title_wath'), + where: 'wath', + checkbox: true, + checked: status.wath + }, { + title: Lang.translate('menu_history'), + where: 'history', + checkbox: true, + checked: status.history + }]; + + if (window.lampa_settings.account_use) { + var marks = ['look', 'viewed', 'scheduled', 'continued', 'thrown']; + menu_favorite.push({ + title: Lang.translate('settings_cub_status'), + separator: true + }); + marks.forEach(function (m) { + menu_favorite.push({ + title: Lang.translate('title_' + m), + where: m, + picked: status[m], + collect: true, + noenter: !Account$1.hasPremium() + }); + }); + } + + object$2.plugins.forEach(function (plugin) { + if (plugin.type == 'video' && plugin.onContextMenu && plugin.onContextLauch) { + menu_plugins.push({ + title: plugin.name, + subtitle: plugin.subtitle || plugin.description, + onSelect: function onSelect() { + if (document.body.classList.contains('search--open')) Search.close(); + + if (!data.imdb_id && data.source == 'tmdb') { + Loading$1.start(function () { + Loading$1.stop(); + Controller.toggle(enabled); + }); + TMDB.external_imdb_id({ + type: data.name ? 'tv' : 'movie', + id: data.id + }, function (imdb_id) { + Loading$1.stop(); + data.imdb_id = imdb_id; + plugin.onContextLauch(data); + }); + } else plugin.onContextLauch(data); + } + }); + } + }); + if (menu_plugins.length) menu_plugins.push({ + title: Lang.translate('more'), + separator: true + }); + var menu_main = menu_plugins.length ? menu_plugins.concat(menu_favorite) : menu_favorite; + if (this.onMenuShow) this.onMenuShow(menu_main, this.card, data); + Select.show({ + title: Lang.translate('title_action'), + items: menu_main, + onBack: function onBack() { + Controller.toggle(enabled); + }, + onCheck: function onCheck(a) { + if (params.object) data.source = params.object.source; + + if (a.where) { + Favorite.toggle(a.where, data); + + _this3.favorite(); + } + }, + onSelect: function onSelect(a) { + if (params.object) data.source = params.object.source; + + if (a.collect) { + Favorite.toggle(a.where, data); + + _this3.favorite(); + } + + if (_this3.onMenuSelect) _this3.onMenuSelect(a, _this3.card, data); + Controller.toggle(enabled); + }, + onDraw: function onDraw(item, elem) { + if (elem.collect) { + if (!Account$1.hasPremium()) { + var wrap = $('
    '); + wrap.append(Template.js('icon_lock')); + item.find('.selectbox-item__checkbox').remove(); + item.append(wrap); + item.on('hover:enter', function () { + Select.close(); + Account$1.showCubPremium(); + }); + } + } + } + }); + }; + /** + * Создать + */ + + + this.create = function () { + var _this4 = this; + + this.build(); + this.card.addEventListener('hover:focus', function () { + _this4.watched(); + + if (_this4.onFocus) _this4.onFocus(_this4.card, data); + }); + this.card.addEventListener('hover:touch', function () { + _this4.watched(); + + if (_this4.onTouch) _this4.onTouch(_this4.card, data); + }); + this.card.addEventListener('hover:hover', function () { + _this4.watched(); + + if (_this4.onHover) _this4.onHover(_this4.card, data); + }); + this.card.addEventListener('hover:enter', function () { + if (_this4.onEnter) _this4.onEnter(_this4.card, data); + }); + this.card.addEventListener('hover:long', function () { + if (_this4.onMenu) _this4.onMenu(_this4.card, data); + }); + this.image(); + }; + /** + * Загружать картинку если видна карточка + */ + + + this.visible = function () { + var src = ''; + if (params.card_wide && data.backdrop_path) src = Api.img(data.backdrop_path, 'w780');else if (params.card_collection && data.backdrop_path) src = Api.img(data.backdrop_path, 'w500');else if (data.poster_path) src = Api.img(data.poster_path);else if (data.profile_path) src = Api.img(data.profile_path);else if (data.poster) src = data.poster;else if (data.img) src = data.img;else src = './img/img_broken.svg'; + this.img.src = src; + this.update(); + if (this.onVisible) this.onVisible(this.card, data); + }; + /** + * Уничтожить + */ + + + this.destroy = function () { + this.img.onerror = function () {}; + + this.img.onload = function () {}; + + this.img.src = ''; + remove(this.card); + this.card = null; + this.img = null; + }; + /** + * Рендер + * @returns {object} + */ + + + this.render = function (js) { + return js ? this.card : $(this.card); + }; + } + + var html$5 = $("
    \n
    \n
    \n \n \n \n \n \n \n
    \n
    \n
    \n
    "); + var body = html$5.find('.helper__text'), + time; + var memorys = {}; + var remember = 1000 * 60 * 60 * 14; + + function show(name, text, elem) { + if (!Storage.field('helper')) return; + var help = memorys[name]; + + if (!help) { + help = { + time: 0, + count: 0 + }; + if (_typeof(memorys) !== 'object') memorys = {}; //хз, вылазит ошибка, что в переменную true нельзя записать значение, откуда там true хз + + memorys[name] = help; + } + + if (help.time + remember < Date.now() && help.count < 3) { + help.time = Date.now(); + help.count++; + Storage.set('helper', memorys); + clearTimeout(time); + time = setTimeout(function () { + html$5.removeClass('helper--visible'); + }, 10000); + body.html(text); + html$5.addClass('helper--visible'); + + if (elem) { + var blink = $(''); + elem.append(blink); + setTimeout(function () { + blink.remove(); + }, 3000); + } + } + } + + function init$q() { + memorys = Storage.cache('helper', 300, {}); + Settings.listener.follow('open', function (e) { + if (e.name == 'more') { + e.body.find('.helper--start-again').on('hover:enter', function () { + memorys = {}; + Storage.set('helper', memorys); + Noty.show(Lang.translate('helper_cleared')); + }); + } + }); + $('body').append(html$5); + } + + var Helper$1 = { + show: show, + init: init$q + }; + + /* + let tizen = { + ApplicationControlData: ()=>{}, + ApplicationControl: ()=>{}, + application:{ + launchAppControl: ()=>{} + } + } + */ + + /** + * Запуск + */ + + function init$p() { + if (typeof tizen !== 'undefined') { + Timer.add(1000 * 60 * 10, lauchPick); + lauchPick(); + deepLink(); + window.addEventListener('appcontrol', deepLink); + + try { + console.log('Tizen', 'current id', tizen.application.getCurrentApplication().appInfo.id); + } catch (e) {} + } + } + /** + * Установить данные + * @param {{sections:[{title:string,position:integer,tiles:[{cardToTile}]}]}} data + */ + + + function setPick(data) { + var service_id = tizen.application.getCurrentApplication().appInfo.id.split('.')[0] + '.service'; + var controll_data = new tizen.ApplicationControlData('caller', ['ForegroundApp', JSON.stringify(data)]); + var controll_app = new tizen.ApplicationControl('http://tizen.org/appcontrol/operation/pick', null, 'image/*', null, [controll_data]); + tizen.application.launchAppControl(controll_app, service_id, function () { + console.log('Tizen', 'service', 'launch success'); + }, function (error) { + console.log('Tizen', 'service', 'error:', JSON.stringify(error)); + }); + } + /** + * Карточку в данные + * @param {{title:string, name:string, poster_path:string, release_date:string}} card - карточка + * @param {string} subtitle + * @returns {{title:string, subtitle:string, image_ratio:string, image_url:string, action_data:string, is_playable:boolean}} + */ + + + function cardToTile(card, subtitle) { + var relise = ((card.release_date || card.first_air_date || '0000') + '').slice(0, 4); + var elem = { + title: card.title || card.name, + subtitle: subtitle || relise, + image_ratio: '1by1', + image_url: card.poster ? card.poster : card.img ? card.img : 'http://imagetmdb.com/t/p/w300/' + card.poster_path, + action_data: JSON.stringify(card), + is_playable: false + }; + return elem; + } + /** + * Строим данные + */ + + + function lauchPick() { + var data = { + sections: [] + }; + console.log('Tizen', 'start pick'); + var status = new Status(3); + + status.onComplite = function (result) { + if (result.popular) data.sections.push(result.popular); + if (result.continues) data.sections.push(result.continues); + if (result.notice) data.sections.push(result.notice); + console.log('Tizen', 'set sections', data.sections.length); + if (data.sections.length) setPick(data); + }; + + Account$1.Api.notices(function (notices) { + var new_notices = notices.filter(function (n) { + return !n.viewed; + }).slice(0, 3); + + if (new_notices.length) { + var section = { + title: Lang.translate('title_notice'), + tiles: [], + position: 0 + }; + new_notices.forEach(function (noty) { + var info = JSON.parse(noty.data); + section.tiles.push(cardToTile(info.card, info.type == 'new_episode' ? Lang.translate('notice_new_episode') : Lang.translate('notice_in_quality'))); + }); + status.append('notice', section); + } else status.error(); + }); + TMDB.get('movie/popular', {}, function (result) { + if (result.results.length) { + var section = { + title: Lang.translate('title_popular_movie'), + position: 2, + tiles: result.results.slice(0, 10).map(function (c) { + return cardToTile(c); + }) + }; + status.append('popular', section); + } else status.error(); + }, status.error.bind(status), { + life: 60 * 24 * 3 + }); + var continues = Favorite.continues('tv'); + + if (continues.length) { + var section = { + title: Lang.translate('title_continue'), + position: 1, + tiles: continues.slice(0, 7).map(function (c) { + return cardToTile(c); + }) + }; + status.append('continues', section); + } else status.error(); + } + /** + * Перехват запроса на открытие карточки + */ + + + function deepLink() { + var requestedAppControl = tizen.application.getCurrentApplication().getRequestedAppControl(); + + if (requestedAppControl) { + var appControlData = requestedAppControl.appControl.data; + + for (var i = 0; i < appControlData.length; i++) { + if (appControlData[i].key == 'PAYLOAD') { + var action_data = JSON.parse(appControlData[i].value[0]).values; + var json = JSON.parse(action_data); + window.start_deep_link = { + url: json.url, + component: 'full', + id: json.id, + method: json.name ? 'tv' : 'movie', + card: json, + source: json.source || 'tmdb' + }; + + if (window.appready) { + Activity.push(window.start_deep_link); + } + + console.log('Tizen', 'open deep link', window.start_deep_link); + } + } + } + } + + var Tizen = { + init: init$p + }; + + function create$1(data) { + var _this = this; + + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var content = Template.js('items_line', { + title: data.title + }); + var body = content.querySelector('.items-line__body'); + var scroll = new Scroll({ + horizontal: true, + step: params.card_wide ? 600 : 300 + }); + var items = []; + var active = 0; + var tv = Platform.screen('tv'); + var view = (tv ? Lampa.Storage.field('interface_size') == 'small' ? 7 : 6 : 12) + (params.align_left ? 4 : 0); + var more; + var last; + console.warn('Component InteractionLine is deprecated.'); + + var onmore = function onmore() { + if (_this.onEnter) _this.onEnter(); + if (data.onMore) data.onMore(data);else if (_this.onMore) { + _this.onMore(data); + } else { + Activity.push({ + url: data.url, + title: data.title || Lang.translate('title_category'), + component: 'category_full', + page: 1, + genres: params.genres, + filter: data.filter, + source: data.source || params.object.source + }); + } + }; + + this.event = function (type) { + Lampa.Listener.send('line', { + line: this, + type: type, + params: params, + data: data, + scroll: scroll, + body: body, + items: items, + active: active + }); + }; + + this.create = function () { + var _this2 = this; + + this.event('create'); + scroll.body(true).addClass('items-cards mapping--line'); + content.querySelector('.items-line__title').innerHTML = data.title; + content.classList.add('items-line--type-' + (params.type || 'none')); + content.addEventListener('visible', this.visible.bind(this)); + data.results.slice(0, view).forEach(this.append.bind(this)); + body.appendChild(scroll.render(true)); + + scroll.onWheel = function (step) { + if (!Controller.own(_this2)) _this2.toggle(); + Controller.enabled().controller[step > 0 ? 'right' : 'left'](); + }; + + scroll.onScroll = this.attach.bind(this); + }; + /* + События + + this.onAppend = function(){} + this.onFocus = function(){} + this.onEnter = function(){} + this.onSelect = function(){} + this.onMore = function(){} + this.onFocusMore = function(){} + this.onLeft = function(){} + this.onBack = function(){} + this.onDown = function(){} + this.onUp = function(){} + */ + + + this.visible = function () { + data.results.slice(0, view).forEach(this.append.bind(this)); + + if ((data.results.length >= 20 || data.more) && !params.nomore) { + var button = document.createElement('div'); + button.classList.add('items-line__more'); + button.classList.add('selector'); + button.innerText = Lang.translate('more'); + button.addEventListener('hover:enter', onmore); + content.querySelector('.items-line__head').appendChild(button); + } + + this.event('visible'); + Layer.visible(scroll.render(true)); + }; + + this.append = function (element) { + var _this3 = this; + + if (element.ready) return; + element.ready = true; + var card = params.cardClass ? params.cardClass(element, params) : element.cardClass ? element.cardClass(element, params) : new Card(element, params); + card.create(); + + card.onFocus = function (target, card_data) { + last = target; + var prev_active = active; + active = items.indexOf(card); + if (active > 0 || prev_active > active) scroll.update(items[active].render(true), params.align_left ? false : true); + if (!data.noimage) Background.change(Utils$1.cardImgBackground(card_data)); + if (_this3.onFocus) _this3.onFocus(card_data); + }; + + card.onEnter = function (target, card_data) { + last = target; + if (_this3.onEnter) _this3.onEnter(target, card_data); + if (_this3.onSelect) return _this3.onSelect(target, card_data); + if (!card_data.source) card_data.source = params.object.source; + + if (typeof card_data.gender !== 'undefined') { + Activity.push({ + url: card_data.url, + title: Lang.translate('title_person'), + component: 'actor', + id: card_data.id, + source: card_data.source || params.object.source + }); + } else { + Activity.push({ + url: card_data.url, + component: 'full', + id: card_data.id, + method: card_data.name ? 'tv' : 'movie', + card: card_data, + source: card_data.source || params.object.source + }); + } + }; + + card.onHover = function (target, card_data) { + if (_this3.onHover) _this3.onHover(card_data); + }; + + card.onVisible = function () { + if (Controller.own(_this3)) Controller.collectionAppend(card.render(true)); + }; + + if (this.onMenu) card.onMenu = this.onMenu; + + if (params.card_events) { + for (var i in params.card_events) { + card[i] = params.card_events[i]; + } + } + + scroll.append(card.render(true)); + items.push(card); + if (this.onAppend) this.onAppend(card); + this.event('append'); + return card.render(true); + }; + + this.more = function () { + var _this4 = this; + + more = new More$1(params); + more.create(); + more.render(true).on('hover:focus', function (target) { + last = target; + active = items.indexOf(more); + scroll.update(more.render(true), params.align_left ? false : true); + if (_this4.onFocusMore) _this4.onFocusMore(); + }); + more.render(true).on('hover:enter', onmore.bind(this)); + scroll.append(more.render(true)); + more.size(items[items.length - 1].render(true)); + items.push(more); + return more.render(true); + }; + + this.attach = function () { + var size = tv ? (Math.round(active / view) + 1) * view + 1 : data.results.length; + data.results.slice(0, size).filter(function (e) { + return !e.ready; + }).forEach(this.append.bind(this)); + + if (!more && !params.nomore && data.results.length == data.results.filter(function (e) { + return e.ready; + }).length && data.results.length >= 20) { + var more_item = this.more(); + if (Controller.own(this)) Controller.collectionAppend(more_item); + } + + Layer.visible(scroll.render(true)); + }; + + this.toggle = function () { + var _this5 = this; + + Controller.add('items_line', { + link: this, + toggle: function toggle() { + Controller.collectionSet(scroll.render(true)); + Controller.collectionFocus(items.length ? last : false, scroll.render(true)); + if (_this5.onToggle) _this5.onToggle(_this5); + + _this5.event('toggle'); + }, + update: function update() {}, + right: function right() { + Navigator.move('right'); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else if (_this5.onLeft) _this5.onLeft();else Controller.toggle('menu'); + }, + down: this.onDown, + up: this.onUp, + gone: function gone() {}, + back: this.onBack + }); + Controller.toggle('items_line'); + }; + + this.render = function (js) { + return js ? content : $(content); + }; + + this.destroy = function () { + Arrays.destroy(items); + scroll.destroy(); + content.remove(); + items = null; + this.event('destroy'); + }; + } + + function component$3(object) { + var scroll = new Scroll({ + mask: true, + over: true, + scroll_by_item: true, + end_ratio: 1.5 + }); + var items = []; + var html = document.createElement('div'); + var active = 0; + console.warn('Component InteractionMain is deprecated.'); + + this.create = function () {}; + + this.empty = function () { + var button; + + if (object.source == 'tmdb') { + button = $(''); + button.find('.selector').on('hover:enter', function () { + Storage.set('source', 'cub'); + Activity.replace({ + source: 'cub' + }); + }); + } + + var empty = new Empty(); + if (button) empty.append(button); + empty.addInfoButton(); + html.appendChild(empty.render(true)); + this.start = empty.start.bind(empty); + this.activity.loader(false); + this.activity.toggle(); + }; + + this.loadNext = function () { + var _this = this; + + if (this.next && !this.next_wait && items.length) { + this.next_wait = true; + this.next(function (new_data) { + _this.next_wait = false; + if (!items.length) return; + new_data.forEach(_this.append.bind(_this)); + Layer.visible(items[active + 1].render(true)); + }, function () { + _this.next_wait = false; + }); + } + }; + + this.build = function (data) { + var _this2 = this; + + scroll.minus(); + + scroll.onWheel = function (step) { + if (!Controller.own(_this2)) _this2.start(); + if (step > 0) _this2.down();else if (active > 0) _this2.up(); + }; + + scroll.onEnd = this.loadNext.bind(this); + if (this.onLinesBuild) this.onLinesBuild(data); + data.forEach(this.append.bind(this)); + html.appendChild(scroll.render(true)); + Layer.update(html); + this.activity.loader(false); + this.activity.toggle(); + Layer.visible(html); + }; + + this.append = function (element) { + if (element.ready) return; + element.ready = true; + var item = new create$1(element, { + url: element.url, + genres: object.genres, + object: object, + card_wide: element.wide, + card_small: element.small, + card_broad: element.broad, + card_collection: element.collection, + card_category: element.category, + card_events: element.card_events, + cardClass: element.cardClass, + nomore: element.nomore, + type: element.line_type || 'cards' + }); + item.create(); + this.push(item, element); + }; + + this.back = function () { + Activity.backward(); + }; + + this.push = function (item, element) { + item.onDown = this.down.bind(this); + item.onUp = this.up.bind(this); + item.onBack = this.back.bind(this); + if (this.onMore) item.onMore = this.onMore.bind(this); + items.push(item); + if (this.onAppend) this.onAppend(item, element); + scroll.append(item.render(true)); + }; + + this.down = function () { + active++; + active = Math.min(active, items.length - 1); + scroll.update(items[active].render(true)); + items[active].toggle(); + }; + + this.up = function () { + active--; + + if (active < 0) { + active = 0; + Controller.toggle('head'); + } else { + items[active].toggle(); + scroll.update(items[active].render(true)); + } + }; + + this.start = function () { + var _this3 = this; + + Controller.add('content', { + link: this, + toggle: function toggle() { + if (_this3.activity.canRefresh()) return false; + if (items.length) items[active].toggle(); + }, + update: function update() {}, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + right: function right() { + Navigator.move('right'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down'); + }, + back: this.back + }); + Controller.toggle('content'); + }; + + this.refresh = function () { + this.activity.needRefresh(); + }; + + this.pause = function () {}; + + this.stop = function () {}; + + this.render = function (js) { + return js ? html : $(html); + }; + + this.destroy = function () { + Arrays.destroy(items); + scroll.destroy(); + html.remove(); + items = []; + if (this.onDestroy) this.onDestroy(); + }; + } + + function component$2(object) { + var network = new Request(); + var scroll = new Scroll({ + mask: true, + over: true, + step: 250, + end_ratio: 2 + }); + var items = []; + var html = document.createElement('div'); + var body = document.createElement('div'); + var total_pages = 0; + var last; + var waitload; + var active = 0; + console.warn('Component InteractionCategory is deprecated.'); + + this.create = function () {}; + + this.empty = function () { + var button; + + if (object.source == 'tmdb') { + button = $(''); + button.find('.selector').on('hover:enter', function () { + Storage.set('source', 'cub'); + Activity.replace({ + source: 'cub' + }); + }); + } + + var empty = new Empty(); + if (button) empty.append(button); + empty.addInfoButton(); + html.appendChild(empty.render(true)); + this.start = empty.start.bind(empty); + this.activity.loader(false); + this.activity.toggle(); + }; + + this.next = function () { + var _this = this; + + if (waitload) return; + + if (object.page < total_pages) { + waitload = true; + object.page++; + this.nextPageReuest(object, function (result) { + _this.append(result, true); + + waitload = false; + + _this.limit(); + }, function () { + waitload = false; + }); + } + }; + + this.nextPageReuest = function (object, resolve, reject) { + Api.list(object, resolve.bind(this), reject.bind(this)); + }; + + this.append = function (data, append) { + var _this2 = this; + + data.results.forEach(function (element) { + var params = { + object: object, + card_category: typeof data.card_category == 'undefined' ? true : data.category, + card_wide: data.wide, + card_small: data.small, + card_broad: data.broad, + card_collection: data.collection, + card_events: data.card_events + }; + var card = data.cardClass ? data.cardClass(element, params) : element.cardClass ? element.cardClass(element, params) : new Card(element, params); + card.create(); + + card.onFocus = function (target, card_data) { + last = target; + active = items.indexOf(card); + scroll.update(card.render(true)); + Background.change(Utils$1.cardImgBackground(card_data)); + }; + + card.onTouch = function (target, card_data) { + last = target; + active = items.indexOf(card); + }; + + card.onEnter = function (target, card_data) { + last = target; + + if (typeof card_data.gender !== 'undefined') { + Activity.push({ + url: element.url, + title: Lang.translate('title_person'), + component: 'actor', + id: element.id, + source: element.source || object.source + }); + } else { + Activity.push({ + url: card_data.url, + component: 'full', + id: element.id, + method: card_data.name ? 'tv' : 'movie', + card: element, + source: element.source || object.source + }); + } + }; + + body.appendChild(card.render(true)); + items.push(card); + if (_this2.cardRender) _this2.cardRender(object, element, card); + if (append) Controller.collectionAppend(card.render(true)); + }); + }; + + this.limit = function () { + var limit_view = 12; + var lilit_collection = 36; + var colection = items.slice(Math.max(0, active - limit_view), active + limit_view); + items.forEach(function (item) { + if (colection.indexOf(item) == -1) { + item.render(true).classList.remove('layer--render'); + } else { + item.render(true).classList.add('layer--render'); + } + }); + Navigator.setCollection(items.slice(Math.max(0, active - lilit_collection), active + lilit_collection).map(function (c) { + return c.render(true); + })); + Navigator.focused(last); + Layer.visible(scroll.render(true)); + }; + + this.build = function (data) { + var _this3 = this; + + if (data.results.length) { + total_pages = data.total_pages; + body.addClass('category-full'); + scroll.minus(); + scroll.onEnd = this.next.bind(this); + scroll.onScroll = this.limit.bind(this); + + scroll.onWheel = function (step) { + if (!Controller.own(_this3)) _this3.start(); + if (step > 0) Navigator.move('down');else Navigator.move('up'); + }; + + this.append(data); + scroll.append(body); + html.appendChild(scroll.render(true)); + this.limit(); + this.activity.loader(false); + this.activity.toggle(); + } else { + this.empty(); + } + }; + + this.start = function () { + var _this4 = this; + + Controller.add('content', { + link: this, + toggle: function toggle() { + if (_this4.activity.canRefresh()) return false; + Controller.collectionSet(scroll.render(true)); + Controller.collectionFocus(last || false, scroll.render(true)); + }, + left: function left() { + if (Navigator.canmove('left')) Navigator.move('left');else Controller.toggle('menu'); + }, + right: function right() { + if (_this4.onRight) { + if (Navigator.canmove('right')) Navigator.move('right');else _this4.onRight(); + } else Navigator.move('right'); + }, + up: function up() { + if (Navigator.canmove('up')) Navigator.move('up');else Controller.toggle('head'); + }, + down: function down() { + if (Navigator.canmove('down')) Navigator.move('down'); + }, + back: function back() { + Activity.backward(); + } + }); + Controller.toggle('content'); + }; + + this.refresh = function () { + this.activity.needRefresh(); + }; + + this.pause = function () {}; + + this.stop = function () {}; + + this.render = function (js) { + return js ? html : $(html); + }; + + this.destroy = function () { + network.clear(); + Arrays.destroy(items); + scroll.destroy(); + html.remove(); + body.remove(); + items = []; + }; + } + + /** + * Открывает окно выбора языка на начальном экране + * @param {function} callSelected - вызывается при выборе языка, получает код языка + * @param {function} callCancel - вызывается при отмене выбора + * @returns {void} + */ + + function open$2(callSelected, callCancel) { + var html = Template.get('lang_choice', {}); + var scroll = new Scroll({ + mask: true, + over: true + }); + var codes = Lang.codes(); + + function selector(code) { + var item = $('
    ' + codes[code] + '
    '); + item.on('hover:enter click', function (e) { + if (callSelected) callSelected(code); + html.fadeOut(300, function () { + scroll.destroy(); + html.remove(); + scroll = null; + html = null; + }); + }).on('hover:focus', function (e) { + scroll.update($(e.target), true); + $('.lang__selector-item', html).removeClass('last-focus'); + $(e.target).addClass('last-focus'); + html.find('.lang__title').text(Lang.translate('lang_choice_title', code)); + html.find('.lang__subtitle').text(Lang.translate('lang_choice_subtitle', code)); + }); + scroll.append(item); + } + + for (var code in codes) { + selector(code); + } + + html.find('.lang__selector').append(scroll.render()); + $('body').append(html); + Controller.add('language', { + toggle: function toggle() { + var focus = html.find('[data-code="' + Storage.get('language', 'ru') + '"]'); + Controller.collectionSet(scroll.render()); + Controller.collectionFocus(focus[0], scroll.render()); + }, + up: function up() { + Navigator.move('up'); + }, + down: function down() { + Navigator.move('down'); + }, + back: function back() { + if (callCancel) { + scroll.destroy(); + html.remove(); + scroll = null; + html = null; + callCancel(); + } + } + }); + Controller.toggle('language'); + } + + var LangChoice = { + open: open$2 + }; + + var player; + var html$4; + var timer; + /** + * Создать плеер YouTube + * @param {string} id - ID видео на YouTube + * @return {void} + */ + + function create(id) { + html$4 = $('
    '); + $('body').append(html$4); + player = new YT.Player('youtube-player', { + height: window.innerHeight, + width: window.innerWidth, + playerVars: { + 'controls': 0, + 'showinfo': 0, + 'autohide': 1, + 'modestbranding': 1, + 'autoplay': 1, + 'suggestedQuality': 'hd1080', + 'setPlaybackQuality': 'hd1080' + }, + videoId: id, + events: { + onReady: function onReady(event) { + event.target.setPlaybackQuality('hd1080'); + event.target.playVideo(); + update$2(); + }, + onStateChange: function onStateChange(state) { + if (state.data == 0) { + Controller.toggle('content'); + } + + if (state.data == YT.PlayerState.BUFFERING) { + state.target.setPlaybackQuality('hd1080'); + } + }, + onPlaybackQualityChange: function onPlaybackQualityChange(state) { + console.log('YouTube', 'quality', state.target.getPlaybackQuality()); + } + } + }); + } + + function update$2() { + timer = setTimeout(function () { + var progress = player.getCurrentTime() / player.getDuration() * 100; + $('#youtube-player__progress').css('width', progress + '%'); + Screensaver$2.resetTimer(); + update$2(); + }, 400); + } + /** + * Начать воспроизведение видео с YouTube + * @param {string} id - ID видео на YouTube (например, dQw4w9WgXcQ) + * @returns {void} + */ + + + function play(id) { + if (typeof YT == 'undefined') return; + create(id); + Controller.add('youtube', { + invisible: true, + toggle: function toggle() {}, + right: function right() { + player.seekTo(player.getCurrentTime() + 10, true); + }, + left: function left() { + player.seekTo(player.getCurrentTime() - 10, true); + }, + enter: function enter() {}, + gone: function gone() { + destroy(); + }, + back: function back() { + Controller.toggle('content'); + } + }); + Controller.toggle('youtube'); + } + + function destroy() { + clearTimeout(timer); + player.destroy(); + html$4.remove(); + html$4 = null; + } + + var YouTube = { + play: play + }; + + /** + * LG webOS добавление/удаление приложения из лаунчера, но только для виджетов ручной установки + */ + + function init$o() { + if (!Platform.is('webos')) return; + var field = $("
    \n
    \n \n \n \n \n \n \n
    \n
    ".concat(Lang.translate('settings_webos_launcher'), "
    \n
    ")); + Settings.main().render().find('[data-component="more"]').after(field); + Settings.main().update(); + Lampa.Template.add('settings_webos_launcher', "
    \n
    \n
    #{settings_webos_launcher_add_device}
    \n
    \n
    \n
    #{settings_webos_launcher_remove_device}
    \n
    \n
    "); + Settings.listener.follow('open', function (e) { + var appid = webOS.fetchAppId(); + console.log('WebOS', 'current appid:', appid); + if (appid.length == 0) appid = window.lampa_settings.iptv ? 'icva' : 'com.lampa.tv'; + + if (e.name == 'webos_launcher') { + e.body.find('[data-name="add"]').unbind('hover:enter').on('hover:enter', function () { + webOS.service.request("luna://com.webos.service.eim", { + method: "addDevice", + parameters: { + "appId": appid, + "pigImage": "/pigImage.jpg", + "type": "MVPD_IP", + "showPopup": true, + "label": "Lampa", + "description": "Lampa app for LG webOS" + }, + onSuccess: function onSuccess(res) { + Noty.show(Lang.translate('settings_added')); + }, + onFailure: function onFailure(res) { + Noty.show(Lang.translate('title_error') + ': ' + res.errorText); + } + }); + }); + e.body.find('[data-name="remove"]').unbind('hover:enter').on('hover:enter', function () { + webOS.service.request("luna://com.webos.service.eim", { + method: "deleteDevice", + parameters: { + "appId": appid, + "showPopup": true + }, + onSuccess: function onSuccess(res) { + Noty.show(Lang.translate('settings_added')); + }, + onFailure: function onFailure(res) { + Noty.show(Lang.translate('title_error') + ': ' + res.errorText); + } + }); + }); + } + }); + } + + var WebOSLauncher = { + init: init$o + }; + + /** + * События через сокет + * @returns {void} + */ + + function Event() { + var ids = {}; + var evokes = {}; + + function callback(data) { + if (data.method == 'callback' && ids[data.callback_name] == data.callback_id) { + evokes[data.callback_id](data); + + evokes[data.callback_id] = function () {}; + } + } + + this.call = function (method, params, call) { + if (!ids[method]) ids[method] = Utils$1.uid(10); + params.callback_id = ids[method]; + params.callback_name = method; + evokes[params.callback_id] = call; + Socket.send('callback', params); + }; + + this.cancel = function (method) { + if (ids[method]) { + evokes[ids[method]] = function () {}; + } + }; + + this.destroy = function () { + Socket.listener.remove('message', callback); + + for (var i in evokes) { + evokes[i] = function () {}; + } + }; + + Socket.listener.follow('message', callback); + } + + /** + * Режим разработчика + * @param {function} callSelected Функция, которая вызывается при закрытии меню разработчика + */ + + function open$1(callSelected) { + var html = Template.get('lang_choice', {}); + var scroll = new Scroll({ + mask: true, + over: true + }); + + function btn(name, select) { + var item = $('
    ' + name + '
    '); + item.on('hover:enter', function (e) { + if (select) select(); + }).on('hover:focus', function (e) { + scroll.update($(e.target), true); + }).on('click', function (e) { + if (select && DeviceInput.canClick(e.originalEvent)) select(); + }); + scroll.append(item); + } + + function destroy() { + html.fadeOut(300, function () { + scroll.destroy(); + html.remove(); + scroll = null; + html = null; + }); + Controller.add('developer', { + toggle: function toggle() {} + }); + } + + function close() { + destroy(); + callSelected(); + } + + var btns = [{ + name: Lang.translate('title_continue_two'), + select: close + }, { + name: Lang.translate('plugins_remove'), + select: function select() { + Storage.set('plugins', []); + close(); + } + }, { + name: Lang.translate('settings_reset'), + select: function select() { + localStorage.clear(); + window.location.reload(); + destroy(); + } + }]; + btns.forEach(function (item) { + btn(item.name, item.select); + }); + html.find('.lang__selector').append(scroll.render()); + $('body').append(html); + Controller.add('developer', { + toggle: function toggle() { + Controller.collectionSet(scroll.render()); + Controller.collectionFocus(false, scroll.render()); + }, + up: function up() { + Navigator.move('up'); + }, + down: function down() { + Navigator.move('down'); + } + }); + Controller.toggle('developer'); + } + + var Developer = { + open: open$1 + }; + + var network; + + function init$n() { + network = new Request(); + Socket.listener.follow('message', function (e) { + if (e.method == 'premiere') update$1(e.data); + }); + } + + function update$1(data) { + var id = data.type + '/' + data.id; + console.log('Premiere', 'load:', data, 'exist:', Boolean(Notice$1.classes.lampa.notices.find(function (n) { + return n.id == id; + }))); + if (Notice$1.classes.lampa.notices.find(function (n) { + return n.id == id; + })) return; + var codes = Arrays.getKeys(Lang.codes()); + network.silent(TMDB$1.api(id + '?append_to_response=translations,credits&language=' + Storage.get('language', 'ru') + '&api_key=' + TMDB$1.key()), function (movie) { + network.silent(TMDB$1.api(id + '/images?include_image_language=' + codes.join(',') + '&language=' + Storage.get('language', 'ru') + '&api_key=' + TMDB$1.key()), function (images) { + var card = Arrays.clone(movie); + console.log('Premiere', 'card loaded', card); + delete card.translations; + delete card.credits; + delete card.credits; + delete card.spoken_languages; + delete card.production_companies; + delete card.production_countries; + var notice = { + id: id, + from: 'cub', + title: {}, + text: {}, + time: Date.now(), + poster: {}, + card: card + }; + var translations = movie && movie.translations && Array.isArray(movie.translations.translations) ? movie.translations.translations : []; + + if (translations.length) { + translations.filter(function (t) { + return codes.indexOf(t.iso_639_1) >= 0; + }).forEach(function (t) { + notice.title[t.iso_639_1] = Lang.translate('premiere_title') + ': ' + (t.data.title || t.data.name || movie.title || movie.name); + notice.text[t.iso_639_1] = (t.data.overview || movie.overview || '').slice(0, 130) + '...'; + }); + } else { + codes.forEach(function (code) { + notice.title[code] = Lang.translate('premiere_title') + ': ' + (movie.title || movie.name || ''); + notice.text[code] = (movie.overview || '').slice(0, 130) + '...'; + }); + } + + var posters = images && Array.isArray(images.posters) ? images.posters : []; + posters.forEach(function (i) { + notice.poster[i.iso_639_1] = i.file_path; + }); + + if (movie.credits && movie.credits.cast) { + var casts = movie.credits.cast.filter(function (c) { + return (c.known_for_department || '').toLowerCase() == 'acting'; + }); + + if (casts.length) { + notice.author = {}; + codes.forEach(function (c) { + notice.author[c] = { + name: casts[0].name || casts[0].character, + img: casts[0].profile_path, + text: Lang.translate('premiere_author_recomend_' + (Math.floor(Math.random() * 5) + 1)) + }; + }); + } + } + + Notice$1.pushNotice('lampa', notice, function () { + console.log('Premiere', 'card added'); + }, function (er) { + console.log('Premiere', 'card added error:', er); + }); + }); + }); + } + + var Premiere = { + init: init$n + }; + + /** + * Показать уведомление о продлении премиум-статуса + * @returns {void} + */ + + function init$m() { + if (Account$1.Permit.access && Lang.selected(['ru', 'uk', 'be', 'bg']) && window.lampa_settings.account_use) { + if (Account$1.Permit.user.premium && !Account$1.hasPremium()) setTimeout(push$2, 5000); + } + } + + function push$2() { + var now = new Date(); + var id = 'extend_premium_' + now.getFullYear() + '_' + now.getMonth(); + if (Notice$1.classes.lampa.notices.find(function (n) { + return n.id == id; + })) return; + var notice = { + id: id, + from: 'cub', + title: { + ru: 'Продлите CUB Premium прямо сейчас!', + uk: 'Продовжіть CUB Premium прямо зараз!', + be: 'Працягнеце CUB Premium прама зараз!', + bg: 'Подновете CUB Premium точно сега!' + }, + text: { + ru: 'Ваша подписка на CUB Premium истекла! Не упустите шанс продлить доступ к эксклюзивному контенту и дополнительным функциям. Обновите премиум-статус сейчас и наслаждайтесь всеми преимуществами CUB без ограничений!', + uk: 'Ваша передплата на CUB Premium закінчилася! Не пропустіть шанс продовжити доступ до ексклюзивного контенту та додаткових функцій. Оновіть преміум-статус зараз та насолоджуйтесь усіма перевагами CUB без обмежень!', + be: 'Ваша падпіска на CUB Premium скончылася! Не выпусціце шанец падоўжыць доступ да эксклюзіўнага кантэнту і дадатковым функцый. Абнавіце прэміум-статус зараз і атрымлівайце асалоду ад усімі перавагамі CUB без абмежаванняў!', + bg: 'Вашият абонамент за CUB Premium е изтекъл! Не пропускайте шанса си да подновите достъпа си до ексклузивно съдържание и допълнителни функции. Надстройте до премиум статус сега и се насладете на всички предимства на CUB без ограничения!' + }, + time: Date.now(), + icon: Utils$1.protocol() + object$2.cub_domain + '/img/icons/premium_two.svg' + }; + Notice$1.pushNotice('lampa', notice, function () {}, function (er) {}); + } + + var Extend = { + init: init$m + }; + + var Manager = new VastManager({ + api: 'banner', + cooling: 1000 * 60 * 20 + }); + var adContainer, adDisplayContainer, adsLoader; + var adsManager = null; + var showTimeout = null; + var timeout = 1000 * 60; + var banner = null; + + function init$l() { + Manager.init(); + Lampa.Player.listener.follow('ready', function () { + Manager.markCooling(); + }); + Lampa.Player.listener.follow('destroy', stop); + Lampa.PlayerPanel.listener.follow('visible', function (e) { + return resize(e.status ? Lampa.PlayerPanel.render()[0].offsetHeight : 0); + }); + Lampa.PlayerFooter.listener.follow('open', function (e) { + return resize(Lampa.PlayerFooter.render().offsetHeight); + }); + Lampa.PlayerFooter.listener.follow('close', function (e) { + return resize(Lampa.PlayerPanel.render()[0].offsetHeight); + }); + var first = true; + Timer.add(1000 * 60, function () { + Manager.params.cooling = 1000 * 60 * (window.lampa_settings.developer.enabled ? 2 : 20); + var play_data = Lampa.Player.playdata(); + var can_show = IMA.canShow(play_data); + var vast_banner = play_data.vast_banner && !(Account$1.hasPremium() || Personal.confirm()); + + if (vast_banner) { + vast_banner = { + url: play_data.vast_banner, + name: 'plugin' + }; + } + + if (Lampa.Player.opened() && Manager.coolingReady() && (can_show || vast_banner)) { + banner = can_show ? Manager.get(play_data, first) : vast_banner; + console.log('Ad', 'show banner', banner); + + if (banner) { + first = false; + Manager.markCooling(); + stop(); + start$3(); + } else { + first = true; + } + } + }); + } + + function stat(method) { + IMA.metric('banner', method, banner.name); + } + + function resize(panelHeight) { + if (!adContainer) return; + adContainer.style.height = window.innerHeight - panelHeight - (panelHeight ? 20 : 0) + 'px'; + + if (adsManager) { + var w = adContainer.offsetWidth || window.innerWidth; + var h = adContainer.offsetHeight || window.innerHeight; + + try { + adsManager.resize(w, h, google.ima.ViewMode.NORMAL); + } catch (ex) {} + } + } + + function loaded(event) { + var video = Lampa.PlayerVideo.video(); + if (!Lampa.Player.opened()) return; + stat('run'); + var adsRenderingSettings = new google.ima.AdsRenderingSettings(); + adsRenderingSettings.uiElements = []; + adsManager = event.getAdsManager(video, adsRenderingSettings); + adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, function (e) { + console.log('Ad', 'banner started'); + stat('started'); + showTimeout = setTimeout(function () { + console.log('Ad', 'banner complete'); + stat('complete'); + stop(); + }, timeout); + }); + adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, function (e) { + console.error('Ad', 'manager error', e.getError()); + error(200); + stop(); + }); + var player = Lampa.Player.render()[0]; + var w = player ? player.offsetWidth : window.innerWidth; + var h = player ? player.offsetHeight : window.innerHeight; + + try { + adsManager.init(w, h, google.ima.ViewMode.NORMAL); + adsManager.start(); + resize(Lampa.Player.render().hasClass('player--panel-visible')); + } catch (e) { + console.error('Ad', 'init error', e); + error(300); + stop(); + } + } + + function start$3() { + IMA.loadSDK3().then(function () { + if (!Lampa.Player.opened()) return; + var video = Lampa.PlayerVideo.video(); // Контейнер должен быть внутри .player, чтобы IMA SDK + // правильно рассчитывал позицию overlay относительно видео + + var player = Lampa.Player.render()[0]; + adContainer = document.createElement('div'); + adContainer.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;pointer-events:none;'; + player.appendChild(adContainer); + adDisplayContainer = new google.ima.AdDisplayContainer(adContainer, video); + adsLoader = new google.ima.AdsLoader(adDisplayContainer); + adsLoader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, loaded); + adsLoader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, function (e) { + console.error('Ad', 'banner loader error', e.getError()); + error(100); + stop(); + }); // initialize() должен вызываться до requestAds() и из пользовательского контекста + + adDisplayContainer.initialize(); + var slotWidth = player.offsetWidth || window.innerWidth; + var slotHeight = player.offsetHeight || window.innerHeight; + var request = new google.ima.AdsRequest(); + request.adTagUrl = IMA.buildUrl(banner.url); + request.linearAdSlotWidth = slotWidth; + request.linearAdSlotHeight = slotHeight; + request.nonLinearAdSlotWidth = slotWidth; + request.nonLinearAdSlotHeight = Math.round(slotHeight * 0.3); + adsLoader.requestAds(request); + stat('launch'); + })["catch"](function (e) { + console.error('Ad', 'banner SDK load failed', e); + }); + } + + function error(code) { + IMA.metric('banner', 'error', banner.name); + IMA.metric('banner', 'error_' + code, banner.name); + } + + function stop() { + clearTimeout(showTimeout); + showTimeout = null; + + if (adsManager) { + try { + adsManager.stop(); + adsManager.destroy(); + } catch (e) {} + + adsManager = null; + } + + if (adsLoader) { + try { + adsLoader.destroy(); + } catch (e) {} + + adsLoader = null; + } + + if (adContainer) { + adContainer.remove(); + adContainer = null; + } + } + + var Banner = { + init: init$l + }; + + function init$k() { + Premiere.init(); + Extend.init(); + + if (!Platform.is(['orsay', 'netcast'])) { + Preroll.init(); + Banner.init(); + } + } + + var AdManager = { + init: init$k + }; + + /** + * Инициализирует навигационную панель (только для мобильных устройств) + * @returns {void} + */ + + function init$j() { + if (Platform.screen('mobile')) { + var bar = Template.get('navigation_bar', {}); + bar.find('.navigation-bar__item').on('click', function () { + var action = $(this).data('action'); + if (action == 'back') Controller.back();else if (action == 'main') { + Activity.push({ + url: '', + title: Lang.translate('title_main') + ' - ' + Storage.field('source').toUpperCase(), + component: 'main', + source: Storage.field('source') + }); + } else if (action == 'search') { + Lampa.Search.open(); + } else if (action == 'settings') { + Controller.toggle('settings'); + } + }); + $('body').append(bar); + } + } + + var NavigationBar = { + init: init$j + }; + + function Endless(onRender) { + var _this = this; + + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var wrap = document.createElement('div'); + var position = params.position || 0; + wrap.addClass('endless'); + wrap.addEventListener('mousewheel', function (e) { + _this.move(e.wheelDelta / 120 > 0 ? -1 : 1); + }); + var touch; + + var touchStart = function touchStart(e) { + var point = e.touches[0] || e.changedTouches[0]; + touch = { + position: position, + from: point.clientY, + to: 0 + }; + window.addEventListener('touchend', touchEnd); + window.addEventListener('touchmove', touchMove); + }; + + var touchMove = function touchMove(e) { + var point = e.touches[0] || e.changedTouches[0]; + + if (touch) { + var to = Math.round((point.clientY - touch.from) / (window.innerHeight * 0.1)); + + if (touch.to !== to) { + var move = touch.position - to; + touchEnd(); + + _this.to(move); + } + } + }; + + var touchEnd = function touchEnd(e) { + window.removeEventListener('touchend', touchEnd); + window.removeEventListener('touchmove', touchMove); + touch = false; + }; + + wrap.addEventListener('touchstart', touchStart); + + this.move = function (dir) { + var dif = position - (position + dir); + position += dir; + this.draw(dif); + }; + + this.to = function (to) { + var dif = position - to; + position = to; + this.draw(dif); + }; + + this.draw = function (dif) { + var render = onRender(position); + + if (render) { + wrap.removeClass('endless-up endless-down'); + wrap.style.animation = 'none'; + wrap.offsetHeight; + wrap.style.animation = null; + wrap.empty().append(render); + wrap.addClass(dif == -1 ? 'endless-down' : 'endless-up'); + } + }; + + this.render = function () { + return wrap; + }; + + this.destroy = function () { + wrap.remove(); + }; + + this.draw(0); + } + + /** + * Скрыть ненужные элементы интерфейса + */ + + function hide() { + Settings.listener.follow('open', function (e) { + if (e.name == 'main') { + e.body.find(['player', 'account', 'parser', 'server', 'plugins'].map(function (a) { + return '[data-component="' + a + '"]'; + }).join(', ')).addClass('hide'); + } else { + e.body.find(['start_page', 'card_quality', 'card_episodes', 'proxy_tmdb_auto', 'proxy_tmdb', 'tmdb_proxy_api', 'tmdb_proxy_image', 'card_interfice_type', 'source'].map(function (a) { + return '[data-name="' + a + '"]'; + }).join(', ')).addClass('hide'); + } + }); + var head = $('.head'); + var menu = $('.menu'); + $('.open--broadcast, .open--search,.open--notice,.open--premium', head).remove(); + $(['catalog', 'feed', 'filter', 'relise', 'anime', 'favorite', 'subscribes', 'timetable', 'mytorrents', 'console', 'about'].map(function (a) { + return '[data-action="' + a + '"]'; + }).join(', '), menu).remove(); + Arrays.remove(TMDB.genres.movie, TMDB.genres.movie.find(function (g) { + return g.id == 99; + })); + var genres_id = [99, 10764, 10766, 10767, 10768, 10763]; + genres_id.forEach(function (id) { + Arrays.remove(TMDB.genres.tv, TMDB.genres.tv.find(function (g) { + return g.id == id; + })); + }); + Lampa.Listener.follow('full', function (e) { + if (e.type == 'complite') { + e.object.activity.render().find('.full-start-new__buttons, .full-start__icons, .full-start__footer').remove(); + } + }); + } + /** + * Инициализация демо режима + * @returns {void} + */ + + + function init$i() { + if (window.lampa_settings.demo) { + Lampa.Listener.follow('app', function (e) { + if (e.type == 'ready') hide(); + }); + } + } + + var Demo = { + init: init$i + }; + + var html$3; + var tout; + var xmlHTTP; + var controll$1; + var active$1 = {}; + var graph = []; + /** + * Инициализация теста скорости + * @returns {void} + */ + + function init$h() { + Settings.listener.follow('open', function (e) { + if (e.name == 'server') { + var btn = $("
    \n
    ".concat(Lang.translate('speedtest_button'), "
    \n
    ")); + btn.on('hover:enter', function () { + if (Torserver.ip()) { + var params = { + url: Torserver.url() + '/download/300' + }; + + if (Storage.field('torrserver_auth')) { + params.login = Storage.get('torrserver_login'); + params.password = Storage.value('torrserver_password'); + } + + start$2(params); + } + }); + $('[data-name="torrserver_url_two"]', e.body).after(btn); + } + }); + } + /** + * Запуск теста скорости + * @param {object} params - параметры теста + * @param {string} params.url - URL для теста скорости + * @param {string} [params.login] - логин для авторизации + * @param {string} [params.password] - пароль для авторизации + * @param {function} [params.onEnd] - вызывается по окончании теста + * @param {function} [params.onBack] - вызывается при выходе из теста + * @returns {void} + */ + + + function start$2(params) { + if (html$3) html$3.remove(); + active$1 = params; + controll$1 = Controller.enabled().name; + html$3 = Template.js('speedtest'); + html$3.append(HeadBackward('', true)); + document.body.append(html$3); + var textpath = Array.from(html$3.querySelectorAll('textpath')); + textpath.forEach(function (element) { + element.html(element.getAttribute('data-text')); + }); + html$3.find('#speedtest_num-text').html('Mbps'); + toggle(); + if (active$1.url) testUrl(active$1.url); + } + + function speed2deg(v) { + v = parseFloat(v); + return v >= 1000 ? 200 : v < 20 ? v * 4 : v < 30 ? (v - 20) * 2 + 80 : v < 60 ? (v - 30) / 1.5 + 100 : v < 100 ? (v - 60) / 2 + 120 : v < 200 ? (v - 100) / 5 + 140 : v < 500 ? (v - 200) / 15 + 160 : (v - 500) / 25 + 180; + } + + function hslToRgb(hue, sat, light) { + hue = hue % 360, hue += hue < 0 ? hue += 360 : 0, sat /= 100, light /= 100; + + function f(n) { + var k = (n + hue / 30) % 12; + var a = sat * Math.min(light, 1 - light); + return parseInt((light - a * Math.max(-1, Math.min(k - 3, 9 - k, 1))) * 255); + } + + return "#" + ((1 << 24) + (f(0) << 16) + (f(8) << 8) + f(4)).toString(16).slice(1); + } + + function setSpeed(v) { + v = parseFloat(v); + html$3.find('#speedtest_num').innerHTML = v < 1 ? v.toFixed(3) : v < 10 ? v.toFixed(2) : v < 100 ? v.toFixed(1) : Math.round(v); + var r = speed2deg(v); + var b = html$3.find('#speedtest_progress'); + var l = 1256.8; + b.style['stroke-dasharray'] = l * r / 360 + ',' + l; + b.style.stroke = hslToRgb(330 + r, 80, 45); + html$3.find('#speedtest_graph').setAttribute('points', graph.map(function (pt) { + return pt.join(','); + }).join(' ')); + } + + function normalizeUrl(base, link) { + if (link[0] === '/') return base.replace(/^(https?:\/\/[^\/]+).*$/i, '$1') + link; + if (/^https?:?\/\//i.test(link)) return link; + base = base.replace(/\/[^\/]*(\?.*)?$/, '') + '/'; + return base + link; + } + + function testUrl(url) { + if (!/\.m3u8?(\?.*)?$/i.test(url)) return testSpeed(url); + + var errorFn = function errorFn(e) { + html$3.find('#speedtest_status').html(Lang.translate('network_error')); + }; + + xmlHTTP = new XMLHttpRequest(); + $.ajax({ + url: url, + cache: false, + dataType: 'text', + xhr: function xhr() { + return xmlHTTP; + }, + success: function success(data) { + if (data.substr(0, 7) !== '#EXTM3U') return errorFn(); + var i = 0, + links = [], + bandwidth = 0, + setLink = false, + m, + l = data.split(/\r?\n/); + data = null; + + for (; links.length < 100 && i < l.length; i++) { + if (!!(m = l[i].match(/^#EXTINF:\s*(-?\d+(\.\d*)?)\s*,.*$/))) { + setLink = true; + } else if (!!(m = l[i].match(/^#EXT-X-STREAM-INF:(.+,)?\s*BANDWIDTH=(\d+)\s*(,.+)?$/))) { + if (bandwidth < parseInt(m[2])) { + bandwidth = parseInt(m[2]); + setLink = true; + } else setLink = false; + } else if (setLink && !!(m = l[i].match(/^[^#].+$/i))) { + links.push(normalizeUrl(xmlHTTP.responseURL, m[0].trim())); + setLink = false; + } + } + + if (links.length === 0) return errorFn(); + if (bandwidth > 0) return testUrl(links.pop()); + testM3u8Stream(links); + }, + error: errorFn + }); + } + + function testM3u8Stream(links) { + if (links.length === 0) { + return html$3.find('#speedtest_status').html(Lang.translate('network_error')); + } + + var status = html$3.find('#speedtest_status'); + var time; + var speed = 0, + speedMbps = 0; + var currentSegment = 0; + var maxSegments = links.length; // Берем все сегменты + + var totalBytes = 0; // Общий счетчик байт + + var startTime; // Время начала всего теста + + status.innerHTML = Lang.translate('speedtest_connect'); + graph = [[-250, -250]]; + setSpeed(0); + + function loadNextSegment() { + if (currentSegment >= maxSegments) { + // Завершаем тест + setSpeed(speedMbps); + status.innerHTML = Lang.translate('speedtest_ready'); + + if (typeof active$1.onEnd === 'function') { + active$1.onEnd.apply(self, [speedMbps, xmlHTTP]); + } + + return; + } + + var segmentUrl = links[currentSegment]; + console.log('Speed', 'testM3u8', 'loading segment', currentSegment + 1, '/', maxSegments, segmentUrl); + xmlHTTP = new XMLHttpRequest(); + xmlHTTP.open('GET', Utils$1.addUrlComponent(segmentUrl, 'vr=' + Date.now()), true); + xmlHTTP.responseType = 'arraybuffer'; + + xmlHTTP.onprogress = function (e) { + if (!time || time === true) return; + var totalTime = e.timeStamp - startTime; // Время от начала всего теста + + var currentBytes = totalBytes + e.loaded; // Общие загруженные байты + // Вычисляем скорость от начала теста + + speed = Math.ceil(currentBytes * 8000 / totalTime); + speedMbps = speed / 1000 / 1000; // График строим по общему времени и данным + + var x = Math.max(Math.min(totalTime, 1e4) * 500 / 1e4, Math.min(currentBytes, 3e8) * 500 / 3e8) - 250; + var y = -(speed2deg(speedMbps) / 4 + 250); + graph.push([x.toFixed(1), y.toFixed(1)]); + setSpeed(speedMbps); + if (totalTime >= 1e4 || currentBytes > 3e8) xmlHTTP.abort(); + }; + + xmlHTTP.onreadystatechange = function (e) { + if (xmlHTTP.readyState === 2) { + if (currentSegment === 0) { + // Устанавливаем время начала только для первого сегмента + time = e.timeStamp; + startTime = e.timeStamp; + status.innerHTML = Lang.translate('speedtest_test'); // Общий таймаут на весь тест + + tout = setTimeout(function () { + xmlHTTP.abort(); + }, 15e3); + } + } + }; + + var endSegment = function endSegment(e) { + if (xmlHTTP.response) { + totalBytes += xmlHTTP.response.byteLength; + } + + currentSegment++; + loadNextSegment(); + }; + + xmlHTTP.onload = endSegment; + + xmlHTTP.onabort = function (e) { + clearTimeout(tout); + setSpeed(speedMbps); + status.innerHTML = Lang.translate('speedtest_ready'); + + if (typeof active$1.onEnd === 'function') { + active$1.onEnd.apply(self, [speedMbps, xmlHTTP]); + } + }; + + xmlHTTP.onerror = endSegment; + xmlHTTP.send(); + } + + loadNextSegment(); + } + + function testSpeed(url) { + var context = this; + var status = html$3.find('#speedtest_status'); + var time; + status.innerHTML = Lang.translate('speedtest_connect'); + graph = [[-250, -250]]; + var speed = 0, + speedMbps = 0; + setSpeed(0); + xmlHTTP = new XMLHttpRequest(); + xmlHTTP.open('GET', Utils$1.addUrlComponent(url, 'vr=' + new Date() * 1), true); + if (active$1.login && active$1.password) xmlHTTP.setRequestHeader("Authorization", "Basic " + Base64.encode(active$1.login + ":" + active$1.password)); + xmlHTTP.responseType = 'arraybuffer'; + + xmlHTTP.onprogress = function (e) { + if (!time || time === true) return; + var load = e.timeStamp - time; + speed = Math.ceil(e.loaded * 8000 / load); // Бит в секунду + + speedMbps = speed / 1000 / 1000; + var x = Math.max(Math.min(load, 1e4) * 500 / 1e4, Math.min(e.loaded, 3e8) * 500 / 3e8) - 250, + y = -(speed2deg(speedMbps) / 4 + 250); + graph.push([x.toFixed(1), y.toFixed(1)]); + setSpeed(speedMbps); + if (load >= 1e4 || e.loaded > 3e8) xmlHTTP.abort(); + }; + + xmlHTTP.onreadystatechange = function (e) { + if (xmlHTTP.readyState === 2) { + time = e.timeStamp; + status.innerHTML = Lang.translate('speedtest_test'); + tout = setTimeout(function () { + xmlHTTP.abort(); + }, 15e3); + } + }; + + var endTest = function endTest(e) { + clearTimeout(tout); + setSpeed(speedMbps); + status.innerHTML = Lang.translate('speedtest_ready'); + time = false; + if (typeof active$1.onEnd === 'function') active$1.onEnd.apply(context, [speedMbps, xmlHTTP]); + }; + + xmlHTTP.onload = endTest; + xmlHTTP.onabort = endTest; + xmlHTTP.onerror = endTest; + xmlHTTP.send(); + } + + function toggle() { + Controller.add('speedtest', { + toggle: function toggle() { + Controller.clear(); + }, + back: close$1 + }); + Controller.toggle('speedtest'); + } + /** + * Закрыть тест скорости + * @returns {void} + */ + + + function close$1() { + if (xmlHTTP) xmlHTTP.abort(); + clearTimeout(tout); + html$3.remove(); + html$3 = false; + xmlHTTP = false; + if (active$1.onBack) active$1.onBack();else Controller.toggle(controll$1); + active$1 = {}; + } + + var Speedtest = { + init: init$h, + close: close$1, + start: start$2 + }; + + var html$2, text; + var processing = []; + /** + * Инициализирует слой прогресса обработки + * @returns {void} + */ + + function init$g() { + html$2 = $('
    '); + text = html$2.find('.processing__text'); + update(); + } + /** + * Обновляет слой прогресса обработки + * @returns {void} + */ + + + function update() { + if (processing.length) { + text.text(processing.length > 1 ? processing.length : '1 / ' + Math.round(processing[0].percent) + '%'); + var complite = processing.find(function (a) { + return a.percent >= 100; + }); + if (complite) Lampa.Arrays.remove(processing, complite); + requestAnimationFrame(update); + } else html$2.addClass('hide'); + } + /** + * Добавляет процесс обработки + * @param {string} id - уникальный идентификатор процесса + * @param {number} percent - процент выполнения процесса (0-100) + * @returns {void} + */ + + + function push$1(id, percent) { + var find = processing.find(function (a) { + return a.id == id; + }); + + if (!find) { + processing.push({ + id: id, + percent: percent, + start: Date.now() + }); + html$2.removeClass('hide'); + update(); + } else find.percent = percent; + } + /** + * Возвращает HTML слой прогресса обработки + * @param {boolean} [js=false] - возвращать как JS объект или jQuery + * @returns {jQuery|HTMLElement} + */ + + + function render(js) { + return js ? html$2[0] : html$2; + } + + var Processing = { + init: init$g, + push: push$1, + render: render + }; + + function init$f() { + if (!window.lampa_settings.iptv) return; + var components = ['tmdb', 'plugins', 'content_rows']; + var titles = ['card_interfice_type']; + var params = ['light_version', 'card_interfice_type', 'card_interfice_reactions', 'player_timecode', 'pages_save_total', 'device_name', 'playlist_next', 'background_type', 'card_views_type', 'hide_outside_the_screen', 'card_interfice_cover', 'card_interfice_poster', 'start_page', 'source', 'card_quality', 'card_episodes', 'player']; + Lang.add({ + about_text: { + ru: 'Наслаждайтесь любимыми телепередачами, фильмами и спортивными событиями на вашем устройстве с нашим приложением для просмотра IPTV каналов. Наше приложение просто в использовании и позволяет настроить список избранных каналов для быстрого доступа к любимым программам. Просматривайте телевизор в любое время и в любом месте, не пропуская ни одного важного момента благодаря нашему надежному и удобному IPTV приложению.', + uk: 'Насолоджуйтесь улюбленими телепередачами, фільмами та спортивними подіями на вашому пристрої з нашим програмою для перегляду IPTV каналів. Наша програма просто у використанні та дозволяє налаштувати список вибраних каналів для швидкого доступу до улюблених програм. Переглядайте телевізор у будь-який час та в будь-якому місці, не пропускаючи жодного важливого моменту завдяки нашому надійному та зручному IPTV додатку.', + be: 'Атрымлівайце асалоду ад любімымі тэлеперадачамі, фільмамі і спартыўнымі падзеямі на вашым прыладзе з нашым дадаткам для прагляду IPTV каналаў. Наша дадатак проста ў выкарыстанні і дазваляе наладзіць спіс абраных каналаў для хуткага доступу да любімых праграм. Праглядайце тэлевізар у любы час і ў любым месцы, не прапускаючы ніводнага важнага моманту дзякуючы нашаму надзейнаму і зручнаму IPTV з дадаткам.', + en: 'Enjoy your favorite TV shows, movies and sports on your device with our IPTV channel viewer app. Our application is easy to use and allows you to set up your favorite channel list for quick access to your favorite programs. Watch TV anytime, anywhere without missing a single important moment thanks to our reliable and convenient IPTV application.', + pt: 'Aproveite seus programas de TV, filmes e esportes favoritos em seu dispositivo com nosso aplicativo visualizador de canais IPTV. Nosso aplicativo é fácil de usar e permite que você configure sua lista de canais favoritos para acesso rápido aos seus programas favoritos. Assista TV a qualquer hora, em qualquer lugar, sem perder um único momento importante, graças ao nosso aplicativo IPTV confiável e conveniente.', + zh: '使用我们的 IPTV 频道查看器应用程序在您的设备上欣赏您最喜爱的电视节目、电影和体育节目。 我们的应用程序易于使用,并允许您设置您最喜爱的频道列表,以便快速访问您最喜爱的节目。 借助我们可靠且方便的 IPTV 应用程序,随时随地观看电视,不会错过任何一个重要时刻。' + }, + empty_title_two: { + ru: 'Произошла ошибка', + uk: 'Виникла помилка', + be: 'Адбылася памылка', + en: 'An error has occurred', + pt: 'Оcorreu um erro', + zh: '发生了错误' + }, + empty_text_two: { + ru: 'К сожалению, приложение не загружается. Рекомендуем попробовать перезагрузить его.', + uk: 'На жаль, програма не завантажується. Рекомендуємо спробувати перезавантажити його.', + be: 'Нажаль, прыкладанне не загружаецца. Рэкамендуем паспрабаваць перазагрузіць яго.', + en: 'Unfortunately, the application does not load. We recommend that you try rebooting it.', + pt: 'Infelizmente, o aplicativo não carrega. Recomendamos que você tente reiniciá-lo.', + zh: '不幸的是,该应用程序未加载。 我们建议您尝试重新启动它。' + } + }); + + window.iptvClearSettingsFunction = function (e) { + titles.forEach(function (t) { + var param = $('[data-name="' + t + '"]', e.body).prev(); + if (param.length && param.hasClass('settings-param-title')) param.remove(); + }); + $(components.map(function (c) { + return '[data-component="' + c + '"]'; + }).join(','), e.body).remove(); + $(params.map(function (c) { + return '[data-name="' + c + '"]'; + }).join(','), e.body).remove(); + }; + + window.iptvClearFunction = function () { + $('.menu .menu__list:eq(0)').empty(); + $('.head .open--notice, .head .open--search, .head .open--feed, .head .open--premium').addClass('hide'); + + window.iptvClearFunction = function () {}; + }; + + setTimeout(function () { + window.iptvClearFunction(); + }, 10); + Lampa.Settings.listener.follow('open', window.iptvClearSettingsFunction); + Utils$1.putScriptOfMirrors([Utils$1.protocol() + object$2.cub_domain + '/plugin/iptv'], function () { + console.log('IPTV', 'load from lampa', 'complite'); + }, function () { + console.log('IPTV', 'load from lampa', 'error'); + }, function () { + console.log('IPTV', 'load from lampa', 'success'); + }, false); + } + + var Iptv = { + init: init$f + }; + + function init$e() { + var keyboard_mode = false; // Style to disable hover effects + + var style = document.createElement("style"); + style.innerHTML = "* { pointer-events: none !important; }"; // Disable hover on any keyboard event + + document.addEventListener("keydown", function (event) { + var tagName = ''; + + try { + tagName = event.target.tagName.toLowerCase(); + } catch (e) {} + + if (!keyboard_mode && !(tagName == "input" || tagName == "textarea")) { + console.log('HoverSwitcher', 'Keyboard moved, disabling pointer events'); + keyboard_mode = true; + document.head.appendChild(style); + } + }); + + function mouse() { + if (keyboard_mode) { + console.log('HoverSwitcher', 'Mouse moved, enabling pointer events'); + keyboard_mode = false; + document.head.removeChild(style); + } + } // Re-enable hover on mouse movement or touch + + + document.addEventListener("mousemove", mouse); + document.addEventListener("touchmove", mouse); + } + + var HoverSwitcher = { + init: init$e + }; + + /** + * Последовательное выполнение задач + * @param {Array} data - массив данных для обработки + * @property {function(object, function)} onProgress - функция, которая будет вызвана для каждого элемента массива, принимает элемент и функцию next для продолжения + * @property {function()} onComplite - функция, которая будет вызвана по завершении всех задач + * @example + * let task = new Task([1,2,3,4,5]) + * task.onProgress = (item, next)=>{ + * console.log('Process item:', item) + * next() //обязательно вызвать для продолжения + * } + * task.onComplite = ()=>{ + * console.log('All items processed') + * } + * task.start() //начать выполнение + */ + function Task$1(data) { + this.data = data; + this.work = 0; + this.need = data.length; + + this.check = function () { + if (this.work >= this.need) this.onComplite(); + }; + + this.next = function () { + var _this = this; + + this.onProgress(this.data[this.work], function () { + _this.work++; + if (_this.work < _this.need) _this.next();else _this.check(); + }); + }; + + this.start = function () { + if (this.need) this.next();else this.check(); + }; + } + + var queue_calls = []; + var secondary_calls = []; + + function queue(call) { + queue_calls.push(call); + } + + function secondary(call) { + secondary_calls.push(call); + } + /** + * Запуск очереди загрузки + * 1. Выполняет задачи из очереди queue_calls последовательно + * 2. После завершения всех задач из очереди queue_calls выполняет задачи из очереди secondary_calls параллельно + */ + + + function start$1() { + var task = new Task$1(queue_calls); + + task.onProgress = function (call, next) { + var called = false; + + var launch = function launch() { + if (!called) next(); + called = true; + }; + + var timer = setTimeout(launch, 16000); + + try { + call(function () { + clearTimeout(timer); + launch(); + }); + } catch (e) { + console.warn('Loader', 'queue task error:', e.message, e.stack); + clearTimeout(timer); + launch(); + } + }; + + task.onComplite = function () { + var progress = new Progress(); + progress.append(secondary_calls); + progress.start(function () {}); + }; + + task.start(); + } + + var Task = { + queue: queue, + secondary: secondary, + start: start$1 + }; + + function init$d() { + var loader; + var waite; + SettingsApi.addParam({ + component: 'more', + param: { + type: 'title' + }, + field: { + name: Lampa.Lang.translate('menu_console') + } + }); + SettingsApi.addParam({ + component: 'more', + param: { + name: 'export', + type: 'button' + }, + field: { + name: Lang.translate('settings_cub_backup_export') + }, + onChange: function onChange() { + if (waite) return; + waite = true; + loader.removeClass('hide'); + push().then(function (code) { + Modal.open({ + title: '', + html: $('
    ' + Lang.translate('account_export_secuses') + ': ' + code + '
    '), + size: 'small', + onBack: closeModal + }); + })["catch"](function (code) { + Noty.show(Lang.translate('account_export_fail' + (code && typeof code == 'number' ? '_' + code : ''))); + })["finally"](function () { + waite = false; + loader.addClass('hide'); + }); + }, + onRender: function onRender(item) { + loader = $('
    '); + item.append(loader); + } + }); + var terminal_elem; + var terminal_code = Storage.get('terminal_access', ''); + + function terminalDrawCode() { + if (!terminal_elem) return; + terminal_code = Storage.get('terminal_access', ''); + terminal_elem.find('.settings-param__descr').text(terminal_code ? Lang.translate('terminal_code') + ': ' + terminal_code : Lang.translate('terminal_no_access')); + } + + function terminalWriteCode(code) { + Storage.set('terminal_access', code); + terminalDrawCode(); + Socket.send('terminal', {}); + } + + SettingsApi.addParam({ + component: 'more', + param: { + name: 'terminal', + type: 'button' + }, + field: { + name: Lang.translate('terminal_title'), + description: Lang.translate('terminal_no_access') + }, + onChange: function onChange(a, b, c) { + Modal.open({ + title: '', + html: $('
    ' + Lang.translate('terminal_text') + '
    '), + size: 'medium', + buttons: [{ + name: Lang.translate(terminal_code ? 'terminal_update' : 'terminal_confirm'), + onSelect: function onSelect() { + closeModal(); + terminalWriteCode(Math.floor(100000 + Math.random() * 900000).toString()); + } + }, { + name: Lang.translate('terminal_deny'), + onSelect: function onSelect() { + closeModal(); + terminalWriteCode(''); + } + }], + onBack: closeModal + }); + }, + onRender: function onRender(item) { + terminal_elem = item; + terminalDrawCode(); + } + }); + } + + function closeModal() { + Modal.close(); + Controller.toggle('settings_component'); + } + + function push() { + return new Promise(function (resolve, reject) { + var file; + var data = JSON.stringify(Console["export"]()); + + try { + file = new File([data], "lampa_logs.json", { + type: "text/plain" + }); + } catch (e) {} + + if (!file) { + try { + file = new Blob([data], { + type: 'text/plain' + }); + file.lastModifiedDate = new Date(); + } catch (e) { + reject(); + } + } + + if (file) { + var formData = new FormData($('
    ')[0]); + formData.append("file", file, "lampa_logs.json"); + $.ajax({ + url: Utils$1.protocol() + object$2.cub_domain + '/api/lampa/logs/write', + type: 'POST', + data: formData, + async: true, + cache: false, + timeout: 10000, + contentType: false, + enctype: 'multipart/form-data', + processData: false, + success: function success(j) { + resolve(j.code); + }, + error: function error(e) { + reject(e.rresponseJSON ? e.responseJSON.code : 0); + } + }); + } + }); + } + + var Logs = { + init: init$d + }; + + var html$1; + var controll; + var active = {}; + /** + * Открыть менеджер хранилища + * @param {object} [params] - параметры + * @param {function} [params.onBack] - вызывается при выходе из менеджера + * @returns {void} + */ + + function open() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + active = params; + controll = Controller.enabled().name; + html$1 = $('
    '); + var keys = Object.keys(localStorage); + var hide = ['parental_', 'vast_', 'account_']; + + if (window.lampa_settings.hide_important_params) { + keys = keys.filter(function (key) { + return !hide.find(function (h) { + return key.indexOf(h) == 0; + }); + }); + } + + keys.sort(function (a, b) { + return a.localeCompare(b); + }); + keys.forEach(function (key) { + var value = Utils$1.shortText(localStorage.getItem(key), 50); // Не показывать метки времени + + if (parseInt(value) > 0 && (value + '').length == 13) return; + var line = $('
    ' + key + ' ' + value + '
    '); + line.on('hover:enter', function () { + Select.show({ + title: key, + items: [{ + title: Lang.translate('settings_remove'), + action: 'delete' + }], + onSelect: function onSelect(selected) { + Controller.toggle('modal'); + + if (selected.action == 'delete') { + localStorage.removeItem(key); + line.remove(); + } + }, + onBack: function onBack() { + Controller.toggle('modal'); + } + }); + }); + html$1.append(line); + }); + Modal.open({ + title: 'StorageManager', + size: 'large', + html: html$1, + onBack: close + }); + } + + function close() { + html$1.remove(); + Modal.close(); + if (active.onBack) active.onBack();else Controller.toggle(controll); + active = {}; + } + + var StorageMenager = { + close: close, + open: open + }; + + var component$1 = 'data'; + var icon$1 = "\n \n \n"; + + function init$c() { + SettingsApi.addComponent({ + component: component$1, + icon: icon$1, + name: Lang.translate('settings_rest_cache_all'), + after: 'parental_control' + }); + var status; + SettingsApi.addParam({ + component: component$1, + param: { + type: 'button' + }, + field: { + name: Lampa.Lang.translate('settings_rest_cache_calculate') + }, + onRender: function onRender(item) { + status = $("
    "); + item.append(status); + }, + onChange: function onChange(a, b) { + status.removeClass('hide'); + Storage.getsize(function (size) { + status.text(Lang.translate('title_left') + ' - ' + Utils$1.bytesToSize(size)); + }); + } + }); + SettingsApi.addParam({ + component: component$1, + param: { + type: 'title' + }, + field: { + name: Lampa.Lang.translate('more') + } + }); + SettingsApi.addParam({ + component: component$1, + param: { + type: 'button' + }, + field: { + name: Lampa.Lang.translate('extensions_edit') + }, + onChange: function onChange() { + StorageMenager.open({ + onBack: function onBack() { + Controller.toggle('settings_component'); + } + }); + } + }); + SettingsApi.addParam({ + component: component$1, + param: { + type: 'button' + }, + field: { + name: Lampa.Lang.translate('fav_clear_title') + }, + onChange: function onChange() { + Favorite.clear('history'); + Noty.show(Lang.translate('torrent_error_made')); + } + }); + SettingsApi.addParam({ + component: component$1, + param: { + type: 'button' + }, + field: { + name: Lampa.Lang.translate('settings_rest_cache') + }, + onChange: function onChange() { + Select.show({ + title: Lang.translate('settings_rest_cache'), + items: [{ + title: Lang.translate('settings_rest_cache_only'), + subtitle: Lang.translate('settings_rest_cache_only_descr') + }, { + title: Lang.translate('settings_rest_cache_all'), + subtitle: Lang.translate('settings_rest_cache_all_descr'), + full: true + }], + onSelect: function onSelect(a) { + Controller.toggle('settings_component'); + Storage.clear(a.full); + Cache.clearAll(); + }, + onBack: function onBack() { + Controller.toggle('settings_component'); + } + }); + } + }); + } + + var DataBase = { + init: init$c + }; + + var EmptyMap = { + Ai: Ai, + Simple: Simple, + Router: Router + }; + + var Helper = new Mask(Arrays.getKeys(EmptyMap)); + Helper.MASK.base = Helper.only('Simple'); + + var classes = { + Card: Card$3, + Main: Full$1, + Category: Full, + Line: Line$4, + Company: Company, + Discuss: Discuss, + Episode: Episode, + Person: Person, + Register: Register, + Season: Season, + CardParser: CardParser, + Empty: Empty + }; + var modules = { + Card: Helper$9, + Main: Helper$7, + Category: Helper$4, + Line: Helper$b, + Company: Helper$3, + Discuss: Helper$5, + Episode: Helper$a, + Person: Helper$6, + Register: Helper$8, + Season: Helper$2, + Empty: Helper + }; + var maps = { + Card: CardMap, + Episode: EpisodeMap, + Main: MainMap, + Category: CategoryMap, + Line: LineMap, + Company: CompanyMap, + Discuss: DiscussMap, + Person: PersonMap, + Register: RegisterMap, + Season: SeasonMap, + Empty: EmptyMap + }; + + var None = /*#__PURE__*/function (_Constructor) { + _inherits(None, _Constructor); + + var _super = _createSuper(None); + + function None() { + _classCallCheck(this, None); + + return _super.apply(this, arguments); + } + + return None; + }(Constructor({})); + + function make(class_name) { + var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var createModule = arguments.length > 2 ? arguments[2] : undefined; + var createName = get(class_name, data, createModule); + var createClass = new createName(data); + + if (data.params.emit && _typeof(data.params.emit) == 'object' && typeof createClass.use == 'function') { + createClass.use(data.params.emit); + + if (typeof data.params.emit.onInit == 'function') { + data.params.emit.onInit(createClass); + } + } + + return createClass; + } + + function get(class_name) { + var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var createModule = arguments.length > 2 ? arguments[2] : undefined; + + if (typeof classes[class_name] == 'undefined') { + console.log('Maker', 'error', 'no class', class_name); + return None; + } else { + Arrays.extend(data, { + params: {} + }); + + if (typeof createModule !== 'undefined') { + if (typeof modules[class_name] !== 'undefined') { + data.params.module = createModule(modules[class_name]); + } + } + + return classes[class_name]; + } + } + + function module$1(class_name) { + if (typeof modules[class_name] !== 'undefined') return modules[class_name]; + console.log('Maker', 'error', 'no module', class_name); + return new Mask([]); + } + + function map(class_name) { + if (typeof maps[class_name] == 'undefined') return {}; + return maps[class_name]; + } + + function list() { + return Object.keys(classes); + } + + var Maker = { + get: get, + make: make, + module: module$1, + list: list, + map: map + }; + + var torrent_net = new Request(); + /** + * Инициализация работы с локальным торрент сервером, проверка доступности и настройка + * @returns {void} + */ + + function init$b() { + Storage.listener.follow('change', function (e) { + if (e.name == 'torrserver_url') check(e.name); + if (e.name == 'torrserver_url_two') check(e.name); + if (e.name == 'torrserver_use_link') check(e.value == 'one' ? 'torrserver_url' : 'torrserver_url_two'); + }); + Settings.listener.follow('open', function (e) { + if (e.name == 'server') { + check(Storage.field('torrserver_use_link') == 'one' ? 'torrserver_url' : 'torrserver_url_two'); + } else torrent_net.clear(); + }); + } + + function check(name) { + if (Platform.is('android') && !Storage.field('internal_torrclient')) return; + var item = $('[data-name="' + name + '"]').find('.settings-param__status').removeClass('active error wait').addClass('wait'); + var url = Storage.get(name); + + if (url) { + torrent_net.timeout(10000); + var head = { + dataType: 'text' + }; + var auth = Storage.field('torrserver_auth'); + + if (auth) { + head.headers = { + Authorization: "Basic " + Base64.encode(Storage.get('torrserver_login') + ':' + Storage.value('torrserver_password')) + }; + } + + torrent_net["native"](Utils$1.checkEmptyUrl(Storage.get(name)), function () { + item.removeClass('wait').addClass('active'); + }, function (a, c) { + if (a.status == 401) { + item.removeClass('wait').addClass('active'); + Noty.show(Lang.translate('torrent_error_check_no_auth') + ' - ' + url, { + time: 5000 + }); + } else { + item.removeClass('wait').addClass('error'); + Noty.show(torrent_net.errorDecode(a, c) + ' - ' + url, { + time: 5000 + }); + } + }, false, head); + } + } + + var ServiceTorserver = { + init: init$b + }; + + /** + * Инициализация отправки информации о просмотренных фильмах/сериалах на сервер, для обновления популярности + * @returns {void} + */ + + function init$a() { + Favorite.listener.follow('add,added', function (e) { + if (e.where == 'history' && e.card.id && (e.card.source == 'tmdb' || e.card.source == 'cub')) { + $.get(Utils$1.protocol() + 'tmdb.' + object$2.cub_domain + '/watch?id=' + e.card.id + '&cat=' + (e.card.original_name ? 'tv' : 'movie')); + } + }); + } + + var ServiceWatched = { + init: init$a + }; + + /** + * Инициализация дополнительных настроек + * @returns {void} + */ + + function init$9() { + Settings.listener.follow('open', function (e) { + if (e.name == 'more' && window.location.protocol == 'https:') { + $('[data-name="protocol"]', e.body).remove(); + } + + if (e.name == 'interface' && window.lampa_settings.lang_use) { + $('.settings-param:eq(0)', e.body).on('hover:enter', function () { + LangChoice.open(function (code) { + Storage.set('language', code, true); + Storage.set('tmdb_lang', code, true); + window.location.reload(); + }, function () { + Controller.toggle('settings_component'); + }); + }).find('.settings-param__value').text(Lang.translate(Lang.codes()[Storage.get('language', 'ru')])); + } + + if (e.name == 'main' && Platform.is('apple_tv')) { + var append = e.body.find('.appletv-setting'); + + if (!append.length) { + append = $("
    \n
    \n \n
    \n
    ".concat(Lang.translate('menu_settings'), "
    \n
    ")); + e.body.find('.scroll__body > div').append(append); + } + + append.unbind('hover:enter').on('hover:enter', function () { + window.open('lampa://showadvancedmenu'); + }); + } + }); + } + + var ServiceSettings = { + init: init$9 + }; + + /** + * Инициализация дополнительных библиотек + * @returns {void} + */ + + function init$8() { + var include = []; // Видео библиотеки + + include = include.concat(['hls/hls.js', 'dash/dash.js', 'qrcode/qrcode.js'].map(function (lib) { + return window.location.protocol == 'file:' || window.location.href.indexOf('chrome-extension') > -1 ? object$2.github_lampa + 'vender/' + lib : './vender/' + lib; + })); // YouTube IFrame API + // больше не актуально, так как youtube плеер теперь использует собственный мост для взаимодействия с iframe, и не зависит от глобального объекта YT + // if(window.youtube_lazy_load && window.lampa_settings.youtube){ + // include.push(Utils.protocol() + 'youtube.com/iframe_api') + // } + // Плагины различные + + if (!window.lampa_settings.iptv && window.lampa_settings.services) { + include.push(Utils$1.protocol() + object$2.cub_domain + '/plugin/sport'); + include.push(Utils$1.protocol() + object$2.cub_domain + '/plugin/tsarea'); + } // Плагин Shots + + + if (window.location.hostname !== 'localhost' && !window.lampa_settings.iptv) include.push(Utils$1.protocol() + object$2.cub_domain + '/plugin/shots'); + Utils$1.putScriptOfMirrors(include, function () {}); + } + + var ServiceLibs = { + init: init$8 + }; + + var open_about = false; + var press_button = 0; + var buttons = ['enabled', 'nopremium', 'nodemo', 'ads', 'fps']; + var icon = "\n\n\n\n\n\n\n"; + + function init$7() { + Modal.listener.follow('toggle', function (e) { + open_about = e.active.about; + + if (e.active.about) { + e.html.find('.modal__body').on('click', function (e) { + if (DeviceInput.canClick(e.originalEvent)) press(); + }); + } + }); + Modal.listener.follow('preshow,close', function (e) { + open_about = false; + press_button = 0; + }); + Keypad.listener.follow('enter', press); + Storage.listener.follow('change', function (e) { + if (e.name == 'developer_nodemo') Storage.set('remove_white_and_demo', e.value, true); + }); + if (Storage.get('developer_enabled', 'false')) activate(); + } + + function press() { + if (!open_about || window.lampa_settings.developer.enabled) return; + press_button++; + + if (press_button == 10) { + Bell.push({ + text: Lang.translate('developer_trigger_help_1'), + icon: icon + }); + } else if (press_button == 20) { + Bell.push({ + text: Lang.translate('developer_trigger_help_2'), + icon: icon + }); + } else if (press_button == 30) { + Bell.push({ + text: Lang.translate('developer_trigger_help_3'), + icon: icon + }); + } else if (press_button == 40) { + Storage.set('developer_enabled', 'true'); + activate(); + Bell.push({ + text: Lang.translate('developer_trigger_help_4'), + icon: icon + }); + } + } + + function params() { + var component = 'developer'; + SettingsApi.addComponent({ + component: component, + icon: icon, + name: Lang.translate('title_developer') + }); + var display = Arrays.clone(buttons); + + if (!Account$1.hasPremium()) { + Arrays.remove(display, 'ads'); + } + + display.forEach(function (name) { + Lampa.SettingsApi.addParam({ + component: component, + param: { + name: 'developer_' + name, + type: 'trigger', + "default": false + }, + field: { + name: Lampa.Lang.translate('developer_param_' + name) + }, + onChange: function onChange(e) { + window.lampa_settings.developer[name] = Storage.get('developer_' + name, 'false'); + } + }); + }); + var values = {}; + object$2.cub_mirrors.forEach(function (domain) { + values[domain] = domain; + }); + Lampa.SettingsApi.addParam({ + component: component, + param: { + name: 'cub_domain', + type: 'select', + values: values, + "default": object$2.cub_domain + }, + field: { + name: Lampa.Lang.translate('settings_cub_domain') + }, + onChange: function onChange(e) { + Storage.set('cub_alive', Utils$1.protocol() + object$2.cub_domain, true); + } + }); + } + + function activate() { + buttons.forEach(function (name) { + window.lampa_settings.developer[name] = Storage.get('developer_' + name, 'false'); + }); + SettingsApi.removeComponent('developer'); + if (window.lampa_settings.developer.enabled) params(); + } + + var ServiceDeveloper = { + init: init$7 + }; + + /** + * Инициализация быстрого доступа к закладкам через цветные кнопки пульта + * @returns {void} + */ + + function init$6() { + var color_keys = { + '406': 'history', + '405': 'wath', + '404': 'like', + '403': 'book' + }; + Keypad.listener.follow('keydown', function (e) { + if (!Player.opened()) { + if (color_keys[e.code]) { + var type = color_keys[e.code]; + Activity.push({ + url: '', + title: type == 'book' ? Lang.translate('title_book') : type == 'like' ? Lang.translate('title_like') : type == 'history' ? Lang.translate('title_history') : Lang.translate('title_wath'), + component: 'favorite', + type: type, + page: 1 + }); + } + } + }); + } + + var ServiceRemoteFavorites = { + init: init$6 + }; + + /** + * Инициализация DMCA, блокировка карточек к показу по требованию правообладателей + * @returns {void} + */ + + function init$5() { + if (!window.lampa_settings.disable_features.dmca) { + // Cache.getData('other', 'dcma', 60 * 24 * 10).then((result)=>{ + // if(result && Arrays.isArray(result)) window.lampa_settings.dcma = result + // else{ + Lampa.Network.silent(Utils$1.protocol() + 'tmdb.' + object$2.cub_domain + '/blocked', function (dcma) { + window.lampa_settings.dcma = dcma; //Cache.rewriteData('other', 'dcma', dcma).catch((e)=>{}) + }); // } + // }).catch(e=>{}) + } + } + + var ServiceDMCA = { + init: init$5 + }; + + /** + * Инициализация DMCA, блокировка карточек к показу по требованию правообладателей + * @returns {void} + */ + + function init$4() { + if (!window.lampa_settings.disable_features.lgbt) { + Cache.getData('other', 'lgbt', 60 * 24 * 10).then(function (result) { + if (result && Arrays.isObject(result)) window.lampa_settings.lgbt = result;else { + Lampa.Network.silent(Utils$1.protocol() + 'tmdb.' + object$2.cub_domain + '/lgbt.json', function (lgbt) { + var map = {}; + lgbt.forEach(function (item) { + map[item.id + '_' + item.type] = true; + }); + window.lampa_settings.lgbt = map; + Cache.rewriteData('other', 'lgbt', map)["catch"](function (e) {}); + }); + } + })["catch"](function (e) {}); + + if (!vpn.is(['ru', 'by'])) { + Lampa.SettingsApi.addParam({ + component: 'more', + param: { + name: 'lgbt_content_block', + type: 'trigger', + "default": false + }, + field: { + name: Lampa.Lang.translate('settings_lgbt_content_block') + } + }); + } + } + } + + var ServiceLGBT = { + init: init$4 + }; + + function init$3() { + var counter = Template.elem('div', { + "class": 'head__fps-counter' + }); + var canvas = Template.elem('canvas', { + "class": 'head__fps-graph' + }); + var ctx = canvas.getContext("2d"); + var html = Template.elem('div', { + "class": 'head__fps', + children: [canvas, counter] + }); + var last_time = typeof performance !== 'undefined' ? performance.now() : Date.now(); + var fps = 0; + var smoothing = 0.8; + var history = []; + var max_history = 0; + + function updateFPS(now) { + var delta = now - last_time; + last_time = now; + var current_fps = 1000 / delta; + fps = fps * smoothing + current_fps * (1 - smoothing); + counter.textContent = fps.toFixed(1); // Добавляем FPS в историю + + history.push(fps); + if (history.length > max_history) history.shift(); + drawGraph(); + if (window.lampa_settings.developer.fps) requestAnimationFrame(updateFPS); + } + + function drawGraph() { + var w = canvas.width; + var h = canvas.height; + var m = 60; // Ищем максимальный FPS в истории для масштабирования + + history.forEach(function (v) { + m = Math.max(m, v); + }); // небольшой запас сверху + + m += m * 0.2; // Масштаб по вертикали + + var scale = h / m; + ctx.clearRect(0, 0, w, h); + var gradient = ctx.createLinearGradient(0, 0, 0, h); + gradient.addColorStop(0, "rgba(0,255,0,0.4)"); + gradient.addColorStop(1, "rgba(0,255,0,0)"); + ctx.beginPath(); + + for (var i = 0; i < history.length; i++) { + var y = h - history[i] * scale; + if (i === 0) ctx.moveTo(i, y);else ctx.lineTo(i, y); + } // Замыкаем форму до низа графика + + + ctx.lineTo(history.length, h); + ctx.lineTo(0, h); + ctx.closePath(); // Заливка + + ctx.fillStyle = gradient; + ctx.fill(); // Контур линии FPS + + ctx.beginPath(); + + for (var _i = 0; _i < history.length; _i++) { + var _y = h - history[_i] * scale; + + if (_i === 0) ctx.moveTo(_i, _y);else ctx.lineTo(_i, _y); + } + + ctx.strokeStyle = "#0f0"; + ctx.lineWidth = 1.5; + ctx.stroke(); + } + + function start() { + Head.render(true).find('.head__title').after(html); + canvas.width = $(canvas).width(); + canvas.height = $(canvas).height(); + history = []; + max_history = canvas.width; + requestAnimationFrame(updateFPS); + } + + Storage.listener.follow('change', function (e) { + if (e.name === 'developer_fps') { + if (e.value == 'true') start();else { + html.remove(); + } + } + }); + if (window.lampa_settings.developer.fps) start(); + } + + var ServiceFPS = { + init: init$3 + }; + + var events = [{ + start: '10-25T00:00:00', + end: '10-31T23:59:00', + name: 'halloween' + }, { + start: '11-24T00:00:00', + end: '11-30T23:59:00', + name: 'black-friday' + }, // Новогодние + { + start: '12-20T00:00:00', + end: '01-04T23:59:00', + name: 'snow' + }, { + start: '01-01T00:00:00', + end: '01-03T23:59:00', + name: 'new-year' + }, { + start: '03-06T00:00:00', + end: '03-10T23:59:00', + name: 'womens-day' + }]; + + function init$2() { + if (!window.lampa_settings.services) return; + events.forEach(function (event) { + var nowDate = new Date(); + var now = nowDate.getTime(); + var year = nowDate.getFullYear(); + var start_time = new Date(year + '-' + event.start).getTime(); + var end_time = new Date(year + '-' + event.end).getTime(); // событие пересекает границу года (например 12-20 -> 01-10) + + var crossYear = end_time < start_time; + + if (crossYear) { + // конец в следующем году + end_time = new Date(year + 1 + '-' + event.end).getTime(); // если сейчас "январская" часть окна, то старт должен быть в прошлом году + + if (now < start_time) { + start_time = new Date(year - 1 + '-' + event.start).getTime(); + end_time = new Date(year + '-' + event.end).getTime(); + } + } + + event.start_time = start_time; + event.end_time = end_time; // обычно удобнее включать границы + + event.enabled = start_time <= now && now <= end_time; + }); + var enabled = events.filter(function (e) { + return e.enabled; + }); + + if (enabled.length) { + Utils$1.putScriptOfMirrors(enabled.map(function (e) { + return Utils$1.protocol() + object$2.cub_domain + '/plugin/' + e.name; + }), function () {}); + } + } + + var ServiceEvents = { + init: init$2 + }; + + function init$1() { + Storage.listener.follow('change', function (e) { + if (e.name == 'account' || e.name == 'parental_control_personal' || e.name == 'source') setChildrenProfile(); + }); + Listener$1.follow('profile_check', setChildrenProfile); + addStyle(); + setChildrenProfile(); + } + + function setChildrenProfile() { + if (!permit.child) return; + Storage.set('source', 'cub', true); + Storage.add('parental_control_personal', 'account_profiles', true); + Storage.add('parental_control_personal', 'settings', true); + document.body.toggleClass('hide-menu', Boolean(permit.child)); + } + + function addStyle() { + var not = ['main', 'movie', 'tv', 'cartoon', 'catalog', 'filter', 'anime', 'favorite', 'history', 'timetable', 'subscribes', 'settings', 'about', 'console', 'edit']; + var css = "\n body.hide-menu .menu__item:not([data-action=\"".concat(not.join('"]):not([data-action="'), "\"]){\n display: none;\n }\n "); + var teg = document.createElement('style'); + teg.type = 'text/css'; + teg.appendChild(document.createTextNode(css)); + document.body.appendChild(teg); + } + + var ServiceChildren = { + init: init$1 + }; + + var max_wait_time = 300000; // 5 минут + + var component = 'remote_configuration'; + var request_code = ''; + var request_time = 0; + var request_timer = false; + var request_html = null; + var request_instlall_log = []; + /** + * Инициализация компонента удалённой конфигурации + */ + + function init() { + if (window.lampa_settings.disable_features.remote_configuration) return; + var icon = "\n \n \n \n \n \n \n \n \n "; + SettingsApi.addComponent({ + component: component, + icon: icon, + name: Lang.translate('remote_configuration_settings_title'), + before: 'more' + }); + Settings.listener.follow('open', function (e) { + if (e.name == component) { + var waite = false; + var body = e.body.find('.scroll__body > div'); + var html = $("
    \n
    \n
    ".concat(Lang.translate('remote_configuration_registration_text'), "
    \n
    \n
    \n
    ").concat(Lang.translate('remote_configuration_open_button'), "
    \n\n
    \n
    \n
    ")); + + if (request_code) { + html = $("
    \n
    \n
    ".concat(Lang.translate('remote_configuration_waite_text'), "
    \n
    \n
    \n
    \n
    \n
    \n ").concat(Lang.translate('remote_configuration_code_life'), " \n
    \n
    \n
    \n
    \n
    ")); + var str = (request_code + '').split(''); + str.forEach(function (num, i) { + html.find('.account-modal-split__code').append("
    ".concat(num, "
    ")); + }); + request_html = html; + } + + var button = $('.modal__button', html); + var loading = $('.broadcast__scan', html); + button.on('hover:enter', function () { + if (waite) return; + waite = true; + loading.removeClass('hide'); + Lampa.Network.silent(api() + 'registration', function (result) { + request_code = result.code; + request_time = Date.now(); + Settings.update(); + start(); + waite = false; + }, function () { + Bell.push({ + text: Lang.translate('remote_configuration_notice_nocode'), + icon: icon + }); + loading.addClass('hide'); + waite = false; + }); + }); + body.append(html); + } + }); + } + + function api() { + return Utils$1.protocol() + object$2.cub_domain + '/api/remote-configuration/'; + } + /** + * Запуск таймера для отслеживания времени действия кода + */ + + + function start() { + if (!request_code) return; + request_timer = setInterval(function () { + var time = Date.now() - request_time; + + if (time > max_wait_time) { + request_code = ''; + request_time = 0; + request_html = null; + request_instlall_log = []; + clearInterval(request_timer); + if (Controller.enabled().name == 'settings_component') Settings.update(); + } else if (request_html) { + var sec_num = Math.round((max_wait_time - time) / 1000); + var minutes = Math.trunc(sec_num % 3600 / 60); + var seconds = Math.round(sec_num % 60); + request_html.find('.timer').text((minutes ? minutes + ' ' + Lang.translate('time_m') + ' ' : '') + (seconds + ' ' + Lang.translate('time_s'))); // Показывать последние 4 действия + + request_html.find('.install-log').html(request_instlall_log.slice(-4).map(function (item) { + return "
    ").concat(item.name, " ").concat(item.value, "
    "); + }).join('')); + } // Каждые 10 секунд делать запрос + + + if (time % 10000 < 1000) accept(); + }, 1000); + } + /** + * Принимать запросы на установку расширений и изменение настроек + */ + + + function accept() { + Lampa.Network.silent(api() + 'accept?code=' + request_code, function (result) { + if (result.delivery.length) result.delivery.forEach(install); + }); + } + /** + * Устанавливать расширения и изменять настройки согласно запросу + */ + + + function install(row) { + row.data.forEach(function (item) { + console.log('Remote configuration', 'install', item); + + try { + if (item.type == 'extension') { + Arrays.extend(item, { + author: '@lampa', + status: 1 + }); + + if (item.url && !Plugins.get().find(function (ext) { + return ext.url == item.url; + })) { + Plugins.add(item); + request_instlall_log.push({ + name: Lang.translate('settings_main_plugins'), + value: Utils$1.shortText(item.url, 30), + icon: 'history' + }); + } + } else if (item.type == 'storage') { + Storage.set(item.name, item.value); + request_instlall_log.push({ + name: Lang.translate('title_settings'), + value: Utils$1.shortText(item.name, 30), + icon: 'settings' + }); + } else if (item.type == 'reload') { + setTimeout(function () { + window.location.reload(); + }, 1000); + } + } catch (e) { + console.error('Remote configuration', 'install error', e); + } + }); + } + + var ServiceRemoteConfiguration = { + init: init + }; + + window.screen_width = window.innerWidth; + window.screen_height = window.innerHeight; + /** + * Настройки приложения + */ + + if (typeof window.lampa_settings == 'undefined') { + window.lampa_settings = {}; + } + + var torrents_use = true; + var agent = navigator.userAgent.toLowerCase(); + var conditions = [agent.indexOf("lampa_client_yasha") > -1, typeof AndroidJS !== 'undefined' && (AndroidJS.appVersion() + '').toLowerCase().indexOf('rustore') > -1 && !localStorage.getItem('parser_use')]; // Если есть условия из списка, то отключаем торренты, дабы пройти модерацию в сторе + + if (conditions.indexOf(true) >= 0) torrents_use = false; + Arrays.extend(window.lampa_settings, { + // Использовать сокеты для синхронизации данных + socket_use: true, + // Адрес сокета, по умолчанию лампа берет адреса из манифеста + socket_url: undefined, + // Обрабатывать сообщения сокетов + socket_methods: true, + // Использовать аккаунты CUB + account_use: true, + // Синхронизировать закладки, таймкоды и прочее + account_sync: true, + // Разрешить установку плагинов и расширений + plugins_use: true, + // Разрешить использование магазина расширений + plugins_store: true, + // Показывать кнопку торрентов + torrents_use: torrents_use, + // Отключить фитчи куба и лампы + disable_features: { + // Блокировку карточек + dmca: false, + // Блокировка ЛГБТ-контента + lgbt: false, + // Реакции + reactions: false, + // Обсуждения + discuss: false, + // ИИ + ai: false, + // Подписка на уведомления + subscribe: false, + // Черный список плагинов + blacklist: false, + // Подписка на актеров + persons: false, + // Вспомогатиленые сервисы на подписку према + ads: false, + // Трейлеры + trailers: false, + // Установка прокси для запросов + install_proxy: false, + // Удаленная конфигурация + remote_configuration: false + }, + // Подключить другие языки интерфейса, по умолчанию только русский и английский + lang_use: true, + // Белая и пушистая лампа, для одобрения модерации + white_use: false, + // Режим только для чтения, без кнопок онлайн и расширений + read_only: false, + // Добавить список блокировки карточек, пример: [{"id":3566556,"cat":"movie"},...] + dcma: false, + // Добавить блокировку ЛГБТ контента, пример: [{"id":3566556,"type":"movie"},...] + lgbt: false, + // Добавлять в адресную строку название текущего экрана + push_state: true, + // Является ли приложение IPTV + iptv: false, + // Показать ленту + feed: true, + // Различные сервисы в приложении + services: true, + // Подключить YouTube API + youtube: true, + // Определять гео по IP, иначе будет RU + geo: true, + // Использовать поиск зеркал + mirrors: true, + // Режим разработчика + developer: { + enabled: false + }, + // Размывать постер для мобильных устройств, эффект стекла + blur_poster: true, + // Скрывать важные параметры в приложении + hide_important_params: true, + // Фикс для виджетов, чтобы не подгружались стили с github + fix_widget: window.localStorage.getItem('fix_widget') ? true : false + }); // Если отключили + + if (window.localStorage.getItem('remove_white_and_demo')) { + window.lampa_settings.demo = false; + window.lampa_settings.white_use = false; + } // Если IPTV, то отключаем все лишнее + + + if (window.lampa_settings.iptv) { + window.lampa_settings.socket_use = false; + window.lampa_settings.plugins_store = false; + window.lampa_settings.plugins_use = false; + window.lampa_settings.account_sync = false; + window.lampa_settings.torrents_use = false; + } + /** + * Делаем классы доступными в глобальной области видимости + */ + + + function initClass() { + window.Lampa = { + Listener: Subscribe$2(), + Lang: Lang, + Subscribe: Subscribe$2, + Storage: Storage, + Platform: Platform, + Utils: Utils$1, + Params: Params, + Menu: Menu$1, + Head: Head, + Notice: Notice$1, + NoticeClass: NoticeClass, + NoticeClassLampa: NoticeLampa, + Background: Background, + Favorite: Favorite, + Select: Select, + Controller: Controller, + Activity: Activity, + Keypad: Keypad, + Template: Template, + Component: Component, + Reguest: Request, + Filter: Filter, + Files: create$3, + Explorer: Explorer$1, + Scroll: Scroll, + Empty: Empty, + Arrays: Arrays, + Noty: Noty, + Player: Player, + PlayerVideo: PlayerVideo, + PlayerInfo: PlayerInfo, + PlayerPanel: PlayerPanel, + PlayerFooter: PlayerFooter, + PlayerIPTV: PlayerIPTV, + PlayerPlaylist: PlayerPlaylist, + PlayerChat: PlayerChat, + Timeline: Timeline$1, + Modal: Modal, + Api: Api, + Settings: Settings, + SettingsApi: SettingsApi, + Android: Android, + Card: Card, + Info: create$2, + Account: Account$1, + Socket: Socket, + Input: Input, + Screensaver: Screensaver$2, + Recomends: Recomends, + TimeTable: TimeTable, + Broadcast: Broadcast, + Helper: Helper$1, + InteractionMain: component$3, + InteractionCategory: component$2, + InteractionLine: create$1, + Status: Status, + Plugins: Plugins, + Extensions: Extensions, + Tizen: Tizen, + Layer: Layer, + Console: Console, + Iframe: Iframe, + Parser: Parser, + Manifest: object$2, + TMDB: TMDB$1, + Base64: Base64, + Loading: Loading$1, + YouTube: YouTube, + WebOSLauncher: WebOSLauncher, + Event: Event, + Search: Search, + DeviceInput: DeviceInput, + Worker: AppWorker, + DB: IndexedDB, + NavigationBar: NavigationBar, + Endless: Endless, + Color: Color, + Cache: Cache, + Torrent: Torrent, + Torserver: Torserver, + Speedtest: Speedtest, + Processing: Processing, + ParentalControl: ParentalControl, + VPN: vpn, + Bell: Bell, + StorageMenager: StorageMenager, + RemoteHelper: RemoteHelper, + Network: new Request(), + Maker: Maker, + MaskHelper: Mask, + ContentRows: ContentRows, + Emit: Emit, + Router: router, + Timer: Timer + }; + } + /** + * Подготовка приложения к запуску + */ + + + function prepareApp() { + if (window.prepared_app) return; + LoadingProgress.init(); + document.body.append(Noty.render()); + Platform.init(); + LoadingProgress.status('Platform init'); + DeviceInput.init(); + LoadingProgress.status('DeviceInput init'); + Params.init(); + LoadingProgress.status('Params init'); + Controller.observe(); + LoadingProgress.status('Controller observe init'); + Console.init(); + LoadingProgress.status('Console init'); + Keypad.init(); + LoadingProgress.status('Keypad init'); + Layer.init(); + LoadingProgress.status('Layer init'); + HoverSwitcher.init(); // Передаем фокус в контроллер + + Navigator.follow('focus', function (event) { + Controller.focus(event.elem); + }); // Выход в начальном скрине + + Keypad.listener.follow('keydown', function (e) { + if (window.appready || Controller.enabled().name == 'modal' || Platform.is('browser') || Platform.desktop()) return; + if (e.code == 8 || e.code == 27 || e.code == 461 || e.code == 10009 || e.code == 88) App.modalClose(); + }); + LoadingProgress.status('Subscribe on keydown'); // Отключаем правый клик + + if (window.innerWidth > 1280) window.addEventListener("contextmenu", function (e) { + return e.preventDefault(); + }); + App.loadStyle(); + LoadingProgress.status('Loaded styles'); + Layer.update(); + LoadingProgress.status('Prepare ready'); + window.prepared_app = true; + } + /** + * Меню разработчика + */ + + + function developerApp(proceed) { + var expect = true; + var pressed = 0; + var timer = setTimeout(function () { + expect = false; + proceed(); + }, 1000); + + var check = function check() { + pressed++; + + if (pressed === 3) { + clearTimeout(timer); + expect = false; + Keypad.enable(); + Developer.open(function () { + Keypad.disable(); + proceed(); + }); + console.log('Developer mode', 'on'); + } + }; + + var keydown = function keydown(event) { + if (expect) { + if (event.keyCode == 38 || event.keyCode == 29460 || event.keyCode == 50400012) check(); + } else { + document.removeEventListener('keydown', keydown); + } + }; + + $('.welcome').on('click', function (e) { + if (expect && DeviceInput.canClick(e.originalEvent)) check(); + }); + window.addEventListener("keydown", keydown); + } + /** + * Старт приложения + */ + + + function startApp() { + if (window.appready || window.app_time_launch) return; + window.app_time_launch = Date.now(); + window.app_time_end = 0; // Стартуем + + LoadingProgress.status('Launching the application'); + Lampa.Listener.send('app', { + type: 'start' + }); // Инициализируем классы + + Timer.init(); + LoadingProgress.status('Timer init'); + Storage.init(); + LoadingProgress.status('Storage init'); + Timeline$1.init(); + LoadingProgress.status('Timeline init'); + Mirrors.init(); + LoadingProgress.status('Mirrors init'); + Personal.init(); + LoadingProgress.status('Personal init'); + Head.init(); + LoadingProgress.status('Head init'); + Settings.init(); + LoadingProgress.status('Settings init'); + Select.init(); + LoadingProgress.status('Select init'); + Favorite.init(); + LoadingProgress.status('Favorite init'); + Background.init(); + LoadingProgress.status('Background init'); + Markers.init(); + LoadingProgress.status('Markers init'); + Notice$1.init(); + LoadingProgress.status('Notice init'); + Bell.init(); + LoadingProgress.status('Bell init'); + Menu$1.init(); + LoadingProgress.status('Menu init'); + Activity.init(); + LoadingProgress.status('Activity init'); + Screensaver$2.init(); + LoadingProgress.status('Screensaver init'); + Socket.init(); + LoadingProgress.status('Socket init'); + Account$1.init(); + LoadingProgress.status('Account init'); + Extensions.init(); + LoadingProgress.status('Extensions init'); + Plugins.init(); + LoadingProgress.status('Plugins init'); + Recomends.init(); + LoadingProgress.status('Recomends init'); + TimeTable.init(); + LoadingProgress.status('Timetable init'); + Helper$1.init(); + LoadingProgress.status('Helper init'); + Tizen.init(); + LoadingProgress.status('Tizen init'); + Player.init(); + LoadingProgress.status('Player init'); + Iframe.init(); + LoadingProgress.status('Iframe init'); + Parser.init(); + LoadingProgress.status('Parser init'); + WebOSLauncher.init(); + LoadingProgress.status('WebOSLauncher init'); + Theme$2.init(); + LoadingProgress.status('Theme init'); + AdManager.init(); + LoadingProgress.status('AdManager init'); + NavigationBar.init(); + LoadingProgress.status('NavigationBar init'); + Demo.init(); + LoadingProgress.status('Demo init'); + Speedtest.init(); + LoadingProgress.status('Speedtest init'); + Processing.init(); + LoadingProgress.status('Processing init'); + ParentalControl.init(); + LoadingProgress.status('ParentalControl init'); + Android.init(); + LoadingProgress.status('Android init'); + Sound$1.init(); + LoadingProgress.status('Sound init'); + Iptv.init(); + LoadingProgress.status('Iptv init'); + Logs.init(); + LoadingProgress.status('Logs init'); + Broadcast.init(); + LoadingProgress.status('Broadcast init'); + Search.init(); + LoadingProgress.status('Search init'); + DataBase.init(); + LoadingProgress.status('DataBase init'); + ContentRows.init(); + LoadingProgress.status('ContentRows init'); // Добавляем источники поиска + + if (window.lampa_settings.account_use && !window.lampa_settings.disable_features.ai) Search.addSource(Ai$1.discovery()); + LoadingProgress.status('Initialization successful'); // Выводим информацию о приложении + + var ratio = window.devicePixelRatio || 1; + console.log('App', 'screen size:', Math.round(window.innerWidth * ratio) + ' / ' + Math.round(window.innerHeight * ratio)); + console.log('App', 'interface size:', window.innerWidth + ' / ' + window.innerHeight); + console.log('App', 'pixel ratio:', window.devicePixelRatio); + console.log('App', 'user agent:', navigator.userAgent); + console.log('App', 'touch points:', navigator.maxTouchPoints); + console.log('App', 'is tv:', Platform.screen('tv')); + console.log('App', 'is mobile:', Platform.screen('mobile')); + console.log('App', 'is touch:', Utils$1.isTouchDevice()); + console.log('App', 'is PWA:', Utils$1.isPWA()); + console.log('App', 'platform:', Storage.get('platform', 'noname')); + console.log('App', 'version:', object$2.app_version); + console.log('App', 'build date:', '2026-10-04 19:56'); + console.log('App', 'hash', '25ee3b0d1c845b4c71b87e7f3af98637'); + console.log('App', 'location:', location.href); // Записываем uid + + if (!Storage.get('lampa_uid', '')) Storage.set('lampa_uid', Utils$1.uid()); // Ренедрим лампу + + Render.app(); + LoadingProgress.status('Render app'); // Инициализируем остальные сервисы + + ServiceDeveloper.init(); + LoadingProgress.status('ServiceDeveloper init'); + ServiceTorserver.init(); + LoadingProgress.status('ServiceTorserver init'); + ServiceWatched.init(); + LoadingProgress.status('ServiceWatched init'); + ServiceSettings.init(); + LoadingProgress.status('ServiceSettings init'); + ServiceMetric.init(); + LoadingProgress.status('ServiceMetric init'); + ServiceRemoteFavorites.init(); + LoadingProgress.status('ServiceRemoteFavorites init'); + ServiceDMCA.init(); + LoadingProgress.status('ServiceDMCA init'); + ServiceFPS.init(); + LoadingProgress.status('ServiceFPS init'); + ServiceEvents.init(); + LoadingProgress.status('ServiceEvents init'); + ServiceLibs.init(); + LoadingProgress.status('ServiceLibs init'); + ServiceLGBT.init(); + LoadingProgress.status('ServiceLGBT init'); + ServiceChildren.init(); + LoadingProgress.status('ServiceChildren init'); + ServiceRemoteConfiguration.init(); + LoadingProgress.status('ServiceRemoteConfiguration init'); // Обновляем слои + + Layer.update(); + LoadingProgress.status('Layer update'); // Сообщаем о готовности + + LoadingProgress.status('Send app ready'); // Лампа полностью готова + + window.appready = true; + window.app_time_end = Date.now(); + Lampa.Listener.send('app', { + type: 'ready' + }); + } + /** + * Показать приложение в любом случае + */ + + + function showApp() { + var _this = this; + + LoadingProgress.status('Show app'); // Скрытие логотипа + + setTimeout(function () { + if (window.show_app) return; + window.show_app = true; + LoadingProgress.destroy(); + Keypad.enable(); + Screensaver$2.enable(); + $('.welcome').fadeOut(500, function () { + $(_this).remove(); + }); + }, 1000); // Старт приложения + + startApp(); + } + /** + * Приоритетная загрузка + */ + + + function loadTask() { + Task.queue(function (next) { + LoadingProgress.status('Open cache database'); + Cache.openDatabase().then(function () { + console.log('Cache', 'worked'); + next(); + })["catch"](function () { + console.log('Cache', 'error', 'no open database'); + next(); + }); + }); + Task.queue(function (next) { + LoadingProgress.status('Storage load reserve'); + Storage.task(next); + }); + Task.queue(function (next) { + LoadingProgress.status('Mirrors initialization'); + LoadingProgress.step(2); + Mirrors.task(next); + }); + Task.queue(function (next) { + LoadingProgress.status('Plugins initialization'); + LoadingProgress.step(3); + Plugins.task(next); + }); + Task.queue(function (next) { + LoadingProgress.status('Proxy initialization'); + LoadingProgress.step(4); + vpn.task(next); + }); + Task.queue(function (next) { + LoadingProgress.status('Account initialization'); + LoadingProgress.step(5); + Account$1.task(next); + }); + Task.secondary(function () { + setTimeout(showApp, 5000); + }); // todo: потом удалить, это костыль для исправления старых адресов джакетта + + Task.secondary(function () { + var tsl1 = window.localStorage.getItem('jackett_url') || ''; + var tsl2 = window.localStorage.getItem('jackett_url_two') || ''; + + try { + if (tsl1.toLowerCase() == 'jacred.xyz') { + window.localStorage.setItem('jackett_url', 'jac.red'); + } + + if (tsl2.toLowerCase() == 'jacred.xyz') { + window.localStorage.setItem('jackett_url_two', 'jac.red'); + } + } catch (e) {} + }); + Task.secondary(function () { + LoadingProgress.status('Loading plugins'); + Plugins.load(showApp); + }); + Task.start(); + } + /** + * Загрузка языка + */ + + + function loadLang() { + var code = window.localStorage.getItem('language') || 'ru'; + LoadingProgress.step(1); + if (['ru', 'en'].indexOf(code) >= 0) loadTask();else { + LoadingProgress.status('Loading language'); + $.ajax({ + url: (location.protocol == 'file:' || Platform.desktop() ? object$2.github_lampa : './') + 'lang/' + code + '.js', + dataType: 'text', + timeout: 10000, + success: function success(data) { + try { + var translate = {}; + eval((data + '').replace(/export default/g, 'translate = ').trim()); + Lang.AddTranslation(code, translate); + } catch (e) {} + + loadTask(); + }, + error: loadTask + }); + } + } + /** + * Первая загрузка приложения + */ + + + function loadApp() { + prepareApp(); // Готовим приложение + // Если язык уже установлен, то запускаем приложение + + if (window.localStorage.getItem('language') || !window.lampa_settings.lang_use) { + // Но сперва ожидаем не вызвали ли пользователь меню разработчика, затем подгружаем язык + developerApp(loadLang); + } else { + // Иначе предлагаем выбрать язык + LangChoice.open(function (code) { + Storage.set('language', code, true); + Storage.set('tmdb_lang', code, true); + Keypad.disable(); + loadLang(); + }); + Keypad.enable(); + } + } + + if (!window.fitst_load) { + window.fitst_load = true; + initClass(); + + if (navigator.userAgent.toLowerCase().indexOf('lampa_client') > -1) { + var checkReady = function checkReady() { + if (window.innerWidth > 0) loadApp();else { + setTimeout(checkReady, 100); + } + }; + + checkReady(); + } else loadApp(); + } + +})(); diff --git a/lampa-main/assembly.json b/lampa-main/assembly.json new file mode 100644 index 0000000..9e18f8e --- /dev/null +++ b/lampa-main/assembly.json @@ -0,0 +1,8 @@ +{ + "app_version": "3.3.5", + "css_version": "3.3.4", + "css_digital": 334, + "app_digital": 335, + "time": 1791132984642, + "hash": "25ee3b0d1c845b4c71b87e7f3af98637" +} \ No newline at end of file diff --git a/lampa-main/css/app.css b/lampa-main/css/app.css new file mode 100644 index 0000000..f1d79c8 --- /dev/null +++ b/lampa-main/css/app.css @@ -0,0 +1,16239 @@ +@charset "UTF-8"; +.welcome { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 100; + background: #000 url(../img/welcome.jpg) no-repeat 50% 50%; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.lang { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #242424; + z-index: 200; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding: 2em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.lang__body { + text-align: center; +} +.lang__logo img { + width: 5.3em; + height: 5em; +} +.lang__title { + margin-top: 1em; + font-size: 2.9em; +} +.lang__subtitle { + font-size: 1.4em; + margin-top: 1em; +} +.lang__selector { + width: 19em; + margin: 0 auto; + margin-top: 2em; +} +.lang__selector-item { + font-size: 1.4em; + padding: 1em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.lang__selector-item.last-focus { + background-color: #444; +} +.lang__selector-item.focus { + background-color: #fff; + color: #242424; +} +.lang__selector > .scroll { + max-height: 18em !important; +} + +@font-face { + font-family: "SegoeUI"; + font-display: swap; + src: url("../fonts/SegoeUI/SegoeUI-Light.eot") format("embedded-opentype"), url("../fonts/SegoeUI/SegoeUI-Light.woff") format("woff"), url("../fonts/SegoeUI/SegoeUI-Light.ttf") format("truetype"); + font-weight: 300; + font-style: normal; +} +@font-face { + font-family: "SegoeUI"; + font-display: swap; + src: url("../fonts/SegoeUI/SegoeUI.eot") format("embedded-opentype"), url("../fonts/SegoeUI/SegoeUI.woff") format("woff"), url("../fonts/SegoeUI/SegoeUI.ttf") format("truetype"); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: "SegoeUI"; + font-display: swap; + src: url("../fonts/SegoeUI/SegoeUI-SemiBold.eot") format("embedded-opentype"), url("../fonts/SegoeUI/SegoeUI-SemiBold.woff") format("woff"), url("../fonts/SegoeUI/SegoeUI-SemiBold.ttf") format("truetype"); + font-weight: 600; + font-style: normal; +} +@font-face { + font-family: "SegoeUI"; + font-display: swap; + src: url("../fonts/SegoeUI/SegoeUI-Bold.eot") format("embedded-opentype"), url("../fonts/SegoeUI/SegoeUI-Bold.woff") format("woff"), url("../fonts/SegoeUI/SegoeUI-Bold.ttf") format("truetype"); + font-weight: 700; + font-style: normal; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + outline: none; + -webkit-user-drag: none; +} + +* { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + /* чтобы не показывало меню при долгом тапе */ +} + +html { + font-size: 16px; +} + +*:after, +*:before { + display: inline-block; + vertical-align: middle; +} + +*:focus { + outline: none !important; +} + +input::-webkit-input-placeholder { + color: #6a6a6a; + opacity: 1; +} + +input:-moz-placeholder { + color: #6a6a6a; + opacity: 1; +} + +input::-moz-placeholder { + color: #6a6a6a; + opacity: 1; +} + +input:-ms-input-placeholder { + color: #6a6a6a; + opacity: 1; +} + +input::-ms-input-placeholder { + color: #6a6a6a; + opacity: 1; +} + +input::placeholder { + color: #6a6a6a; + opacity: 1; +} + +::-webkit-scrollbar { + display: none; +} + +input.hover::-webkit-input-placeholder, input.enter::-webkit-input-placeholder { + color: #fff; + opacity: 1; +} + +input.hover:-moz-placeholder, input.enter:-moz-placeholder { + color: #fff; + opacity: 1; +} + +input.hover::-moz-placeholder, input.enter::-moz-placeholder { + color: #fff; + opacity: 1; +} + +input.hover:-ms-input-placeholder, input.enter:-ms-input-placeholder { + color: #fff; + opacity: 1; +} + +input.hover::-ms-input-placeholder, input.enter::-ms-input-placeholder { + color: #fff; + opacity: 1; +} + +input.hover::placeholder, +input.enter::placeholder { + color: #fff; + opacity: 1; +} + +*:not(input) { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +body { + line-height: 1; + font-size: 16px; + color: #ffffff; + position: relative; + font-family: "SegoeUI", sans-serif; + background: #1d1f20; + padding: 0; + margin: 0; + overflow: hidden; + position: fixed; + width: 100%; + height: 100%; + left: 0; + top: 0; + -webkit-user-select: none !important; + -moz-user-select: none !important; + -ms-user-select: none !important; + user-select: none !important; + -webkit-touch-callout: none !important; +} +body.black--style { + background: #000 !important; +} +@media screen and (max-width: 480px) { + body.black--style .selectbox__content, +body.black--style .modal__content, +body.black--style .settings__content { + background-color: #000 !important; + } +} + +img { + vertical-align: middle; + max-width: 100%; + -o-object-fit: cover; + object-fit: cover; +} + +svg { + width: 100%; + height: 100%; +} + +ul { + list-style: none; + padding: 0; +} + +.mouse-layer { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 300; +} + +.hide { + display: none !important; +} + +.selector { + cursor: pointer; +} + +body.no--mask .scroll--mask { + -webkit-mask-image: unset !important; + mask-image: unset !important; +} + +body.no--animation * { + -webkit-transition: none !important; + -o-transition: none !important; + -moz-transition: none !important; + transition: none !important; +} + +body.no--cursor { + cursor: none; +} + +/** Фиг знает, баг **/ +body.no--animation .background canvas { + -webkit-transition: opacity 0.1s !important; + -o-transition: opacity 0.1s !important; + -moz-transition: opacity 0.1s !important; + transition: opacity 0.1s !important; +} + +.endless-up { + -webkit-animation: endless-up 0.2s ease; + -moz-animation: endless-up 0.2s ease; + -o-animation: endless-up 0.2s ease; + animation: endless-up 0.2s ease; +} +.endless-down { + -webkit-animation: endless-down 0.2s ease; + -moz-animation: endless-down 0.2s ease; + -o-animation: endless-down 0.2s ease; + animation: endless-down 0.2s ease; +} + +.normalization { + position: absolute; + top: 50%; + right: 1.5em; + padding: 0.4em; + height: auto; + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + z-index: 60; + opacity: 0; + -webkit-transform: translateY(-50%) translateX(100%); + -moz-transform: translateY(-50%) translateX(100%); + -ms-transform: translateY(-50%) translateX(100%); + -o-transform: translateY(-50%) translateX(100%); + transform: translateY(-50%) translateX(100%); + -webkit-transition: all 0.1s; + -o-transition: all 0.1s; + -moz-transition: all 0.1s; + transition: all 0.1s; +} +.normalization canvas { + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + height: 9em; + width: 0.4em; +} +.normalization--visible { + opacity: 1; + -webkit-transform: translateY(-50%) translateX(0); + -moz-transform: translateY(-50%) translateX(0); + -ms-transform: translateY(-50%) translateX(0); + -o-transform: translateY(-50%) translateX(0); + transform: translateY(-50%) translateX(0); +} + +.text-markdow { + line-height: 1.6; + font-weight: 100; + font-size: 1.15em; +} +.text-markdow > *:first-child { + margin-top: 0; +} +.text-markdow h2, .text-markdow h3, .text-markdow h4, .text-markdow h5 { + font-size: 1.4em; + font-weight: 400; +} +.text-markdow--compressed-sides { + padding-left: 1.5em; + padding-right: 1.5em; +} + +.content-loading { + position: relative; + padding: 5em 0; +} +.content-loading::after { + content: ""; + display: block; + height: 3em; + width: 3em; + background: url(../img/loader.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + position: absolute; + top: 50%; + left: 50%; + margin-left: -1.5em; + margin-top: -1.5em; +} + +body.platform--browser .normalization { + -webkit-backdrop-filter: blur(5px); + backdrop-filter: blur(5px); +} + +body.platform--apple .normalization, +body.selectbox--open .normalization, +body.keyboard-input--visible .normalization { + display: none; +} + +body.ambience--enable .wrap, +body.ambience--enable .head, +body:not(.glass--style).keyboard-input--visible .wrap, +body:not(.glass--style).keyboard-input--visible .head { + display: none; +} + +.icon--blink:not(.focus).animate { + background: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 40%, white 50%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0) 100%); + background: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 40%, white 50%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0) 100%); + background: -o-linear-gradient(45deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 40%, white 50%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0) 100%); + background: linear-gradient(45deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 40%, white 50%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0) 100%); + -webkit-background-size: 400% 400%; + -moz-background-size: 400% 400%; + -o-background-size: 400% 400%; + background-size: 400% 400%; + -webkit-animation: head-icon-blick 1s ease forwards; + -moz-animation: head-icon-blick 1s ease forwards; + -o-animation: head-icon-blick 1s ease forwards; + animation: head-icon-blick 1s ease forwards; +} + +.notice--icon.animate svg { + -webkit-transform-origin: 50% 0; + -moz-transform-origin: 50% 0; + -ms-transform-origin: 50% 0; + -o-transform-origin: 50% 0; + transform-origin: 50% 0; + -webkit-animation: head-icon-notice 1s ease forwards; + -moz-animation: head-icon-notice 1s ease forwards; + -o-animation: head-icon-notice 1s ease forwards; + animation: head-icon-notice 1s ease forwards; +} + +.overhide { + overflow: hidden; +} + +.no-shrink { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} + +/* Фикс для orsay */ +.online-prestige-watched__icon { + width: 1.5em; + height: 1.5em; +} + +@-webkit-keyframes head-icon-blick { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 50%; + } +} + +@-moz-keyframes head-icon-blick { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 50%; + } +} + +@-o-keyframes head-icon-blick { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 50%; + } +} + +@keyframes head-icon-blick { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 50%; + } +} +@-webkit-keyframes head-icon-notice { + 0% { + -webkit-transform: rotateZ(0); + transform: rotateZ(0); + } + 10% { + -webkit-transform: rotateZ(30deg); + transform: rotateZ(30deg); + } + 20% { + -webkit-transform: rotateZ(-30deg); + transform: rotateZ(-30deg); + } + 30% { + -webkit-transform: rotateZ(20deg); + transform: rotateZ(20deg); + } + 40% { + -webkit-transform: rotateZ(-20deg); + transform: rotateZ(-20deg); + } + 50% { + -webkit-transform: rotateZ(10deg); + transform: rotateZ(10deg); + } + 60% { + -webkit-transform: rotateZ(-10deg); + transform: rotateZ(-10deg); + } + 70% { + -webkit-transform: rotateZ(5deg); + transform: rotateZ(5deg); + } + 80% { + -webkit-transform: rotateZ(-5deg); + transform: rotateZ(-5deg); + } + 90% { + -webkit-transform: rotateZ(0); + transform: rotateZ(0); + } +} +@-moz-keyframes head-icon-notice { + 0% { + -moz-transform: rotateZ(0); + transform: rotateZ(0); + } + 10% { + -moz-transform: rotateZ(30deg); + transform: rotateZ(30deg); + } + 20% { + -moz-transform: rotateZ(-30deg); + transform: rotateZ(-30deg); + } + 30% { + -moz-transform: rotateZ(20deg); + transform: rotateZ(20deg); + } + 40% { + -moz-transform: rotateZ(-20deg); + transform: rotateZ(-20deg); + } + 50% { + -moz-transform: rotateZ(10deg); + transform: rotateZ(10deg); + } + 60% { + -moz-transform: rotateZ(-10deg); + transform: rotateZ(-10deg); + } + 70% { + -moz-transform: rotateZ(5deg); + transform: rotateZ(5deg); + } + 80% { + -moz-transform: rotateZ(-5deg); + transform: rotateZ(-5deg); + } + 90% { + -moz-transform: rotateZ(0); + transform: rotateZ(0); + } +} +@-o-keyframes head-icon-notice { + 0% { + -o-transform: rotateZ(0); + transform: rotateZ(0); + } + 10% { + -o-transform: rotateZ(30deg); + transform: rotateZ(30deg); + } + 20% { + -o-transform: rotateZ(-30deg); + transform: rotateZ(-30deg); + } + 30% { + -o-transform: rotateZ(20deg); + transform: rotateZ(20deg); + } + 40% { + -o-transform: rotateZ(-20deg); + transform: rotateZ(-20deg); + } + 50% { + -o-transform: rotateZ(10deg); + transform: rotateZ(10deg); + } + 60% { + -o-transform: rotateZ(-10deg); + transform: rotateZ(-10deg); + } + 70% { + -o-transform: rotateZ(5deg); + transform: rotateZ(5deg); + } + 80% { + -o-transform: rotateZ(-5deg); + transform: rotateZ(-5deg); + } + 90% { + -o-transform: rotateZ(0); + transform: rotateZ(0); + } +} +@keyframes head-icon-notice { + 0% { + -webkit-transform: rotateZ(0); + -moz-transform: rotateZ(0); + -o-transform: rotateZ(0); + transform: rotateZ(0); + } + 10% { + -webkit-transform: rotateZ(30deg); + -moz-transform: rotateZ(30deg); + -o-transform: rotateZ(30deg); + transform: rotateZ(30deg); + } + 20% { + -webkit-transform: rotateZ(-30deg); + -moz-transform: rotateZ(-30deg); + -o-transform: rotateZ(-30deg); + transform: rotateZ(-30deg); + } + 30% { + -webkit-transform: rotateZ(20deg); + -moz-transform: rotateZ(20deg); + -o-transform: rotateZ(20deg); + transform: rotateZ(20deg); + } + 40% { + -webkit-transform: rotateZ(-20deg); + -moz-transform: rotateZ(-20deg); + -o-transform: rotateZ(-20deg); + transform: rotateZ(-20deg); + } + 50% { + -webkit-transform: rotateZ(10deg); + -moz-transform: rotateZ(10deg); + -o-transform: rotateZ(10deg); + transform: rotateZ(10deg); + } + 60% { + -webkit-transform: rotateZ(-10deg); + -moz-transform: rotateZ(-10deg); + -o-transform: rotateZ(-10deg); + transform: rotateZ(-10deg); + } + 70% { + -webkit-transform: rotateZ(5deg); + -moz-transform: rotateZ(5deg); + -o-transform: rotateZ(5deg); + transform: rotateZ(5deg); + } + 80% { + -webkit-transform: rotateZ(-5deg); + -moz-transform: rotateZ(-5deg); + -o-transform: rotateZ(-5deg); + transform: rotateZ(-5deg); + } + 90% { + -webkit-transform: rotateZ(0); + -moz-transform: rotateZ(0); + -o-transform: rotateZ(0); + transform: rotateZ(0); + } +} +@-webkit-keyframes endless-up { + 0% { + -webkit-transform: translate3d(0, -5em, 0); + transform: translate3d(0, -5em, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes endless-up { + 0% { + -moz-transform: translate3d(0, -5em, 0); + transform: translate3d(0, -5em, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes endless-up { + 0% { + transform: translate3d(0, -5em, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes endless-up { + 0% { + -webkit-transform: translate3d(0, -5em, 0); + -moz-transform: translate3d(0, -5em, 0); + transform: translate3d(0, -5em, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes endless-down { + 0% { + -webkit-transform: translate3d(0, 5em, 0); + transform: translate3d(0, 5em, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes endless-down { + 0% { + -moz-transform: translate3d(0, 5em, 0); + transform: translate3d(0, 5em, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes endless-down { + 0% { + transform: translate3d(0, 5em, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes endless-down { + 0% { + -webkit-transform: translate3d(0, 5em, 0); + -moz-transform: translate3d(0, 5em, 0); + transform: translate3d(0, 5em, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes endless-left { + 0% { + -webkit-transform: translate3d(5em, 0, 0); + transform: translate3d(5em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes endless-left { + 0% { + -moz-transform: translate3d(5em, 0, 0); + transform: translate3d(5em, 0, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes endless-left { + 0% { + transform: translate3d(5em, 0, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes endless-left { + 0% { + -webkit-transform: translate3d(5em, 0, 0); + -moz-transform: translate3d(5em, 0, 0); + transform: translate3d(5em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes endless-right { + 0% { + -webkit-transform: translate3d(-5em, 0, 0); + transform: translate3d(-5em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes endless-right { + 0% { + -moz-transform: translate3d(-5em, 0, 0); + transform: translate3d(-5em, 0, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes endless-right { + 0% { + transform: translate3d(-5em, 0, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes endless-right { + 0% { + -webkit-transform: translate3d(-5em, 0, 0); + -moz-transform: translate3d(-5em, 0, 0); + transform: translate3d(-5em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes pulse { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + 20% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@-moz-keyframes pulse { + 0% { + -moz-transform: scale(1); + transform: scale(1); + } + 20% { + -moz-transform: scale(1.3); + transform: scale(1.3); + } + 100% { + -moz-transform: scale(1); + transform: scale(1); + } +} +@-o-keyframes pulse { + 0% { + -o-transform: scale(1); + transform: scale(1); + } + 20% { + -o-transform: scale(1.3); + transform: scale(1.3); + } + 100% { + -o-transform: scale(1); + transform: scale(1); + } +} +@keyframes pulse { + 0% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } + 20% { + -webkit-transform: scale(1.3); + -moz-transform: scale(1.3); + -o-transform: scale(1.3); + transform: scale(1.3); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } +} +.navigation-bar { + position: fixed; + left: 0; + bottom: 0; + right: 0; + padding: 0 1.5em 2em 1.5em; + z-index: 11; + display: none; +} +.navigation-bar__body { + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + background: #262829; + padding: 1.2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-justify-content: space-around; + -ms-flex-pack: distribute; + justify-content: space-around; +} +.navigation-bar__item { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.navigation-bar__icon { + width: 1.8em; + height: 1.8em; + margin: 0 auto; +} +.navigation-bar__label { + font-size: 0.9em; + margin-top: 0.9em; +} + +body.true--mobile .navigation-bar { + display: block; +} + +body.true--mobile.orientation--landscape .navigation-bar { + top: 0; + left: auto; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding: 1.5em; + padding-left: 0; +} +body.true--mobile.orientation--landscape .navigation-bar .navigation-bar__body { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +body.platform--apple .navigation-bar__body { + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; +} + +body.ambience--enable .navigation-bar { + visibility: hidden; +} + +.head-backward { + padding: 1.5em; + position: relative; + margin-bottom: 1.8em; + margin-top: -1.5em; + display: none; +} +.head-backward__button { + position: absolute; + top: 0.4em; + left: 0; + padding: 1.5em; +} +.head-backward__button > svg { + width: 1.7em !important; + height: 1.7em !important; +} +.head-backward__title { + font-size: 2em; + line-height: 1.4; + text-align: center; + min-height: 1.4em; + padding: 0 2em; +} + +body.true--mobile .head-backward, +body.mouse--controll .head-backward { + display: block; +} + +.wrap { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + position: relative; + z-index: 10; +} +.wrap__left { + width: 15em; + padding-top: 4em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-left: -15em; + z-index: 2; + position: relative; + -webkit-transition: -webkit-transform 0.2s; + transition: -webkit-transform 0.2s; + -o-transition: -o-transform 0.2s; + -moz-transition: transform 0.2s, -moz-transform 0.2s; + transition: transform 0.2s; + transition: transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; + will-change: transform; +} +.wrap__left .scroll--mask .scroll__content { + padding: 1.9em 0; +} +.wrap__left--hidden { + visibility: hidden; +} +.wrap__content { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding-top: 4em; + -webkit-transition: -webkit-transform 0.2s; + transition: -webkit-transform 0.2s; + -o-transition: -o-transform 0.2s; + -moz-transition: transform 0.2s, -moz-transform 0.2s; + transition: transform 0.2s; + transition: transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; + will-change: transform; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.wrap__content > * { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} + +body.menu--open:not(.light--version) .wrap__left { + -webkit-transform: translate3d(15em, 0, 0); + -moz-transform: translate3d(15em, 0, 0); + transform: translate3d(15em, 0, 0); +} +body.menu--open:not(.light--version) .wrap__content { + -webkit-transform: translate3d(15em, 0, 0); + -moz-transform: translate3d(15em, 0, 0); + transform: translate3d(15em, 0, 0); +} +body.menu--open:not(.light--version) .background { + opacity: 0.5; +} + +body.menu--always:not(.light--version) .wrap__left { + width: 5em; + margin-left: 0; + visibility: visible; +} +body.menu--always:not(.light--version) .wrap__left .menu__text { + display: none; +} + +body.menu--always.menu--open:not(.light--version) .wrap__left { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +body.menu--always.menu--open:not(.light--version) .wrap__left > .scroll { + width: 15em; +} +body.menu--always.menu--open:not(.light--version) .wrap__left .menu__text { + display: block; +} +body.menu--always.menu--open:not(.light--version) .wrap__content { + -webkit-transform: translate3d(10em, 0, 0); + -moz-transform: translate3d(10em, 0, 0); + transform: translate3d(10em, 0, 0); +} + +body.light--version .wrap__left { + visibility: visible; +} + +@media screen and (max-width: 767px) { + body.menu--open .wrap__left { + -webkit-transform: translate3d(15em, 0, 0); + -moz-transform: translate3d(15em, 0, 0); + transform: translate3d(15em, 0, 0); + } +} +@-webkit-keyframes marker-status-live { + 0% { + -webkit-box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + background-color: #76e67a; + } + 70% { + -webkit-box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.5); + } + 100% { + -webkit-box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.4); + } +} +@-moz-keyframes marker-status-live { + 0% { + -moz-box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + background-color: #76e67a; + } + 70% { + -moz-box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.5); + } + 100% { + -moz-box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.4); + } +} +@-o-keyframes marker-status-live { + 0% { + box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + background-color: #76e67a; + } + 70% { + box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.5); + } + 100% { + box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.4); + } +} +@keyframes marker-status-live { + 0% { + -webkit-box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + -moz-box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + box-shadow: 0 0 0 0 rgba(118, 230, 122, 0.7); + background-color: #76e67a; + } + 70% { + -webkit-box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + -moz-box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + box-shadow: 0 0 0 0.4em rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.5); + } + 100% { + -webkit-box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + -moz-box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + box-shadow: 0 0 0 0 rgba(234, 78, 78, 0); + background-color: rgba(255, 255, 255, 0.4); + } +} +@-webkit-keyframes marker-status-pass { + 0% { + background-color: #76e67a; + } + 65% { + background-color: rgba(255, 255, 255, 0.4); + } + 100% { + background-color: rgba(255, 255, 255, 0.4); + } +} +@-moz-keyframes marker-status-pass { + 0% { + background-color: #76e67a; + } + 65% { + background-color: rgba(255, 255, 255, 0.4); + } + 100% { + background-color: rgba(255, 255, 255, 0.4); + } +} +@-o-keyframes marker-status-pass { + 0% { + background-color: #76e67a; + } + 65% { + background-color: rgba(255, 255, 255, 0.4); + } + 100% { + background-color: rgba(255, 255, 255, 0.4); + } +} +@keyframes marker-status-pass { + 0% { + background-color: #76e67a; + } + 65% { + background-color: rgba(255, 255, 255, 0.4); + } + 100% { + background-color: rgba(255, 255, 255, 0.4); + } +} +.head { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 15; +} +.head__body { + padding: 0.5em 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.head__logo-icon { + width: 2.7em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-right: 1em; + position: relative; +} +.head__logo-local { + position: absolute; + bottom: 0; + right: 0; + background-color: #EA4E4E; + color: #fff; + font-size: 0.7em; + padding: 0.1em 0.3em; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; +} +.head__menu-icon, .head__backward { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-right: 1em; + display: none; + cursor: pointer; +} +.head__menu-icon svg, .head__backward svg { + width: 2.1em !important; + height: 2.1em !important; +} +.head__backward { + cursor: pointer; +} +.head__backward svg { + height: 1.7em !important; +} +.head__split { + background: url(../img/icons/split.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + width: 1em; + height: 1.3em; + margin: 0 1em; + opacity: 0.5; +} +.head__actions { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +@media screen and (max-width: 767px) { + .head__actions + .head__split { + display: none; + } +} +.head__title { + font-size: 1.7em; + font-weight: 300; + margin-right: auto; + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + line-height: 1.4; +} +.head__action { + width: 2.8em; + height: 2.8em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + padding: 0.6em; + margin-left: 1.5em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.head__action.focus, .head__action.hover { + background-color: #fff; + color: #000; +} +.head__action.active { + position: relative; +} +.head__action.active::after { + content: ""; + display: block; + width: 0.5em; + height: 0.5em; + position: absolute; + top: 0; + right: 0; + background-color: #EA4E4E; + border: 0.15em solid #fff; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; +} +.head__action.open--profile { + padding: 0.2em; +} +.head__action.open--profile img, +.head__action.open--profile svg { + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + width: 2.4em !important; + height: 2.4em !important; +} +@media screen and (max-width: 480px) { + .head__action { + margin-left: 0.5em; + } +} +.head__time { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + white-space: nowrap; + margin-top: -0.2em; +} +.head__time-now { + font-weight: 600; + font-size: 2em; + line-height: 0.9; + margin-right: 0.5em; +} +.head__time-date { + font-size: 0.9em; + line-height: 1; +} +.head__time-week { + font-size: 0.9em; + line-height: 1; +} +@media screen and (max-width: 767px) { + .head__time { + display: none; + } +} +.head__markers { + margin: 0 1em; +} +.head__markers-item { + width: 0.32em; + height: 0.32em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background: rgba(255, 255, 255, 0.4); + position: relative; +} +.head__markers-item + .head__markers-item { + margin-top: 0.25em; +} +.head__markers-item.status--live { + background: #76e67a; +} +.head__markers-item.status--bad { + background: #f8d183; +} +.head__markers-item.status--error { + background: #ff6868; +} +.head__markers-item.status--pass { + -webkit-animation: marker-status-pass 0.1s ease infinite; + -moz-animation: marker-status-pass 0.1s ease infinite; + -o-animation: marker-status-pass 0.1s ease infinite; + animation: marker-status-pass 0.1s ease infinite; +} +.head__fps { + position: relative; + width: 11em; + height: 2.8em; +} +.head__fps-graph { + position: absolute; + left: 0; + top: 0; + width: 11em; + height: 2.8em; + border: 1px solid #fff; +} +.head__fps-counter { + position: absolute; + right: 0.2em; + bottom: 0.1em; + font-size: 0.9em; + font-weight: 300; + color: #fff; +} +.head__navigator { + -webkit-align-self: center; + -ms-flex-item-align: center; + align-self: center; +} + +body.true--mobile .head__logo-icon, +body.true--mobile .head__action.open--search, +body.true--mobile .head__action.open--settings { + display: none; +} +body.true--mobile .head__menu-icon { + display: block; + margin-left: 0.3em; + margin-right: 1.2em; +} +body.true--mobile .head__action { + margin-left: 1em; + height: 3em; + width: 3em; +} +body.true--mobile.orientation--landscape .head .head__body { + padding-right: 10em; +} + +body.mouse--controll:not(.true--mobile) .head__logo-icon { + display: none; +} +body.mouse--controll:not(.true--mobile) .head__menu-icon { + display: block; + margin-right: 1.2em; +} +body.mouse--controll:not(.true--mobile) .head__backward { + display: block; +} + +.processing { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.processing > div { + background-color: rgba(255, 255, 255, 0.3); + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 0.3em; +} +.processing__loader { + background-image: url(../img/loader.svg); + background-position: 50% 50%; + background-repeat: no-repeat; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + width: 1.6em; + height: 1.6em; +} +.processing__text { + padding-left: 0.5em; + padding-right: 0.3em; +} + +.navigation-tabs { + padding: 0.4em; + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + border-radius: 0.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-bottom: 2em; +} +.navigation-tabs__split { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding: 0.6em; + opacity: 0.4; +} +.navigation-tabs__badge { + background: #e75454; + font-size: 0.8em; + padding: 0.1em 0.3em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + margin-left: 0.6em; + margin-top: -0.5em; + font-weight: 600; + color: #fff; +} +.navigation-tabs__button { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + padding: 0.6em; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + position: relative; +} +.navigation-tabs__button.active { + background-color: rgba(255, 255, 255, 0.35); +} +.navigation-tabs__button.focus { + background-color: #fff; + color: #000; +} + +.activitys { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.activitys__slides { + position: relative; + width: 100%; +} + +.activity { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + -webkit-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + -moz-transition: opacity 0.3s; + transition: opacity 0.3s; +} +.activity__body { + position: relative; + opacity: 1; + -webkit-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + -moz-transition: opacity 0.3s; + transition: opacity 0.3s; +} +.activity__loader { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: none; + background: url(../img/loader.svg) no-repeat 50% 50%; +} +.activity--load .activity__body, +.activity--load .activity__refresh { + opacity: 0; +} +.activity--load .activity__loader { + display: block; +} +.activity--active { + opacity: 1; + z-index: 1; +} + +.activity-wait-refresh { + padding: 1.5em; + line-height: 1.4; +} +.activity-wait-refresh__title { + font-size: 1.8em; + margin-bottom: 0.3em; +} +.activity-wait-refresh__text { + font-size: 1.2em; + margin-bottom: 1.7em; + font-weight: 300; +} +.activity-wait-refresh__items { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin: 0 -0.5em; +} +.activity-wait-refresh__items > div { + padding: 0.5em; + width: 16.66%; +} +.activity-wait-refresh__items > div > div { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: rgba(255, 255, 255, 0.5); +} +.activity-wait-refresh__items > div > div:nth-child(1) { + padding-bottom: 150%; + margin-bottom: 1em; +} +.activity-wait-refresh__items > div > div:nth-child(2) { + height: 1.4em; + width: 80%; + margin-bottom: 1em; +} +.activity-wait-refresh__items > div > div:nth-child(3) { + height: 1em; + width: 20%; +} + +.menu { + width: 100%; +} +.menu__split { + margin: 1em 1em; + width: 2.3em; + border-top: 2px solid rgba(255, 255, 255, 0.1); + margin-left: 1.7em; +} +.menu__list { + margin: 0; + padding-left: 0.6em; +} +.menu__item { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + color: #fff; + position: relative; + padding: 0.9em 1.5em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.menu__item + li { + margin-top: 0.1em; +} +.menu__item.focus, .menu__item.traverse, .menu__item.hover { + background-color: #fff; + color: #000; +} +.menu__item.focus .menu__ico > img, .menu__item.traverse .menu__ico > img, .menu__item.hover .menu__ico > img { + -webkit-filter: invert(1); + filter: invert(1); +} +.menu__item.focus .menu__ico [stroke], .menu__item.traverse .menu__ico [stroke], .menu__item.hover .menu__ico [stroke] { + stroke: #000; +} +.menu__item.focus .menu__ico path[fill], +.menu__item.focus .menu__ico rect[fill], +.menu__item.focus .menu__ico circle[fill], .menu__item.traverse .menu__ico path[fill], +.menu__item.traverse .menu__ico rect[fill], +.menu__item.traverse .menu__ico circle[fill], .menu__item.hover .menu__ico path[fill], +.menu__item.hover .menu__ico rect[fill], +.menu__item.hover .menu__ico circle[fill] { + fill: #000; +} +.menu__item.traverse::before, .menu__item.traverse::after { + position: absolute; + left: 27%; + margin-left: -0.5em; + color: #fff; +} +.menu__item.traverse::before { + content: "▲"; + top: -1.1em; +} +.menu__item.traverse::after { + content: "▼"; + bottom: -1.1em; +} +.menu__ico { + margin-right: 1.5em; + width: 1.5em; + height: 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.menu__ico > img { + width: 1.5em; + height: 1.5em; +} +.menu__text { + font-size: 1.4em; + font-weight: 300; + line-height: 0.8; + margin-top: -0.1em; +} +.menu:not(.editable) .menu__item.hidden { + display: none; +} +.menu.editable .menu__item.hidden { + opacity: 0.5; +} +.menu.editable .menu__item.focus:not(.traverse)::after { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 492.49284 492'%3E%3Cpath d='m304.140625 82.472656-270.976563 270.996094c-1.363281 1.367188-2.347656 3.09375-2.816406 4.949219l-30.035156 120.554687c-.898438 3.628906.167969 7.488282 2.816406 10.136719 2.003906 2.003906 4.734375 3.113281 7.527344 3.113281.855469 0 1.730469-.105468 2.582031-.320312l120.554688-30.039063c1.878906-.46875 3.585937-1.449219 4.949219-2.8125l271-270.976562zm0 0' fill='%23000000'%3E%3C/path%3E%3Cpath d='m476.875 45.523438-30.164062-30.164063c-20.160157-20.160156-55.296876-20.140625-75.433594 0l-36.949219 36.949219 105.597656 105.597656 36.949219-36.949219c10.070312-10.066406 15.617188-23.464843 15.617188-37.714843s-5.546876-27.648438-15.617188-37.71875zm0 0' fill='%23000000'%3E%3C/path%3E%3C/svg%3E"); + position: absolute; + right: 0.7em; + top: 50%; + color: #000; + width: 1em; + height: 1em; + margin-top: -0.5em; +} + +.menu-edit-list__item { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding: 0.3em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.menu-edit-list__item:nth-child(even) { + background: rgba(255, 255, 255, 0.1); +} +.menu-edit-list__icon { + width: 2.4em; + height: 2.4em; + margin-right: 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.menu-edit-list__icon > svg, .menu-edit-list__icon > img { + width: 1.4em !important; + height: 1.4em !important; +} +.menu-edit-list__title { + font-size: 1.3em; + font-weight: 300; + line-height: 1.2; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} +.menu-edit-list__move, .menu-edit-list__toggle { + width: 2.4em; + height: 2.4em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.menu-edit-list__move svg, .menu-edit-list__toggle svg { + width: 1em !important; + height: 1em !important; +} +.menu-edit-list__move.focus, .menu-edit-list__toggle.focus { + background: white; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + color: #000; +} +.menu-edit-list__toggle svg { + width: 1.2em !important; + height: 1.2em !important; +} + +body.light--version .menu__item { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} + +.warning-box { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + background: rgba(0, 0, 0, 0.5); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding: 1.5em; +} +.warning-box__icon { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + color: #FF6A56; +} +.warning-box__icon > * { + width: 6em; + height: 6em; +} +.warning-box__content { + -webkit-box-flex: 1; + -webkit-flex: 1; + -moz-box-flex: 1; + -ms-flex: 1; + flex: 1; + line-height: 1.4; + padding: 0 2em; +} +.warning-box__title { + font-size: 1.4em; +} +.warning-box__descr { + font-size: 1.2em; + font-weight: 100; + margin-top: 0.3em; +} +.warning-box__right { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.warning-box .simple-button { + margin-right: 0; +} +.warning-box.selector.focus .simple-button { + background-color: white; + color: #000; +} +@media screen and (max-width: 480px) { + .warning-box { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + text-align: center; + } + .warning-box__content { + padding: 2em; + } +} +.warning-box--full-adult { + width: 70%; + margin-top: 2em; +} +@media screen and (max-width: 767px) { + .warning-box--full-adult { + width: 100%; + } +} + +.ai-search-animation { + position: relative; + width: 12em; + max-width: 100%; +} +.ai-search-animation__loupe { + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + width: 4.5em; + height: 4.5em; + -webkit-animation: ai-animation-loupe linear 1.5s infinite; + -moz-animation: ai-animation-loupe linear 1.5s infinite; + -o-animation: ai-animation-loupe linear 1.5s infinite; + animation: ai-animation-loupe linear 1.5s infinite; +} +.ai-search-animation__loupe > svg { + margin-top: 2em; + margin-left: 2em; + -webkit-animation: ai-animation-loupe-icon linear 1.5s infinite; + -moz-animation: ai-animation-loupe-icon linear 1.5s infinite; + -o-animation: ai-animation-loupe-icon linear 1.5s infinite; + animation: ai-animation-loupe-icon linear 1.5s infinite; +} +.ai-search-animation__data { + -webkit-animation: ai-animation-data ease 1.5s infinite; + -moz-animation: ai-animation-data ease 1.5s infinite; + -o-animation: ai-animation-data ease 1.5s infinite; + animation: ai-animation-data ease 1.5s infinite; +} +.ai-box-scroll { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.ai-agent__ring { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + background: conic-gradient(from 0deg, #050505 0%, #2A3944 15%, #335855 32%, #050D09 48%, #26F3A0 60%, #090909 74%, #97E9DD 86%, #020202 100%); +} +.ai-agent__core { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + background-color: #262829; + position: absolute; + left: 0.2em; + top: 0.2em; + right: 0.2em; + bottom: 0.2em; + color: #26F3A0; +} +.ai-agent__core > svg { + width: 2em; + height: 2em; +} +.ai-agent--icon { + width: 3em; + height: 3em; +} +.ai-agent--absolute { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +.ai-agent--absolute .ai-agent__core > svg { + position: absolute; + left: 50%; + top: 50%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + width: 60%; + height: 60%; +} +.ai-agent.animate .ai-agent__ring { + -webkit-animation: ai-animation-agent linear 1.5s infinite; + -moz-animation: ai-animation-agent linear 1.5s infinite; + -o-animation: ai-animation-agent linear 1.5s infinite; + animation: ai-animation-agent linear 1.5s infinite; +} + +@-webkit-keyframes ai-animation-agent { + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@-moz-keyframes ai-animation-agent { + to { + -moz-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@-o-keyframes ai-animation-agent { + to { + -o-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes ai-animation-agent { + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@-webkit-keyframes ai-animation-data { + 0% { + opacity: 0; + -webkit-transform: translate3d(70%, 0, 0); + transform: translate3d(70%, 0, 0); + } + 40% { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 100% { + opacity: 0; + -webkit-transform: translate3d(-70%, 0, 0); + transform: translate3d(-70%, 0, 0); + } +} +@-moz-keyframes ai-animation-data { + 0% { + opacity: 0; + -moz-transform: translate3d(70%, 0, 0); + transform: translate3d(70%, 0, 0); + } + 40% { + opacity: 1; + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 60% { + opacity: 1; + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 100% { + opacity: 0; + -moz-transform: translate3d(-70%, 0, 0); + transform: translate3d(-70%, 0, 0); + } +} +@-o-keyframes ai-animation-data { + 0% { + opacity: 0; + transform: translate3d(70%, 0, 0); + } + 40% { + opacity: 1; + transform: translate3d(0, 0, 0); + } + 60% { + opacity: 1; + transform: translate3d(0, 0, 0); + } + 100% { + opacity: 0; + transform: translate3d(-70%, 0, 0); + } +} +@keyframes ai-animation-data { + 0% { + opacity: 0; + -webkit-transform: translate3d(70%, 0, 0); + -moz-transform: translate3d(70%, 0, 0); + transform: translate3d(70%, 0, 0); + } + 40% { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 100% { + opacity: 0; + -webkit-transform: translate3d(-70%, 0, 0); + -moz-transform: translate3d(-70%, 0, 0); + transform: translate3d(-70%, 0, 0); + } +} +@-webkit-keyframes ai-animation-loupe { + 0% { + -webkit-transform: translate(-30%, -50%) rotate(0deg); + transform: translate(-30%, -50%) rotate(0deg); + } + 100% { + -webkit-transform: translate(-30%, -50%) rotate(360deg); + transform: translate(-30%, -50%) rotate(360deg); + } +} +@-moz-keyframes ai-animation-loupe { + 0% { + -moz-transform: translate(-30%, -50%) rotate(0deg); + transform: translate(-30%, -50%) rotate(0deg); + } + 100% { + -moz-transform: translate(-30%, -50%) rotate(360deg); + transform: translate(-30%, -50%) rotate(360deg); + } +} +@-o-keyframes ai-animation-loupe { + 0% { + -o-transform: translate(-30%, -50%) rotate(0deg); + transform: translate(-30%, -50%) rotate(0deg); + } + 100% { + -o-transform: translate(-30%, -50%) rotate(360deg); + transform: translate(-30%, -50%) rotate(360deg); + } +} +@keyframes ai-animation-loupe { + 0% { + -webkit-transform: translate(-30%, -50%) rotate(0deg); + -moz-transform: translate(-30%, -50%) rotate(0deg); + -o-transform: translate(-30%, -50%) rotate(0deg); + transform: translate(-30%, -50%) rotate(0deg); + } + 100% { + -webkit-transform: translate(-30%, -50%) rotate(360deg); + -moz-transform: translate(-30%, -50%) rotate(360deg); + -o-transform: translate(-30%, -50%) rotate(360deg); + transform: translate(-30%, -50%) rotate(360deg); + } +} +@-webkit-keyframes ai-animation-loupe-icon { + 0% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } + 100% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } +} +@-moz-keyframes ai-animation-loupe-icon { + 0% { + -moz-transform: rotate(360deg); + transform: rotate(360deg); + } + 100% { + -moz-transform: rotate(0deg); + transform: rotate(0deg); + } +} +@-o-keyframes ai-animation-loupe-icon { + 0% { + -o-transform: rotate(360deg); + transform: rotate(360deg); + } + 100% { + -o-transform: rotate(0deg); + transform: rotate(0deg); + } +} +@keyframes ai-animation-loupe-icon { + 0% { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); + } + 100% { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); + } +} +.background { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; + will-change: opacity; +} +.background__one, .background__two, .background__fade { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + opacity: 0; + -webkit-transition: opacity 0.5s; + -o-transition: opacity 0.5s; + -moz-transition: opacity 0.5s; + transition: opacity 0.5s; + will-change: opacity; +} +.background__one.visible, .background__two.visible, .background__fade.visible { + opacity: 1; +} +.background__fade { + opacity: 1; +} + +.settings { + position: fixed; + top: 0; + right: 0; + z-index: 20; +} +.settings__layer { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: none; +} +@media screen and (max-width: 480px) { + .settings__layer { + -webkit-backdrop-filter: blur(1em); + backdrop-filter: blur(1em); + } +} +.settings__content { + position: fixed; + top: 0; + left: 100%; + -webkit-transition: -webkit-transform 0.2s; + transition: -webkit-transform 0.2s; + -o-transition: -o-transform 0.2s; + -moz-transition: transform 0.2s, -moz-transform 0.2s; + transition: transform 0.2s; + transition: transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; + background: #262829; + width: 35%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + will-change: transform; +} +@media screen and (max-width: 767px) { + .settings__content { + width: 50%; + } +} +@media screen and (max-width: 580px) { + .settings__content { + width: 70%; + } +} +@media screen and (max-width: 480px) { + .settings__content { + width: 100%; + left: 0; + top: unset; + bottom: 0; + height: auto !important; + -webkit-transition: none; + -o-transition: none; + -moz-transition: none; + transition: none; + -webkit-transform: translate3d(0, 100%, 0); + -moz-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + -webkit-border-top-left-radius: 2em; + -moz-border-radius-topleft: 2em; + border-top-left-radius: 2em; + -webkit-border-top-right-radius: 2em; + -moz-border-radius-topright: 2em; + border-top-right-radius: 2em; + } +} +.settings__head { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding: 2em; + padding-bottom: 0; +} +.settings__body { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +@media screen and (max-width: 480px) { + .settings__body { + height: auto !important; + font-size: 1.15em; + } +} +.settings__body > * { + width: 100%; +} +.settings__title { + font-size: 2.2em; + font-weight: 300; +} +.settings-folder { + padding: 1.5em 2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + will-change: transform; +} +.settings-folder__icon { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-right: 1.5em; + width: 2em; + height: 2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.settings-folder__icon > * { + width: 2em; + height: 2em; +} +.settings-folder__name { + font-size: 1.4em; + line-height: 1.3; +} +.settings-folder.focus { + background-color: #353535; +} +.settings-param { + padding: 1.5em 2em; + position: relative; + will-change: transform; +} +.settings-param__name { + font-size: 1.3em; + margin-bottom: 0.4em; +} +.settings-param__value { + font-size: 1.1em; +} +.settings-param__descr { + opacity: 0.5; + margin-top: 1.2em; + line-height: 1.4; +} +.settings-param__label { + background-color: #fff !important; + color: #232425 !important; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 0.2em 0.5em; + display: inline-block; +} +.settings-param__status { + position: absolute; + left: 0.8em; + top: 2em; + width: 0.6em; + height: 0.6em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; +} +.settings-param__status.wait { + background-color: #d6d6d6; +} +.settings-param__status.error { + background-color: #f53f32; +} +.settings-param__status.active { + background-color: #93d46d; +} +.settings-param.focus { + background-color: #353535; +} +.settings-param--button .settings-param__name { + margin-bottom: 0; +} +.settings-param-title { + padding: 1.5em 2em; +} +.settings-param-title > span { + font-size: 1.2em; + font-weight: 600; + color: #6f6f6f; +} +.settings-param-text { + padding: 1.5em 2em; + line-height: 1.4; +} +.settings-input { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + z-index: 21; +} +.settings-input__content { + background-color: #232425; + width: 65%; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding: 1.5em; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +@media screen and (max-width: 767px) { + .settings-input__content { + width: 100%; + } +} +.settings-input__input { + font-size: 2.1em; + margin-bottom: 1em; + min-height: 2.3em; + border-bottom: 2px solid rgba(221, 221, 221, 0.06); + padding: 0.6em 0; +} +.settings-input__input.filled::after { + content: ""; + display: inline-block; + border-right: 0.15em solid #fff; + height: 1em; + margin: -1em 0; + margin-left: 0.1em; + -webkit-animation: animation-search-input-line 0.8s infinite; + -moz-animation: animation-search-input-line 0.8s infinite; + -o-animation: animation-search-input-line 0.8s infinite; + animation: animation-search-input-line 0.8s infinite; +} +.settings-input__links { + margin-top: 1em; + background: rgba(221, 221, 221, 0.06); + -webkit-border-radius: 10em; + -moz-border-radius: 10em; + border-radius: 10em; + padding: 0.7em 1em; + font-size: 1.2em; + text-align: center; +} +@media screen and (max-width: 767px) { + .settings-input__links { + display: none; + } +} +.settings-input__title { + font-size: 2.2em; + margin-bottom: 0.7em; +} +.settings-input--free { + background-color: #232425; +} +.settings-input--free .settings-input__content { + margin: 0 auto; +} +.settings-input--focus .settings-input__content { + -webkit-box-pack: start; + -webkit-justify-content: start; + -moz-box-pack: start; + -ms-flex-pack: start; + justify-content: start; +} +.settings-input--align-top .settings-input__content { + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -moz-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} +.settings-input--align-center .settings-input__content { + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.settings-input--align-bottom .settings-input__content { + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + -moz-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; +} + +body.settings--open .settings__layer { + display: block; +} +@media screen and (min-width: 480px) { + body.settings--open .settings__content { + -webkit-transform: translate3d(-100%, 0, 0); + -moz-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.discuss-rules { + position: fixed; + top: 0; + right: 0; + z-index: 22; + background: #262829; + width: 35%; + height: 100%; +} +@media screen and (max-width: 767px) { + .discuss-rules { + display: none; + } +} +.discuss-rules__body { + padding: 1.5em; + line-height: 1.6; +} +.discuss-rules__title { + font-size: 1.8em; + font-weight: 300; + margin-bottom: 1.8em; +} +.discuss-rules__items > div { + position: relative; + font-size: 1.1em; + margin-top: 1em; + padding-left: 1em; +} +.discuss-rules__items > div::after { + position: absolute; + content: "●"; + display: block; + left: 0; + top: 0.1em; + font-size: 0.9em; +} + +.discuss-rules-helper { + font-size: 1.2em; + color: #fff; + line-height: 1.2; + background: rgba(255, 255, 255, 0.1); + padding: 0.7em; + -webkit-border-radius: 0.6em; + -moz-border-radius: 0.6em; + border-radius: 0.6em; + margin-top: 1.2em; + padding-left: 2.4em; + position: relative; +} +.discuss-rules-helper::before { + content: "🚫"; + color: #ff5757; + margin-right: 0.5em; + vertical-align: text-bottom; + display: inline-block; + position: absolute; + left: 0.6em; +} + +.scroll { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.scroll__content { + padding: 1.5em 0; + width: 100%; +} +@media screen and (max-width: 400px) { + .scroll__content { + padding: 1em 0; + } +} +.scroll__body { + -webkit-transition: -webkit-transform 0.3s; + transition: -webkit-transform 0.3s; + -o-transition: -o-transform 0.3s; + -moz-transition: transform 0.3s, -moz-transform 0.3s; + transition: transform 0.3s; + transition: transform 0.3s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; + will-change: transform; +} +.scroll__body.notransition, .scroll__body.transition-reset { + -webkit-transition: unset; + -o-transition: unset; + -moz-transition: unset; + transition: unset; +} + +.scroll--over { + overflow: hidden; +} +.scroll--mask { + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0)), color-stop(8%, white), color-stop(92%, white), to(rgba(255, 255, 255, 0))); + -webkit-mask-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, white 8%, white 92%, rgba(255, 255, 255, 0) 100%); + mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0)), color-stop(8%, white), color-stop(92%, white), to(rgba(255, 255, 255, 0))); + mask-image: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, white 8%, white 92%, rgba(255, 255, 255, 0) 100%); +} +.scroll--mask .scroll__content { + padding: 2.5em 0; +} +@media screen and (max-width: 400px) { + .scroll--mask .scroll__content { + padding: 1.5em 0; + } +} +.scroll--horizontal .scroll__content { + padding: 0 1.5em; +} +.scroll--horizontal.scroll--mask { + -webkit-mask-image: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), color-stop(8%, white), color-stop(92%, white), to(rgba(255, 255, 255, 0))); + -webkit-mask-image: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, white 8%, white 92%, rgba(255, 255, 255, 0) 100%); + mask-image: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), color-stop(8%, white), color-stop(92%, white), to(rgba(255, 255, 255, 0))); + mask-image: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, white 8%, white 92%, rgba(255, 255, 255, 0) 100%); +} +.scroll--horizontal.scroll--mask .scroll__content { + padding: 0 2.5em; +} +@media screen and (max-width: 400px) { + .scroll--horizontal.scroll--mask .scroll__content { + padding: 0 1.5em; + } +} +.scroll--nopadding .scroll__content { + padding: 0; +} +.scroll--horizontal-scroll { + cursor: ew-resize; +} + +.items-line { + padding-bottom: 3em; +} +.items-line__head { + padding: 0 1.5em; + margin-bottom: 1.4em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -moz-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} +.items-line__title { + font-size: 1.6em; + font-weight: 400; +} +.items-line__title .full-person__name { + font-size: 1em; +} +.items-line__title .full-person__photo { + width: 2em; + height: 2em; +} +.items-line__title .full-person__photo svg { + width: 1em !important; + height: 1em !important; +} +.items-line__title .full-person--svg .full-person__photo { + padding: 0.5em; +} +.items-line__more { + margin-left: 2em; + padding: 0.4em 1em; + background: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; +} +.items-line__more.focus { + background-color: #fff; + color: #000; +} +.items-line--type-cards { + min-height: 24em; +} +.items-line--type-collection { + min-height: 15em; +} +.items-line--type-player-cards .items-line__head { + padding-left: 0.8em; +} +.items-line--type-player-cards .items-line__body .scroll__content { + padding: 0 1em; +} +.items-line--type-top .items-cards .card:nth-child(1), .items-line--type-top .items-cards .card:nth-child(2), .items-line--type-top .items-cards .card:nth-child(3) { + margin-left: 6em; +} +.items-line--type-top .items-cards .card:nth-child(1)::before, .items-line--type-top .items-cards .card:nth-child(2)::before, .items-line--type-top .items-cards .card:nth-child(3)::before { + content: "1"; + position: absolute; + top: 0.2em; + right: 84%; + font-size: 16em; + color: #000000; + font-weight: 900; + -webkit-text-stroke: 0.01em #ffffff; + z-index: -1; +} +.items-line--type-top .items-cards .card:nth-child(2) { + margin-left: 4.5em; +} +.items-line--type-top .items-cards .card:nth-child(2)::before { + content: "2"; + right: 74%; +} +.items-line--type-top .items-cards .card:nth-child(3) { + margin-left: 3.7em; +} +.items-line--type-top .items-cards .card:nth-child(3)::before { + content: "3"; + right: 82%; +} + +.items-cards { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: self-start; + -webkit-align-items: self-start; + -moz-box-align: self-start; + -ms-flex-align: self-start; + align-items: self-start; +} +@media screen and (max-width: 767px) { + .items-cards .card--collection { + width: 19.7em; + } +} + +@media screen and (max-width: 767px) { + .items-line .mapping--line .card--collection { + width: 19.7em; + } +} + +.tag-count { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.6em; + -moz-border-radius: 0.6em; + border-radius: 0.6em; + padding: 0.3em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.tag-count__name { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + font-size: 1.2em; + padding: 0.2em 0.7em; +} +.tag-count__count { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + background-color: #fff; + color: #000; + font-size: 1.3em; + padding: 0.4em 0.6em; + font-weight: 600; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.tag-count.focus { + background-color: #fff; + color: #000; +} + +.reaction { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding: 0.5em; + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; +} +.reaction__icon { + width: 1.6em; + height: 1.6em; +} +.reaction__count { + padding: 0 0.5em; + font-weight: 600; + font-size: 1.1em; +} +.reaction--voted { + background-color: rgba(255, 255, 255, 0.3); +} + +.register { + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding: 1em; + line-height: 1.4; + position: relative; + min-width: 9em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.register__name { + font-size: 1.1em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + max-width: 7em; + white-space: nowrap; + min-width: 3em; +} +.register__counter { + font-size: 2em; + font-weight: 600; + white-space: nowrap; +} +.register__limit { + font-size: 0.6em; + margin-left: 0.5em; + opacity: 0.7; + font-weight: 300; +} +.register__chart { + float: right; + height: 3.9em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: end; + -webkit-align-items: end; + -moz-box-align: end; + -ms-flex-align: end; + align-items: end; + padding-left: 1em; +} +.register__chart > div { + width: 0.4em; + margin-left: 0.6em; + background-color: #fff; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; +} +.register--tag { + padding: 0.6em 1em; + min-width: auto; +} +.register--tag .register__counter { + font-size: 1.3em; +} +.register--icon .register__name svg { + width: 1.7em; + height: 1.7em; + margin-right: 0.5em; + vertical-align: middle; +} +.register.focus::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + z-index: -1; + pointer-events: none; +} + +.card { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 12.75em; + position: relative; + will-change: transform; +} +.card__img { + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: #3E3E3E; +} +.card__img-broken { + position: absolute; + top: 25%; + left: 1em; + right: 1em; + word-break: break-all; + line-height: 1.4; + background: #3E3E3E; + bottom: 20%; + color: #ffffff82; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.card__view { + margin-bottom: 1em; + position: relative; + padding-bottom: 150%; +} +.card__filter { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + mix-blend-mode: overlay; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.card__title { + font-size: 1.3em; + max-height: 3.6em; + overflow: hidden; + line-height: 1.2; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 3; + line-clamp: 3; + -webkit-box-orient: vertical; + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + transform: translateZ(0); +} +.card__age { + font-size: 0.9em; + margin-top: 0.6em; + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + transform: translateZ(0); +} +.card__icons { + position: absolute; + top: 0.9em; + left: 0; + right: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + z-index: 1; +} +.card__icons-inner { + background: rgba(0, 0, 0, 0.5); + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.card__marker { + position: absolute; + left: 0.4em; + bottom: 0.4em; + background: rgba(0, 0, 0, 0.5); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding: 0.2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-right: 0.6em; + z-index: 1; +} +.card__marker::before { + content: ""; + display: block; + width: 1em; + height: 1em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background-color: #fff; + margin-right: 0.4em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.card__marker > span { + font-size: 0.8em; + overflow: hidden; + max-width: 5em; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; +} +.card__marker--look::before { + background-color: #5DBFF5; +} +.card__marker--viewed::before { + background-color: #FFD028; +} +.card__marker--scheduled::before { + background-color: #fff; +} +.card__marker--thrown::before { + background-color: #E54747; +} +.card__marker--continued::before { + background-color: #be95ff; +} +.card__icon { + width: 1.8em; + height: 1.8em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + -webkit-background-size: 60% 60%; + -moz-background-size: 60%; + -o-background-size: 60%; + background-size: 60%; + background-position: 50% 50%; + background-repeat: no-repeat; +} +.card__icon.icon--book { + background-image: url(../img/icons/menu/bookmark.svg); +} +.card__icon.icon--wath { + background-image: url(../img/icons/menu/time.svg); +} +.card__icon.icon--like { + background-image: url(../img/icons/menu/like.svg); +} +.card__icon.icon--history { + background-image: url(../img/icons/settings/player.svg); +} +.card__promo { + position: absolute; + left: 0; + bottom: 0; + right: 0; + padding: 3em 1.5em 1.5em 1.5em; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.85))); + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 100%); + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 100%); + background: -o-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 100%); + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 100%); + -webkit-border-bottom-left-radius: 1em; + -moz-border-radius-bottomleft: 1em; + border-bottom-left-radius: 1em; + -webkit-border-bottom-right-radius: 1em; + -moz-border-radius-bottomright: 1em; + border-bottom-right-radius: 1em; + color: #fff; +} +.card__promo-title { + font-size: 2em; + line-height: 1.2; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; +} +.card__promo-text { + font-size: 1.3em; + line-height: 1.2; + margin-top: 1em; + font-weight: 300; +} +.card__type { + position: absolute; + left: -0.8em; + top: 1.4em; + padding: 0.4em 0.4em; + background: #fff; + color: #000; + font-size: 0.8em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + z-index: 1; +} +.card__new-episode { + position: absolute; + right: 0; + left: 0; + text-align: center; + bottom: 0.8em; +} +.card__new-episode > div { + background-color: #57F570; + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + padding: 0.5em 1em; + color: #17491C; + display: inline-block; +} +.card__quality { + position: absolute; + left: -0.8em; + bottom: 3em; + padding: 0.4em 0.4em; + background: #ffe216; + color: #000; + font-size: 0.8em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + text-transform: uppercase; + z-index: 1; +} +.card__vote { + position: absolute; + right: 0.3em; + bottom: 0.3em; + background: rgba(0, 0, 0, 0.5); + color: #fff; + font-size: 1.3em; + font-weight: 700; + font-weight: 700; + padding: 0.2em 0.5em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + z-index: 1; +} +.card__textbox { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + padding: 1em; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), color-stop(52%, rgba(0, 0, 0, 0.85)), to(rgba(0, 0, 0, 0.85))); + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 52%, rgba(0, 0, 0, 0.85) 100%); + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 52%, rgba(0, 0, 0, 0.85) 100%); + background: -o-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 52%, rgba(0, 0, 0, 0.85) 100%); + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 52%, rgba(0, 0, 0, 0.85) 100%); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + line-height: 1.5; + -webkit-box-align: end; + -webkit-align-items: flex-end; + -moz-box-align: end; + -ms-flex-align: end; + align-items: flex-end; +} +.card__subscribe { + background: rgba(0, 0, 0, 0.3); + padding: 0.4em 0.7em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + margin-bottom: 0.6em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + line-height: 1.4; +} +.card__subscribe-status { + width: 0.6em; + height: 0.6em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background-color: #ddd; + margin-right: 0.6em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.card__subscribe-status.on { + background-color: #9bce54; +} +.card__subscribe-status.off { + background-color: #f05757; +} +.card__subscribe-position { + font-weight: 700; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.card__subscribe-voice { + margin-left: auto; + padding-left: 1em; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} +.card.focus .card__view::after, .card.hover .card__view::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + z-index: -1; + pointer-events: none; +} +.card.hover .card__view::after { + border-color: rgba(255, 255, 255, 0.5); +} +.card--prefab { + min-height: 19em; +} +.card--tv .card__type { + background: #ff4242; + color: #fff; +} +.card--disabled { + opacity: 0.5; +} +.card--wide { + width: 34.3em; +} +.card--wide .card__view { + padding-bottom: 56%; +} +.card--wide .card-watched { + top: 1em; + left: 1.4em; + right: 62%; + bottom: auto; +} +.card--wide .card-watched__title { + display: none; +} +.card--wide .card-watched__body { + padding-top: 1em; +} +.card--wide .card-watched__item { + margin: 0; +} +.card--wide .card-watched__item:not(:first-child) { + display: none; +} +.card--collection { + padding-bottom: 1em; + width: 25%; +} +.card--collection .card__view { + padding-bottom: 60%; +} + +@media screen and (min-width: 767px) { + body.size--bigger .card { + font-size: 1.14em; + } + body.size--bigger .card--category { + width: 20%; + } + body.size--bigger .card--explorer { + width: 25%; + } + body.size--bigger .card--collection { + width: 33.33%; + } +} +body.platform--orsay .card__title, +body.platform--netcast .card__title { + -webkit-line-clamp: 1; + line-clamp: 1; + height: 1.4em; +} + +.card-parser { + padding: 0.75em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 14.6em; + background-color: rgba(255, 255, 255, 0.2); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + position: relative; +} +.card-parser__footer { + margin-top: auto; + padding-top: 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.card-parser__title { + font-size: 1.4em; + line-height: 1.3; +} +.card-parser__size { + background-color: #fff; + color: #000; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + font-size: 1.3em; + padding: 0.3em 0.4em 0.4em; + margin-left: auto; + font-weight: 600; +} +.card-parser__details { + color: rgba(255, 255, 255, 0.6); + line-height: 1.4; +} +.card-parser__details span { + color: #fff; + font-weight: 700; +} +.card-parser.focus::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + z-index: -1; + pointer-events: none; +} + +.card-watched { + position: absolute; + top: auto; + left: 1em; + right: 1em; + bottom: 3em; + z-index: 1; + background-color: rgba(0, 0, 0, 0.9); + display: none; + pointer-events: none; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.card-watched__inner { + padding: 0 1em 1em 1em; +} +.card-watched__body { + font-size: 0.8em; +} +.card-watched__item { + margin-top: 1em; +} +.card-watched__item > span { + display: block; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; +} +.card-watched__item:nth-child(1) { + color: #fff; +} +.card-watched__item:nth-child(2) { + color: #9f9f9f; +} +.card-watched__item:nth-child(3) { + color: #6c6c6c; +} +.card-watched__item:nth-child(4) { + color: #5e5e5e; +} +.card-watched__item:nth-child(5) { + color: #4c4c4c; +} +.card-watched__item .time-line { + margin-top: 0.5em; +} + +.card.focus .card-watched { + display: block; +} + +.full-start { + padding: 0 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding-bottom: 4em; + position: relative; +} +.full-start__tags { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-bottom: 2.5em; +} +.full-start__deta { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-bottom: 1em; +} +.full-start__pg, .full-start__status { + font-size: 1.2em; + border: 1px solid #fff; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + padding: 0.3em; +} +.full-start__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + height: 30em; +} +@media screen and (max-width: 767px) { + .full-start__body { + height: auto; + padding-bottom: 3em; + } +} +@media screen and (max-width: 400px) { + .full-start__body { + display: block; + } +} +@media screen and (max-width: 580px) { + .full-start__body { + padding-bottom: 0em; + } +} +.full-start__right { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +@media screen and (max-width: 580px) { + .full-start__right { + -webkit-box-ordinal-group: 2; + -webkit-order: 1; + -moz-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } +} +.full-start__left { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + padding-left: 3em; + overflow: hidden; +} +@media screen and (max-width: 580px) { + .full-start__left { + padding-left: 0em; + overflow: inherit; + } +} +@media screen and (max-width: 400px) { + .full-start__left { + margin-top: -17em; + z-index: 1; + position: relative; + } +} +.full-start__background { + position: absolute; + left: 8em; + width: 100%; + z-index: -1; + -webkit-mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAjCAYAAAA5dzKxAAAD+UlEQVRYhcWZ61IaQRCFz7KAgBgvyfu/XSqVquSXGrlKfjDH/Wh7FowYp6prVthl+5u+TE/b7HY7nWE07/y8Sa53Pc/7vh1leETJtygyKNcDXFPiPf68Te7N4AigMm+LbCSt+2CyVWkwU5lW0lDSqMyUAe5pw/1+xn+3AZjv8rAltpJWRZ4k3ddgaivEVbcyF5LGZZ5AxkVGgBwHuSjie1rMmbUM8qy9NZYF5EnSzwyGKxLdgStupaeSZpLmki7L9ax8Z2Wp/ATfTcs1gWkh6uLxXMSWWRT5HmEy3yaElZsA4ErSlzJfFSBDEYhCMFrQbkmhhzheItBG0m1mGVpigFXzSl4GiJsiBJoDhm41SpT33OrQIoRg4GdQjaQtYTIf9cvGALmSdC3ptshdALK7TYPSYyhNd4pBT4C4yBGMbjjvczO6mF3CMDcF4qukbwXKMAaxO9F1mN36UngcNTBaqx3iS4tfwDQ6Vhfsc3XudQeo6wI6U5ehsnQbE0vfFnBsHGTbWszQMnYzxwxh6GbX6qzi9Eqlszj4V4h09MUMYZwAZupc7UsQBz1dK1P87BCEiS8iTM06huLewoDnHpGNsygfR4wZXxOEpQo3vSmEwd6q35U+bBwrNOPGaZeLe4djhGXIfx81V8iyW7QWhWn200aEeUtK7CvTP2VEmOykxgMQa6It/n7W4TnjU0bNzaLyLrk3ktZFfJZYl88N6Gfjb304JBMAVzZawRAr7c8QC+3PEC6/J+rSfG1nj8Xi2d3RMD5v74J4tQ1iiMciD+rOIwP8Fnd/gmTl/NmghgHEL6F70a0M8iDpXl2J75RsSxouljRxPyPkWWA4ai5mq/xRZw0Xk2151uArHRaa8bCVVcseZ6vNTnGxsfYWoaIEWWpf3hiW55ZagyOz2LthIpAzWFtghtpbhhulQWi5ubqzPSuE2iHt2AnTevWNRuibxQTwchTVfsVZATCwDeys9qjX538XqKNw7VqPTRJaK2tmZMMJZ5PVZhmQ44YrFTskTzqsoGvNDAPacuze0GpZRvTMfcu6rGLMNPjSD24rwLaKYR7VHQ9i78xCwKkO+2zs1mRNjgzGC7qT9DuLmbj6NRC74FpdvFghWoBVNq1AkClmPkv3i3uUF9M6vOqbUWEFmCxtO4NFV7EibCcxGRCMCxDdk41Bbsp8/6Lo8KMWM9xEXUTGTOcfG5Yfi31jukmtH51ZjgtTg4n730LSr6bnXxpxM4vNiTbMgyN/sxfHA59BY1MwdncyGHvGUtJ9H0wGFEuRmKqznT37LD4bU3/ce+J2QCDL8hhMDa5vjgXlKeVKtlBZPZdV9i9x/NZ/NkXyU1cigzilaq59l+rxF+5FNzBsTB9XAAAAAElFTkSuQmCC"); + mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAjCAYAAAA5dzKxAAAD+UlEQVRYhcWZ61IaQRCFz7KAgBgvyfu/XSqVquSXGrlKfjDH/Wh7FowYp6prVthl+5u+TE/b7HY7nWE07/y8Sa53Pc/7vh1leETJtygyKNcDXFPiPf68Te7N4AigMm+LbCSt+2CyVWkwU5lW0lDSqMyUAe5pw/1+xn+3AZjv8rAltpJWRZ4k3ddgaivEVbcyF5LGZZ5AxkVGgBwHuSjie1rMmbUM8qy9NZYF5EnSzwyGKxLdgStupaeSZpLmki7L9ax8Z2Wp/ATfTcs1gWkh6uLxXMSWWRT5HmEy3yaElZsA4ErSlzJfFSBDEYhCMFrQbkmhhzheItBG0m1mGVpigFXzSl4GiJsiBJoDhm41SpT33OrQIoRg4GdQjaQtYTIf9cvGALmSdC3ptshdALK7TYPSYyhNd4pBT4C4yBGMbjjvczO6mF3CMDcF4qukbwXKMAaxO9F1mN36UngcNTBaqx3iS4tfwDQ6Vhfsc3XudQeo6wI6U5ehsnQbE0vfFnBsHGTbWszQMnYzxwxh6GbX6qzi9Eqlszj4V4h09MUMYZwAZupc7UsQBz1dK1P87BCEiS8iTM06huLewoDnHpGNsygfR4wZXxOEpQo3vSmEwd6q35U+bBwrNOPGaZeLe4djhGXIfx81V8iyW7QWhWn200aEeUtK7CvTP2VEmOykxgMQa6It/n7W4TnjU0bNzaLyLrk3ktZFfJZYl88N6Gfjb304JBMAVzZawRAr7c8QC+3PEC6/J+rSfG1nj8Xi2d3RMD5v74J4tQ1iiMciD+rOIwP8Fnd/gmTl/NmghgHEL6F70a0M8iDpXl2J75RsSxouljRxPyPkWWA4ai5mq/xRZw0Xk2151uArHRaa8bCVVcseZ6vNTnGxsfYWoaIEWWpf3hiW55ZagyOz2LthIpAzWFtghtpbhhulQWi5ubqzPSuE2iHt2AnTevWNRuibxQTwchTVfsVZATCwDeys9qjX538XqKNw7VqPTRJaK2tmZMMJZ5PVZhmQ44YrFTskTzqsoGvNDAPacuze0GpZRvTMfcu6rGLMNPjSD24rwLaKYR7VHQ9i78xCwKkO+2zs1mRNjgzGC7qT9DuLmbj6NRC74FpdvFghWoBVNq1AkClmPkv3i3uUF9M6vOqbUWEFmCxtO4NFV7EibCcxGRCMCxDdk41Bbsp8/6Lo8KMWM9xEXUTGTOcfG5Yfi31jukmtH51ZjgtTg4n730LSr6bnXxpxM4vNiTbMgyN/sxfHA59BY1MwdncyGHvGUtJ9H0wGFEuRmKqznT37LD4bU3/ce+J2QCDL8hhMDa5vjgXlKeVKtlBZPZdV9i9x/NZ/NkXyU1cigzilaq59l+rxF+5FNzBsTB9XAAAAAElFTkSuQmCC"); + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; + -webkit-mask-position: 100% 50%; + mask-position: 100% 50%; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + opacity: 0; + -webkit-transition: opacity 0.5s ease-in-out; + -o-transition: opacity 0.5s ease-in-out; + -moz-transition: opacity 0.5s ease-in-out; + transition: opacity 0.5s ease-in-out; + height: 108%; + top: -6em; +} +.full-start__background.loaded { + opacity: 0.5; +} +.full-start__background.dim { + opacity: 0.2; +} +.full-start__poster { + position: relative; +} +.full-start__poster.focus img { + -webkit-box-shadow: 0 0 0 0.4em #fff; + -moz-box-shadow: 0 0 0 0.4em #fff; + box-shadow: 0 0 0 0.4em #fff; +} +.full-start__poster:before { + display: none; +} +@media screen and (max-width: 480px) { + .full-start__poster { + font-size: 0.9em; + } +} +@media screen and (max-width: 400px) { + .full-start__poster { + padding-bottom: 150%; + margin: 0 -1.8em; + margin-top: -2em; + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, color-stop(40%, white), to(rgba(255, 255, 255, 0))); + -webkit-mask-image: -webkit-linear-gradient(top, white 40%, rgba(255, 255, 255, 0) 100%); + mask-image: -webkit-gradient(linear, left top, left bottom, color-stop(40%, white), to(rgba(255, 255, 255, 0))); + mask-image: linear-gradient(to bottom, white 40%, rgba(255, 255, 255, 0) 100%); + } + .full-start__poster.background--poster { + padding-bottom: 100%; + } +} +.full-start__img { + position: relative; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + width: 17em; + height: 25.5em; +} +@media screen and (max-width: 767px) { + .full-start__img { + font-size: 1.3em; + } +} +@media screen and (max-width: 580px) { + .full-start__img { + font-size: 0.8em; + } +} +@media screen and (max-width: 400px) { + .full-start__img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } +} +.full-start__tag { + -webkit-border-radius: 0.6em; + -moz-border-radius: 0.6em; + border-radius: 0.6em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-right: 1em; + font-size: 1.15em; + white-space: nowrap; + margin-bottom: 0.4em; + background-color: rgba(0, 0, 0, 0.3); + padding: 0.3em 0.5em 0.3em 0.3em; +} +.full-start__tag > img { + width: 1em; + height: 1em; + margin-right: 0.8em; +} +.full-start__tag > div { + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.full-start__tag.tag--quality { + -webkit-border-radius: 0.6em; + -moz-border-radius: 0.6em; + border-radius: 0.6em; + background: #ffe216; + color: #000; + padding: 0.3em 0.4em; + text-transform: uppercase; +} +.full-start__title { + font-size: 3.2em; + font-weight: 400; + margin-bottom: 0.1em; + max-width: 90%; + max-height: 2.6em; + overflow: hidden; + line-height: 1.3; +} +@media screen and (max-width: 767px) { + .full-start__title { + font-size: 3em; + } +} +.full-start__title-original { + font-size: 2.2em; + font-weight: 300; + max-width: 80%; + margin-bottom: 0.9em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 1; + line-clamp: 1; + -webkit-box-orient: vertical; + line-height: 1.3; +} +.full-start__descr { + max-width: 80%; + font-size: 1.3em; + line-height: 1.4; + font-weight: 300; + height: 8em; + margin-bottom: 1em; + overflow: hidden; + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(68%, white), to(rgba(255, 255, 255, 0))); + -webkit-mask-image: -webkit-linear-gradient(top, white 0%, white 68%, rgba(255, 255, 255, 0) 100%); + mask-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(68%, white), to(rgba(255, 255, 255, 0))); + mask-image: linear-gradient(to bottom, white 0%, white 68%, rgba(255, 255, 255, 0) 100%); +} +@media screen and (max-width: 767px) { + .full-start__descr { + display: none; + } +} +.full-start__buttons { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.full-start__buttons-line { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +@media screen and (max-width: 480px) { + .full-start__buttons-line { + margin: -1.5em; + } + .full-start__buttons-line .full-start__buttons { + padding: 0 1.5em; + } +} +.full-start__buttons-scroll { + margin-left: -1.5em; + margin-right: -1.5em; +} +.full-start__button { + margin-right: 0.75em; + font-size: 1.3em; + background-color: rgba(0, 0, 0, 0.3); + padding: 0.3em 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + height: 2.8em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.full-start__button > svg { + width: 1.5em; + height: 1.5em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.full-start__button > svg + span { + margin-left: 0.75em; + margin-top: -0.2em; +} +.full-start__button.focus { + background-color: #fff; + color: #000; +} +.full-start__button.loading { + position: relative; +} +.full-start__button.loading > svg { + opacity: 0; +} +.full-start__button.loading:before { + content: ""; + position: absolute; + top: 0.6em; + left: 1em; + width: 1.5em; + height: 1.5em; + background: url(../img/loader.svg) center center no-repeat; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; +} +.full-start__button.loading.focus:before { + -webkit-filter: invert(1); + filter: invert(1); +} +.full-start__ratings { + margin-left: 2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.full-start__rating { + text-align: right; +} +.full-start__rating-name { + text-transform: uppercase; + font-size: 0.7em; +} +.full-start__rating-value { + font-size: 3em; + font-weight: 600; +} +.full-start__rating + div { + margin-left: 2em; +} +.full-start__rate { + background: rgba(0, 0, 0, 0.15); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + font-size: 1.45em; + margin-right: 1em; +} +.full-start__rate > div:first-child { + width: 1.8em; + height: 1.5em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + background: rgba(0, 0, 0, 0.15); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.full-start__rate > div:last-child { + font-size: 0.7em; + padding: 0 0.5em; +} +.full-start__icons { + margin-left: auto; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.full-start .info__rate { + margin: 0; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + font-size: 0.75em; + margin-right: 1.5em; + position: relative; +} +.full-start .info__rate > div { + position: absolute; + bottom: -0.6em; + right: 0; + background-color: #fff; + color: #000; + padding: 0.3em; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; +} +.full-start .info__icon { + margin-left: 0; + margin-right: 1em; +} + +body.touch-device .full-start__background { + left: 0; +} + +body.card--no-cover .full-start__background { + display: none; +} + +body.touch-device.orientation--landscape .full-start__background { + width: 113%; + max-width: 113%; +} + +@media screen and (min-width: 767px) { + body.no--poster .full-start__right { + display: none; + } + body.no--poster .full-start__left { + padding-left: 0; + overflow: inherit; + } +} +.full-start-new { + padding: 0 1.5em; + padding-bottom: 4em; +} +.full-start-new__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: end; + -webkit-align-items: flex-end; + -moz-box-align: end; + -ms-flex-align: end; + align-items: flex-end; +} +@media screen and (max-width: 580px) { + .full-start-new__body { + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + } +} +@media screen and (max-width: 480px) { + .full-start-new__body { + display: block; + } +} +.full-start-new__left { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 17em; + margin-right: 3em; +} +@media screen and (max-width: 580px) { + .full-start-new__left { + width: 30%; + } +} +@media screen and (max-width: 480px) { + .full-start-new__left { + width: auto; + margin: -1.5em; + } +} +.full-start-new__right { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} +@media screen and (max-width: 580px) { + .full-start-new__right { + overflow: hidden; + } +} +@media screen and (max-width: 480px) { + .full-start-new__right { + margin-left: -1.5em; + margin-right: -1.5em; + padding: 1.5em; + margin-top: -14em; + margin-top: -20vh; + position: relative; + z-index: 1; + -webkit-border-top-left-radius: 2em; + -moz-border-radius-topleft: 2em; + border-top-left-radius: 2em; + -webkit-border-top-right-radius: 2em; + -moz-border-radius-topright: 2em; + border-top-right-radius: 2em; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.8)), to(rgba(0, 0, 0, 0))); + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%); + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%); + background: -o-linear-gradient(top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%); + background: linear-gradient(to bottom, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%); + } +} +.full-start-new__poster { + position: relative; + padding-bottom: 150%; + background-color: #3E3E3E; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.full-start-new__poster.loaded { + background-color: transparent; +} +.full-start-new__poster.loaded img { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.full-start-new__poster.with-out img { + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, color-stop(40%, white), to(rgba(255, 255, 255, 0))); + -webkit-mask-image: -webkit-linear-gradient(top, white 40%, rgba(255, 255, 255, 0) 100%); + mask-image: -webkit-gradient(linear, left top, left bottom, color-stop(40%, white), to(rgba(255, 255, 255, 0))); + mask-image: linear-gradient(to bottom, white 40%, rgba(255, 255, 255, 0) 100%); +} +@media screen and (max-width: 480px) { + .full-start-new__poster { + padding-bottom: 100%; + background: transparent; + } + .full-start-new__poster .card__type { + left: 1.4em; + top: 3.2em; + font-size: 1em; + } +} +.full-start-new__img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + opacity: 0; +} +@media screen and (max-width: 480px) { + .full-start-new__img { + -webkit-transform: translate3d(0, 2em, 0); + -moz-transform: translate3d(0, 2em, 0); + transform: translate3d(0, 2em, 0); + -webkit-transition: opacity 0.2s, -webkit-transform 0.4s; + transition: opacity 0.2s, -webkit-transform 0.4s; + -o-transition: opacity 0.2s, -o-transform 0.4s; + -moz-transition: opacity 0.2s, transform 0.4s, -moz-transform 0.4s; + transition: opacity 0.2s, transform 0.4s; + transition: opacity 0.2s, transform 0.4s, -webkit-transform 0.4s, -moz-transform 0.4s, -o-transform 0.4s; + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; + } +} +.full-start-new__head { + color: rgba(255, 255, 255, 0.6); + font-size: 1.2em; +} +.full-start-new__head span { + color: #fff; +} +@media screen and (max-width: 580px) { + .full-start-new__head { + margin-bottom: 0.5em; + } +} +.full-start-new__title { + font-size: 4em; + font-weight: 600; + margin-bottom: 0.2em; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 1; + line-clamp: 1; + -webkit-box-orient: vertical; + margin-left: -0.03em; + line-height: 1.3; +} +.full-start-new__title.twolines { + -webkit-line-clamp: 2; + line-clamp: 2; + font-size: 3.5em; +} +@media screen and (max-width: 580px) { + .full-start-new__title { + font-size: 2.8em; + } +} +@media screen and (max-width: 480px) { + .full-start-new__title { + -webkit-line-clamp: 3; + line-clamp: 3; + font-size: 2.6em; + } +} +.full-start-new__tagline { + font-size: 1.8em; + line-height: 1.2; + margin-bottom: 1em; + margin-top: -0.3em; +} +@media screen and (max-width: 580px) { + .full-start-new__tagline { + font-size: 1.5em; + } +} +.full-start-new__details { + color: #fff; + margin: -0.45em; + margin-bottom: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + min-height: 1.9em; + font-size: 1.1em; +} +.full-start-new__details > * { + margin: 0.45em; +} +@media screen and (max-width: 767px) { + .full-start-new__details { + width: auto; + } +} +.full-start-new__reactions { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: -0.5em; + margin-bottom: 1em; + min-height: 3.6em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.full-start-new__reactions > div { + padding: 0.5em; +} +.full-start-new__rate-line { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-bottom: 2.2em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.full-start-new__rate-line .full-start__rate { + margin: 0; +} +.full-start-new__rate-line > * { + margin-left: 0 !important; + margin-right: 1em !important; +} +.full-start-new__rate-line .full-start__pg { + font-size: 1.12em; +} +@media screen and (max-width: 580px) { + .full-start-new__rate-line { + font-size: 0.9em; + } +} +@media screen and (max-width: 480px) { + .full-start-new__rate-line { + padding-top: 1.3em; + } +} +.full-start-new__split { + font-size: 0.7em; +} +.full-start-new__description { + font-size: 1.2em; + font-weight: 300; + line-height: 1.5; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 4; + line-clamp: 4; + -webkit-box-orient: vertical; + width: 70%; +} +.full-start-new__creator .full-person { + font-size: 0.9em; +} +.full-start-new__creator .full-person__photo { + width: 5em; + height: 5em; +} +.full-start-new__buttons { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +@media screen and (max-width: 580px) { + .full-start-new__buttons { + overflow: auto; + } +} +.full-start-new__buttons .full-start__button:not(.focus) span { + display: none; +} + +@media screen and (min-width: 767px) { + body.no--poster .full-start-new__left { + display: none; + } +} +.full-descr { + padding: 0 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +@media screen and (max-width: 580px) { + .full-descr { + display: block; + } +} +.full-descr__text { + font-size: 1.3em; + line-height: 1.4; + font-weight: 300; + max-height: 70vh; + overflow: hidden; + max-height: 41vh; + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(80%, white), to(rgba(255, 255, 255, 0))); + -webkit-mask-image: -webkit-linear-gradient(top, white 0%, white 80%, rgba(255, 255, 255, 0) 100%); + mask-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(80%, white), to(rgba(255, 255, 255, 0))); + mask-image: linear-gradient(to bottom, white 0%, white 80%, rgba(255, 255, 255, 0) 100%); + width: 70%; +} +@media screen and (max-width: 991px) { + .full-descr__text { + width: 100%; + } +} +.full-descr__left { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} +.full-descr__right { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 30%; + padding-left: 2.3em; +} +@media screen and (max-width: 580px) { + .full-descr__right { + width: 100%; + padding-left: 0; + padding-top: 2em; + } +} +.full-descr__details { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: -1em; +} +.full-descr__details > * { + margin: 1em; +} +.full-descr__line { + margin-top: 2em; +} +.full-descr__line-name { + font-size: 1.2em; + margin-bottom: 1em; +} +.full-descr__line-body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: -0.2em; +} +.full-descr__info-name { + font-size: 1.2em; + margin-bottom: 0.7em; +} +.full-descr__info-body { + font-size: 1.3em; + font-weight: 300; +} +.full-descr__tag { + -webkit-border-radius: 0.6em; + -moz-border-radius: 0.6em; + border-radius: 0.6em; + background-color: rgba(0, 0, 0, 0.3); + padding: 0.4em 0.8em 0.5em 0.8em; + font-size: 1.2em; + margin: 0.2em; +} +.full-descr__tag.focus { + background-color: #fff; + color: #000; +} +.full-descr__tags { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: -0.5em; + margin-top: 1.5em; +} +@media screen and (max-width: 480px) { + .full-descr__tags { + font-size: 0.9em; + } +} +.full-descr__tags > * { + margin: 0.5em; +} + +.full-metadata { + padding: 0 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} +.full-metadata > * { + margin: 0.5em; +} + +.full-person { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding-right: 1.7em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + font-size: 1.1em; +} +.full-person__photo { + width: 7em; + height: 7em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + background-color: #fff; + margin-right: 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + background-position: 50% 50%; + overflow: hidden; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.full-person__photo > img { + width: 100%; + opacity: 0; +} +.full-person__name { + font-size: 1.5em; +} +.full-person__role { + font-size: 1.1em; + margin-top: 0.7em; +} +.full-person.hover { + background-color: rgba(255, 255, 255, 0.3); +} +.full-person.focus { + background-color: #fff; + color: #000; +} +.full-person--loaded .full-person__photo > img { + opacity: 1; +} + +.full-review { + padding: 1.5em; + background-color: rgba(0, 0, 0, 0.4); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.full-review__text { + font-size: 1.2em; + line-height: 1.3; + margin-bottom: 1.5em; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; +} +.full-review__footer { + font-size: 1.2em; + margin-top: auto; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.full-review__user { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-right: 2em; +} +.full-review__user-icon { + width: 2em; + height: 2em; + margin-right: 1em; +} +.full-review__user-img { + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.full-review__user-email { + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + max-width: 7em; + line-height: 1.4; + white-space: nowrap; +} +.full-review__user:not(.loaded) .full-review__user-icon { + background: #494949; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; +} +.full-review__user:not(.loaded) .full-review__user-img { + opacity: 0; +} +.full-review__like { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-left: auto; +} +.full-review__like-icon { + margin-right: 0.7em; +} +.full-review__like-icon svg { + width: 1.1em !important; + height: 1.2em !important; +} +.full-review.type--vertical { + margin-bottom: 1.5em; + min-width: unset; + max-width: unset; +} +.full-review.type--vertical + .full-review { + margin-left: 0; +} +.full-review.focus { + background-color: #fff; + color: #000; +} +.full-review.bad--comment { + opacity: 0.5; +} +.full-review.bad--comment .full-review__like-icon { + -webkit-transform: scaleY(-1) translateY(-0.2em); + -moz-transform: scaleY(-1) translateY(-0.2em); + -ms-transform: scaleY(-1) translateY(-0.2em); + -o-transform: scaleY(-1) translateY(-0.2em); + transform: scaleY(-1) translateY(-0.2em); +} +.full-review--full-text .full-review__text { + -webkit-line-clamp: 12; + line-clamp: 12; +} + +.full-review-add { + padding: 1.5em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + border: dashed 2px #ddd; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + position: relative; + min-height: 10em; +} +.full-review-add::before { + content: ""; + display: block; + position: absolute; + left: 50%; + top: 50%; + width: 2em; + height: 2em; + background: url(../img/icons/add.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + margin-left: -1em; + margin-top: -1em; +} +.full-review-add.focus::after { + content: ""; + position: absolute; + left: -0.5em; + top: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + pointer-events: none; +} + +.full-review-all { + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + min-width: 12em; +} +.full-review-all__text { + font-size: 1.2em; +} +.full-review-all__count { + font-size: 2em; + margin-top: 0.5em; +} + +.mapping--line > .full-review { + min-width: 20em; + max-width: 30em; +} +.mapping--line > .full-review-add { + width: 12em; +} + +.full-episode { + position: relative; +} +.full-episode__img { + padding-bottom: 57%; + position: relative; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + background-color: rgba(0, 0, 0, 0.3); + -webkit-transition: background-color 0.2s; + -o-transition: background-color 0.2s; + -moz-transition: background-color 0.2s; + transition: background-color 0.2s; +} +.full-episode__img img { + position: absolute; + left: 0; + right: 0; + width: 100%; + height: 100%; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + opacity: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.full-episode__body { + padding: 1em; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + display: none; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + background-color: rgba(0, 0, 0, 0.5); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + -moz-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; +} +.full-episode__name { + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + font-size: 1.3em; +} +.full-episode__date { + font-size: 1em; + margin-top: 0.6em; +} +.full-episode__num { + font-size: 2em; + margin-bottom: 0.7em; +} +.full-episode__viewed { + position: absolute; + top: 0.5em; + right: 0.5em; + display: none; +} +.full-episode__viewed > svg { + width: 1.4em !important; + height: 1.4em !important; +} +.full-episode.focus .full-episode__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.full-episode.focus::after { + content: ""; + position: absolute; + left: -0.5em; + top: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + pointer-events: none; +} +.full-episode--loaded .full-episode__img { + background: transparent; +} +.full-episode--loaded .full-episode__img img { + opacity: 1; +} +.full-episode--viewed .full-episode__viewed { + display: block; +} +.full-episode--small { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 15em; +} +.full-episode--next .full-episode__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + background-color: transparent; +} +.full-episode--next .full-episode__img { + background-color: transparent; +} +.full-episode--next .full-episode__img img { + opacity: 0; +} +.full-episode--next .full-episode__img:after { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 0.2em dashed rgba(255, 255, 255, 0.2); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.full-episode--wath-all .full-episode__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.full-episode--wath-all .full-episode__date, .full-episode--wath-all .full-episode__num { + display: none; +} +.full-episode--wath-all .full-episode__name { + text-align: center; +} +.full-episode--wath-all .full-episode__img { + opacity: 0; +} + +body.true--mobile .full-episode .full-episode__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} + +@media screen and (min-width: 767px) { + body.size--bigger .full-episode--small { + font-size: 1.14em; + } +} +.card-episode { + width: 19.65em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.card-episode__body { + margin-bottom: 1em; +} +.card-episode__footer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.card-episode__footer .card__imgbox { + width: 33.3%; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + max-width: 4em; +} +.card-episode__footer .card__view { + margin: 0; +} +.card-episode__footer .card__left { + padding-left: 1em; + padding-top: 0.6em; +} +.card-episode .full-episode__img--loaded { + background-color: transparent; +} +.card-episode .full-episode__img--loaded img { + opacity: 1; +} +.card-episode .full-episode__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.card-episode.focus .full-episode::after { + content: ""; + position: absolute; + left: -0.5em; + top: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + pointer-events: none; +} + +.player { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: #000; + z-index: 50; +} +.player.tv .player-panel__timeline, +.player.tv .player-panel__line-one { + display: none; +} +.player--ios .player-panel, +.player--ios .player-info__line, +.player--ios .player-info__values, +.player--ios .player-info__error { + display: none !important; +} +.player--loading > div:not(.player-info) { + pointer-events: none; +} + +body.selectbox--open .player .player-panel, +body.selectbox--open .player .player-info, +body.selectbox--open .player .player-footer { + display: none; +} + +body.keyboard-input--visible .player { + display: none; +} + +body.player--viewing #app { + visibility: hidden; +} + +.player:not(.player--panel-visible) .player-panel, +.player:not(.player--panel-visible) .player-info, +.player:not(.player--panel-visible) .player-footer { + visibility: hidden; +} + +video::-webkit-media-controls-panel-container { + display: none !important; +} + +.player-video__video { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.player-video__overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: none; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), color-stop(53%, rgba(0, 0, 0, 0.3)), to(rgba(11, 13, 16, 0.8))); + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.3) 53%, rgba(11, 13, 16, 0.8) 100%); + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.3) 53%, rgba(11, 13, 16, 0.8) 100%); + background: -o-linear-gradient(top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.3) 53%, rgba(11, 13, 16, 0.8) 100%); + background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.3) 53%, rgba(11, 13, 16, 0.8) 100%); +} +.player-video__paused, .player-video__loader { + position: fixed; + left: 50%; + top: 50%; + width: 8em; + height: 8em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + padding: 2em; + background: rgba(255, 255, 255, 0.1); + margin-left: -4em; + margin-top: -4em; +} +.player-video__loader { + background-image: url(../img/loader.svg); + background-repeat: no-repeat; + background-position: 50% 50%; + -webkit-background-size: 80% 80%; + -moz-background-size: 80% 80%; + -o-background-size: 80% 80%; + background-size: 80% 80%; + display: none; +} +.player-video__noise { + pointer-events: none; +} +.player-video__noise-canvas, .player-video__noise-box { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +.player-video__noise-canvas { + -ms-interpolation-mode: nearest-neighbor; + image-rendering: -webkit-optimize-contrast; + image-rendering: -moz-crisp-edges; + image-rendering: -o-pixelated; + image-rendering: pixelated; +} +.player-video__noise-box { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.player-video__noise-icon svg { + width: 6em; + height: 6em; + margin-bottom: 1em; +} +.player-video__noise-text { + font-size: 1.4em; + line-height: 1.3; + text-align: center; + background-color: rgba(255, 255, 255, 0.1); + padding: 0.4em 0.8em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.player-video__youtube { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; +} +.player-video__youtube iframe { + pointer-events: none; + position: fixed; + left: 0; + right: 0; + width: 100%; + height: 100%; + border: 0; +} +.player-video__youtube-line-top, .player-video__youtube-line-bottom { + position: fixed; + left: 0; + right: 0; + height: 7em; + background-color: #000; + display: none; +} +.player-video__youtube-line-top { + top: 0; +} +.player-video__youtube-line-bottom { + bottom: 0; +} +.player-video__youtube-icon { + width: 9em !important; + height: 7em !important; + margin-bottom: 1em; +} +.player-video__youtube-noplayed { + position: fixed; + left: 0; + right: 0; + top: 50%; + text-align: center; + font-size: 1.2em; + padding: 0 2em; + line-height: 1.5; + -webkit-transform: translateY(-60%); + -moz-transform: translateY(-60%); + -ms-transform: translateY(-60%); + -o-transform: translateY(-60%); + transform: translateY(-60%); +} +.player-video__youtube-noplayed div { + max-width: 30em; + margin: 0 auto; +} +.player-video__youtube-needclick { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: #000; +} +.player-video__youtube-needclick > img { + position: fixed; + top: 0%; + left: 0%; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + opacity: 0.3; +} +.player-video__youtube-needclick > div { + position: fixed; + left: 0; + top: 0; + right: 0; + top: 50%; + text-align: center; + font-size: 1.2em; + padding: 0 2em; + line-height: 1.5; +} +.player-video__youtube.ended iframe { + opacity: 0; +} +.player-video__subtitles { + position: fixed; + bottom: 0; + left: 0; + right: 0; + margin: 1.5em; + text-align: center; + font-size: 2.5em; + font-weight: 600; + line-height: 1.25; + -webkit-transition: -webkit-transform 0.2s; + transition: -webkit-transform 0.2s; + -o-transition: -o-transform 0.2s; + -moz-transition: transform 0.2s, -moz-transform 0.2s; + transition: transform 0.2s; + transition: transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; + pointer-events: none; +} +.player-video__subtitles.size--large { + font-size: 3em; +} +.player-video__subtitles.size--small { + font-size: 2em; +} +.player-video__subtitles.has--backdrop .player-video__subtitles-text { + background: rgba(0, 0, 0, 0.55); +} +.player-video__subtitles.has--stroke { + text-shadow: 0 2px 1px #000000, 0 -2px 1px #000000, -2px 1px 0 #000000, 2px 0px 1px #000000; +} +.player-video__subtitles.on-top { + top: 0; +} +.player-video__backwork-icon, .player-video__forward-icon { + position: fixed; + top: 50%; + font-size: 1.3em; + display: none; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-top: -0.5em; + opacity: 0; + text-shadow: 0 0 0.4em black; +} +.player-video__backwork-icon > i, .player-video__forward-icon > i { + margin: 0 1em; +} +.player-video__backwork-icon.rewind, .player-video__forward-icon.rewind { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + opacity: 1; +} +.player-video__backwork-icon { + left: 10%; +} +.player-video__backwork-icon.rewind > i { + -webkit-animation: videoRewindBackwork 0.7s; + -moz-animation: videoRewindBackwork 0.7s; + -o-animation: videoRewindBackwork 0.7s; + animation: videoRewindBackwork 0.7s; +} +.player-video__forward-icon { + right: 10%; +} +.player-video__forward-icon.rewind > i { + -webkit-animation: videoRewindForward 0.7s; + -moz-animation: videoRewindForward 0.7s; + -o-animation: videoRewindForward 0.7s; + animation: videoRewindForward 0.7s; +} +.player-video__subtitles-text { + display: inline-block; + padding: 0.25em 0.5em; + -webkit-border-radius: 0.25em; + -moz-border-radius: 0.25em; + border-radius: 0.25em; +} +.player-video__subtitles-text.bold { + font-weight: 700; +} +.player-video__subtitles-text.italic { + font-style: italic; +} +.player-video__subtitles-text.underline { + text-decoration: underline; +} +.player-video__subtitles-text:empty { + display: none; +} +.player-video.video--load .player-video__loader { + display: block; +} +.player-video.video--load .player-video__paused { + display: none; +} +.player-video--error .player-video__loader, .player-video--error .player-video__paused, .player-video--error .player-video__overlay, .player-video--error .player-video__subtitles { + display: none !important; +} + +.player-video__paused { + background: rgba(255, 255, 255, 0.1); +} + +.player.player--panel-visible .player-video__overlay { + display: block; + -webkit-animation: animation-opacity 0.3s; + -moz-animation: animation-opacity 0.3s; + -o-animation: animation-opacity 0.3s; + animation: animation-opacity 0.3s; +} +.player.player--panel-visible .player-video__subtitles { + -webkit-transform: translate3d(0, -3.6em, 0); + -moz-transform: translate3d(0, -3.6em, 0); + transform: translate3d(0, -3.6em, 0); +} + +@-webkit-keyframes videoRewindBackwork { + 0% { + opacity: 0; + -webkit-transform: translateX(0px); + transform: translateX(0px); + } + 100% { + opacity: 1; + -webkit-transform: translateX(-20px); + transform: translateX(-20px); + } +} + +@-moz-keyframes videoRewindBackwork { + 0% { + opacity: 0; + -moz-transform: translateX(0px); + transform: translateX(0px); + } + 100% { + opacity: 1; + -moz-transform: translateX(-20px); + transform: translateX(-20px); + } +} + +@-o-keyframes videoRewindBackwork { + 0% { + opacity: 0; + -o-transform: translateX(0px); + transform: translateX(0px); + } + 100% { + opacity: 1; + -o-transform: translateX(-20px); + transform: translateX(-20px); + } +} + +@keyframes videoRewindBackwork { + 0% { + opacity: 0; + -webkit-transform: translateX(0px); + -moz-transform: translateX(0px); + -o-transform: translateX(0px); + transform: translateX(0px); + } + 100% { + opacity: 1; + -webkit-transform: translateX(-20px); + -moz-transform: translateX(-20px); + -o-transform: translateX(-20px); + transform: translateX(-20px); + } +} +@-webkit-keyframes videoRewindForward { + 0% { + opacity: 0; + -webkit-transform: translateX(-20px); + transform: translateX(-20px); + } + 100% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } +} +@-moz-keyframes videoRewindForward { + 0% { + opacity: 0; + -moz-transform: translateX(-20px); + transform: translateX(-20px); + } + 100% { + opacity: 1; + -moz-transform: translateX(0); + transform: translateX(0); + } +} +@-o-keyframes videoRewindForward { + 0% { + opacity: 0; + -o-transform: translateX(-20px); + transform: translateX(-20px); + } + 100% { + opacity: 1; + -o-transform: translateX(0); + transform: translateX(0); + } +} +@keyframes videoRewindForward { + 0% { + opacity: 0; + -webkit-transform: translateX(-20px); + -moz-transform: translateX(-20px); + -o-transform: translateX(-20px); + transform: translateX(-20px); + } + 100% { + opacity: 1; + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + transform: translateX(0); + } +} +body.true--mobile.orientation--portrait .player-video__paused { + display: none; +} + +.player-panel { + position: fixed; + left: 0; + bottom: 0; + right: 0; + -webkit-transform: translateY(150%); + -moz-transform: translateY(150%); + -ms-transform: translateY(150%); + -o-transform: translateY(150%); + transform: translateY(150%); + -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; + transition: opacity 0.3s, -webkit-transform 0.3s; + -o-transition: opacity 0.3s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.3s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; + width: auto; +} +.player-panel.panel--visible { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -ms-transform: translateY(0); + -o-transform: translateY(0); + transform: translateY(0); +} +.player-panel.panel--footer-open { + -webkit-transform: translateY(-100%); + -moz-transform: translateY(-100%); + -ms-transform: translateY(-100%); + -o-transform: translateY(-100%); + transform: translateY(-100%); + opacity: 0; +} +.player-panel__body { + padding: 1.5em; + position: relative; +} +.player-panel__apex { + position: relative; + -webkit-transform: translateY(-2em); + -moz-transform: translateY(-2em); + -ms-transform: translateY(-2em); + -o-transform: translateY(-2em); + transform: translateY(-2em); + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: end; + -webkit-align-items: flex-end; + -moz-box-align: end; + -ms-flex-align: end; + align-items: flex-end; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} +.player-panel__apex > div { + position: relative; +} +.player-panel__apex-top-side, .player-panel__apex-bottom-side { + width: 100%; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.player-panel__apex-left-side, .player-panel__apex-right-side { + width: 50%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.player-panel__apex-left-side { + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; +} +.player-panel__apex-right-side { + -webkit-box-align: end; + -webkit-align-items: flex-end; + -moz-box-align: end; + -ms-flex-align: end; + align-items: flex-end; +} +.player-panel__timeline { + position: relative; + height: 0.4em; + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; + margin-bottom: 0.6em; +} +.player-panel__timeline::after { + content: ""; + display: block; + position: absolute; + top: -1em; + bottom: -1em; + right: 0; + left: 0; +} +.player-panel__timeline.focus { + -webkit-box-shadow: 0 0 0 0.1em #fff; + -moz-box-shadow: 0 0 0 0.1em #fff; + box-shadow: 0 0 0 0.1em #fff; +} +.player-panel__timeline.focus .player-panel__position > div:after { + -webkit-transform: translateY(-50%) translateX(50%) scale(1.5) !important; + -moz-transform: translateY(-50%) translateX(50%) scale(1.5) !important; + -ms-transform: translateY(-50%) translateX(50%) scale(1.5) !important; + -o-transform: translateY(-50%) translateX(50%) scale(1.5) !important; + transform: translateY(-50%) translateX(50%) scale(1.5) !important; + display: block; +} +.player-panel__timeline-segment { + position: absolute; + height: 100%; + top: 0; + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; +} +.player-panel__timeline-segment--ad { + background-color: rgba(252, 198, 60, 0.5); +} +.player-panel__timeline-segment--skip { + background-color: rgba(110, 219, 255, 0.5); +} +.player-panel__peding, .player-panel__position { + position: absolute; + top: 0; + left: 0; + height: 100%; + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; +} +.player-panel__peding { + background-color: rgba(255, 255, 255, 0.3); +} +.player-panel__position { + background-color: #fff; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + -moz-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; +} +.player-panel__position > div { + position: relative; +} +.player-panel__position > div:after { + position: absolute; + content: ""; + display: none; + width: 1em; + height: 1em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + background-color: #fff; + top: 50%; + right: 0; + -webkit-transform: translateY(-50%) translateX(50%); + -moz-transform: translateY(-50%) translateX(50%); + -ms-transform: translateY(-50%) translateX(50%); + -o-transform: translateY(-50%) translateX(50%); + transform: translateY(-50%) translateX(50%); + font-size: 0.8em; + z-index: 1; +} +.player-panel__time { + position: absolute; + bottom: 100%; + background: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); + margin-bottom: 0.5em; + padding: 0.4em; +} +.player-panel__time-touch-zone { + position: absolute; + left: 0; + bottom: -1.3em; + right: 0; + top: -1.8em; + z-index: 1; +} +.player-panel__line { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.player-panel__line-one { + margin-bottom: 1em; +} +.player-panel__box-buttons { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + background: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 4em; + -moz-border-radius: 4em; + border-radius: 4em; +} +.player-panel__box-buttons + .player-panel__box-buttons { + margin-left: 0.5em; +} +.player-panel__timeend { + margin-left: auto; +} +.player-panel__left, .player-panel__right { + width: 35%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.player-panel__right { + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + -moz-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; +} +.player-panel__center { + width: 30%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.player-panel .button { + padding: 0.9em; + width: 3em; + height: 3em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + position: relative; +} +.player-panel .button .tooltip { + position: absolute; + left: 50%; + top: 100%; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); + padding: 0.4em 0.8em; + font-size: 1.1em; + opacity: 0; + pointer-events: none; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; + color: #fff; + white-space: nowrap; +} +.player-panel .button.animate-trigger-enter { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +.player-panel .button svg { + width: 1.2em !important; + height: 1.2em !important; +} +.player-panel .button.focus { + background-color: #fff; + color: #000; +} +.player-panel .button.focus .tooltip { + opacity: 1; +} +.player-panel__playpause { + font-size: 1.4em; + margin: 0; + padding: 1em; +} +.player-panel__playpause > div:first-child { + display: none; +} +.player-panel__playpause:not(.focus) { + background: rgba(255, 255, 255, 0.1); +} +.player-panel__filename { + font-size: 1.7em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + margin-bottom: 2em; +} +.player-panel__quality { + width: auto !important; + text-transform: uppercase; + padding: 0 1em !important; + -webkit-border-radius: 5em !important; + -moz-border-radius: 5em !important; + border-radius: 5em !important; +} +.player-panel__next-episode-name { + -webkit-align-self: center; + -ms-flex-item-align: center; + align-self: center; + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + padding-left: 1em; + line-height: 1.6; +} +.player-panel__iptv { + display: none; +} +.player-panel__volume { + position: relative; +} +.player-panel__volume-drop { + display: none; + position: absolute; + left: 50%; + bottom: 100%; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); + padding: 0.3em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + background: #fff; +} +.player-panel__volume-range { + -webkit-appearance: slider-vertical; + -moz-appearance: slider-vertical; + appearance: slider-vertical; + width: 0.5em; + height: 8em; +} +.player-panel__volume:hover > div { + display: block; +} +.player-panel__mobile-visible { + display: none; +} +.player-panel.panel--paused .player-panel__playpause > div:first-child { + display: block; +} +.player-panel.panel--paused .player-panel__playpause > div:last-child { + display: none; +} +.player-panel.panel--norewind .player-panel__timeline, +.player-panel.panel--norewind .player-panel__line-one { + display: none; +} +.player-panel.panel--norewind .player-panel__line-two { + margin-top: 0; +} + +.player-panel-iptv { + position: relative; + height: 8em; +} +.player-panel-iptv__arrow-up, .player-panel-iptv__arrow-down, .player-panel-iptv__position { + position: absolute; + left: 18%; +} +@media screen and (max-width: 767px) { + .player-panel-iptv__arrow-up, .player-panel-iptv__arrow-down, .player-panel-iptv__position { + left: 25%; + } +} +@media screen and (max-width: 480px) { + .player-panel-iptv__arrow-up, .player-panel-iptv__arrow-down, .player-panel-iptv__position { + display: none; + } +} +.player-panel-iptv__arrow-up > svg, .player-panel-iptv__arrow-down > svg { + width: 1.8em !important; + height: 1.8em !important; +} +.player-panel-iptv__arrow-up { + top: 0; +} +.player-panel-iptv__arrow-down { + bottom: 0; +} +.player-panel-iptv__position { + top: 50%; + font-size: 2.5em; + font-weight: 600; + margin-left: -0.5em; + margin-top: -0.5em; +} +.player-panel-iptv__channel > div { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + opacity: 0; + -webkit-transition: opacity 0.2s, -webkit-transform 0.2s; + transition: opacity 0.2s, -webkit-transform 0.2s; + -o-transition: opacity 0.2s, -o-transform 0.2s; + -moz-transition: transform 0.2s, opacity 0.2s, -moz-transform 0.2s; + transition: transform 0.2s, opacity 0.2s; + transition: transform 0.2s, opacity 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; + will-change: transform, opacity; +} + +.player-panel-iptv-item { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.player-panel-iptv-item__left { + width: 27%; +} +.player-panel-iptv-item__left svg, +.player-panel-iptv-item__left img { + width: 45% !important; + opacity: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.player-panel-iptv-item__left svg.loaded, +.player-panel-iptv-item__left img.loaded { + opacity: 1; +} +@media screen and (max-width: 480px) { + .player-panel-iptv-item__left svg, +.player-panel-iptv-item__left img { + width: 75% !important; + } +} +.player-panel-iptv-item__left svg { + height: 100% !important; +} +@media screen and (max-width: 767px) { + .player-panel-iptv-item__left { + width: 36%; + } +} +.player-panel-iptv-item__body { + width: 73%; + line-height: 1.4; +} +@media screen and (max-width: 767px) { + .player-panel-iptv-item__body { + width: 64%; + } +} +.player-panel-iptv-item__group { + font-size: 1.2em; + opacity: 0.5; + margin-bottom: 0.3em; +} +.player-panel-iptv-item__name { + font-size: 2.6em; + font-weight: 900; +} +@media screen and (max-width: 580px) { + .player-panel-iptv-item__name { + font-size: 2em; + } +} +@media screen and (max-width: 480px) { + .player-panel-iptv-item__name { + font-size: 1.6em; + } +} +.player-panel-iptv-item__icons-item { + display: inline-block; + background-color: rgba(255, 255, 255, 0.2); + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + padding: 0.2em; + margin-left: 0.5em; + margin-top: -0.2em; + vertical-align: middle; +} +.player-panel-iptv-item__icons-item svg, +.player-panel-iptv-item__icons-item img { + width: 0.5em !important; + height: 0.5em !important; +} +.player-panel-iptv-item__prog { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-top: 0.4em; + height: 1.5em; + font-size: 1.1em; +} +.player-panel-iptv-item__prog-load { + font-size: 1.1em; + opacity: 0.3; + padding-top: 0.1em; +} +.player-panel-iptv-item__prog-item { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + position: relative; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.player-panel-iptv-item__prog-item span { + opacity: 0.5; + font-size: 1.2em; + max-width: 17em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; +} +.player-panel-iptv-item__prog-item + .player-panel-iptv-item__prog-item::before { + content: "|"; + display: inline-block; + margin: 0 1em; + opacity: 0.5; +} +@media screen and (max-width: 767px) { + .player-panel-iptv-item__prog-item + .player-panel-iptv-item__prog-item { + display: none; + } +} +.player-panel-iptv-item__prog-item.watch span { + opacity: 1; +} +.player-panel-iptv-item__prog-timeline { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + background-color: rgba(255, 255, 255, 0.2); + margin-left: 1em; + width: 9em; + margin-top: 0.4em; +} +.player-panel-iptv-item__prog-timeline > div { + height: 0.2em; + background-color: #fff; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + min-height: 2px; +} +@media screen and (max-width: 580px) { + .player-panel-iptv-item__prog-timeline { + width: 4em; + } +} + +body.true--mobile .player-panel__tv-visible { + display: none; +} +body.true--mobile .player-panel__mobile-visible { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.true--mobile .player-panel__apex-left-side, body.true--mobile .player-panel__apex-right-side { + width: 100%; +} +body.true--mobile .player-panel__line-two { + font-size: 1.3em; +} + +.player.youtube .player-video__loader, +.player.youtube .player-panel__settings { + display: none !important; +} + +.player.iptv .player-panel__body > div { + display: none; +} +.player.iptv .player-panel__body > .player-panel__iptv { + display: block; +} + +.player.player--loading .player-panel__peding, .player.player--loading .player-panel__position { + display: none; +} +.player.player--loading .player-panel__timeline::after { + content: ""; + display: block; + background-color: #fff; + position: absolute; + left: 0%; + height: 100%; + width: 20%; + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + -webkit-animation-duration: 1s; + -moz-animation-duration: 1s; + -o-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-name: scan; + -moz-animation-name: scan; + -o-animation-name: scan; + animation-name: scan; + -webkit-animation-iteration-count: infinite; + -moz-animation-iteration-count: infinite; + -o-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -webkit-animation-direction: alternate; + -moz-animation-direction: alternate; + -o-animation-direction: alternate; + animation-direction: alternate; + -webkit-animation-timing-function: linear; + -moz-animation-timing-function: linear; + -o-animation-timing-function: linear; + animation-timing-function: linear; +} + +.player-info { + position: fixed; + top: 0; + left: 0; + right: 0; + -webkit-transform: translateY(-150%); + -moz-transform: translateY(-150%); + -ms-transform: translateY(-150%); + -o-transform: translateY(-150%); + transform: translateY(-150%); + -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; + transition: opacity 0.3s, -webkit-transform 0.3s; + -o-transition: opacity 0.3s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.3s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; +} +.player-info__body { + padding: 1.5em; + position: relative; +} +.player-info.info--visible { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -ms-transform: translateY(0); + -o-transform: translateY(0); + transform: translateY(0); +} +.player-info__name { + font-size: 1.4em; + text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.5); + margin-top: 0.5em; +} +.player-info__title { + font-size: 2.4em; + font-weight: 600; + line-height: 1.4; + width: 60%; + text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.5); + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; +} +.player-info__line { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.player-info__time { + margin-left: auto; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding-left: 1em; + position: absolute; + top: 2.4em; + right: 1.5em; +} +.player-info__time span { + font-size: 1.5em; +} +.player-info__time-end { + position: absolute; + top: 4.5em; + right: 1.5em; +} +.player-info__time-end span { + font-size: 1.1em; +} +.player-info__error { + margin-top: 1em; + font-size: 1.2em; +} +.player-info__values { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-top: 1.2em; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.5); + line-height: 1.6; +} +.player-info__values > div { + margin-right: 1em; +} +.player-info__values > div span { + font-size: 1.3em; +} +.player-info__values .value--name span { + font-weight: 600; +} +.player-info__values .value--size span { + padding: 0.1em 0.5em; + background: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.player-info__values .value--pieces { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 0.3em 0; +} +.player-info__values .value--pieces span { + font-size: 1em; + width: 0.8em; + height: 0.8em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background-color: rgba(255, 255, 255, 0.1); + display: block; +} +.player-info__values .value--pieces span.active { + background-color: #fff; +} +.player-info__values .value--pieces span + span { + margin-left: 0.5em; +} +.player-info__values .value--pieces span.red { + background-color: #e17171; +} +.player-info__values .value--pieces span.green { + background-color: #a5d15f; +} +.player-info__values .value--pieces span.yellow { + background-color: #dfc154; +} +@media screen and (max-width: 400px) { + .player-info__values .value--pieces { + width: 100%; + margin-top: 0.4em; + } +} + +body.true--mobile .player-info__title { + font-size: 1.8em; + width: 100%; + padding-top: 0.15em; +} +body.true--mobile .player-info__line { + display: none; +} + +.player.iptv .player-info__body { + padding-top: 2.2em; +} +.player.iptv .player-info__name, .player.iptv .player-info__title, .player.iptv .player-info__time-end { + display: none; +} +.player.iptv .player-info__line { + position: relative; +} +.player.iptv .player-info__time { + position: absolute; + top: 0.2em; +} +.player.iptv .player-info__values { + margin-top: 0; +} + +.player.player--loading .player-info__values { + display: none; +} + +body.mouse--controll .player-info__body, +body.true--mobile .player-info__body { + padding-left: 5em; +} +body.mouse--controll .player-info .head-backward, +body.true--mobile .player-info .head-backward { + position: absolute; + left: 0; + top: 2em; +} +body.mouse--controll .player-info .head-backward__title, +body.true--mobile .player-info .head-backward__title { + display: none; +} + +.player-footer { + position: fixed; + left: 0; + bottom: 0; + right: 0; + width: 100%; + -webkit-transform: translateY(150%); + -moz-transform: translateY(150%); + -ms-transform: translateY(150%); + -o-transform: translateY(150%); + transform: translateY(150%); + -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; + transition: opacity 0.3s, -webkit-transform 0.3s; + -o-transition: opacity 0.3s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.3s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; + width: auto; + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + border-radius: 0.5em; +} +@media screen and (max-width: 480px) { + .player-footer { + right: 0; + left: 0; + bottom: 0; + } +} +.player-footer.open { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -ms-transform: translateY(0); + -o-transform: translateY(0); + transform: translateY(0); +} +.player-footer__body { + position: relative; +} +.player-footer__row { + padding: 1.5em; +} +.player-footer__row .items-line { + padding-bottom: 0 !important; +} +.player-footer__row .items-line__head { + padding: 0; +} +.player-footer .card-watched__body .card-watched__item { + display: none; +} +.player-footer .card-watched__body .card-watched__item:nth-child(1), .player-footer .card-watched__body .card-watched__item:nth-child(2) { + display: block; +} + +.player-footer-card { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + line-height: 1.4; +} +.player-footer-card__left { + width: 7em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.player-footer-card__tags { + margin-bottom: 0.7em; + margin-top: 0.5em; +} +.player-footer-card__title { + font-size: 1.8em; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; +} +.player-footer-card__body { + padding-left: 2em; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} +.player-footer-card__poster { + position: relative; + padding-bottom: 150%; +} +.player-footer-card__poster img { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; +} +.player-footer-card__text { + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 3; + line-clamp: 3; + -webkit-box-orient: vertical; + width: 70%; + font-size: 1.1em; + font-weight: 300; +} +.player-footer-card.notext .player-footer-card__text > * { + display: block; + background-color: rgba(255, 255, 255, 0.2); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + height: 0.8em; + margin-top: 0.6em; +} +.player-footer-card.notext .player-footer-card__text > *:nth-child(1) { + width: 80%; +} +.player-footer-card.notext .player-footer-card__text > *:nth-child(2) { + width: 100%; +} +.player-footer-card.notext .player-footer-card__text > *:nth-child(3) { + width: 60%; +} + +@media screen and (min-width: 767px) { + .player-footer .card { + margin-bottom: 0 !important; + } + + body.size--bigger .player-footer .card--collection { + font-size: 1em; + } + body.size--bigger .player-footer .card--collection { + width: 25%; + } +} +.player-skip { + position: absolute; + right: 1.5em; + bottom: 1.5em; + padding: 0.8em 1.2em; + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; + background-color: rgba(255, 255, 255, 0.1); + -webkit-transition: bottom 0.3s, opacity 0.2s, -webkit-transform 0.2s; + transition: bottom 0.3s, opacity 0.2s, -webkit-transform 0.2s; + -o-transition: bottom 0.3s, opacity 0.2s, -o-transform 0.2s; + -moz-transition: bottom 0.3s, opacity 0.2s, transform 0.2s, -moz-transform 0.2s; + transition: bottom 0.3s, opacity 0.2s, transform 0.2s; + transition: bottom 0.3s, opacity 0.2s, transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; +} +.player-skip__text { + font-size: 1.2em; +} +.player-skip svg { + width: 1.4em !important; + height: 1.4em !important; + vertical-align: middle; + margin-left: 1em; + margin-top: -0.2em; +} +.player-skip__progress { + position: absolute; + left: 1.7em; + right: 1.7em; + bottom: -0.6em; + height: 0.25em; + pointer-events: none; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + overflow: hidden; + background-color: rgba(255, 255, 255, 0.1); +} +.player-skip__progress-line { + height: 100%; + background-color: white; + -webkit-transform: scaleX(1); + -moz-transform: scaleX(1); + -ms-transform: scaleX(1); + -o-transform: scaleX(1); + transform: scaleX(1); + -webkit-transform-origin: left center; + -moz-transform-origin: left center; + -ms-transform-origin: left center; + -o-transform-origin: left center; + transform-origin: left center; + -webkit-transition: -webkit-transform 0.25s linear; + transition: -webkit-transform 0.25s linear; + -o-transition: -o-transform 0.25s linear; + -moz-transition: transform 0.25s linear, -moz-transform 0.25s linear; + transition: transform 0.25s linear; + transition: transform 0.25s linear, -webkit-transform 0.25s linear, -moz-transform 0.25s linear, -o-transform 0.25s linear; +} +.player-skip__progress-line--instant { + -webkit-transition: none; + -o-transition: none; + -moz-transition: none; + transition: none; +} +.player-skip.focus { + background-color: #fff; + color: #000; +} +.player-skip--preview { + opacity: 0.75; + pointer-events: none; +} +.player-skip--preview .player-skip__progress { + display: none; +} + +.player--panel-visible .player-skip { + bottom: 12em; +} + +.player-next__episode { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +@media screen and (max-width: 767px) { + .player-next__episode { + font-size: 0.8em; + } +} +.player-next__body { + line-height: 1.6; +} +.player-next__title { + font-size: 1.1em; +} +.player-next__episode-title { + font-size: 1.5em; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 1; + line-clamp: 1; + -webkit-box-orient: vertical; +} +.player-next__episode-description { + font-size: 1.1em; + opacity: 0.7; +} +.player-next__thumbnail { + margin-right: 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + overflow: hidden; + background-color: #262829; +} +.player-next__thumbnail-img { + width: 9em; + height: 5.4em; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + background-position: center; + opacity: 0; +} +.player-next__thumbnail.loaded { + background: transparent; +} +.player-next__thumbnail.loaded .player-next__thumbnail-img { + opacity: 1; +} + +.player-chat { + position: absolute; + top: 14em; + left: 1.5em; + -webkit-transform: translateY(-20%); + -moz-transform: translateY(-20%); + -ms-transform: translateY(-20%); + -o-transform: translateY(-20%); + transform: translateY(-20%); + -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; + transition: opacity 0.3s, -webkit-transform 0.3s; + -o-transition: opacity 0.3s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.3s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; +} +.player-chat__message { + margin-bottom: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -moz-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} +.player-chat__message.animate { + -webkit-animation: animation-up 0.3s forwards; + -moz-animation: animation-up 0.3s forwards; + -o-animation: animation-up 0.3s forwards; + animation: animation-up 0.3s forwards; +} +.player-chat__body { + background-color: rgba(255, 255, 255, 0.1); + padding: 0.8em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; + max-width: 21em; +} +.player-chat__text { + font-size: 1.1em; + line-height: 1.2; +} +.player-chat__icon { + margin-right: 0.5em; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + background-color: rgba(255, 255, 255, 0.1); + position: relative; + width: 2.7em; + height: 2.7em; +} +.player-chat__icon > img { + width: 2.7em; + height: 2.7em; +} +.player-chat__icon > svg { + width: 1.7em; + height: 1.7em; + margin: 0.5em; +} + +.player.player--panel-visible .player-chat { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -ms-transform: translateY(0); + -o-transform: translateY(0); + transform: translateY(0); +} + +.player-charts { + text-shadow: 0 0.1em 0.2em rgba(0, 0, 0, 0.3); + line-height: 1.5; +} +.player-charts__graph { + position: relative; + height: 12em; +} +.player-charts__graph.graph--metadata { + height: auto; +} +.player-charts__text { + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; + padding: 0.6em; + margin-bottom: 1em; +} +.player-charts__text > div { + font-size: 1.1em; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 4; + line-clamp: 4; + -webkit-box-orient: vertical; +} + +.player-charts-segment { + position: absolute; + bottom: 0; + padding: 0 0.3em; +} +.player-charts-segment__bar { + height: 0.4em; + background-color: #fff; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.player-charts-segment__label { + font-family: 1.1em; + margin-bottom: 1em; + font-weight: 600; +} +.player-charts-segment--current .player-charts-segment__bar { + background-color: #ffd73f; +} +.player-charts-segment.focus .player-charts-segment__text { + background-color: white; + color: #000; + text-shadow: none; +} +.player-charts-segment.focus .player-charts-segment__bar { + background-color: rgba(255, 255, 255, 0.2); + outline: 0.2em solid #fff; +} + +.player-agent-chat__user > div { + background-color: rgba(255, 255, 255, 0.1); + display: inline-block; + padding: 0.3em 1em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-border-top-left-radius: 0; + -moz-border-radius-topleft: 0; + border-top-left-radius: 0; +} +.player-agent-chat__assistant { + position: relative; +} +.player-agent-chat__assistant-title { + font-weight: 600; +} +.player-agent-chat__assistant-time { + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + border-radius: 0.5em; + padding: 0.1em 0.6em; + font-size: 0.9em; + margin-right: 1em; +} +.player-agent-chat__assistant-text { + padding-top: 1em; +} +.player-agent-chat__assistant.focus .player-agent-chat__assistant-time { + background-color: rgba(70, 70, 70, 0.3); +} + +.selectbox { + position: fixed; + top: 0; + right: 0; + z-index: 55; +} +.selectbox__layer { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: none; +} +@media screen and (max-width: 480px) { + .selectbox__layer { + -webkit-backdrop-filter: blur(1em); + backdrop-filter: blur(1em); + } +} +.selectbox__content { + position: fixed; + top: 0; + left: 100%; + -webkit-transition: -webkit-transform 0.2s; + transition: -webkit-transform 0.2s; + -o-transition: -o-transform 0.2s; + -moz-transition: transform 0.2s, -moz-transform 0.2s; + transition: transform 0.2s; + transition: transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; + background: #262829; + width: 35%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + will-change: transform; +} +@media screen and (max-width: 767px) { + .selectbox__content { + width: 50%; + } +} +@media screen and (max-width: 580px) { + .selectbox__content { + width: 70%; + } +} +@media screen and (max-width: 480px) { + .selectbox__content { + width: 100%; + left: 0; + top: unset; + bottom: 0; + height: auto !important; + -webkit-transition: none; + -o-transition: none; + -moz-transition: none; + transition: none; + -webkit-transform: translate3d(0, 100%, 0); + -moz-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + -webkit-border-top-left-radius: 2em; + -moz-border-radius-topleft: 2em; + border-top-left-radius: 2em; + -webkit-border-top-right-radius: 2em; + -moz-border-radius-topright: 2em; + border-top-right-radius: 2em; + } +} +.selectbox__head { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding: 2em; + padding-bottom: 0; +} +.selectbox__body { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +@media screen and (max-width: 480px) { + .selectbox__body { + height: auto !important; + } +} +.selectbox__body > * { + width: 100%; +} +.selectbox__title { + font-size: 2.2em; + font-weight: 300; +} +.selectbox__text { + line-height: 1.6; + padding: 1.5em 2em; +} +.selectbox__text > div { + font-size: 1.2em; +} +.selectbox--fullsize .selectbox__content { + width: 100%; +} + +body.selectbox--open .selectbox__layer { + display: block; +} +@media screen and (min-width: 480px) { + body.selectbox--open .selectbox__content { + -webkit-transform: translate3d(-100%, 0, 0); + -moz-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.selectbox-item { + padding: 1.5em 2em; + position: relative; + will-change: transform; +} +.selectbox-item__title { + font-size: 1.3em; + line-height: 1.3; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.selectbox-item__title sub { + vertical-align: super; + margin-left: 0.7em; + opacity: 0.5; + font-size: 0.8em; +} +.selectbox-item__subtitle { + font-size: 1.1em; + margin-top: 0.4em; + opacity: 0.7; + line-height: 1.4; +} +.selectbox-item__checkbox { + width: 1.4em; + height: 1.4em; + border: 0.2em solid rgba(255, 255, 255, 0.2); + position: absolute; + top: 1.7em; + right: 2em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.selectbox-item__icon { + margin-right: 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.selectbox-item__icon > * { + width: 2.7em; + height: 2.7em; +} +.selectbox-item__icon > *.size-youtube { + width: 6.9em; + height: 3.9em; +} +.selectbox-item__lock { + position: absolute; + top: 50%; + right: 1.7em; + opacity: 0.5; + margin-top: -1.1em; + opacity: 0.5; +} +.selectbox-item__lock > svg { + width: 2em !important; + height: 2em !important; +} +.selectbox-item--checkbox { + padding-right: 4em; +} +.selectbox-item--checked .selectbox-item__checkbox { + border-color: #fff; +} +.selectbox-item--checked .selectbox-item__checkbox::after { + content: ""; + display: block; + width: 0.3em; + height: 0.6em; + border-right: 0.2em solid #fff; + border-bottom: 0.2em solid #fff; + position: absolute; + top: 0em; + right: 0.25em; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} +.selectbox-item--icon { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.selectbox-item.selected:not(.nomark), .selectbox-item.picked { + padding-right: 4em; +} +.selectbox-item.selected:not(.nomark)::after, .selectbox-item.picked::after { + content: ""; + display: block; + width: 0.6em; + height: 1.2em; + border-right: 0.2em solid #fff; + border-bottom: 0.2em solid #fff; + position: absolute; + top: 50%; + right: 2em; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + margin-top: -0.9em; +} +.selectbox-item.focus { + background-color: #353535; +} + +.youtube-player { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: #000; + z-index: 50; +} +.youtube-player > iframe { + pointer-events: none; + position: absolute; + top: -60px; + left: 0; + width: 100%; + height: -webkit-calc(100% + 120px); + height: -moz-calc(100% + 120px); + height: calc(100% + 120px); +} +.youtube-player__progress { + position: absolute; + bottom: 0; + left: 0; + height: 0.5em; + background-color: #fff; +} + +.birthday__poster { + position: relative; + padding-bottom: 65%; + background: url("../img/loader.svg") no-repeat 50% 50%; +} +.birthday__img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + opacity: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.birthday__text { + line-height: 1.4; + font-size: 1.1em; + margin-top: 2em; +} +.birthday__text a { + text-decoration: none; + color: #D8C39A; +} +.birthday.loaded .birthday__img { + opacity: 1; +} +.birthday.noload .birthday__poster { + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + background: #585858 url("../img/logo.svg") no-repeat 50% 50%; +} + +.info { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + height: 10em; + padding: 2em 1.5em; + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + padding-top: 1em; +} +.info__title { + font-size: 3em; + font-weight: 400; + line-height: 1.2; + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.info__title-original { + font-size: 1.8em; + line-height: 1.3; +} +@media screen and (max-width: 580px) { + .info__title-original { + font-size: 1.4em; + } +} +@media screen and (max-width: 580px) { + .info__title { + font-size: 2.5em; + } +} +.info__left { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + overflow: hidden; +} +.info__right { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding-top: 1em; +} +@media screen and (max-width: 580px) { + .info__right { + display: none; + } +} +.info__create { + font-size: 1.2em; + margin-top: 1em; +} +.info__rate { + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.6em; + -moz-border-radius: 0.6em; + border-radius: 0.6em; + padding: 0.6em 1em 1em 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-right: 2em; + margin-top: 0.2em; +} +.info__rate > span { + font-size: 3.2em; + font-weight: 700; + line-height: 1.2; +} +@media screen and (max-width: 580px) { + .info__rate { + font-size: 0.9em; + } +} +.info__footer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-top: 0.2em; +} +.info__vote { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-right: 2em; +} +.info__vote > svg { + width: 1.8em !important; + height: 1.8em !important; + margin-right: 1em; +} +.info__vote > span { + font-size: 1.8em; + font-weight: 600; + line-height: 1.3; +} +.info__icon { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-left: 1em; + background-color: rgba(0, 0, 0, 0.3); + background-position: 50% 50%; + background-repeat: no-repeat; + -webkit-background-size: 37% 37%; + -moz-background-size: 37%; + -o-background-size: 37%; + background-size: 37%; + position: relative; + width: 4em; + height: 4em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.info__icon > svg { + width: 1.6em; + height: 1.6em; +} +.info__icon.active::after { + content: ""; + display: block; + position: absolute; + top: -0.5em; + right: -0.5em; + width: 2em; + height: 2em; + background: #fff url(../img/icons/check_dark.svg) no-repeat 50% 50%; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + -webkit-background-size: 50% 50%; + -moz-background-size: 50%; + -o-background-size: 50%; + background-size: 50%; +} +.info__icon.icon--book { + background-image: url(../img/icons/menu/bookmark.svg); +} +.info__icon.icon--like { + background-image: url(../img/icons/menu/like.svg); +} +.info__icon.icon--wath { + background-image: url(../img/icons/menu/time.svg); +} +.info__icon.focus { + -webkit-box-shadow: 0 0 0 0.3em #fff; + -moz-box-shadow: 0 0 0 0.3em #fff; + box-shadow: 0 0 0 0.3em #fff; +} +@media screen and (max-width: 767px) { + .info { + font-size: 0.85em; + } +} +@media screen and (max-width: 580px) { + .info { + height: 8.6em; + } +} + +.card-more { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 12.75em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.card-more__box { + -webkit-transition: border-color 0.2s, -webkit-transform 0.3s; + transition: border-color 0.2s, -webkit-transform 0.3s; + -o-transition: border-color 0.2s, -o-transform 0.3s; + -moz-transition: transform 0.3s, border-color 0.2s, -moz-transform 0.3s; + transition: transform 0.3s, border-color 0.2s; + transition: transform 0.3s, border-color 0.2s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; + background: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + position: relative; +} +.card-more__title { + position: absolute; + top: 50%; + left: 0; + right: 0; + text-align: center; + font-size: 1.8em; + font-weight: 300; + margin-top: -0.7em; +} +.card-more.focus .card-more__box::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + z-index: -1; +} +.card-more--small-radius .card-more__box { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.card-more--small-radius.focus .card-more__box::after { + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; +} +.card-more--fixed-size { + display: block; +} + +@media screen and (min-width: 767px) { + body.size--bigger .card-more { + font-size: 1.14em; + } +} +.loading-layer { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 100; + padding-top: 0.5em; + padding-bottom: 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: end; + -webkit-align-items: flex-end; + -moz-box-align: end; + -ms-flex-align: end; + align-items: flex-end; + background: rgba(0, 0, 0, 0.3); +} +.loading-layer__box { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 0.3em 1em; + min-width: 10em; + background-color: rgba(0, 0, 0, 0.8); + margin: 0 auto; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -moz-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding-right: 0.5em; +} +.loading-layer__text { + font-size: 1.1em; + margin-top: -0.2em; + padding-right: 1em; +} +.loading-layer__ico { + width: 1.9em; + height: 1.9em; + background: url(../img/loader.svg) no-repeat center; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; +} + +.media-loading { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 5; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + overflow: hidden; + background-color: #1d1f20; + opacity: 1; + -webkit-transition: opacity 0.3s ease; + -o-transition: opacity 0.3s ease; + -moz-transition: opacity 0.3s ease; + transition: opacity 0.3s ease; +} +.media-loading--standalone { + z-index: 100; +} +.media-loading--leaving { + opacity: 0; + pointer-events: none; +} +.media-loading__backdrop { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + opacity: 0.58; +} +.media-loading__shade { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(4, 4, 8, 0.3)), color-stop(60%, rgba(4, 4, 8, 0.58)), to(rgba(4, 4, 8, 0.82))); + background: -webkit-linear-gradient(top, rgba(4, 4, 8, 0.3) 0%, rgba(4, 4, 8, 0.58) 60%, rgba(4, 4, 8, 0.82) 100%); + background: -moz-linear-gradient(top, rgba(4, 4, 8, 0.3) 0%, rgba(4, 4, 8, 0.58) 60%, rgba(4, 4, 8, 0.82) 100%); + background: -o-linear-gradient(top, rgba(4, 4, 8, 0.3) 0%, rgba(4, 4, 8, 0.58) 60%, rgba(4, 4, 8, 0.82) 100%); + background: linear-gradient(180deg, rgba(4, 4, 8, 0.3) 0%, rgba(4, 4, 8, 0.58) 60%, rgba(4, 4, 8, 0.82) 100%); +} +.media-loading__content { + position: relative; + z-index: 1; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + max-width: 90%; + text-align: center; +} +.media-loading__mark { + position: relative; + width: 46em; + max-width: 46em; + height: 13em; + -webkit-animation: mediaLoadingPulse 2s ease-in-out infinite; + -moz-animation: mediaLoadingPulse 2s ease-in-out infinite; + -o-animation: mediaLoadingPulse 2s ease-in-out infinite; + animation: mediaLoadingPulse 2s ease-in-out infinite; +} +.media-loading__mark-background, .media-loading__mark-fill { + position: absolute; + top: 0; + bottom: 0; + left: 0; + overflow: hidden; +} +.media-loading__mark-background { + right: 0; + opacity: 0.2; +} +.media-loading__mark-fill { + width: 0; + -webkit-transition: width 0.18s ease-out; + -o-transition: width 0.18s ease-out; + -moz-transition: width 0.18s ease-out; + transition: width 0.18s ease-out; +} +.media-loading__mark-content { + position: absolute; + top: 0; + left: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 46em; + max-width: 46em; + height: 13em; +} +.media-loading__logo { + display: block; + max-width: 100%; + max-height: 100%; + width: auto; + height: auto; + -o-object-fit: contain; + object-fit: contain; +} +.media-loading__title { + width: 100%; + color: #fff; + font-size: 3.6em; + font-weight: 700; + line-height: 1.08; + letter-spacing: -0.025em; + text-shadow: 0 0.08em 0.3em rgba(0, 0, 0, 0.65); + overflow: hidden; + line-height: 1.2; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 3; + line-clamp: 3; + -webkit-box-orient: vertical; +} +.media-loading__status { + position: fixed; + left: 50%; + bottom: 3em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + min-height: 1.5em; + max-width: 88%; + padding: 0.75em 1.35em; + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; + background-color: rgba(255, 255, 255, 0.1); + -webkit-box-shadow: 0 0.35em 1.2em rgba(0, 0, 0, 0.28); + -moz-box-shadow: 0 0.35em 1.2em rgba(0, 0, 0, 0.28); + box-shadow: 0 0.35em 1.2em rgba(0, 0, 0, 0.28); + color: rgba(255, 255, 255, 0.72); + font-size: 1.05em; + white-space: nowrap; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); +} +.media-loading__percent { + color: #fff; + font-weight: 600; + font-variant-numeric: tabular-nums; +} +.media-loading__separator { + width: 0.22em; + height: 0.22em; + margin: 0 0.8em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background-color: rgba(255, 255, 255, 0.55); + -webkit-box-flex: 0; + -webkit-flex: none; + -moz-box-flex: 0; + -ms-flex: none; + flex: none; +} +.media-loading__peers-value { + color: rgba(255, 255, 255, 0.92); + font-variant-numeric: tabular-nums; +} +.media-loading__peers { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.media-loading__peers-icon { + width: 1.15em; + height: 1.15em; + margin-right: 0.45em; + fill: none; + stroke: currentColor; + stroke-width: 1.8; + stroke-linecap: round; + stroke-linejoin: round; + opacity: 0.82; +} +@media screen and (max-width: 580px) { + .media-loading__mark, .media-loading__mark-content { + width: 82vw; + height: 10em; + } + .media-loading__title { + font-size: 2.4em; + } + .media-loading__status { + bottom: 4vh; + padding: 0.65em 1em; + font-size: 0.9em; + } + .media-loading__separator { + margin: 0 0.55em; + } +} + +@-webkit-keyframes mediaLoadingPulse { + 0%, 100% { + -webkit-transform: scale(1); + transform: scale(1); + } + 50% { + -webkit-transform: scale(1.035); + transform: scale(1.035); + } +} + +@-moz-keyframes mediaLoadingPulse { + 0%, 100% { + -moz-transform: scale(1); + transform: scale(1); + } + 50% { + -moz-transform: scale(1.035); + transform: scale(1.035); + } +} + +@-o-keyframes mediaLoadingPulse { + 0%, 100% { + -o-transform: scale(1); + transform: scale(1); + } + 50% { + -o-transform: scale(1.035); + transform: scale(1.035); + } +} + +@keyframes mediaLoadingPulse { + 0%, 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } + 50% { + -webkit-transform: scale(1.035); + -moz-transform: scale(1.035); + -o-transform: scale(1.035); + transform: scale(1.035); + } +} +.category-full { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding: 0 1em; +} +.category-full .card { + margin-left: 0; + padding-left: 0.5em; + padding-right: 0.5em; +} +@media screen and (max-width: 480px) { + .category-full .card { + padding-left: 0.5em; + padding-right: 0.5em; + } +} +.category-full__more { + text-align: center; + padding: 2em; + margin-top: 1.5em; + width: 100%; +} +.category-full__more > span { + font-size: 1.2em; +} +.category-full__more.focus { + border-color: #fff; + color: #000; +} + +body.platform--orsay .category-full, +body.platform--netcast .category-full { + display: block; +} +body.platform--orsay .category-full .card, +body.platform--netcast .category-full .card { + float: left; +} +body.platform--orsay .category-full .card__title, +body.platform--netcast .category-full .card__title { + min-height: 3.6em; +} +body.platform--orsay .category-full:after, +body.platform--netcast .category-full:after { + display: block; + content: ""; + clear: both; +} + +@-webkit-keyframes animation-search-input-line { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@-moz-keyframes animation-search-input-line { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@-o-keyframes animation-search-input-line { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes animation-search-input-line { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +.search { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: transparent; + z-index: 50; + width: 100%; +} +.search .scroll--horizontal { + padding-top: 0 !important; + padding-bottom: 0.6em !important; +} +.search .scroll > .scroll__content > .scroll__body:after { + display: none !important; +} +.search__input { + font-size: 2em; + margin-bottom: 0.7em; + padding-left: 0.7em; +} +.search__input.filled::after { + content: ""; + display: inline-block; + border-right: 0.15em solid #fff; + height: 1em; + margin: -1em 0; + margin-left: 0.1em; + -webkit-animation: animation-search-input-line 0.8s infinite; + -moz-animation: animation-search-input-line 0.8s infinite; + -o-animation: animation-search-input-line 0.8s infinite; + animation: animation-search-input-line 0.8s infinite; +} +.search__keypad { + padding: 0 1.5em; +} +.search__keypad .simple-keyboard { + margin-bottom: 5px; +} +@media screen and (min-width: 991px) { + .search__keypad .simple-keyboard .hg-button-MIC, +.search__keypad .simple-keyboard .hg-button-LANG, +.search__keypad .simple-keyboard .hg-button-SIM, +.search__keypad .simple-keyboard .hg-button-BKSP { + -webkit-box-flex: 0; + -webkit-flex-grow: 0; + -moz-box-flex: 0; + -ms-flex-positive: 0; + flex-grow: 0; + min-width: 2.1em; + } + .search__keypad .simple-keyboard .hg-button-SPACE { + -webkit-box-flex: 0; + -webkit-flex-grow: 0; + -moz-box-flex: 0; + -ms-flex-positive: 0; + flex-grow: 0; + min-width: 7em; + } +} +.search__history, .search__sources { + margin-bottom: 0.6em; +} +.search__history .scroll__body, .search__sources .scroll__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.search__results .broadcast__text { + margin-top: 2.6em; +} +.search__results-offset { + padding-top: 1.5em; +} +.search .simple-keyboard-buttons { + display: none; +} + +.search-history-key { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: rgba(221, 221, 221, 0.06); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 0 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.search-history-key:before { + content: ""; + display: block; + width: 1.3em; + height: 1.3em; + margin-right: 0.7em; + background-image: url(../img/icons/menu/time.svg); + -webkit-background-size: 100% 100%; + -moz-background-size: 100%; + -o-background-size: 100%; + background-size: 100%; + background-position: center; + background-repeat: no-repeat; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.search-history-key > div { + font-size: 1.6em; + padding: 0.5em; + padding-top: 0.2em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 100%; + line-height: 1.2; + -webkit-transition: background-color 0.3s; + -o-transition: background-color 0.3s; + -moz-transition: background-color 0.3s; + transition: background-color 0.3s; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.search-history-key.focus { + background: rgba(221, 221, 221, 0.3); +} +.search-history-key + div { + margin-left: 5px; +} +@media screen and (max-width: 580px) { + .search-history-key { + font-size: 0.8em; + } +} + +.search-history-empty { + font-size: 1.3em; + color: rgba(255, 255, 255, 0.6); + line-height: 1.4; +} + +.search-looking { + padding-left: 1.5em; +} +.search-looking__text { + margin-top: 3.3em; + font-size: 1.3em; + color: rgba(255, 255, 255, 0.6); + line-height: 1.6; + max-width: 50%; +} +@media screen and (max-width: 580px) { + .search-looking__text { + max-width: 100%; + } +} + +.search-source { + font-size: 1.3em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 0.2em 0.8em; + background: rgba(221, 221, 221, 0.06); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + opacity: 0.5; +} +.search-source__tab { + padding: 0.4em 0 0.5em; + white-space: nowrap; +} +.search-source__count { + background-color: rgba(0, 0, 0, 0.6); + margin-left: 0.5em; + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + font-size: 0.8em; + padding: 0.1em 0.2em 0.2em; + min-width: 1.3em; + text-align: center; + font-weight: 700; + color: #fff; +} +.search-source--loading .search-source__count { + background-image: url(../img/loader.svg); + background-repeat: no-repeat; + background-position: center; + -webkit-background-size: 1.2em 1.2em; + -moz-background-size: 1.2em; + -o-background-size: 1.2em; + background-size: 1.2em; +} +.search-source.active { + opacity: 1; + background-color: #fff; + color: #000; +} +.search-source.focus { + background: rgba(221, 221, 221, 0.3); + opacity: 1; + color: #fff; +} +.search-source + .search-source { + margin-left: 0.6em; +} + +body.touch-device .search .hg-button { + min-width: 1em; +} +body.touch-device .search .search__results .scroll__content { + padding-top: 0.5em; +} + +body.true--mobile .search .simple-keyboard input { + background-color: rgba(221, 221, 221, 0.06); + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + border-radius: 0.5em; + padding-left: 1.3em; + height: 2.7em; +} + +.simple-keyboard { + background: transparent; + padding: 0; + font-family: inherit; + color: #9e9e9e; +} +.simple-keyboard .hg-row { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.simple-keyboard .hg-row .hg-button-container { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.simple-keyboard .hg-layout-numeric .hg-button { + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.simple-keyboard .hg-button { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + border: 0; + font-size: 2em; + height: auto; + width: auto; + line-height: 1.2; + background: rgba(221, 221, 221, 0.06); + color: #fff; +} +.simple-keyboard .hg-button.hg-activeButton, .simple-keyboard .hg-button.focus, .simple-keyboard .hg-button:hover { + background: rgba(221, 221, 221, 0.3); + color: #fff; +} +@media screen and (max-width: 580px) { + .simple-keyboard .hg-button { + font-size: 1.5em; + padding: 5px 0; + } +} +.simple-keyboard .hg-button[data-skbtn="{BKSP}"]:after, +.simple-keyboard .hg-button[data-skbtn="{ENTER}"]:after, +.simple-keyboard .hg-button[data-skbtn="{SHIFT}"]:after, +.simple-keyboard .hg-button[data-skbtn="{LANG}"]:after, +.simple-keyboard .hg-button[data-skbtn="{SPACE}"]:after { + content: ""; + display: block; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + background-repeat: no-repeat; + background-position: 50% 50%; + height: 1em; + width: 1em; +} +.simple-keyboard .hg-button[data-skbtn="{BKSP}"]:after { + background-image: url(../img/icons/keyboard/bksp.svg); +} +.simple-keyboard .hg-button[data-skbtn="{SIM}"]:after { + background-image: url(../img/icons/keyboard/sym.svg); + width: 1.2em; +} +.simple-keyboard .hg-button[data-skbtn="{ENTER}"]:after { + background-image: url(../img/icons/keyboard/enter.svg); +} +.simple-keyboard .hg-button[data-skbtn="{SHIFT}"]:after { + background-image: url(../img/icons/keyboard/up.svg); + -webkit-background-size: 80% 80%; + -moz-background-size: 80%; + -o-background-size: 80%; + background-size: 80%; +} +.simple-keyboard .hg-button[data-skbtn="{SPACE}"]:after { + background-image: url(../img/icons/keyboard/space.svg); + width: 1.4em; + margin-top: 0.4em; + height: 0.6em; +} +.simple-keyboard .hg-button[data-skbtn="{LANG}"]:after { + background-image: url(../img/icons/keyboard/lang.svg); + width: 0.9em; +} +.simple-keyboard .hg-button[data-skbtn="{BKSP}"] span, +.simple-keyboard .hg-button[data-skbtn="{ENTER}"] span, +.simple-keyboard .hg-button[data-skbtn="{SHIFT}"] span, +.simple-keyboard .hg-button[data-skbtn="{LANG}"] span, +.simple-keyboard .hg-button[data-skbtn="{SPACE}"] span { + width: 0; + height: 0; + display: block; +} +.simple-keyboard[shifted=true] .hg-button[data-skbtn="{SHIFT}"] { + -webkit-transform: scaleY(-1); + -moz-transform: scaleY(-1); + -ms-transform: scaleY(-1); + -o-transform: scaleY(-1); + transform: scaleY(-1); +} +.simple-keyboard .hg-button[data-skbtn="{MIC}"] { + color: #fff; +} +.simple-keyboard .hg-button[data-skbtn="{MIC}"] svg { + width: 0.9em; + height: 1em; +} +.simple-keyboard .hg-button svg { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.simple-keyboard-input { + background-color: transparent; + font-size: 1.6em; + height: 2.1em; + width: 100%; + border: 0; + padding: 0; + color: #fff; + font-family: "SegoeUI", sans-serif; +} +.simple-keyboard-input::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.5); +} +.simple-keyboard-input:-moz-placeholder { + color: rgba(255, 255, 255, 0.5); +} +.simple-keyboard-input::-moz-placeholder { + color: rgba(255, 255, 255, 0.5); +} +.simple-keyboard-input:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.5); +} +.simple-keyboard-input::-ms-input-placeholder { + color: rgba(255, 255, 255, 0.5); +} +.simple-keyboard-input::placeholder { + color: rgba(255, 255, 255, 0.5); +} +@media screen and (max-width: 480px) { + .simple-keyboard-input { + font-size: 1.5em; + } +} +.simple-keyboard-buttons { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-top: 1.5em; + font-size: 1.1em; +} +.simple-keyboard-buttons > div + div { + margin-left: 1em; +} +.simple-keyboard-buttons__enter { + font-size: 1.2em; + padding: 0.7em; + background: rgba(255, 255, 255, 0.12); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + color: #fff; +} +.simple-keyboard-buttons__cancel { + padding: 0.7em; + font-size: 1.2em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.simple-keyboard-buttons__enter, .simple-keyboard-buttons__cancel { + cursor: pointer; +} +.simple-keyboard-buttons__enter:hover, .simple-keyboard-buttons__cancel:hover { + background-color: #fff; + color: #000; +} +.simple-keyboard-mic { + width: 2.8em; + height: 2.8em; + margin-right: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.simple-keyboard-mic > svg { + width: 1.7em; + height: 1.7em; +} +.simple-keyboard-mic.focus { + background: #ffffff; + color: #0e0e0e; +} +.simple-keyboard-mic.record { + background: #ffffff; + color: red; +} +.simple-keyboard--with-mic { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + color: #fff; + position: relative; +} +.simple-keyboard--with-mic .simple-keyboard-buttons { + position: absolute; + top: 100%; + left: 3.4em; +} +.simple-keyboard--with-textarea { + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; +} +.simple-keyboard--with-textarea .simple-keyboard-input { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + resize: none; + overflow-y: hidden; + line-height: 1.4; + border: 1px solid rgba(221, 221, 221, 0.21); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 0.2em 0.4em; +} + +body.platform--apple_tv #orsay-keyboard.focus { + border: 4px solid #fff; + -webkit-border-radius: 12px; + -moz-border-radius: 12px; + border-radius: 12px; + padding-left: 12px; +} + +.modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.3); + padding: 1.5em; + z-index: 50; +} +@media screen and (max-width: 480px) { + .modal { + -webkit-backdrop-filter: blur(1em); + backdrop-filter: blur(1em); + } +} +.modal__content { + background-color: #262829; + padding: 1.5em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + margin: 0 auto; + max-width: 37%; + position: relative; +} +@media screen and (max-width: 767px) { + .modal__content { + max-width: 50%; + } +} +@media screen and (max-width: 580px) { + .modal__content { + max-width: 80%; + } +} +@media screen and (max-width: 480px) { + .modal__content { + max-width: 100%; + -webkit-border-top-left-radius: 2em; + -moz-border-radius-topleft: 2em; + border-top-left-radius: 2em; + -webkit-border-top-right-radius: 2em; + -moz-border-radius-topright: 2em; + border-top-right-radius: 2em; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; + position: fixed; + left: 0; + bottom: 0; + width: 100%; + } +} +.modal .head-backward { + margin: 0; +} +.modal__head { + margin-bottom: 2em; +} +.modal__body .scroll__content { + max-height: 37.2em; +} +.modal__title { + font-size: 2.2em; + font-weight: 300; +} +.modal__icon { + width: 7em; + height: 7em; + margin: 0 auto; +} +.modal__icon > svg { + width: 7em; + height: 7em; +} +@media screen and (max-width: 480px) { + .modal__icon { + display: none; + } +} +.modal__footer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding-top: 2em; +} +@media screen and (max-width: 480px) { + .modal__footer { + display: block; + } +} +.modal__button { + padding: 0.9em 1.3em; + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; + background: rgba(255, 255, 255, 0.1); + font-size: 1.2em; +} +.modal__button.focus { + background: #fff; + color: #000; +} +@media screen and (max-width: 480px) { + .modal__button { + text-align: center; + } +} +.modal__button + .modal__button { + margin-left: 1em; +} +@media screen and (max-width: 480px) { + .modal__button + .modal__button { + margin-left: 0; + margin-top: 1em; + } +} +.modal__close-button { + position: absolute; + top: -0.8em; + right: -0.8em; + background: #fff; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + padding: 0.4em; + color: #000; + cursor: pointer; +} +.modal__close-button > svg { + width: 1.1em; + height: 1.1em; +} +@media screen and (max-width: 480px) { + .modal__close-button { + display: none; + } +} +.modal--align-center { + text-align: center; +} +.modal--align-center .modal__footer { + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.modal--cub-premium .modal__icon { + margin-bottom: -2em; +} +@media screen and (min-width: 767px) { + .modal--cub-premium .modal__content { + max-width: 44%; + } +} +.modal--medium .modal__content { + max-width: 60%; +} +@media screen and (max-width: 767px) { + .modal--medium .modal__content { + max-width: 80%; + } +} +@media screen and (max-width: 580px) { + .modal--medium .modal__content { + max-width: 100%; + } +} +.modal--large .modal__content { + max-width: 80%; +} +@media screen and (max-width: 767px) { + .modal--large .modal__content { + max-width: 100%; + } +} +.modal--full { + padding: 0; +} +.modal--full .modal__content { + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + padding: 0; +} +.modal--full .modal__head { + padding: 1em 1.5em; +} +.modal--full .modal__footer { + padding: 1em 1.5em; +} +.modal--empty-title .modal__head { + display: none; +} +.modal--overlay { + z-index: 60; +} +.modal--buttons-column .modal__footer { + display: block; +} +.modal--buttons-column .modal__button { + width: 100%; + text-align: center; +} +.modal--buttons-column .modal__button + .modal__button { + margin-left: 0; + margin-top: 1em; +} +.modal .scroll--mask .scroll__content { + padding: 1.5em 0; +} + +.modal-loading { + height: 6em; + background: url(../img/loader.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; +} + +.modal-pending { + text-align: center; +} +.modal-pending__loading { + background: url(../img/loader.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + height: 6em; +} +.modal-pending__text { + font-size: 1.2em; + margin-top: 1em; +} + +.speedtest { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #262829; + z-index: 50; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.speedtest__body { + width: 30em; +} +.speedtest__body svg { + height: inherit !important; +} +.speedtest__body svg text { + fill: rgba(255, 255, 255, 0.2); + font-weight: 600; +} +.speedtest__frequency { + stroke-dasharray: 1 69; + stroke-dashoffset: 5; +} +.speedtest__progress { + stroke-dashoffset: -624; + -webkit-transition: 0.34s ease; + -o-transition: 0.34s ease; + -moz-transition: 0.34s ease; + transition: 0.34s ease; + stroke: #df3d3d; + stroke-dasharray: 0, 1256.8; + stroke-linecap: round; +} +.speedtest__fill { + stroke: rgba(255, 255, 255, 0.1); + stroke-linecap: round; + stroke-dashoffset: -624; + stroke-dasharray: 0, 1256.8; + stroke-dasharray: 1256.8, 1256.8; +} +.speedtest #speedtest_graph { + -webkit-transition: 0.1s ease; + -o-transition: 0.1s ease; + -moz-transition: 0.1s ease; + transition: 0.1s ease; +} +.speedtest #speedtest_num { + fill: #fff; +} +.speedtest #speedtest_status { + font-weight: 400; +} +.speedtest .head-backward { + position: absolute; + top: 1.5em; + left: 0; + right: 0; +} + +.company > div { + font-size: 1.4em; + line-height: 1.2; +} +.company > div + div { + margin-top: 0.6em; +} +.company > div.company__name { + font-size: 2.1em; +} + +.company-start { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + line-height: 1.4; +} +.company-start__left { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 10em; +} +@media screen and (max-width: 580px) { + .company-start__left { + width: 8em; + } +} +@media screen and (max-width: 400px) { + .company-start__left { + width: 6.5em; + } +} +.company-start__right { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + padding-left: 3em; +} +.company-start__icon { + position: relative; + padding-bottom: 93%; + background-color: #fff; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.company-start__img { + position: absolute; + top: 10%; + left: 10%; + width: 80%; + height: 80%; + -o-object-fit: contain; + object-fit: contain; + opacity: 0; + -webkit-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + -moz-transition: opacity 0.3s; + transition: opacity 0.3s; +} +.company-start__img.loaded { + opacity: 1; +} +.company-start__name { + font-size: 4em; + font-weight: 700; +} +@media screen and (max-width: 580px) { + .company-start__name { + font-size: 3em; + } +} +@media screen and (max-width: 400px) { + .company-start__name { + font-size: 2em; + } +} +.company-start__place { + font-size: 2.3em; + font-weight: 300; + max-width: 80%; +} +@media screen and (max-width: 580px) { + .company-start__place { + font-size: 1.8em; + max-width: 100%; + } +} +@media screen and (max-width: 400px) { + .company-start__place { + font-size: 1.5em; + } +} +.company-start.icon--broken .company-start__icon { + background-color: #3e3e3e; +} + +.person-start { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.person-start__tags { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-bottom: 1.4em; +} +@media screen and (max-width: 480px) { + .person-start__tags { + font-size: 0.9em; + margin-bottom: 1.3em; + } +} +.person-start__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.person-start__right { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.person-start__left { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + padding-left: 3em; +} +@media screen and (max-width: 580px) { + .person-start__left { + padding-left: 2em; + } +} +.person-start__poster { + position: relative; +} +.person-start__poster:before { + display: none; +} +.person-start__img { + position: relative; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + width: 15em; + height: 15em; + opacity: 0; + -webkit-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + -moz-transition: opacity 0.3s; + transition: opacity 0.3s; +} +.person-start__img.loaded { + opacity: 1; +} +@media screen and (max-width: 580px) { + .person-start__img { + width: 11em; + height: 14em; + } +} +@media screen and (max-width: 480px) { + .person-start__img { + width: 9em; + height: 12em; + } +} +.person-start__tag { + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + padding: 0.3em 0.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-right: 1em; + font-size: 1.05em; +} +.person-start__tag > img { + width: 1em; + height: 1em; + margin-right: 0.8em; +} +.person-start__name { + font-size: 3.5em; + font-weight: 700; + margin-bottom: 0.3em; + max-width: 90%; +} +@media screen and (max-width: 580px) { + .person-start__name { + font-size: 3em; + max-width: 100%; + } +} +@media screen and (max-width: 480px) { + .person-start__name { + font-size: 2em; + } +} +.person-start__place { + font-size: 1.8em; + font-weight: 300; + max-width: 80%; + margin-bottom: 1.1em; +} +@media screen and (max-width: 991px) { + .person-start__place { + font-size: 1.8em; + } +} +@media screen and (max-width: 580px) { + .person-start__place { + font-size: 1.8em; + max-width: 100%; + margin-bottom: 0.9em; + } +} +@media screen and (max-width: 480px) { + .person-start__place { + font-size: 1.5em; + margin-bottom: 1.1em; + } +} +.person-start__descr { + max-width: 80%; + font-size: 1.3em; + line-height: 1.4; + font-weight: 300; + height: 6.7em; + margin-bottom: 1em; + overflow: hidden; + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(68%, white), to(rgba(255, 255, 255, 0))); + -webkit-mask-image: -webkit-linear-gradient(top, white 0%, white 68%, rgba(255, 255, 255, 0) 100%); + mask-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(68%, white), to(rgba(255, 255, 255, 0))); + mask-image: linear-gradient(to bottom, white 0%, white 68%, rgba(255, 255, 255, 0) 100%); +} +@media screen and (max-width: 991px) { + .person-start__descr { + max-width: 100%; + } +} +@media screen and (max-width: 580px) { + .person-start__descr { + display: none; + } +} +.person-start__descr-mobile { + font-size: 1.3em; + line-height: 1.4; + display: none; +} +@media screen and (max-width: 580px) { + .person-start__descr-mobile { + display: block; + } +} +.person-start__icons { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.person-start__icons > div { + margin-left: 0; +} +.person-start__bottom { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.empty { + width: 100%; + text-align: center; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin: 0 auto; +} +.empty__img { + height: 17em; + background: url(../img/empty.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + margin-bottom: 3em; +} +.empty__icon svg, .empty__icon img { + width: 22em !important; + height: 14em !important; + margin-bottom: 3em; +} +.empty__title { + font-size: 2.4em; + line-height: 1.4; +} +.empty__descr { + font-size: 1.4em; + margin-top: 0.8em; + line-height: 1.6; +} +.empty__footer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin-top: 2em; +} +@media screen and (max-width: 580px) { + .empty__footer { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + gap: 1em; + } + .empty__footer .simple-button { + margin-right: 0; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + } +} +.empty--list { + height: auto; + text-align: left; + padding: 2em 0; +} +.empty--list .empty__footer { + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -moz-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} +.empty--noicon .empty__img { + display: none; +} +.empty--noicon .empty__title { + position: relative; +} +.empty--noicon .empty__title::after { + content: ""; + display: block; + width: 30%; + height: 0.1em; + background: #fff; + position: absolute; + bottom: -0.7em; + left: 50%; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + border-radius: 0.5em; +} +.empty--noicon .empty__descr { + margin-top: 2.5em; +} +.empty--custom-icon .empty__img { + display: none; +} +.empty--width-large { + max-width: 90%; +} +.empty--width-medium { + max-width: 60%; +} +.empty--width-small { + max-width: 35%; +} +@media screen and (max-width: 480px) { + .empty--width-medium { + max-width: 90%; + } + .empty--width-small { + max-width: 70%; + } +} + +.empty-filter { + line-height: 1.4; +} +.empty-filter__title { + font-size: 1.8em; + margin-bottom: 0.3em; +} +.empty-filter__subtitle { + font-size: 1.2em; + font-weight: 300; + margin-bottom: 1.6em; +} +.empty-filter__buttons { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.empty-filter__buttons > * + * { + margin-left: 1em; +} +.empty-filter__buttons .simple-button { + font-size: 1.2em; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + margin-bottom: 2.4em; +} +.empty-filter__templates .empty-template:nth-child(2) { + opacity: 0.5; +} +.empty-filter__templates .empty-template:nth-child(2) .empty-template__body { + width: 40%; +} +.empty-filter__templates .empty-template:nth-child(3) { + opacity: 0.2; +} +.empty-filter__templates .empty-template:nth-child(3) .empty-template__body { + width: 55%; +} + +.empty-template { + background-color: rgba(255, 255, 255, 0.3); + padding: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.empty-template > * { + background: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.empty-template__ico { + width: 4em; + height: 4em; + margin-right: 2.4em; +} +.empty-template__body { + height: 1.7em; + width: 70%; +} +.empty-template + .empty-template { + margin-top: 1em; +} + +.account-modal { + text-align: center; +} +.account-modal__icon { + width: 9em; + height: 9em; + margin: 0 auto; + margin-bottom: 2em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background-color: rgba(255, 255, 255, 0.1); + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.account-modal__icon > svg { + width: 4em; + height: 4em; +} +.account-modal__icon-svg { + margin-bottom: 2em; +} +.account-modal__icon-svg > svg { + width: 9.1em; + height: 9.1em; +} +.account-modal__desc { + font-size: 1.2em; + line-height: 1.6; +} +.account-modal__site { + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 0.2em 0.5em; + padding-top: 0em; +} + +.account-add-device { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + text-align: center; +} +.account-add-device__site { + background: rgba(0, 0, 0, 0.3); + display: inline-block; + padding: 0.1em 0.4em; + -webkit-border-radius: 0.4em; + -moz-border-radius: 0.4em; + border-radius: 0.4em; + color: #D8C39A; +} +.account-add-device .about { + margin-bottom: 2em; +} +.account-add-device .simple-button { + margin: 0; +} +.account-add-device .account-add-device__qr { + width: 12em; + height: 12em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding: 0.6em; + background: #fff; + margin-bottom: 1.8em; + opacity: 0; +} +.account-add-device.loaded .account-add-device__qr { + opacity: 1; +} + +.account-modal-split { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + line-height: 1.6; +} +.account-modal-split__qr { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + text-align: center; + width: 45%; +} +.account-modal-split__qr-img { + width: 16em; + height: 16em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding: 0.5em; + background: #3c3e3f; + margin-bottom: 1.8em; + opacity: 0; + -webkit-transform: translate3d(0, 20%, 0); + -moz-transform: translate3d(0, 20%, 0); + transform: translate3d(0, 20%, 0); + -webkit-transition: opacity 0.2s, -webkit-transform 0.2s; + transition: opacity 0.2s, -webkit-transform 0.2s; + -o-transition: opacity 0.2s, -o-transform 0.2s; + -moz-transition: opacity 0.2s, transform 0.2s, -moz-transform 0.2s; + transition: opacity 0.2s, transform 0.2s; + transition: opacity 0.2s, transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; +} +.account-modal-split__qr-img.loaded { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.account-modal-split__qr-code { + width: 16em; + height: 16em; + padding: 0.5em; + background: #3c3e3f; + -webkit-border-radius: 1.1em; + -moz-border-radius: 1.1em; + border-radius: 1.1em; + margin: 0 auto; + margin-bottom: 1.8em; +} +.account-modal-split__qr-code svg { + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; + width: 15em !important; + height: 15em !important; +} +.account-modal-split__qr-text { + font-size: 1em; + font-size: 1em; + max-width: 16em; + margin: 0 auto; +} +.account-modal-split__info { + width: 55%; + padding-right: 1.5em; +} +.account-modal-split__title { + font-size: 2.2em; + margin-bottom: 0.5em; + font-weight: 300; +} +.account-modal-split__text { + font-size: 1.2em; + margin-bottom: 2em; +} +.account-modal-split__code { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-bottom: 4em; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -moz-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + width: 80%; +} +.account-modal-split__code-num { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + background: #ffffff0f; + padding: 1.6em 1.4em; + position: relative; +} +.account-modal-split__code-num > span { + display: block; + line-height: 1; + font-size: 2em; + width: 0.6em; + text-align: center; + font-weight: 700; +} +.account-modal-split__code-num:before { + display: block; + content: ""; + position: absolute; + bottom: -1em; + left: 0; + width: 100%; + height: 0.2em; + background-color: #ddd; +} +.account-modal-split__keyboard { + width: 80%; +} +.account-modal-split__keyboard .hg-button { + padding: 0.5em 0; +} +.account-modal-split .account-modal__site { + color: #D8C39A; +} +.account-modal-split--mobile .account-modal-split__qr { + display: none; +} +.account-modal-split--mobile .account-modal-split__info { + width: 100%; + padding: 0; +} +.account-modal-split--mobile .account-modal-split__keyboard, +.account-modal-split--mobile .account-modal-split__code { + width: 100%; +} + +.cub-premium { + text-align: center; +} +.cub-premium__title { + color: #d8c39a; + font-size: 2.1em; + margin-bottom: 1em; +} +.cub-premium__descr { + font-size: 1.2em; + line-height: 1.6; + margin-bottom: 1em; +} +.cub-premium__url { + background-color: #D8C39A; + -webkit-border-radius: 3em; + -moz-border-radius: 3em; + border-radius: 3em; + padding: 0.8em 1.5em; + display: inline-block; + color: #000; + font-size: 1.2em; +} +.cub-premium__icon { + position: relative; + width: 24em; + margin: 0 auto; + margin-bottom: 3em; +} +.cub-premium__icon > svg { + width: 24em; + height: 14em; +} +.cub-premium__icon > span { + color: #D8C39A; + font-size: 2.3em; + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + font-weight: 600; + white-space: nowrap; +} +.cub-premium__includes { + max-width: 80%; + margin: 0 auto; + margin-bottom: 3em; +} +.cub-premium__includes > div { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -moz-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 1.4em 1.6em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: rgba(255, 255, 255, 0.01); + font-size: 1.2em; + line-height: 1.2; +} +.cub-premium__includes > div > div:first-child { + text-align: left; + padding-right: 2em; +} +.cub-premium__includes > div > div:first-child > span { + display: block; + padding-top: 1em; + font-size: 0.9em; + font-weight: 100; + line-height: 1.4; +} +.cub-premium__includes > div > div:last-child { + text-align: right; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + font-weight: 600; + color: #d8c39a; +} +.cub-premium__includes > div.focus { + background-color: rgba(255, 255, 255, 0.1); +} +.cub-premium__includes > div + div { + margin-top: 1em; +} +@media screen and (max-width: 580px) { + .cub-premium__includes { + max-width: 100%; + } +} +.cub-premium--detail { + padding-left: 1.5em; + padding-right: 1.5em; + padding-bottom: 2em; +} +.cub-premium--detail .cub-premium__icon + .cub-premium__descr { + max-width: 70%; + margin: 0 auto; + margin-bottom: 3em; +} +@media screen and (max-width: 580px) { + .cub-premium--detail .cub-premium__icon + .cub-premium__descr { + max-width: 100%; + } +} + +.notice { + font-weight: 300; + padding: 1.5em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + overflow: hidden; +} +.notice__head { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.notice__title { + font-size: 1.5em; + font-weight: 400; +} +.notice__descr { + font-size: 1.2em; + margin-top: 0.9em; + line-height: 1.4; +} +.notice__descr span, .notice__descr b { + font-weight: 300; + color: #d8c39a; +} +.notice__time { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-left: auto; + padding-left: 2em; + padding-top: 0.2em; +} +.notice + .notice { + margin-top: 1em; +} +.notice__left { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-right: 2em; + width: 7em; +} +.notice__body { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} +.notice__img { + padding-bottom: 147%; + position: relative; + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + -webkit-transition: background, -webkit-border-radius 0.2s; + transition: background, -webkit-border-radius 0.2s; + -o-transition: background, border-radius 0.2s; + -moz-transition: background, border-radius 0.2s, -moz-border-radius 0.2s; + transition: background, border-radius 0.2s; + transition: background, border-radius 0.2s, -webkit-border-radius 0.2s, -moz-border-radius 0.2s; +} +.notice__img img, +.notice__img svg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + opacity: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.notice__img svg { + opacity: 1; +} +.notice__footer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-top: 1em; + margin: -0.3em; +} +.notice__footer > div { + padding: 0.5em; + background-color: rgba(221, 221, 221, 0.15); + margin: 0.3em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.notice__author { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-top: 1.5em; + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; +} +.notice__author-img { + -webkit-border-radius: 1.1em; + -moz-border-radius: 1.1em; + border-radius: 1.1em; + overflow: hidden; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + background: rgba(0, 0, 0, 0.3); + -webkit-transition: background 0.2s; + -o-transition: background 0.2s; + -moz-transition: background 0.2s; + transition: background 0.2s; +} +.notice__author-img img { + width: 4em; + height: 4em; + opacity: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.notice__author-body { + padding-left: 1.5em; + line-height: 1.4; +} +.notice__author-name { + font-size: 1.1em; + font-weight: 500; +} +.notice__author-text { + font-size: 1.2em; +} +.notice--card { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.notice.image--none .notice__left { + display: none; +} +.notice.image--icon .notice__img { + padding-bottom: 100%; +} +.notice.image--img .notice__img { + padding-bottom: 0; +} +.notice.image--img .notice__img img { + position: static; + height: auto; +} +.notice.image--loaded .notice__img { + background: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.notice.image--loaded .notice__img img { + opacity: 1; +} +.notice.image-author--loaded .notice__author-img { + background: transparent; +} +.notice.image-author--loaded .notice__author-img img { + opacity: 1; +} +.notice.focus { + background-color: rgba(255, 255, 255, 0.1); +} + +body.true--mobile .notice { + padding-left: 0; + padding-right: 0; +} + +.bell { + position: absolute; + top: 0; + left: 50%; + width: 20em; + z-index: 100; + margin-left: -10em; + -webkit-transition: opacity 0.2s, -webkit-transform 0.3s; + transition: opacity 0.2s, -webkit-transform 0.3s; + -o-transition: opacity 0.2s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.2s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.2s; + transition: transform 0.3s, opacity 0.2s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; + -webkit-transform: translate3d(0, -100%, 0); + -moz-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + opacity: 0; + pointer-events: none; + padding-top: 1em; +} +@media screen and (max-width: 580px) { + .bell { + width: 80%; + padding: 1.5em; + font-size: 1.2em; + margin-left: -40%; + } +} +@media screen and (max-width: 480px) { + .bell { + width: 100%; + margin-left: -50%; + padding: 0.8em; + } +} +.bell__item { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 1.3em; + background: #1d1f20; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + margin-bottom: 1em; + opacity: 0; + -webkit-transform: translate3d(0, -1em, 0); + -moz-transform: translate3d(0, -1em, 0); + transform: translate3d(0, -1em, 0); + -webkit-transition: opacity 0.2s, -webkit-transform 0.3s; + transition: opacity 0.2s, -webkit-transform 0.3s; + -o-transition: opacity 0.2s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.2s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.2s; + transition: transform 0.3s, opacity 0.2s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; +} +@media screen and (max-width: 480px) { + .bell__item { + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; + } +} +.bell__item-icon { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 2em; + height: 2em; + margin-right: 1.3em; +} +.bell__item-text { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + font-size: 1.1em; + line-height: 1.4; +} +.bell__item.show { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.bell.show { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; +} + +.torrent-list { + padding: 0 1.5em; +} + +.torrent-files .torrent-file + .torrent-serial, +.torrent-files .torrent-serial + .torrent-file, +.torrent-files .torrent-serial + .torrent-serial, +.torrent-files .torrent-file + .torrent-file { + margin-top: 1em; +} + +.torrent-item { + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 1em; + line-height: 1.2; + position: relative; +} +.torrent-item__title { + font-size: 1.3em; + word-break: break-all; +} +.torrent-item__details { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + color: rgba(255, 255, 255, 0.5); + margin-top: 0.6em; + font-weight: 600; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + white-space: nowrap; +} +@media screen and (max-width: 767px) { + .torrent-item__details > * { + margin: 0.3em 0.3em 0 0 !important; + } +} +@media screen and (max-width: 580px) { + .torrent-item__details { + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + } +} +.torrent-item__date { + margin-right: 1em; +} +.torrent-item__tracker { + margin-right: 1em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} +@media screen and (max-width: 580px) { + .torrent-item__tracker { + width: 100%; + } +} +.torrent-item__size { + background-color: #fff; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + color: #000; + padding: 0.3em 0.5em; +} +@media screen and (max-width: 580px) { + .torrent-item__size { + margin-left: auto !important; + } +} +.torrent-item__bitrate, .torrent-item__grabs, .torrent-item__seeds { + margin-right: 1em; +} +.torrent-item__bitrate > span, .torrent-item__grabs > span, .torrent-item__seeds > span { + color: #fff; +} +@media screen and (min-width: 767px) { + .torrent-item__bitrate > span, .torrent-item__grabs > span, .torrent-item__seeds > span { + background: rgba(255, 255, 255, 0.2); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 0.1em 0.3em; + padding-bottom: 0.15em; + min-width: 1.8em; + display: inline-block; + text-align: center; + } +} +@media screen and (max-width: 480px) { + .torrent-item__bitrate { + width: 100%; + } +} +.torrent-item__size { + font-weight: 600; +} +@media screen and (max-width: 767px) { + .torrent-item__size { + width: auto; + } +} +.torrent-item__viewed { + position: absolute; + top: -0.75em; + left: -0.75em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + width: 1.5em; + height: 1.5em; + padding: 0.3em; + color: #000; + background-color: #fff; +} +.torrent-item__stat { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + background-color: rgba(0, 0, 0, 0.25); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + line-height: 1.4; + margin-top: 0.7em; + font-size: 0.9em; +} +.torrent-item__stat > div { + padding: 0.2em 0.8em; +} +.torrent-item__ffprobe { + padding-top: 0.3em; +} +.torrent-item__ffprobe > div { + float: left; + background: rgba(255, 255, 255, 0.19); + padding: 0.4em; + margin-right: 0.5em; + margin-top: 0.5em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + white-space: nowrap; +} +.torrent-item__ffprobe > div::before { + content: ""; + width: 1em; + height: 1em; + margin-right: 0.5em; + display: inline-block; + background-repeat: no-repeat; + background-position: 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + margin-top: -0.2em; +} +.torrent-item__ffprobe > div.m-video::before { + background-image: url(../img/icons/film.svg); +} +.torrent-item__ffprobe > div.m-channels::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 512 512' xml:space='preserve' class=''%3E%3Cpath d='M410.832 86.797c-13.048 0-23.663 10.639-23.663 23.717V401.64c1.194 31.473 46.23 31.36 47.416 0V110.514c0-13.077-10.655-23.717-23.753-23.717zM256 86.797c-13.098 0-23.753 10.639-23.753 23.717V401.64c1.197 31.429 46.321 31.404 47.507 0V110.514c0-13.077-10.656-23.717-23.754-23.717zM333.415 173.517c-13.047 0-23.661 10.639-23.661 23.717v117.687c1.194 31.475 46.229 31.358 47.415 0V197.234c0-13.078-10.656-23.717-23.754-23.717zM488.247 216.878c-13.047 0-23.662 10.639-23.662 23.717v30.966c1.194 31.474 46.229 31.359 47.415 0v-30.966c0-13.078-10.655-23.717-23.753-23.717zM23.754 216.878C10.656 216.878 0 227.517 0 240.594v30.966c1.198 31.382 46.233 31.451 47.415 0v-30.966c0-13.077-10.614-23.716-23.661-23.716zM101.169 130.157c-13.098 0-23.754 10.639-23.754 23.717V358.28c1.198 31.384 46.234 31.45 47.417 0V153.874c0-13.078-10.615-23.717-23.663-23.717zM178.585.077c-13.098 0-23.753 10.639-23.753 23.717V488.36c1.197 31.383 46.232 31.45 47.415 0V23.794c0-13.078-10.615-23.717-23.662-23.717z' fill='%23fff'%3E%3C/path%3E%3C/svg%3E"); +} +.torrent-item__ffprobe > div.m-audio::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 24 24' xml:space='preserve'%3E%3Cpath d='M12 2a5 5 0 0 0-5 5v5a5 5 0 0 0 10 0V7a5 5 0 0 0-5-5z' fill='%23fff'%3E%3C/path%3E%3Cpath d='M6 11a1 1 0 1 0-2 0v1a8.001 8.001 0 0 0 7 7.938V21a1 1 0 1 0 2 0v-1.062A8.001 8.001 0 0 0 20 12v-1a1 1 0 1 0-2 0v1a6 6 0 0 1-12 0z' fill='%23fff'%3E%3C/path%3E%3C/svg%3E"); +} +.torrent-item__ffprobe > div.m-subtitle::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 32 32' xml:space='preserve'%3E%3Cpath d='M27 27H5a3 3 0 0 1-3-3V8a3 3 0 0 1 3-3h22a3 3 0 0 1 3 3v16a3 3 0 0 1-3 3zM5 7a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h22a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1zm7 9a1 1 0 0 0-1-1H8a1 1 0 0 0 0 2h3a1 1 0 0 0 1-1zm13 0a1 1 0 0 0-1-1h-8a1 1 0 0 0 0 2h8a1 1 0 0 0 1-1zm0 5a1 1 0 0 0-1-1h-3a1 1 0 0 0 0 2h3a1 1 0 0 0 1-1zm-8 0a1 1 0 0 0-1-1H8a1 1 0 0 0 0 2h8a1 1 0 0 0 1-1z' fill='%23fff'%3E%3C/path%3E%3C/svg%3E"); +} +.torrent-item__ffprobe > div.m-resolution { + background: rgba(0, 0, 0, 0.2); + font-weight: 600; + -webkit-box-shadow: inset 0 0 0 0.1em rgba(255, 255, 255, 0.3); + -moz-box-shadow: inset 0 0 0 0.1em rgba(255, 255, 255, 0.3); + box-shadow: inset 0 0 0 0.1em rgba(255, 255, 255, 0.3); +} +.torrent-item__ffprobe > div.m-resolution::before { + display: none; +} +.torrent-item__ffprobe > div.m-general { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + font-size: 1.39em; + background: transparent; + outline: 0.1em solid rgba(255, 255, 255, 0.3); + padding: 0; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.torrent-item__ffprobe > div.m-general > div:nth-child(1) { + font-weight: 600; + background: rgba(255, 255, 255, 0.3); + -webkit-border-radius: 0.25em; + -moz-border-radius: 0.25em; + border-radius: 0.25em; + padding: 0.65em; + font-size: 1.2em; +} +.torrent-item__ffprobe > div.m-general > div:nth-child(2) { + padding: 0.9em; +} +.torrent-item__ffprobe > div.m-general::before { + display: none; +} +.torrent-item__ffprobe::after { + content: ""; + display: block; + clear: both; +} +.torrent-item + .torrent-item { + margin-top: 1em; +} +.torrent-item.focus::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; + z-index: -1; +} +.torrent-item--popular { + background-color: rgba(255, 255, 255, 0.2); +} + +.torrent-file { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + background: rgba(0, 0, 0, 0.2); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 1em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + position: relative; + padding-bottom: 2em; +} +.torrent-file__title { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + font-size: 1.3em; + line-height: 1.2; + overflow: hidden; + padding-right: 1em; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.torrent-file__title .exe { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background: rgba(255, 255, 255, 0.06); + padding: 0.2em 0.4em; + display: inline-block; + margin-left: 0.6em; +} +.torrent-file__size { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background: #262829; + font-size: 1.3em; + padding: 0.3em 0.5em; +} +.torrent-file .time-line { + position: absolute; + left: 1em; + right: 1em; + bottom: 1em; + display: block !important; +} +.torrent-file.focus { + background-color: rgba(255, 255, 255, 0.2); +} + +.torrent-error > div + div { + margin-top: 1.3em; +} +.torrent-error > div { + line-height: 1.2; +} +.torrent-error > div > div { + font-size: 1.4em; +} +.torrent-error > div > ul { + margin: 0; + margin-top: 0.2em; + font-size: 1.2em; + font-weight: 300; +} +.torrent-error > div > ul > li { + position: relative; + padding-left: 1em; +} +.torrent-error > div > ul > li::before { + content: ""; + display: block; + width: 0.3em; + height: 0.3em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background-color: #ddd; + position: absolute; + top: 0.5em; + left: 0; +} +.torrent-error > div > ul > li + li { + margin-top: 0.2em; +} +.torrent-error code { + background-color: #4c4c4c; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + padding: 0 0.5em; + word-break: break-all; + font-family: inherit; + font-size: inherit; +} + +.error + .torrent-error { + margin-top: 2em; +} + +.torrent-filter { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-bottom: 2em; +} +@media screen and (min-width: 767px) { + .torrent-filter .simple-button.filter--back { + display: none; + } +} +@media screen and (max-width: 580px) { + .torrent-filter { + white-space: nowrap; + } + .torrent-filter .simple-button.filter--search div { + display: none; + } +} + +.torrent-serial { + position: relative; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background: #1d1f20; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.torrent-serial__progress { + width: 0.3em; + position: absolute; + height: 0; + background: #fff; + top: 50%; + right: 0; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + -webkit-transition: height 0.1s linear; + -o-transition: height 0.1s linear; + -moz-transition: height 0.1s linear; + transition: height 0.1s linear; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); +} +.torrent-serial__img { + width: 12em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + height: 7em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + -webkit-align-self: flex-start; + -ms-flex-item-align: start; + align-self: flex-start; + opacity: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.torrent-serial__img.loaded { + opacity: 1; +} +@media screen and (max-width: 400px) { + .torrent-serial__img { + width: 7em; + height: 5em; + } +} +.torrent-serial__content { + padding: 0.8em 1em; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + overflow: hidden; +} +@media screen and (max-width: 480px) { + .torrent-serial__content { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + } +} +.torrent-serial__body { + float: left; + max-width: 80%; +} +@media screen and (max-width: 580px) { + .torrent-serial__body { + max-width: 72%; + } +} +.torrent-serial__title { + font-size: 1.7em; + overflow: hidden; + line-height: 1.2; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + margin-top: -0.1em; +} +@media screen and (max-width: 580px) { + .torrent-serial__title { + font-size: 1.6em; + } +} +@media screen and (max-width: 400px) { + .torrent-serial__title { + font-size: 1.4em; + } +} +.torrent-serial__line { + font-size: 1.1em; + margin-top: 0.5em; + font-weight: 300; + line-height: 1.2; +} +.torrent-serial__line b { + font-weight: 500; +} +.torrent-serial__line span + span:before { + content: "•"; + display: inline-block; + margin: 0 0.5em; + vertical-align: baseline; +} +@media screen and (max-width: 400px) { + .torrent-serial__line span:last-child { + display: none; + } +} +@media screen and (max-width: 580px) { + .torrent-serial__line { + font-size: 1em; + } +} +@media screen and (max-width: 400px) { + .torrent-serial__line { + padding-right: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + } + .torrent-serial__line span + span { + margin-top: 0.5em; + } + .torrent-serial__line span + span:before { + display: none; + } +} +.torrent-serial__clear { + clear: both; +} +.torrent-serial__size { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background: #262829; + font-size: 1.3em; + padding: 0.3em 0.5em; +} +.torrent-serial__exe { + font-size: 1.4em; + margin-top: 0.2em; +} +.torrent-serial__detail { + text-align: right; + margin-left: auto; + white-space: nowrap; + float: right; +} +@media screen and (max-width: 400px) { + .torrent-serial__detail { + font-size: 0.9em; + } +} +.torrent-serial__episode { + position: absolute; + background-color: rgba(0, 0, 0, 0.7); + left: 0; + top: 0; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + padding: 0.3em 0.5em; + font-size: 1.4em; + font-weight: 600; +} +@media screen and (max-width: 400px) { + .torrent-serial__episode { + font-size: 1.2em; + } +} +.torrent-serial.focus { + background-color: #353535; +} +@media screen and (max-width: 400px) { + .torrent-serial { + padding-bottom: 3.4em; + } +} +@media screen and (max-width: 400px) { + .torrent-serial { + padding-bottom: 0; + } +} +.torrent-serial .time-line { + display: block !important; +} +@media screen and (max-width: 480px) { + .torrent-serial .time-line { + position: absolute; + top: 5em; + left: 1em; + width: 10em; + } +} +@media screen and (max-width: 400px) { + .torrent-serial .time-line { + top: 3em; + width: 5em; + } +} + +.torrent-install { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +@media screen and (max-width: 580px) { + .torrent-install { + display: block; + } +} +.torrent-install__left, .torrent-install__details { + width: 50%; +} +@media screen and (max-width: 580px) { + .torrent-install__left, .torrent-install__details { + width: 100%; + } +} +.torrent-install__left { + padding-right: 3em; +} +@media screen and (max-width: 580px) { + .torrent-install__left { + display: none; + } +} +.torrent-install__title { + font-size: 2em; + line-height: 1.4; + margin-bottom: 0.7em; +} +.torrent-install__descr { + font-size: 1.3em; + line-height: 1.4em; + margin-bottom: 3em; +} +.torrent-install__label { + font-size: 1.2em; + margin-bottom: 1em; +} +.torrent-install__links:after { + display: block; + content: ""; + clear: both; +} +.torrent-install__link { + float: left; + margin-right: 1em; + margin-bottom: 1em; + padding: 1em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: #363636; +} +.torrent-install__link > div:first-child { + font-size: 1.1em; + margin-bottom: 0.4em; +} +.torrent-install__link > div:last-child { + font-size: 1.2em; +} + +.torrent-checklist__title { + font-size: 2em; + line-height: 1.4; + margin-bottom: 0.7em; +} +.torrent-checklist__descr { + font-size: 1.2em; + line-height: 1.4em; + margin-bottom: 2em; +} +.torrent-checklist__progress-steps { + margin-bottom: 1em; +} +.torrent-checklist__progress-bar { + background-color: rgba(255, 255, 255, 0.15); + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + margin-bottom: 2em; +} +.torrent-checklist__progress-bar > div { + height: 0.5em; + background-color: #fff; + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; +} +.torrent-checklist__content { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.torrent-checklist__footer { + margin-top: 2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.torrent-checklist__steps, .torrent-checklist__info { + width: 50%; +} +@media screen and (max-width: 480px) { + .torrent-checklist__steps { + display: none; + } +} +.torrent-checklist__list { + margin: 0; +} +.torrent-checklist__list > li { + margin-bottom: 1em; + color: #8D8D8D; +} +.torrent-checklist__list > li.wait { + color: #fff; +} +.torrent-checklist__list > li.check { + text-decoration: line-through; +} +.torrent-checklist__info > div { + font-size: 1.2em; + line-height: 1.6; +} +@media screen and (max-width: 480px) { + .torrent-checklist__info { + width: 100%; + } +} + +.torrnet-folder-name { + font-size: 1.4em; + padding: 1.4em 0; + opacity: 0.5; +} +.torrnet-folder-name::before { + content: ""; + display: inline-block; + width: 1em; + height: 1em; + background: url(../img/icons/menu/catalog.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; + margin-right: 0.7em; + margin-top: -0.3em; +} + +body.platform--orsay .torrnet-folder-name::before, +body.platform--netcast .torrnet-folder-name::before { + display: none; +} +body.platform--orsay .torrent-item__ffprobe > div::before, +body.platform--netcast .torrent-item__ffprobe > div::before { + display: none; +} + +.feed { + padding: 0 1.5em; +} + +.feed-head { + padding-bottom: 3em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.feed-head__icon { + width: 8.2em; + height: 8.2em; + position: relative; + margin-right: 2em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +@media screen and (max-width: 580px) { + .feed-head__icon { + margin: 0; + margin-bottom: 1em; + font-size: 1.2em; + } +} +.feed-head__img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; +} +.feed-head__body { + line-height: 1.4; +} +.feed-head__title { + font-size: 2.2em; +} +.feed-head__info { + font-size: 1.4em; + margin-top: 0.1em; + font-weight: 300; +} +@media screen and (max-width: 580px) { + .feed-head { + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + text-align: center; + } +} + +.feed-item { + position: relative; + padding-left: 3em; +} +@media screen and (max-width: 580px) { + .feed-item { + padding-left: 0; + } +} +.feed-item__head { + margin-bottom: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.feed-item__icon { + padding: 0.5em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background: rgba(255, 255, 255, 0.15); + margin-right: 1em; +} +.feed-item__icon svg { + width: 1.8em !important; + height: 1.8em !important; +} +.feed-item__label { + padding: 0.3em 0.5em; + background: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + font-size: 1.1em; +} +.feed-item__label--top { + background-color: #D69517; +} +.feed-item__label--now { + background-color: #6F8DDC; +} +.feed-item__label--now_playing { + background-color: #DA6FDC; +} +.feed-item__label--uhd { + background-color: #69B96C; +} +.feed-item__label--popular { + background-color: #B9A769; +} +.feed-item__label--trailer { + background-color: #9291A4; +} +.feed-item__label--episode { + background-color: #CD5050; +} +.feed-item__body { + padding-left: 3.8em; + line-height: 1.4; + width: 60%; +} +@media screen and (max-width: 400px) { + .feed-item__body { + width: 90%; + } +} +.feed-item__title { + font-size: 2.5em; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 1; + line-clamp: 1; + -webkit-box-orient: vertical; +} +@media screen and (max-width: 580px) { + .feed-item__title { + font-size: 2em; + } +} +.feed-item__info { + font-size: 1.3em; + opacity: 0.5; + margin-top: 0.7em; +} +@media screen and (max-width: 580px) { + .feed-item__info { + font-size: 1.1em; + } +} +.feed-item__descr { + font-size: 1.3em; + font-weight: 300; + margin-top: 1.7em; + line-height: 1.6; + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 5; + line-clamp: 5; + -webkit-box-orient: vertical; +} +.feed-item__tags { + margin-top: 1.3em; +} +.feed-item__right { + position: absolute; + top: 0; + right: 8%; + width: 20%; +} +@media screen and (max-width: 767px) { + .feed-item__right { + width: 26%; + } +} +@media screen and (max-width: 400px) { + .feed-item__right { + position: relative; + width: 67%; + margin-left: 3.7em; + right: 0; + padding-bottom: 1em; + } +} +.feed-item__poster-img, .feed-item__image-img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + opacity: 0; +} +.feed-item__poster-box, .feed-item__image-box { + position: relative; + padding-bottom: 150%; + background: #262829; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.feed-item__poster-box.loaded, .feed-item__image-box.loaded { + background: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.feed-item__poster-box.loaded .feed-item__poster-img, +.feed-item__poster-box.loaded .feed-item__image-img, .feed-item__image-box.loaded .feed-item__poster-img, +.feed-item__image-box.loaded .feed-item__image-img { + opacity: 1; +} +.feed-item__image-box { + padding-bottom: 56%; +} +.feed-item__minicard { + position: absolute; + top: 50%; + right: -2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: end; + -webkit-align-items: flex-end; + -moz-box-align: end; + -ms-flex-align: end; + align-items: flex-end; +} +.feed-item__minicard-poster { + width: 9em; + margin-left: 2em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.feed-item__minicard .feed-item__title { + font-size: 1.7em; + max-width: 11em; +} +.feed-item__minicard .feed-item__info { + font-size: 1.1em; +} +.feed-item__buttons { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + margin-top: 3em; +} +.feed-item__tags::before { + content: url(../img/icons/menu/bookmark.svg); + width: 1em; + height: 1em; + height: 1.2em; + margin-right: 0.7em; +} +.feed-item + .feed-item { + margin-top: 6em; +} +.feed-item:not(:last-child)::after { + content: ""; + display: block; + background-color: rgba(255, 255, 255, 0.3); + position: absolute; + top: 2.8em; + left: 4.4em; + bottom: -6em; + width: 2px; +} +@media screen and (max-width: 580px) { + .feed-item:not(:last-child)::after { + left: 1.3em; + } +} +.feed-item--episode .feed-item__body, .feed-item--trailer .feed-item__body { + width: 48%; +} +.feed-item--episode .feed-item__right, .feed-item--trailer .feed-item__right { + width: 35%; +} +.feed-item--episode .feed-item__descr, .feed-item--trailer .feed-item__descr { + min-height: 6em; +} +@media screen and (max-width: 767px) { + .feed-item--trailer .feed-item__body, .feed-item--episode .feed-item__body { + width: 87%; + } + .feed-item--trailer .feed-item__minicard, .feed-item--episode .feed-item__minicard { + top: auto; + bottom: -5em; + left: 0; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -moz-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + } + .feed-item--trailer .feed-item__right, .feed-item--episode .feed-item__right { + position: relative; + width: 80%; + right: 0; + margin-left: 3.7em; + margin-bottom: 7em; + } + .feed-item--trailer .feed-item__title, .feed-item--episode .feed-item__title { + font-size: 2em; + } + .feed-item--trailer .feed-item__poster-img, .feed-item--episode .feed-item__poster-img { + width: 23%; + min-width: 9em; + } +} + +.files { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + overflow: hidden; +} +.files__left { + width: 20em; + padding: 2.5em 1.5em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.files__left .full-start__poster { + display: inline-block; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +@media screen and (max-width: 580px) { + .files__left .full-start__poster { + display: none; + margin-right: 2em; + } + .files__left .full-start__poster .full-start__img { + font-size: 0.28em; + } +} +@media screen and (max-width: 767px) { + .files__left { + width: 17em; + } +} +@media screen and (max-width: 580px) { + .files__left { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + width: 100%; + padding-bottom: 1em; + } +} +.files__body { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + max-width: -webkit-calc(100% - 20em); + max-width: -moz-calc(100% - 20em); + max-width: calc(100% - 20em); +} +@media screen and (max-width: 767px) { + .files__body { + max-width: -webkit-calc(100% - 17em); + max-width: -moz-calc(100% - 17em); + max-width: calc(100% - 17em); + } +} +@media screen and (max-width: 580px) { + .files__body { + width: 100%; + max-width: 100%; + } +} +.files__info { + overflow: hidden; +} +.files__title { + font-size: 2em; + font-weight: 700; + margin-top: 1.1em; +} +@media screen and (max-width: 580px) { + .files__title { + margin-top: 0.5em; + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + margin-top: 0; + } +} +.files__title-original { + font-size: 1.5em; + margin-top: 0.8em; +} +@media screen and (max-width: 580px) { + .files { + display: block; + } +} + +.explorer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.explorer__left { + width: 27%; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +@media screen and (max-width: 767px) { + .explorer__left { + display: none; + } +} +.explorer__card { + padding-left: 1.5em; +} +.explorer__files { + width: 73%; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.explorer__files-head { + padding: 1.5em; + padding-bottom: 0; + line-height: 1.4; +} +.explorer__files-head .scroll__body::after { + display: none !important; +} +@media screen and (max-width: 767px) { + .explorer__files { + width: 100%; + } +} +.explorer__files .torrent-filter { + margin-bottom: 0; +} +.explorer__files .torrent-filter .simple-button { + font-size: 1.2em; + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; +} +.explorer__files .torrent-filter .simple-button:not(.focus) { + background-color: rgba(0, 0, 0, 0.07); +} +.explorer__files .empty-filter { + max-width: 100%; + padding: 3em 1.5em 0 1.5em; +} +.explorer__search { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.explorer__search > svg { + width: 1.2em; + height: 1.2em; + margin-right: 1em; +} +.explorer__search > span { + font-size: 1.1em; +} +.explorer--fullsize .explorer__card, +.explorer--fullsize .explorer__left { + display: none; +} +.explorer--fullsize .explorer__files { + width: 100%; +} + +.explorer-list { + padding: 0 1.5em; +} + +.explorer-card { + line-height: 1.4; +} +.explorer-card__head { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + margin-bottom: 3.3em; +} +.explorer-card__head-left { + width: 7em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-right: 1.5em; +} +.explorer-card__head-body { + padding-top: 0.7em; +} +.explorer-card__head-img { + position: relative; + padding-bottom: 150%; +} +.explorer-card__head-img > img { + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: #3E3E3E; +} +.explorer-card__head-img.focus::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; + z-index: -1; + pointer-events: none; +} +.explorer-card__head-create { + font-size: 1.1em; +} +.explorer-card__head-rate { + margin-top: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.explorer-card__head-rate > svg { + width: 1.5em !important; + height: 1.5em !important; + margin-right: 0.5em; +} +.explorer-card__head-rate > span { + font-size: 1.5em; + font-weight: 600; +} +.explorer-card__head-age { + border: 1px solid #fff; + display: inline-block; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + padding: 0.2em 0.3em; + margin-top: 1.4em; + font-size: 0.9em; +} +.explorer-card__title { + font-size: 2.3em; + font-weight: 700; + line-height: 1.1; + margin-bottom: 0.3em; +} +.explorer-card__title.small { + font-size: 1.6em; +} +.explorer-card__genres { + margin-bottom: 2em; +} +.explorer-card__descr { + font-size: 1.15em; + font-weight: 300; +} + +@media screen and (max-width: 991px) { + body.light--version .explorer__left { + display: none; + } + body.light--version .explorer__files { + width: 100%; + } +} + +.bookmarks-folder__layer { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + background-color: #3E3E3E; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.bookmarks-folder__body { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + background-color: rgba(255, 255, 255, 0.1); + border-radius: 1em; + position: relative; +} +.bookmarks-folder__body .i-1 { + height: 80%; + top: 20%; +} +.bookmarks-folder__body .i-2 { + height: 60%; + top: 40%; +} +.bookmarks-folder__head { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding: 1em; + line-height: 1.3; +} +.bookmarks-folder__title { + font-weight: 300; + font-size: 1.5em; +} +.bookmarks-folder__num { + font-weight: 600; + font-size: 1.2em; +} + +.about { + font-size: 1.4em; + line-height: 1.3; + font-weight: 300; +} +.about > div + div { + margin-top: 1.5em; +} +.about small { + font-weight: 400; +} +.about__contacts { + padding-top: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: -0.5em; +} +.about__contacts > div { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + padding: 0.5em; + width: 50%; +} +.about__contacts > div span { + max-width: 90%; + overflow: hidden; + display: block; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.about__rules { + padding-top: 1em; + font-size: 0.9em; +} +.about__rules ol { + list-style-type: none; + counter-reset: item; +} +.about__rules li { + counter-increment: item; + display: table; +} +.about__rules li > h6 { + font-size: 1em; +} +.about__rules h1, .about__rules h2, .about__rules h3, .about__rules h4, .about__rules h5, .about__rules h6 { + font-weight: 500; + margin: 0; +} +.about__rules li > * + * { + margin-top: 1.5em; +} +.about__rules li > *:first-child { + padding-top: 0px; +} +.about__rules li:before { + content: counters(item, ".") ". "; + display: table-cell; + vertical-align: top; + padding-right: 0.9em; + padding-top: 0em; + font-size: 1em; +} +.about__rules li li:before { + content: counters(item, ".") " "; +} +.about__rules li + li { + margin-top: 1.8em; +} +.about__rules ol { + padding-left: 0px; +} +.about__rules > ol > li:before { + padding-top: 0px; + font-size: 1em; + font-weight: 700; + padding-right: 0.48em; +} +.about__rules a { + color: inherit; +} + +body.platform--orsay .about__contacts, +body.platform--netcast .about__contacts { + display: block; +} +body.platform--orsay .about__contacts > div, +body.platform--netcast .about__contacts > div { + float: left; +} + +.error { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.error__ico { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-right: 2em; + width: 7em; + height: 7em; + background: url(../img/error.svg) no-repeat 50% 50%; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; +} +.error__text { + font-size: 1.4em; + line-height: 1.2; + margin-top: 0.7em; + font-weight: 300; +} +.error__title { + font-size: 1.7em; +} + +.season-info { + position: relative; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: rgba(0, 0, 0, 0.3); + padding: 1.2em; + margin-bottom: 1.5em; + line-height: 1.4; +} +.season-info__title { + font-size: 1.7em; +} +.season-info__head { + margin-top: 0.5em; + font-weight: 100; +} +.season-info__overview { + margin-top: 1em; +} +.season-info.focus::after, .season-info.hover::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; + z-index: -1; + pointer-events: none; +} + +.season-episode { + position: relative; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: rgba(0, 0, 0, 0.3); + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + will-change: transform; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.season-episode__body { + padding: 1.2em; + line-height: 1.3; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + position: relative; +} +@media screen and (max-width: 480px) { + .season-episode__body { + padding: 0.8em 1.2em; + } +} +.season-episode__img { + position: relative; + width: 13em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + min-height: 8.2em; +} +.season-episode__img > img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + opacity: 0; + -webkit-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + -moz-transition: opacity 0.3s; + transition: opacity 0.3s; +} +.season-episode__img--loaded > img { + opacity: 1; +} +@media screen and (max-width: 480px) { + .season-episode__img { + width: 7em; + min-height: 6em; + } +} +.season-episode__folder { + padding: 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.season-episode__folder > svg { + width: 4.4em !important; + height: 4.4em !important; +} +.season-episode__viewed { + position: absolute; + top: 1em; + left: 1em; + background: rgba(0, 0, 0, 0.45); + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + padding: 0.25em; + font-size: 0.76em; +} +.season-episode__viewed > svg { + width: 1.5em !important; + height: 1.5em !important; +} +.season-episode__episode-number { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + font-size: 2em; +} +.season-episode__loader { + position: absolute; + top: 50%; + left: 50%; + width: 2em; + height: 2em; + margin-left: -1em; + margin-top: -1em; + background: url(../img/loader.svg) no-repeat center center; + -webkit-background-size: contain; + -moz-background-size: contain; + -o-background-size: contain; + background-size: contain; +} +.season-episode__head, .season-episode__footer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -moz-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.season-episode__timeline { + margin: 0.8em 0; +} +.season-episode__timeline > .time-line { + display: block !important; +} +.season-episode__title { + font-size: 1.7em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 1; + line-clamp: 1; + -webkit-box-orient: vertical; +} +@media screen and (max-width: 480px) { + .season-episode__title { + font-size: 1.4em; + } +} +.season-episode__time { + padding-left: 2em; +} +.season-episode__info { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.season-episode__info > * { + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 1; + line-clamp: 1; + -webkit-box-orient: vertical; +} +.season-episode__quality { + padding-left: 1em; + white-space: nowrap; +} +.season-episode__scan-file { + position: absolute; + bottom: 0; + left: 0; + right: 0; +} +.season-episode__scan-file .broadcast__scan { + margin: 0; +} +.season-episode.focus::after { + content: ""; + position: absolute; + top: -0.6em; + left: -0.6em; + right: -0.6em; + bottom: -0.6em; + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; + border: solid 0.3em #fff; + z-index: -1; + pointer-events: none; +} +.season-episode--folder .season-episode__footer { + margin-top: 0.8em; +} +.season-episode-split { + font-size: 0.8em; + margin: 0 1em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.season-episode-rate { + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -moz-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.season-episode-rate > svg { + width: 1.3em !important; + height: 1.3em !important; +} +.season-episode-rate > span { + font-weight: 600; + font-size: 1.1em; + padding-left: 0.7em; +} + +.simple-button { + margin-right: 1em; + font-size: 1.3em; + background-color: rgba(0, 0, 0, 0.3); + padding: 0.3em 1.2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + height: 2.8em; +} +.simple-button > svg { + width: 1.5em; + height: 1.5em; +} +.simple-button > svg + span { + margin-left: 1em; +} +.simple-button > span { + margin-top: -0.2em; +} +.simple-button.focus { + background-color: #fff; + color: #000; +} +.simple-button--filter > span { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.simple-button--filter > div { + font-size: 0.7em; + padding: 0.3em 0.5em; + background-color: rgba(255, 255, 255, 0.3); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + margin-left: 1em; +} +.simple-button--filter > div::first-letter { + text-transform: uppercase; +} +@media screen and (min-width: 767px) { + .simple-button--filter { + overflow: hidden; + } + .simple-button--filter > div { + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + } +} +.simple-button--inline { + display: inline; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -moz-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; +} +.simple-button--invisible:not(.focus) { + background-color: rgba(0, 0, 0, 0.07); +} +@media screen and (max-width: 580px) { + .simple-button.filter--search span { + display: none; + } +} + +.search-box { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: transparent; + z-index: 50; + width: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding: 1.5em; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.search-box .search__input { + padding-left: 0; + width: 50%; +} +.search-box .search__input.filled::after { + content: ""; + display: inline-block; + border-right: 0.15em solid #fff; + height: 1em; + margin: -1em 0; + margin-left: 0.1em; + -webkit-animation: animation-search-input-line 0.8s infinite; + -moz-animation: animation-search-input-line 0.8s infinite; + -o-animation: animation-search-input-line 0.8s infinite; + animation: animation-search-input-line 0.8s infinite; +} +@media screen and (max-width: 767px) { + .search-box .search__input { + width: 100%; + } +} +.search-box__keypad { + width: 50%; +} +@media screen and (max-width: 767px) { + .search-box__keypad { + width: 100%; + } +} +.search-box--focus { + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -moz-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} + +body.system--keyboard .search-box .simple-keyboard-input { + border-bottom: 2px solid rgba(255, 255, 255, 0.15); +} + +.console { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: #1d1f20; + z-index: 100; + padding: 1.5em 0; +} +.console__line { + padding: 0.3em 1.5em; + font-size: 1.1em; + line-height: 1.2; + word-break: break-all; +} +.console__line:nth-child(2n) { + background-color: rgba(255, 255, 255, 0.05); +} +.console__line.focus { + background-color: rgba(255, 255, 255, 0.2); +} +.console__tabs .scroll__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.console__tab { + font-size: 1.1em; + background-color: #3e3e3e; + padding: 0.6em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + white-space: nowrap; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.console__tab + .console__tab { + margin-left: 1em; +} +.console__tab > span { + font-size: 0.7em; + background-color: #ddd3; + padding: 0.3em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + text-align: center; + min-width: 1.8em; + display: inline-block; +} +.console__tab.focus { + background: #fff; + color: #000; +} +.console__time { + color: #7c7c7c; + font-weight: 300; +} + +.time-line { + margin-top: 1em; + -webkit-border-radius: 3em; + -moz-border-radius: 3em; + border-radius: 3em; + background-color: rgba(255, 255, 255, 0.3); +} +.time-line > div { + height: 0.3em; + -webkit-border-radius: 3em; + -moz-border-radius: 3em; + border-radius: 3em; + background-color: #fff; +} + +.noty { + position: fixed; + left: 0; + right: 0; + bottom: 0; + z-index: 99; + background: #65eaa7; + color: #000; + -webkit-transform: translateY(100%); + -moz-transform: translateY(100%); + -ms-transform: translateY(100%); + -o-transform: translateY(100%); + transform: translateY(100%); + -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; + transition: opacity 0.3s, -webkit-transform 0.3s; + -o-transition: opacity 0.3s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.3s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; + opacity: 0; + line-height: 1.4; +} +.noty__body { + padding: 1.5em; + text-align: center; +} +.noty__text { + font-size: 1.2em; +} +.noty--visible { + -webkit-transform: translateY(0%); + -moz-transform: translateY(0%); + -ms-transform: translateY(0%); + -o-transform: translateY(0%); + transform: translateY(0%); + opacity: 1; +} +.noty--style--glass { + background: rgba(255, 255, 255, 0.2); + -webkit-backdrop-filter: blur(1em); + backdrop-filter: blur(1em); + color: #fff; +} + +.helper { + background: #4b8dcb; + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 98; + -webkit-transform: translateY(100%); + -moz-transform: translateY(100%); + -ms-transform: translateY(100%); + -o-transform: translateY(100%); + transform: translateY(100%); + -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; + transition: opacity 0.3s, -webkit-transform 0.3s; + -o-transition: opacity 0.3s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.3s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; + opacity: 0; + pointer-events: none; + text-align: center; + color: #fff; +} +.helper__ico { + margin-right: 1em; + width: 1.8em; + height: 1.8em; +} +.helper__body { + font-size: 1.3em; + padding: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.helper--visible { + -webkit-transform: translateY(0%); + -moz-transform: translateY(0%); + -ms-transform: translateY(0%); + -o-transform: translateY(0%); + transform: translateY(0%); + opacity: 1; +} + +@-webkit-keyframes helper-blink { + from { + opacity: 0; + } + to { + opacity: 0.3; + } +} + +@-moz-keyframes helper-blink { + from { + opacity: 0; + } + to { + opacity: 0.3; + } +} + +@-o-keyframes helper-blink { + from { + opacity: 0; + } + to { + opacity: 0.3; + } +} + +@keyframes helper-blink { + from { + opacity: 0; + } + to { + opacity: 0.3; + } +} +.helper-blink { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + background-color: #fff; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + -webkit-animation-duration: 0.2s; + -moz-animation-duration: 0.2s; + -o-animation-duration: 0.2s; + animation-duration: 0.2s; + -webkit-animation-name: helper-blink; + -moz-animation-name: helper-blink; + -o-animation-name: helper-blink; + animation-name: helper-blink; + -webkit-animation-iteration-count: infinite; + -moz-animation-iteration-count: infinite; + -o-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -webkit-animation-direction: alternate; + -moz-animation-direction: alternate; + -o-animation-direction: alternate; + animation-direction: alternate; + pointer-events: none; +} + +.pincode { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: #1d1f20; + z-index: 20; +} +.pincode__container { + margin: auto; + max-width: 80%; + padding-top: 6em; +} +.pincode__title { + font-size: 2.2em; + margin-bottom: 0.7em; + line-height: 1.4; + font-weight: 300; + width: 100%; +} +.pincode__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.pincode__left { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + padding-top: 1.6em; +} +.pincode__right { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + font-size: 1.2em; + -webkit-transform: translate3d(0, 50%, 0); + -moz-transform: translate3d(0, 50%, 0); + transform: translate3d(0, 50%, 0); + opacity: 0; + -webkit-transition: opacity 0.1s, -webkit-transform 0.3s; + transition: opacity 0.1s, -webkit-transform 0.3s; + -o-transition: opacity 0.1s, -o-transform 0.3s; + -moz-transition: transform 0.3s, opacity 0.1s, -moz-transform 0.3s; + transition: transform 0.3s, opacity 0.1s; + transition: transform 0.3s, opacity 0.1s, -webkit-transform 0.3s, -moz-transform 0.3s, -o-transform 0.3s; +} +.pincode__code { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding-bottom: 4em; +} +.pincode__code > div { + position: relative; + width: 3em; + height: 3.8em; + -webkit-border-radius: 0.4em; + -moz-border-radius: 0.4em; + border-radius: 0.4em; + background-color: #3E3E3E; +} +.pincode__code > div::before { + display: block; + content: ""; + position: absolute; + bottom: -1em; + left: 0; + width: 100%; + height: 0.2em; + background-color: #ddd; +} +.pincode__code > div + div { + margin-left: 2em; +} +.pincode__code > div.fill::after { + display: block; + content: ""; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + background-color: #ddd; + position: absolute; + top: 50%; + left: 50%; + width: 1em; + height: 1em; + margin: -0.5em; +} +.pincode__text { + margin-top: 2em; + max-width: 62%; + line-height: 1.6; + font-size: 1.2em; +} +.pincode .head-backward { + margin: 0; +} +.pincode.mobile .pincode__container { + padding-top: 2em; + height: 90vh; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +@media screen and (min-width: 580px) { + .pincode.mobile .pincode__container { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + -moz-box-orient: horizontal; + -moz-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: normal; + -webkit-justify-content: normal; + -moz-box-pack: normal; + -ms-flex-pack: normal; + justify-content: normal; + } +} +.pincode.mobile .pincode__code { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 3em; +} +@media screen and (min-width: 580px) { + .pincode.mobile .pincode__code { + width: 40%; + gap: 1.8em; + } +} +.pincode.mobile .pincode__code > div { + width: auto; + min-height: 4em; + height: 7vh; +} +.pincode.mobile .pincode__code > div + div { + margin-left: 0; +} +.pincode.animate .pincode__right { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; +} + +body.mouse--controll .pincode__container { + padding-top: 1em; +} +@media screen and (min-width: 580px) { + body.mouse--controll .pincode.mobile .pincode__container { + padding: 0; + height: 80vh; + } +} + +.pincode-remote { + height: 30em; + width: 13em; + background: -webkit-gradient(linear, left top, left bottom, from(black), to(transparent)); + background: -webkit-linear-gradient(top, black, transparent); + background: -moz-linear-gradient(top, black, transparent); + background: -o-linear-gradient(top, black, transparent); + background: linear-gradient(180deg, black, transparent); + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + position: relative; + padding-top: 10em; +} +.pincode-remote__light { + position: absolute; + top: 1em; + right: 1em; + background-color: red; + width: 0.5em; + height: 0.5em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.pincode-remote__circle { + width: 9em; + height: 9em; + margin: auto; + position: relative; +} +.pincode-remote__circle-center { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + height: 4.4em; +} +.pincode-remote__circle-pulse { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + opacity: 0; + border: 0.2em solid #fff; +} +.pincode-remote__nums { + position: absolute; + top: 0; + left: 0; + width: 9em; + height: 9em; +} +.pincode-remote__nums span { + font-size: 1.2em; + padding: 0.2em 0.3em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + min-width: 1.4em; + display: inline-block; +} +.pincode-remote__num-top, .pincode-remote__num-bottom { + height: 2.3em; + text-align: center; + padding-top: 0.3em; +} +.pincode-remote__num-left, .pincode-remote__num-right { + width: 2.3em; + text-align: center; +} +.pincode-remote__num-center { + width: 4.4em; + text-align: center; +} +.pincode-remote__remove { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 9em; + margin: auto; + margin-top: 2em; +} +.pincode-remote__remove-icon { + width: 1.6em; + height: 1.6em; + margin-right: 1em; +} +.pincode-remote__remove-text { + font-size: 0.9em; +} +.pincode-remote.push .pincode-remote__circle-pulse { + -webkit-animation: animation-pincode-remote-pulse 300ms linear forwards; + -moz-animation: animation-pincode-remote-pulse 300ms linear forwards; + -o-animation: animation-pincode-remote-pulse 300ms linear forwards; + animation: animation-pincode-remote-pulse 300ms linear forwards; +} +.pincode-remote.push .pincode-remote__circle svg { + -webkit-animation: animation-pincode-remote-pulse-circle 200ms ease 0s 1 normal forwards; + -moz-animation: animation-pincode-remote-pulse-circle 200ms ease 0s 1 normal forwards; + -o-animation: animation-pincode-remote-pulse-circle 200ms ease 0s 1 normal forwards; + animation: animation-pincode-remote-pulse-circle 200ms ease 0s 1 normal forwards; +} +.pincode-remote.push .pincode-remote__light { + -webkit-animation: animation-pincode-remote-light 300ms ease 0s 1 normal forwards; + -moz-animation: animation-pincode-remote-light 300ms ease 0s 1 normal forwards; + -o-animation: animation-pincode-remote-light 300ms ease 0s 1 normal forwards; + animation: animation-pincode-remote-light 300ms ease 0s 1 normal forwards; +} + +@-webkit-keyframes animation-pincode-remote-pulse { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; + } + 100% { + -webkit-transform: scale(1.2); + transform: scale(1.2); + opacity: 0; + } +} + +@-moz-keyframes animation-pincode-remote-pulse { + 0% { + -moz-transform: scale(1); + transform: scale(1); + opacity: 1; + } + 100% { + -moz-transform: scale(1.2); + transform: scale(1.2); + opacity: 0; + } +} + +@-o-keyframes animation-pincode-remote-pulse { + 0% { + -o-transform: scale(1); + transform: scale(1); + opacity: 1; + } + 100% { + -o-transform: scale(1.2); + transform: scale(1.2); + opacity: 0; + } +} + +@keyframes animation-pincode-remote-pulse { + 0% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + opacity: 1; + } + 100% { + -webkit-transform: scale(1.2); + -moz-transform: scale(1.2); + -o-transform: scale(1.2); + transform: scale(1.2); + opacity: 0; + } +} +@-webkit-keyframes animation-pincode-remote-pulse-circle { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + 50% { + -webkit-transform: scale(1.1); + transform: scale(1.1); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@-moz-keyframes animation-pincode-remote-pulse-circle { + 0% { + -moz-transform: scale(1); + transform: scale(1); + } + 50% { + -moz-transform: scale(1.1); + transform: scale(1.1); + } + 100% { + -moz-transform: scale(1); + transform: scale(1); + } +} +@-o-keyframes animation-pincode-remote-pulse-circle { + 0% { + -o-transform: scale(1); + transform: scale(1); + } + 50% { + -o-transform: scale(1.1); + transform: scale(1.1); + } + 100% { + -o-transform: scale(1); + transform: scale(1); + } +} +@keyframes animation-pincode-remote-pulse-circle { + 0% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } + 50% { + -webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -o-transform: scale(1.1); + transform: scale(1.1); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes animation-pincode-remote-light { + 0%, 50%, 100% { + opacity: 1; + } + 25%, 75% { + opacity: 0; + } +} +@-moz-keyframes animation-pincode-remote-light { + 0%, 50%, 100% { + opacity: 1; + } + 25%, 75% { + opacity: 0; + } +} +@-o-keyframes animation-pincode-remote-light { + 0%, 50%, 100% { + opacity: 1; + } + 25%, 75% { + opacity: 0; + } +} +@keyframes animation-pincode-remote-light { + 0%, 50%, 100% { + opacity: 1; + } + 25%, 75% { + opacity: 0; + } +} +.pincode-keyboard { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 3em; + height: 40vh; + margin-top: 3em; + background: #3e3e3e; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding: 3em; + -webkit-box-shadow: 0px 1 3em #000; + -moz-box-shadow: 0px 1 3em #000; + box-shadow: 0px 1 3em #000; +} +@media screen and (min-width: 580px) { + .pincode-keyboard { + margin-top: 0; + margin-left: auto; + width: 40%; + height: 70vh; + } +} +.pincode-keyboard > div { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.pincode-keyboard > div span { + font-size: 2.2em; + font-weight: 600; +} +.pincode-keyboard > div svg { + width: 2.4em !important; + height: 2.4em !important; +} +.pincode-keyboard > div.focus { + background: white; + color: #000; +} +.pincode-keyboard > div.focus svg { + -webkit-filter: invert(1); + filter: invert(1); +} + +.no-network { + position: fixed; + z-index: 100; + background: #1e1f21; + left: 0; + right: 0; + bottom: 0; + top: 0; + padding: 2em; +} +.no-network__title { + font-size: 2.2em; +} +.no-network__desc { + font-size: 1.5em; + margin-top: 0.7em; + line-height: 1.2; +} + +.screensaver-layer { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 10000; + display: none; +} + +.screensaver { + position: fixed; + right: 0; + bottom: 0; + z-index: 10000; + background-color: #000; + top: 0; + left: 0; +} +.screensaver__video { + position: fixed; + top: 0; + width: 100%; + height: 100%; + left: 0; + -o-object-fit: cover; + object-fit: cover; +} +.screensaver__video-overlay { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + opacity: 1; + background-color: #000; +} +.screensaver__title { + position: fixed; + bottom: 10%; + z-index: 3; + left: 5%; + width: 50%; + text-shadow: 2px 2px 2px #000; + opacity: 0; + -webkit-transition: opacity 0.5s; + -o-transition: opacity 0.5s; + -moz-transition: opacity 0.5s; + transition: opacity 0.5s; +} +.screensaver__title.visible { + opacity: 0.5; +} +.screensaver__title-name { + font-size: 3em; + font-weight: 300; + margin-bottom: 0.25em; +} +.screensaver__title-tagline { + font-weight: 300; + font-size: 1.5em; +} +.screensaver__preload { + position: fixed; + top: 0; + width: 100%; + height: 100%; + left: 0; + background: url(../img/loader.svg) no-repeat 50% 50%; +} +.screensaver__slides > img { + position: fixed; + top: 0; + width: 100%; + height: 100%; + left: 0; + -webkit-transition: opacity 0.5s; + -o-transition: opacity 0.5s; + -moz-transition: opacity 0.5s; + transition: opacity 0.5s; + opacity: 0; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + transform-origin: 50% 50%; +} +.screensaver__slides > img.visible { + opacity: 1; +} +.screensaver__slides > img.lt { + -webkit-transform-origin: 0 0; + -moz-transform-origin: 0 0; + -ms-transform-origin: 0 0; + -o-transform-origin: 0 0; + transform-origin: 0 0; +} +.screensaver__slides > img.rt { + -webkit-transform-origin: 100% 0; + -moz-transform-origin: 100% 0; + -ms-transform-origin: 100% 0; + -o-transform-origin: 100% 0; + transform-origin: 100% 0; +} +.screensaver__slides > img.br { + -webkit-transform-origin: 100% 100%; + -moz-transform-origin: 100% 100%; + -ms-transform-origin: 100% 100%; + -o-transform-origin: 100% 100%; + transform-origin: 100% 100%; +} +.screensaver__slides > img.lb { + -webkit-transform-origin: 0 100%; + -moz-transform-origin: 0 100%; + -ms-transform-origin: 0 100%; + -o-transform-origin: 0 100%; + transform-origin: 0 100%; +} +.screensaver__slides > img.ct { + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + transform-origin: 50% 50%; +} +.screensaver__slides > img.animate { + -webkit-animation: screensaver-slide-animate 45s linear; + -moz-animation: screensaver-slide-animate 45s linear; + -o-animation: screensaver-slide-animate 45s linear; + animation: screensaver-slide-animate 45s linear; +} +.screensaver__gradient { + position: fixed; + bottom: 0; + left: 0; + width: 100%; + height: 45%; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), color-stop(1%, rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.75))); + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 1%, rgba(0, 0, 0, 0.75) 100%); + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 1%, rgba(0, 0, 0, 0.75) 100%); + background: -o-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 1%, rgba(0, 0, 0, 0.75) 100%); + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 1%, rgba(0, 0, 0, 0.75) 100%); + z-index: 2; +} +.screensaver__datetime { + position: fixed; + bottom: 10%; + z-index: 3; + right: 5%; + width: 50%; + text-shadow: 2px 2px 2px #000; + text-align: right; + opacity: 1; + -webkit-transition: opacity 0.5s; + -o-transition: opacity 0.5s; + -moz-transition: opacity 0.5s; + transition: opacity 0.5s; + opacity: 0.5; +} +.screensaver__datetime-time { + font-size: 3em; + font-weight: 300; + margin-bottom: 0.25em; +} +.screensaver__datetime-date { + font-weight: 300; + font-size: 1.5em; +} +.screensaver-chrome { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 10000; +} +.screensaver-chrome__iframe { + position: fixed; + border: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 1; +} +.screensaver-chrome__overlay { + position: fixed; + border: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 2; +} + +@-webkit-keyframes screensaver-slide-animate { + from { + -webkit-transform: scale(1); + transform: scale(1); + } + to { + -webkit-transform: scale(1.2); + transform: scale(1.2); + } +} + +@-moz-keyframes screensaver-slide-animate { + from { + -moz-transform: scale(1); + transform: scale(1); + } + to { + -moz-transform: scale(1.2); + transform: scale(1.2); + } +} + +@-o-keyframes screensaver-slide-animate { + from { + -o-transform: scale(1); + transform: scale(1); + } + to { + -o-transform: scale(1.2); + transform: scale(1.2); + } +} + +@keyframes screensaver-slide-animate { + from { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } + to { + -webkit-transform: scale(1.2); + -moz-transform: scale(1.2); + -o-transform: scale(1.2); + transform: scale(1.2); + } +} +.plugins-catalog__title { + font-size: 1.7em; + line-height: 1.4; +} +.plugins-catalog__descr { + font-size: 1.2em; + line-height: 1.6; + margin-bottom: 1.2em; + font-weight: 300; +} +.plugins-catalog__line { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 1em 1em; + font-size: 1.2em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: #323232; + white-space: nowrap; +} +.plugins-catalog__line:nth-child(2n) { + background-color: transparent; +} +.plugins-catalog__line.focus { + background-color: #fff; + color: #323232; +} +@media screen and (min-width: 767px) { + .plugins-catalog__line.focus .plugins-catalog__detail { + display: none; + } + .plugins-catalog__line.focus .plugins-catalog__button { + display: block; + } +} +@media screen and (max-width: 480px) { + .plugins-catalog__line { + display: block; + } +} +.plugins-catalog__url { + padding-right: 2em; + margin-right: auto; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +@media screen and (max-width: 480px) { + .plugins-catalog__url { + margin-bottom: 0.6em; + } +} +.plugins-catalog__button { + display: none; +} +.plugins-catalog__block + .plugins-catalog__block { + margin-top: 4em; +} + +@-webkit-keyframes scan { + from { + left: 0%; + } + to { + left: 80%; + } +} + +@-moz-keyframes scan { + from { + left: 0%; + } + to { + left: 80%; + } +} + +@-o-keyframes scan { + from { + left: 0%; + } + to { + left: 80%; + } +} + +@keyframes scan { + from { + left: 0%; + } + to { + left: 80%; + } +} +.broadcast__text { + font-size: 1.2em; + line-height: 1.6; + margin-bottom: 1em; + text-align: center; +} +.broadcast__scan { + position: relative; + height: 0.2em; + margin-bottom: 1em; +} +.broadcast__scan > div { + background-color: #fff; + position: absolute; + left: 0%; + height: 100%; + width: 20%; + -webkit-border-radius: 5em; + -moz-border-radius: 5em; + border-radius: 5em; + -webkit-animation-duration: 1s; + -moz-animation-duration: 1s; + -o-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-name: scan; + -moz-animation-name: scan; + -o-animation-name: scan; + animation-name: scan; + -webkit-animation-iteration-count: infinite; + -moz-animation-iteration-count: infinite; + -o-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -webkit-animation-direction: alternate; + -moz-animation-direction: alternate; + -o-animation-direction: alternate; + animation-direction: alternate; + -webkit-animation-timing-function: linear; + -moz-animation-timing-function: linear; + -o-animation-timing-function: linear; + animation-timing-function: linear; +} +.broadcast__device { + font-size: 1.2em; + padding: 1em; + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.broadcast__device:nth-child(2n) { + background-color: transparent; +} +.broadcast__device.focus { + background-color: #fff; + color: #000; +} + +.watched-history { + position: relative; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: rgba(0, 0, 0, 0.3); + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + padding: 1em; + margin-bottom: 1em; +} +.watched-history__icon { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.watched-history__icon > svg { + width: 1.5em !important; + height: 1.5em !important; +} +.watched-history__body { + padding-left: 1em; + padding-top: 0.1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} +.watched-history__body > span + span::before { + content: " ● "; + vertical-align: top; + display: inline-block; + margin: 0 0.5em; +} +.watched-history.focus::after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + -webkit-border-radius: 0.7em; + -moz-border-radius: 0.7em; + border-radius: 0.7em; + border: solid 0.3em #fff; + z-index: -1; + pointer-events: none; +} + +.timetable { + padding: 0 1.5em; +} +.timetable:after { + content: ""; + display: block; + clear: both; +} +.timetable__inner { + padding-bottom: 100%; +} +@media screen and (max-width: 480px) { + .timetable__inner { + padding-bottom: 120%; + } +} +@media screen and (max-width: 400px) { + .timetable__inner { + padding-bottom: 115%; + } +} +.timetable__item { + float: left; + width: 14.28%; + position: relative; +} +@media screen and (max-width: 767px) { + .timetable__item { + width: 20%; + } +} +@media screen and (max-width: 580px) { + .timetable__item { + width: 25%; + } +} +@media screen and (max-width: 400px) { + .timetable__item { + width: 33.33%; + } +} +.timetable__item:before { + content: ""; + display: block; + position: absolute; + top: 0.2em; + left: 0.2em; + right: 0.2em; + bottom: 0.2em; + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.timetable__item--any:before { + background-color: rgba(255, 255, 255, 0.3); +} +.timetable__item.focus { + color: #000; +} +.timetable__item.focus:before { + background-color: #fff; +} +.timetable__body { + position: absolute; + left: 1em; + bottom: 1em; + right: 1em; +} +.timetable__body > div { + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + line-height: 1.4; +} +.timetable__body > div > span { + display: inline-block; + width: 0.5em; + height: 0.9em; + margin-right: 0.5em; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + margin-bottom: -0.1em; +} +.timetable__date { + position: absolute; + top: 1em; + left: 1em; + font-size: 0.9em; +} +.timetable__preview { + margin-bottom: 0.8em; +} +.timetable__preview > img { + width: 5em; + height: 3.1em; + margin-bottom: 0.3em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.timetable__preview > div { + font-size: 0.9em; +} + +.extensions { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + z-index: 20; + background-color: #232425; +} +.extensions__head { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + padding: 1em 1.5em; +} +.extensions__head-title { + font-size: 1.5em; +} +.extensions__block-head { + padding: 0 1.5em; + margin-bottom: 1em; +} +.extensions__block-title { + font-size: 1.2em; +} +.extensions__block-body { + min-height: 10em; +} +.extensions__block-body .scroll__body { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.extensions__block-empty, .extensions__block-add { + padding: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -moz-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 20em; + min-height: 10em; + position: relative; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.extensions__block-empty.focus:after, .extensions__block-add.focus:after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + z-index: -1; + pointer-events: none; +} +.extensions__block-add { + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + background-color: #404040; + margin-right: 1em; +} +.extensions__block + .extensions__block { + margin-top: 2.4em; +} +.extensions__item { + background-color: #404040; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + padding: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -moz-box-orient: vertical; + -moz-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + min-height: 10em; + width: 20em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + position: relative; + will-change: transform; +} +.extensions__item-author { + color: #8D8D8D; + font-size: 0.84em; + margin-bottom: 0.4em; +} +.extensions__item-name { + font-size: 1.1em; + line-height: normal; + margin-bottom: 0.8em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.extensions__item-descr { + line-height: 1.5; + margin-bottom: 0.3em; + font-size: 0.84em; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.extensions__item-footer { + margin-top: auto; + padding-top: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.extensions__item-check { + width: 1.2em; + height: 1.2em; + background-color: rgba(0, 0, 0, 0.18); + background-image: url(../img/loader.svg); + background-repeat: no-repeat; + -webkit-background-size: 1em 1em; + -moz-background-size: 1em; + -o-background-size: 1em; + background-size: 1em; + background-position: 50% 50%; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; +} +.extensions__item-code { + background-color: rgba(0, 0, 0, 0.18); + -webkit-border-radius: 0.1em; + -moz-border-radius: 0.1em; + border-radius: 0.3em; + padding: 0.3em 0.4em 0.4em; + font-size: 0.78em; + margin-right: 1em; +} +.extensions__item-code.success { + color: #6DCE4B; +} +.extensions__item-code.error { + color: #DD7337; +} +.extensions__item-code.yellow { + color: #ffd016; +} +.extensions__item-error { + width: 1.2em; + height: 1.2em; + background: #d74545; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + margin-right: 0.5em; + position: relative; +} +.extensions__item-error::after { + content: "!"; + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + color: #fff; + font-size: 0.8em; + font-weight: 900; +} +.extensions__item-proto { + margin-right: 0.5em; +} +.extensions__item-proto > svg { + width: 1em !important; + height: 1em !important; +} +.extensions__item-proto.protocol-https { + color: #6DCE4B; +} +.extensions__item-proto.protocol-http { + opacity: 0.3; +} +.extensions__item-status { + font-size: 0.78em; + color: #8D8D8D; +} +.extensions__item-disabled { + background-color: rgba(0, 0, 0, 0.18); + -webkit-border-radius: 0.1em; + -moz-border-radius: 0.1em; + border-radius: 0.3em; + padding: 0.3em 0.4em 0.4em; + font-size: 0.78em; + margin-left: auto; + color: #DD7337; +} +.extensions__item-included { + width: 1.2em; + height: 1.2em; + background-color: rgba(0, 0, 0, 0.18); + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + text-align: center; + padding-top: 0.24em; + margin-right: 0.5em; +} +.extensions__item-included:after { + content: ""; + display: inline-block; + width: 0.2em; + height: 0.4em; + border-right: 0.15em solid #fff; + border-bottom: 0.15em solid #fff; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} +.extensions__item-premium { + margin-left: 1em; + background-color: #D8C39A; + color: #000; + padding: 0.1em 0.5em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + font-size: 0.8em; +} +.extensions__item-body { + padding: 1em; +} +.extensions__item-imagebox { + position: relative; + padding-bottom: 57%; + background-color: #5c5c5c; + -webkit-border-top-left-radius: 1em; + -moz-border-radius-topleft: 1em; + border-top-left-radius: 1em; + -webkit-border-top-right-radius: 1em; + -moz-border-radius-topright: 1em; + border-top-right-radius: 1em; +} +.extensions__item-image { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + -webkit-transition: opacity 0.2s; + -o-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; + -webkit-border-top-left-radius: 1em; + -moz-border-radius-topleft: 1em; + border-top-left-radius: 1em; + -webkit-border-top-right-radius: 1em; + -moz-border-radius-topright: 1em; + border-top-right-radius: 1em; +} +.extensions__item-image.loaded { + opacity: 1; +} +.extensions__item-overlay { + position: absolute; + bottom: 0; + right: 0; + padding: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + left: 0; + background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), color-stop(99%, rgba(0, 0, 0, 0.89)), to(rgba(0, 0, 0, 0.89))); + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.89) 99%, rgba(0, 0, 0, 0.89) 100%); + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.89) 99%, rgba(0, 0, 0, 0.89) 100%); + background: -o-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.89) 99%, rgba(0, 0, 0, 0.89) 100%); + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.89) 99%, rgba(0, 0, 0, 0.89) 100%); + -webkit-border-bottom-right-radius: 1em; + -moz-border-radius-bottomright: 1em; + border-bottom-right-radius: 1em; + -webkit-border-bottom-left-radius: 1em; + -moz-border-radius-bottomleft: 1em; + border-bottom-left-radius: 1em; + padding-top: 4em; +} +.extensions__item + .extensions__item { + margin-left: 1em; +} +.extensions__item.focus:after { + content: ""; + position: absolute; + top: -0.5em; + left: -0.5em; + right: -0.5em; + bottom: -0.5em; + border: 0.3em solid #fff; + -webkit-border-radius: 1.4em; + -moz-border-radius: 1.4em; + border-radius: 1.4em; + z-index: -1; + pointer-events: none; +} +.extensions__item--recomend { + padding: 0; + width: 32.7%; + min-width: 20em; +} +.extensions__item--theme, .extensions__item--screensaver { + padding: 0; +} +.extensions__item--theme .extensions__item-name, .extensions__item--screensaver .extensions__item-name { + margin-bottom: 0; +} +.extensions__item--theme .extensions__item-premium, .extensions__item--screensaver .extensions__item-premium { + position: absolute; + top: 0; + left: 50%; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); + -webkit-border-top-left-radius: 0; + -moz-border-radius-topleft: 0; + border-top-left-radius: 0; + -webkit-border-top-right-radius: 0; + -moz-border-radius-topright: 0; + border-top-right-radius: 0; + margin: 0; +} +.extensions__item--screensaver { + width: 30%; + min-width: 20em; +} +.extensions__item--screensaver .extensions__item-imagebox, +.extensions__item--screensaver .extensions__item-image { + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.extensions__item--screensaver .extensions__item-time { + padding-left: 1em; + margin-left: auto; +} +.extensions__item.active:before { + content: "✔"; + position: absolute; + top: 1em; + right: 1em; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + border-radius: 100%; + width: 2em; + height: 2em; + background-color: #fff; + display: block; + z-index: 1; + color: #000; + text-align: center; + line-height: 2em; +} +.extensions__cub { + position: absolute; + top: 1em; + right: 1em; + background-color: rgba(0, 0, 0, 0.18); + -webkit-border-radius: 0.1em; + -moz-border-radius: 0.1em; + border-radius: 0.3em; + padding: 0.3em 0.4em 0.4em; + font-size: 0.78em; +} + +.extensions-info { + line-height: 1.8; +} +.extensions-info > * + * { + margin-top: 2em; +} +.extensions-info__image { + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; + width: 100%; +} +.extensions-info__descr { + font-size: 1.2em; +} +.extensions-info__instruction { + font-size: 1.1em; +} +.extensions-info__footer { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} +.extensions-info__footer > div { + width: 50%; + padding-top: 0.5em; +} +.extensions-info__label { + padding-top: 0.1em; + color: rgba(255, 255, 255, 0.5); +} +.extensions-info__value { + font-size: 1.1em; + word-break: break-all; + padding-right: 1em; +} + +.ad-countdown { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + background-color: rgba(0, 0, 0, 0.3); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.ad-countdown__text { + padding: 0.4em; +} +.ad-countdown__time { + min-width: 1em; + text-align: center; + background-color: #ffe216; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 0.4em; + min-width: 2em; + color: #000; +} +.ad-countdown--player { + position: absolute; + right: 0; + bottom: 100%; + margin-bottom: 3em; + -webkit-transition: margin-bottom 0.3s; + -o-transition: margin-bottom 0.3s; + -moz-transition: margin-bottom 0.3s; + transition: margin-bottom 0.3s; +} + +.player .player-panel.panel--visible .ad-countdown.ad-countdown--player { + margin-bottom: 1em; +} + +@-webkit-keyframes ad-video-loader { + 0% { + background-position: -150% 0, -150% 0; + } + 66% { + background-position: 250% 0, -150% 0; + } + 100% { + background-position: 250% 0, 250% 0; + } +} + +@-moz-keyframes ad-video-loader { + 0% { + background-position: -150% 0, -150% 0; + } + 66% { + background-position: 250% 0, -150% 0; + } + 100% { + background-position: 250% 0, 250% 0; + } +} + +@-o-keyframes ad-video-loader { + 0% { + background-position: -150% 0, -150% 0; + } + 66% { + background-position: 250% 0, -150% 0; + } + 100% { + background-position: 250% 0, 250% 0; + } +} + +@keyframes ad-video-loader { + 0% { + background-position: -150% 0, -150% 0; + } + 66% { + background-position: 250% 0, -150% 0; + } + 100% { + background-position: 250% 0, 250% 0; + } +} +.ad-video-block { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #000; + z-index: 60; +} +.ad-video-block__loader { + position: absolute; + left: 50%; + top: 50%; + height: 0.5em; + width: 10em; + margin: -0.2em 0 0 -5em; + background: no-repeat -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffe216)), no-repeat -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff)), rgba(255, 255, 255, 0.1); + background: no-repeat -webkit-linear-gradient(#ffe216 0 0), no-repeat -webkit-linear-gradient(#fff 0 0), rgba(255, 255, 255, 0.1); + background: no-repeat -moz-linear-gradient(#ffe216 0 0), no-repeat -moz-linear-gradient(#fff 0 0), rgba(255, 255, 255, 0.1); + background: no-repeat -o-linear-gradient(#ffe216 0 0), no-repeat -o-linear-gradient(#fff 0 0), rgba(255, 255, 255, 0.1); + background: no-repeat linear-gradient(#ffe216 0 0), no-repeat linear-gradient(#fff 0 0), rgba(255, 255, 255, 0.1); + -webkit-background-size: 60% 100%; + -moz-background-size: 60% 100%; + -o-background-size: 60% 100%; + background-size: 60% 100%; + -webkit-animation: ad-video-loader 3s infinite; + -moz-animation: ad-video-loader 3s infinite; + -o-animation: ad-video-loader 3s infinite; + animation: ad-video-loader 3s infinite; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} +.ad-video-block__video { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; +} +.ad-video-block__video.loaded { + opacity: 1; +} +.ad-video-block__vast { + position: fixed; + top: 0px; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; +} +.ad-video-block__vast-line { + position: fixed; + left: 0; + bottom: 0; + width: 100%; + background-color: #000; + height: 4em; +} +.ad-video-block__footer { + position: fixed; + left: 0; + right: 0; + bottom: 0; +} +.ad-video-block__text { + padding: 1em; + color: #fff; + text-shadow: 0 0em 0.4em #000; + max-width: 80%; +} +.ad-video-block__info { + position: fixed; + top: 0; + left: 0; + padding: 1em; + color: #fff; + text-shadow: 0 0em 0.4em #000; + font-size: 0.9em; +} +.ad-video-block__progress { + background-color: rgba(0, 0, 0, 0.3); +} +.ad-video-block__progress-fill { + background-color: #ffe216; + height: 0.3em; + width: 0%; + -webkit-transition: width 0.1s linear; + -o-transition: width 0.1s linear; + -moz-transition: width 0.1s linear; + transition: width 0.1s linear; +} +.ad-video-block__skip { + position: fixed; + right: 1em; + bottom: 1em; + background-color: rgba(0, 0, 0, 0.5); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.ad-video-block__skip span { + display: inline-block; + padding: 0.4em; + min-width: 2em; + text-align: center; +} + +.ad-preroll { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 60; +} +.ad-preroll__bg, .ad-preroll__over { + position: fixed; + background: #454545; + left: 0; + top: 0; + width: 100%; + height: 100%; + -webkit-transform: translate3d(-100%, 0, 0); + -moz-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + -webkit-transition: -webkit-transform 0.4s; + transition: -webkit-transform 0.4s; + -o-transition: -o-transform 0.4s; + -moz-transition: transform 0.4s, -moz-transform 0.4s; + transition: transform 0.4s; + transition: transform 0.4s, -webkit-transform 0.4s, -moz-transform 0.4s, -o-transform 0.4s; +} +.ad-preroll__bg.animate, .ad-preroll__over.animate { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.ad-preroll__over { + background: #000; +} +.ad-preroll__text { + position: fixed; + text-align: center; + left: 0; + top: 50%; + width: 100%; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + -webkit-transition: opacity 0.4s, -webkit-transform 0.6s; + transition: opacity 0.4s, -webkit-transform 0.6s; + -o-transition: opacity 0.4s, -o-transform 0.6s; + -moz-transition: transform 0.6s, opacity 0.4s, -moz-transform 0.6s; + transition: transform 0.6s, opacity 0.4s; + transition: transform 0.6s, opacity 0.4s, -webkit-transform 0.6s, -moz-transform 0.6s, -o-transform 0.6s; + color: #fff; + font-size: 4em; + font-weight: 700; + opacity: 0; +} +@media screen and (max-width: 580px) { + .ad-preroll__text { + font-size: 2.3em; + } +} +.ad-preroll__text.animate { + -webkit-transform: translate3d(0, -50%, 0); + -moz-transform: translate3d(0, -50%, 0); + transform: translate3d(0, -50%, 0); + opacity: 1; +} + +.ad-server { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -webkit-align-items: flex-start; + -moz-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + position: relative; + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + margin: 1.5em 2em; +} +.ad-server__text { + padding: 1em; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -moz-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + line-height: 1.4; +} +.ad-server__qr { + width: 8em; + height: 8em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.ad-server__qr svg { + width: 8em !important; + height: 8em !important; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.ad-server__label { + position: absolute; + left: 0; + bottom: 0; + background-color: #ffe216; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + padding: 0.5em; + color: #000; +} + +.online { + padding: 1.2em; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + background-color: rgba(0, 0, 0, 0.3); + position: relative; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.online__title { + font-size: 1.6em; +} +.online__body { + position: relative; +} +.online .time-line { + position: absolute; + left: 0; + bottom: 0; + right: 0; +} +.online__quality { + margin-top: 1em; +} +.online + .online { + margin-top: 1em; +} +.online.focus { + -webkit-box-shadow: 0 0 0 0.2em #fff; + -moz-box-shadow: 0 0 0 0.2em #fff; + box-shadow: 0 0 0 0.2em #fff; + margin-left: -0.8em; + margin-right: -0.8em; + padding: 1.2em 1.8em; +} + +@-webkit-keyframes animation-remote-button-blink { + 0% { + fill-opacity: 0.4; + } + 20% { + fill-opacity: 1; + } + 60% { + fill-opacity: 1; + } + 100% { + fill-opacity: 0.4; + } +} + +@-moz-keyframes animation-remote-button-blink { + 0% { + fill-opacity: 0.4; + } + 20% { + fill-opacity: 1; + } + 60% { + fill-opacity: 1; + } + 100% { + fill-opacity: 0.4; + } +} + +@-o-keyframes animation-remote-button-blink { + 0% { + fill-opacity: 0.4; + } + 20% { + fill-opacity: 1; + } + 60% { + fill-opacity: 1; + } + 100% { + fill-opacity: 0.4; + } +} + +@keyframes animation-remote-button-blink { + 0% { + fill-opacity: 0.4; + } + 20% { + fill-opacity: 1; + } + 60% { + fill-opacity: 1; + } + 100% { + fill-opacity: 0.4; + } +} +.remote-helper { + position: absolute; + top: 100%; + right: 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + z-index: 10; + pointer-events: none; + opacity: 0; + -webkit-transition: opacity 0.15s ease, -webkit-transform 0.2s ease; + transition: opacity 0.15s ease, -webkit-transform 0.2s ease; + -o-transition: opacity 0.15s ease, -o-transform 0.2s ease; + -moz-transition: opacity 0.15s ease, transform 0.2s ease, -moz-transform 0.2s ease; + transition: opacity 0.15s ease, transform 0.2s ease; + transition: opacity 0.15s ease, transform 0.2s ease, -webkit-transform 0.2s ease, -moz-transform 0.2s ease, -o-transform 0.2s ease; + line-height: 1.4; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.remote-helper.active { + opacity: 1; + -webkit-transform: translate3d(0, -100%, 0); + -moz-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); +} +.remote-helper__textbox { + background: rgba(0, 0, 0, 0.6); + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + border-radius: 0.5em; + padding: 0.8em 1em; + margin-right: 1em; + width: 11em; + margin-top: 1.5em; +} +.remote-helper__text { + overflow: hidden; + -o-text-overflow: "."; + text-overflow: "."; + display: -webkit-box; + -webkit-line-clamp: 3; + line-clamp: 3; + -webkit-box-orient: vertical; +} +.remote-helper__remote { + width: 9.5em; + height: auto; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +.remote-helper__remote svg { + width: 9.5em !important; + height: 12.8em !important; +} +.remote-helper.highlight--ok .remote-helper__button-ok { + -webkit-animation: animation-remote-button-blink 1s ease infinite; + -moz-animation: animation-remote-button-blink 1s ease infinite; + -o-animation: animation-remote-button-blink 1s ease infinite; + animation: animation-remote-button-blink 1s ease infinite; +} +.remote-helper.highlight--up .remote-helper__button-up { + -webkit-animation: animation-remote-button-blink 1s ease infinite; + -moz-animation: animation-remote-button-blink 1s ease infinite; + -o-animation: animation-remote-button-blink 1s ease infinite; + animation: animation-remote-button-blink 1s ease infinite; +} +.remote-helper.highlight--down .remote-helper__button-down { + -webkit-animation: animation-remote-button-blink 1s ease infinite; + -moz-animation: animation-remote-button-blink 1s ease infinite; + -o-animation: animation-remote-button-blink 1s ease infinite; + animation: animation-remote-button-blink 1s ease infinite; +} +.remote-helper.highlight--left .remote-helper__button-left { + -webkit-animation: animation-remote-button-blink 1s ease infinite; + -moz-animation: animation-remote-button-blink 1s ease infinite; + -o-animation: animation-remote-button-blink 1s ease infinite; + animation: animation-remote-button-blink 1s ease infinite; +} +.remote-helper.highlight--right .remote-helper__button-right { + -webkit-animation: animation-remote-button-blink 1s ease infinite; + -moz-animation: animation-remote-button-blink 1s ease infinite; + -o-animation: animation-remote-button-blink 1s ease infinite; + animation: animation-remote-button-blink 1s ease infinite; +} + +.iframe { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 100; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + background-color: rgba(0, 0, 0, 0.8); +} +.iframe__body { + position: fixed; + top: 2em; + right: 2em; + bottom: 2em; + left: 2em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + background: url(../img/loader.svg) no-repeat 50% 50%; +} +.iframe__window { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 100%; + height: 100%; + background-color: transparent; + border: 0; + pointer-events: none; +} +.iframe--loaded .iframe__window { + background-color: #fff; +} + +.mapping--line { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +.mapping--line > * + * { + margin-left: 1em; +} +.mapping--list { + padding: 0 1em; +} +.mapping--list > * + * { + margin-top: 1em; +} +.mapping--grid { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding: 0 1em; +} +.mapping--grid > * { + padding: 0 0.5em 1em 0.5em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} + +.cols--3 > * { + width: 33.3333333333%; +} +@media screen and (max-width: 767px) { + .cols--3 > * { + width: 50%; + } +} +@media screen and (max-width: 580px) { + .cols--3 > * { + width: 100%; + } +} +@media screen and (max-width: 480px) { + .cols--3 > * { + width: 100%; + } +} + +.cols--4 > * { + width: 25%; +} +@media screen and (max-width: 767px) { + .cols--4 > * { + width: 33.3333333333%; + } +} +@media screen and (max-width: 580px) { + .cols--4 > * { + width: 50%; + } +} +@media screen and (max-width: 480px) { + .cols--4 > * { + width: 100%; + } +} + +.cols--5 > * { + width: 20%; +} +@media screen and (max-width: 767px) { + .cols--5 > * { + width: 25%; + } +} +@media screen and (max-width: 580px) { + .cols--5 > * { + width: 33.3333333333%; + } +} +@media screen and (max-width: 480px) { + .cols--5 > * { + width: 50%; + } +} + +.cols--6 > * { + width: 16.6666666667%; +} +@media screen and (max-width: 767px) { + .cols--6 > * { + width: 20%; + } +} +@media screen and (max-width: 580px) { + .cols--6 > * { + width: 25%; + } +} +@media screen and (max-width: 480px) { + .cols--6 > * { + width: 33.3333333333%; + } +} + +@media screen and (min-width: 767px) { + body.size--bigger .cols--3 > * { + width: 50%; + } + body.size--bigger .cols--4 > * { + width: 33.3333333333%; + } + body.size--bigger .cols--5 > * { + width: 25%; + } + body.size--bigger .cols--6 > * { + width: 20%; + } +} +.cols--3 > * { + width: 33.3333333333%; +} +@media screen and (max-width: 767px) { + .cols--3 > * { + width: 50%; + } +} +@media screen and (max-width: 580px) { + .cols--3 > * { + width: 100%; + } +} +@media screen and (max-width: 480px) { + .cols--3 > * { + width: 100%; + } +} + +.cols--4 > * { + width: 25%; +} +@media screen and (max-width: 767px) { + .cols--4 > * { + width: 33.3333333333%; + } +} +@media screen and (max-width: 580px) { + .cols--4 > * { + width: 50%; + } +} +@media screen and (max-width: 480px) { + .cols--4 > * { + width: 100%; + } +} + +.cols--5 > * { + width: 20%; +} +@media screen and (max-width: 767px) { + .cols--5 > * { + width: 25%; + } +} +@media screen and (max-width: 580px) { + .cols--5 > * { + width: 33.3333333333%; + } +} +@media screen and (max-width: 480px) { + .cols--5 > * { + width: 50%; + } +} + +@media screen and (min-width: 767px) { + body.size--bigger .cols--3 > * { + width: 50%; + } + body.size--bigger .cols--4 > * { + width: 33.3333333333%; + } + body.size--bigger .cols--5 > * { + width: 25%; + } +} +.cols--3 > * { + width: 33.3333333333%; +} +@media screen and (max-width: 767px) { + .cols--3 > * { + width: 50%; + } +} +@media screen and (max-width: 580px) { + .cols--3 > * { + width: 100%; + } +} +@media screen and (max-width: 480px) { + .cols--3 > * { + width: 100%; + } +} + +.cols--4 > * { + width: 25%; +} +@media screen and (max-width: 767px) { + .cols--4 > * { + width: 33.3333333333%; + } +} +@media screen and (max-width: 580px) { + .cols--4 > * { + width: 50%; + } +} +@media screen and (max-width: 480px) { + .cols--4 > * { + width: 100%; + } +} + +@media screen and (min-width: 767px) { + body.size--bigger .cols--3 > * { + width: 50%; + } + body.size--bigger .cols--4 > * { + width: 33.3333333333%; + } +} +.cols--3 > * { + width: 33.3333333333%; +} +@media screen and (max-width: 767px) { + .cols--3 > * { + width: 50%; + } +} +@media screen and (max-width: 580px) { + .cols--3 > * { + width: 100%; + } +} +@media screen and (max-width: 480px) { + .cols--3 > * { + width: 100%; + } +} + +@media screen and (min-width: 767px) { + body.size--bigger .cols--3 > * { + width: 50%; + } +} +body.platform--orsay .cols--3, +body.platform--orsay .cols--4, +body.platform--orsay .cols--5, +body.platform--orsay .cols--6, +body.platform--netcast .cols--3, +body.platform--netcast .cols--4, +body.platform--netcast .cols--5, +body.platform--netcast .cols--6 { + display: block; +} +body.platform--orsay .cols--3::after, +body.platform--orsay .cols--4::after, +body.platform--orsay .cols--5::after, +body.platform--orsay .cols--6::after, +body.platform--netcast .cols--3::after, +body.platform--netcast .cols--4::after, +body.platform--netcast .cols--5::after, +body.platform--netcast .cols--6::after { + content: ""; + display: block; + clear: both; +} +body.platform--orsay .cols--3 > *, +body.platform--orsay .cols--4 > *, +body.platform--orsay .cols--5 > *, +body.platform--orsay .cols--6 > *, +body.platform--netcast .cols--3 > *, +body.platform--netcast .cols--4 > *, +body.platform--netcast .cols--5 > *, +body.platform--netcast .cols--6 > * { + float: left; +} + +body.platform--orsay svg, +body.platform--netcast svg { + max-width: 100%; + width: 100%; + max-height: 100%; + height: 100%; +} +body.platform--orsay .head__time, +body.platform--netcast .head__time { + position: absolute; + top: 1em; + right: 1.5em; +} +body.platform--orsay .head__split, +body.platform--netcast .head__split { + display: none; +} +body.platform--orsay .head__logo-icon, +body.platform--netcast .head__logo-icon { + margin-right: 1.5em; +} +body.platform--orsay .head__actions, +body.platform--netcast .head__actions { + position: absolute; + top: 0.4em; + right: 18em; +} +body.platform--orsay .head__markers, +body.platform--netcast .head__markers { + position: absolute; + top: 1.15em; + right: 15em; +} +body.platform--orsay .head__action svg, +body.platform--netcast .head__action svg { + width: 1.6em; + height: 1.6em; +} +body.platform--orsay .full-start__button > svg, +body.platform--netcast .full-start__button > svg { + width: 1.5em; + height: 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .full-start__button > span, +body.platform--netcast .full-start__button > span { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .full-start__tags > div, +body.platform--netcast .full-start__tags > div { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .full-start__tag > img, +body.platform--netcast .full-start__tag > img { + height: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .full-start__tag > div, +body.platform--netcast .full-start__tag > div { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .full-start__buttons-scroll, +body.platform--netcast .full-start__buttons-scroll { + width: auto; +} +body.platform--orsay .simple-button > svg, +body.platform--netcast .simple-button > svg { + width: 1.5em; + height: 1.5em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .simple-button > svg + span, +body.platform--netcast .simple-button > svg + span { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .simple-button--filter > div, +body.platform--netcast .simple-button--filter > div { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .menu__ico, +body.platform--netcast .menu__ico { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: left; + -webkit-align-items: left; + -moz-box-align: left; + -ms-flex-align: left; + align-items: left; + -webkit-box-pack: left; + -webkit-justify-content: left; + -moz-box-pack: left; + -ms-flex-pack: left; + justify-content: left; +} +body.platform--orsay .menu__ico > svg, +body.platform--netcast .menu__ico > svg { + position: absolute; + width: 1.2em; + height: 1.2em; + margin-right: 1em; + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .menu__text, +body.platform--netcast .menu__text { + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; +} +body.platform--orsay .player-panel__timeend, +body.platform--netcast .player-panel__timeend { + position: absolute; + right: 1.5em; +} +body.platform--orsay .player-panel__position > div::after, +body.platform--netcast .player-panel__position > div::after { + top: 0.25em; +} +body.platform--orsay .player-panel__playpause div, +body.platform--netcast .player-panel__playpause div { + width: 1em; +} +body.platform--orsay .player-panel__next-episode-name, +body.platform--netcast .player-panel__next-episode-name { + padding-top: 0.5em; +} +body.platform--orsay .settings-folder__icon svg, +body.platform--netcast .settings-folder__icon svg { + width: 2em; + height: 2em; +} +body.platform--orsay .menu__ico svg, +body.platform--netcast .menu__ico svg { + width: 1.5em; + height: 1.5em; +} +body.platform--orsay .torrent-filter, +body.platform--netcast .torrent-filter { + margin-bottom: 0; + padding-bottom: 2em; +} +body.platform--orsay .info__icon.icon--book, +body.platform--orsay .card__icon.icon--book, +body.platform--netcast .info__icon.icon--book, +body.platform--netcast .card__icon.icon--book { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF62lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0wOC0wNlQxMzo1MTo1MyswMzowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMDgtMDZUMTM6NTI6MjYrMDM6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMDgtMDZUMTM6NTI6MjYrMDM6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDA1OGI1ZmYtMmFiNy05NzQ2LTgyN2QtMDEyMzRjMTI0YTA0IiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6NGViZWE3MzgtOWY5NS1iYzQwLWFiMjgtOWU5MmYyYTBkOWFkIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZjRlYjQwNDAtMWUwYi1hYTQwLWI0MjYtNzA5YmEzNjAxMmE0Ij4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpmNGViNDA0MC0xZTBiLWFhNDAtYjQyNi03MDliYTM2MDEyYTQiIHN0RXZ0OndoZW49IjIwMjItMDgtMDZUMTM6NTE6NTMrMDM6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjAwNThiNWZmLTJhYjctOTc0Ni04MjdkLTAxMjM0YzEyNGEwNCIgc3RFdnQ6d2hlbj0iMjAyMi0wOC0wNlQxMzo1MjoyNiswMzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5VtBfmAAACJ0lEQVRoge3aO2gVQRSA4S8So1aCmghKYiU+CIKpLGws7ARFtBLfhZJSO0EUC1stIkQQNZjGF0IKCxEbK8GIIiKICFooiBaCxkjQY7G3CMtNdu6LbLE/DJfZ2TNz/mV2bzGnKyIksAIj2I2/mEkJaoFu9OARTuJLYUREFLV1EfE0Fo43ETEUBXkuSng6h7C9pefbGptrOcxLd8JE63P9T/iIZU0klcI0VufW7S0KShGZzvUv4XJyWs2xH3dm9f8UBaRsraSvwUKTIrIQNJxXWUUaphIpG5VI2ahEykYlUjYqkbJRiZSNSqRsVCJloxIpG5VI2ahEykYlUjYqkbJRiZSNSiSRfozjLjZ2cqFOigzjPQ5gH97ibKcW64TIVrzCFdkR82wuyM4fd7R70XaK9GAUL7BlnvsG8AQPsLJdi7dLZC++4kSdsXu4Wef6HlkhwHA7EmhVpF/2dO9jeW7sN47JTmiPyqomvuXuWSzbgq8x1EoizYhM1X7PmXu/j6MPN2Zdm8Aa2fF2nkFM4lqt/73RpJoRGcJDnEdXbuyDrEriIH7WiZ3BKWzC8zrjx/ESuxrOqqjGIyKuJtaMnEmYK98OR8SvhLmvt6MWpYjHWIuLTcSOycozxlpNIkVk6RzXf8i+VjvxuYUcpnAE2/BujnuWFE2SIlIvyRGskv0XtItn2IDT+JcbK375E/Zxb0Tcqu3VyYgYbOJdaLT1RcREbc3bETFQFPMfBi4+MPqpLd0AAAAASUVORK5CYII="); +} +body.platform--orsay .info__icon.icon--like, +body.platform--orsay .card__icon.icon--like, +body.platform--netcast .info__icon.icon--like, +body.platform--netcast .card__icon.icon--like { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF62lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0wOC0wNlQxMzo1MjozMCswMzowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMDgtMDZUMTM6NTI6NDUrMDM6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMDgtMDZUMTM6NTI6NDUrMDM6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NmFjZTliMDUtNTczMy01ZDQ2LTgwNzMtYTg2MjhmYWE1YzhmIiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZGM2YWYxZTMtMmYwMC1hZDRmLWJkYWEtNTdmZDdlZDU0OGU5IiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ODhkYWRlYTMtMDEzNi03MzRiLTkzZTItYTMwYzIzYjQ1YzNmIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo4OGRhZGVhMy0wMTM2LTczNGItOTNlMi1hMzBjMjNiNDVjM2YiIHN0RXZ0OndoZW49IjIwMjItMDgtMDZUMTM6NTI6MzArMDM6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjZhY2U5YjA1LTU3MzMtNWQ0Ni04MDczLWE4NjI4ZmFhNWM4ZiIgc3RFdnQ6d2hlbj0iMjAyMi0wOC0wNlQxMzo1Mjo0NSswMzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz42yx8HAAAEKklEQVRogd2aW4iVVRiGn9lTNmnFNJjmCUowEtMJC7GyiEiUIJBIogNMQVEERkoHu7Cwbgwl7Co6kDeGRRFoTgVZZJJoRmBpdCAUsywtlSm0rOHpYu8ta9as+d2Hf2/39MKCtdf6vvd73/Wf/3+3qfwfcEYVsW3ALGA6MLH0+zfgO2AHcLhGDaNKvFOBMaWxA8BuYDvwTyUklRgpAHcBNwLXAhdF84eBz4CPgHXA/koKA53AnSXeq4Cx0fxPwJYS71rgeCabmtUWq/usHP3qK+qYDM4OdZXaVwXvQXVZltahJi5Wt1dRKMaf6m0J3hvUn+vg/Ua9PMFLm4MP9muATUBHYgN+CGwDfqG4744GLgPmAecn4p8AVpT6dwNrEjHHgfeAncAhisfeWOAKYD7QnshZAKzP2rWmDrESKyxupaG24Ei1x/RueLs6LzF+RH1I7crgHacuVf9K5F8fxoZJ7erviU05LaNQ3NrVNcmlGIiNamcVvBPVTyOO/pAjDF4bBe5Sz6yiWNhWZph4rUZO1A8irk9iIzOigBPquXUURH05YaK3Tk7UAxHn3NDIm9HkrTkURF0XcH6cE+eVkdZtZSMXRhM7cipYbovUR3LmfCvSPAP1vmjwlpyLNqJ1R5qXFSjeHpRxDHg/cd5uNewEfgx+X1cAZgYDuymaGQ7YFvQnF4AJwcDe5mqpC7uCfmcBGBkMHGmymHpwNOifVQBOBAPnNFdLXTg76P9bAA4GA5OaLKYeTAn6fQXgy2BgGsW7z+GAWUF/f4GBR38XMKe5emrCeIqPD2VsLQDvRkFLmqenZixi4J7TW75Sbo0v+S1w9R6qdVq8hS9jj0qh5Gh55Hg9rYsNcFI3wNPAgOeReKu83QKrH7fnI417ynNh0DgH48UWEF9uTyX0daeMoC5MBK9qAROLE7oeDmMqTXryNJq4N6FnZRw3VPLjieSlp8FET0LH6lRsFskzCZIHm2hiQaL+q0PFn4psdYKspwkm5ibqvp6VUwnpSwnSRj4Oz07Ue+dUeZWSv5Egn9sAE9MTdTZXkltNkd5Ekdk5mpis/hHxf15pfrXFNifMdOdgYrx6NOL9Vh3RKCOUVinEMfWSOkx0qfsjzn3qqGp4ailcUL+OCh9VJ9TA1aH+EHEdUkdXy1XrKo60eMMW4lezPxHErU39KuLoUyfVoqlWI6gXOPjr0171vArz4y9ix9VLa9VTjxEsvjc+HAn63lMfpFuinH6Lp96atdRrBHWK+nck7IuM+I0Oxpx6deRhBHVmQtymRFz8MUn1pjw05GUE9eqEyA3B/AuJ+YV51c/TCOr8hNhn1ccS4/fkWTtvI6g3J0THuD/vuo0wgnpHholHG1GzUUZQH0iYWN6oeo00grokMDHoOTvPVs3fnGrBcxRf/484+SKtQUj9F2VY4j/PoZgrWh6XUQAAAABJRU5ErkJggg=="); +} +body.platform--orsay .info__icon.icon--wath, +body.platform--orsay .card__icon.icon--wath, +body.platform--netcast .info__icon.icon--wath, +body.platform--netcast .card__icon.icon--wath { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF62lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0wOC0wNlQxMzo1Mjo1MCswMzowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMDgtMDZUMTM6NTM6MDQrMDM6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMDgtMDZUMTM6NTM6MDQrMDM6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N2JlMWUxZTMtZTA1MC1jYjRhLTk0OTEtZjk5ZWNhZTJlYTkxIiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6OTIyZThhY2EtMWJkZS02NzQyLWIwNjUtNDcxMDE4NjJjNzI0IiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NTg1MDgxYmEtMTM0ZS04NjRmLThhM2QtM2I4M2QxZWIwN2YyIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo1ODUwODFiYS0xMzRlLTg2NGYtOGEzZC0zYjgzZDFlYjA3ZjIiIHN0RXZ0OndoZW49IjIwMjItMDgtMDZUMTM6NTI6NTArMDM6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjdiZTFlMWUzLWUwNTAtY2I0YS05NDkxLWY5OWVjYWUyZWE5MSIgc3RFdnQ6d2hlbj0iMjAyMi0wOC0wNlQxMzo1MzowNCswMzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7vBmHKAAAEu0lEQVRogc2aWWxVRRjHfz0hlMVWEYGyWW0UsbEulIjGgKA+GBdiNOGBoA/VxBdfjBF948UXX0Rc4oI2UYu4gIVIorgUI1gVKyoSCJomVZEqrWJBWjDavw/TQ+dO59ye7V76Tya5M/PN//v+d2bO8p2pkEROuBBYBFwN1AFzgBqgeqj/OHAE+AXoAjqAz4Ef83BekVFIDbACuBO4PiXHbqAVeAMjMB0kpSmXSmqWdFL54k1JC9PElHRApaS1CQLrl9QrqUfSiQTjnpM0JUlsSZbWbcAzQG1E/29AG7ATOAB0A73AACBgIjAVsxwvAa4DbgLmRvD1Ag8CLbGii6l4TZF/70NJKyRNSPIPDpVA0nJJW4rwr4vDFcfZWxEOtku6JkXwUeUySW9H+Pooq5CtHtIBSU05CnDLXZL+8PhtTytkk4esQ1JdCUWEZYbMknUROTNRRGs8JNvLIMAtGzxxPB9XyA2ewR+cARFhafHEs9K1811+/wLOtur7gIZYl0A/bgXGY+7eadEGLLPqg5hHnxOnWxxlTznKByVNz/BvPmZxrc/AUynpqBNbq21jG8/2TOGqDM6RdNzhS3OvCcsyT3xX+YRsdIw+yygCSV0W3zFJVRn5tjgxfuoKqfaonZeDkE6L76ikyRn55njivEASwdBWucfZXO3ADxk2Z6lwCHjHabsfOD0jHY7K23OYjVLMCDL7wsahcEZqgEZLYR/wbln+33T4Bui06rOBhoDC6zOMbREhNjv1mwPgWqexrUzBZMEup74gwCQNbOSSDCgxOp16bYDJdtg4XMIA8krZ/AqcsurTAmCm1TAA/JmTMxeDQH9OXH0YMSHOCYDJVsPfOToDqLR+VwP35cjdZ/sJnM7csnWhA+v3OGA98FpO3AWxBhTOwFmYbEdeeMjTtgrYS7ZXAyh81fgnAH63GiYBUzI6sPEqsJjC9QxGxF7g3pS8VcAsq94XYHKxNmaSL3YB9fhvtC8BL6fgnEXhyukJgJ8co4tSEI+GY8By4FFPXxPwHXB+Ar46p/5zAHzpNC5NQJgUj+NfapcDzQl43KeRb33P+L05PfkWK1UamW76OMH4/c7YxrBjn9NxYxnEIOkRSYclfSWpNuaY+U6sRyRVhJ2rnc5ypn/GJbR/xYl1nTScDjoP6HHW3VzMG9lYwlRMlt5GPXAgvLP3AtscgxdLHVUKPOHU92A+YRRkUS7WSNxSxiU2WlngiW9x2O8aNzuG/cqewsmrdDuxFexj13i8pFPOgJ1jQMRmjcS0YkKQ+T7hYuMZFPGkJ54HXLuowU97Bm8YIyI2+WyLkXziIXlfCb+2piwTJL3u8b8nasxohO0esm7ll8DzlSUqTOyFOChpYlohyMyCDy2SGnIUUCfzfd2H3Rrl6hnXybMRDiSzd5ZmELBI0guS/ovgj3WhSXJgoAlYy/AhGRf7gfeAL4CDDB8YsHEuJkU7D1iI+Zp1ZQTfv8DqIZ+jIumhmhmYx4SVMWxPYk5DhNmOKoyISTHGtgIPMzIRF42Uy2GJpG1Fllta7FDKx6Ksx5zqgbuBO4D5KTm6gK2YNNHXaQPJKsRGI+bM1hWYd+rpmJRNuJQGMMusB5Mn+B7YgdlTmfE/MLYJX09+eAkAAAAASUVORK5CYII="); +} +body.platform--orsay .info__icon.icon--history, +body.platform--orsay .card__icon.icon--history, +body.platform--netcast .info__icon.icon--history, +body.platform--netcast .card__icon.icon--history { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFEmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0wOC0wOVQxODoxNDo0MCswMzowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMDgtMDlUMTg6MTY6MDErMDM6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMDgtMDlUMTg6MTY6MDErMDM6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6YWYyYjJiNmItMDY0ZS0zNTQyLTllMDItNjdkYzBjNzAyZjUzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOmFmMmIyYjZiLTA2NGUtMzU0Mi05ZTAyLTY3ZGMwYzcwMmY1MyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmFmMmIyYjZiLTA2NGUtMzU0Mi05ZTAyLTY3ZGMwYzcwMmY1MyI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6YWYyYjJiNmItMDY0ZS0zNTQyLTllMDItNjdkYzBjNzAyZjUzIiBzdEV2dDp3aGVuPSIyMDIyLTA4LTA5VDE4OjE0OjQwKzAzOjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ps2f9JwAAASiSURBVGiBzZpbbBdFFMZ/XSmlXoBYm1JrBaKEBiIWbPCCUQyiJGKURI2Jt4i+IUYSI/KgiT4QjfEC1niJCUb7AHjDRPFBU0LwkmpRQQIPmHCpJNKiSQvhouLnw3TjOv/Z7e7OtPRLzsPMznznfDu7szNnp0oSgTAFuBKYC1wCXAQ0AOOBKmAA6AV+BfYD3cC3wN4Qzqs8hTQCdwFLgOtLcnwHbALWA/tKRyKpjM2UtE7SSYXFRklzy8RUtEONpDWBg3fhTUl1RWIr8mjdBqwFLs5o0wv8AHQBBwbLxwev1QIXAM2Yd2kO0JTB9QewAng3V3Q5FT+TcfdOSeqQdKuk2gJ3cYykRZLekjSQwd+ehy+Pww9THJyWtFrShQWCT7M6SasyBHVKqvIR8mkK8eeSpgUQYNskSetTfHaVFfJxCuGjwyDAtgdTfG8pKuTZFKKbR0BEbG2SjjlieDuvkIUpIq4ZQRGxtcj93txvt3VNv/2YZUUSC4DOXNNgeFwG7HTUT8AsewCIrIvtVIpYzpkTAfAzcIejvuN/pcTwNDuGcNsZeJzSbIMjvjnx9aEaNowCAbHVqPJ9+coWMt4h4vlRELxtjzvinJoUstzR4FwPh0/LLFuaAwsZq8op+bmkkO3WxY0eziYneI5JujuwmFesWA/FQhpViRs9HE138LVLOiuQkBkO/lkRcIM1rfUDX3pMl3876pYBu4BZHrwxdmO2ykksioCrrMpvAjhzoQXYATwSgMu+0bMjYKpVOVxCYrwKfASc58HRZZUnR5hsRxL7PRzkxRJgD3Bdyf6HrHJ9hMmEJPF7SfKiaAK2AqtL9LVjnBgB51iVxxlZrAI2FOxzwirX2ItGgGAZuwLISmjkQkTlCNT6khbEB8BNBfuMs8p/RsBhq/L80iEVx1LgTuBowX52jP0R0GNVeg9zDuzAfBzXlexvT1B9EXDQqry6JHlerAFaMRumsmizyj0RlR+XeR4OsjCA+X48FoBroVX+Cbl3htd6LOqmOfg+k8lZhVg0Xurgb4vfkd2WwqUed+sfq/wUcAvwmwdnEg9Y5SPA9ljlSkvhX5KqS96xMZLek/S9pHmBRiFpR6xY10r/bazqHcP15DAE4WsPOeKckRSCpM1Wg1Py2+4Ohx22YvwxvpZs1OJQu2kUBB/ba4745ruEIPNs27hnFIhY4IirM9nGTpmOw8z31dbMcDnutOVIoAn4hcr11SQSyyt79XsSuNdB9jUwPWR0OdGA+YVti1iBvUZMGcrXHUM5oESKcgRsiqSDjjic720W0TYHiRQ+T+WyxZKOOnzvTOszFGFXiph3JE0cBgFjJb2c4nOvMj4HQxFHkr5IIe6V9IRM3thXQLWkZZL2pfjqljQhiyOvozdSHEhmyfCCyp1YaJX59d2Twf9+Hq4iBwYeBl4iOx+1Z3CW6cYcnunDJAqE2ULXYabT2ZjtQlbm8TSwEngxV3QF72Cj0n8fh8QnKvj7u+wzPV+Va7MQ2CozYxWOyfeY00zgPuB2yn8wD2COOXVgHslS8BWSxBWYM1utmHxyPebP69mYg2cnMJn+PkxadhewBbPV9g7iX1LytK49HD5tAAAAAElFTkSuQmCC"); +} +body.platform--orsay .player-info__name, +body.platform--netcast .player-info__name { + padding-right: 4em; +} + +body.platform--orsay.system--keyboard .settings-input__content, +body.platform--orsay.system--keyboard .search-box { + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -moz-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} + +body.orsay-player--show { + background: transparent; +} +body.orsay-player--show #app, +body.orsay-player--show .modal, +body.orsay-player--show .helper { + visibility: hidden; +} +body.orsay-player--show #app *, +body.orsay-player--show .modal *, +body.orsay-player--show .helper * { + visibility: hidden !important; +} +body.orsay-player--show .player { + background: transparent; +} + +.https { + padding: 4em; + text-align: center; +} +.https__icon { + width: 10em; + margin: auto; +} +.https__icon > svg { + width: 10em; + height: 4em; +} +.https__text { + font-size: 1.3em; + line-height: 1.8; + margin: auto; + max-width: 20em; + padding-top: 3em; +} + +body.touch-device .scroll { + overflow: auto !important; +} +body.touch-device .scroll > .scroll__content > .scroll__body:after { + content: ""; + display: block; + width: 1.5em; + height: 1.5em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +body.touch-device .scroll--horizontal { + padding-top: 1em; + padding-bottom: 1em; +} +body.touch-device .full-start__buttons-scroll .scroll__body:after { + display: none !important; +} +body.touch-device .full-start__buttons-scroll .scroll__body .full-start__buttons:after { + content: ""; + display: block; + width: 0.75em; + height: 1.5em; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} +@media screen and (max-width: 480px) { + body.touch-device .settings__body .scroll, +body.touch-device .modal__body .scroll, +body.touch-device .selectbox__body .scroll { + -ms-scroll-chaining: none; + overscroll-behavior: none; + } +} + +@-webkit-keyframes animation-card-focus { + 40% { + -webkit-transform: translate3d(0, -1em, 0); + transform: translate3d(0, -1em, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@-moz-keyframes animation-card-focus { + 40% { + -moz-transform: translate3d(0, -1em, 0); + transform: translate3d(0, -1em, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@-o-keyframes animation-card-focus { + 40% { + transform: translate3d(0, -1em, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} + +@keyframes animation-card-focus { + 40% { + -webkit-transform: translate3d(0, -1em, 0); + -moz-transform: translate3d(0, -1em, 0); + transform: translate3d(0, -1em, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes animation-trigger-enter { + 40% { + -webkit-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@-moz-keyframes animation-trigger-enter { + 40% { + -moz-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -moz-transform: scale(1); + transform: scale(1); + } +} +@-o-keyframes animation-trigger-enter { + 40% { + -o-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -o-transform: scale(1); + transform: scale(1); + } +} +@keyframes animation-trigger-enter { + 40% { + -webkit-transform: scale(1.2); + -moz-transform: scale(1.2); + -o-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes animation-file-focus { + 40% { + -webkit-transform: translate3d(-1em, 0, 0); + transform: translate3d(-1em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes animation-file-focus { + 40% { + -moz-transform: translate3d(-1em, 0, 0); + transform: translate3d(-1em, 0, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes animation-file-focus { + 40% { + transform: translate3d(-1em, 0, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes animation-file-focus { + 40% { + -webkit-transform: translate3d(-1em, 0, 0); + -moz-transform: translate3d(-1em, 0, 0); + transform: translate3d(-1em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes animation-button-focus { + 40% { + -webkit-transform: scale(0.9); + transform: scale(0.9); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@-moz-keyframes animation-button-focus { + 40% { + -moz-transform: scale(0.9); + transform: scale(0.9); + } + 100% { + -moz-transform: scale(1); + transform: scale(1); + } +} +@-o-keyframes animation-button-focus { + 40% { + -o-transform: scale(0.9); + transform: scale(0.9); + } + 100% { + -o-transform: scale(1); + transform: scale(1); + } +} +@keyframes animation-button-focus { + 40% { + -webkit-transform: scale(0.9); + -moz-transform: scale(0.9); + -o-transform: scale(0.9); + transform: scale(0.9); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes animation-modal { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -5em, 0) scale(0.9); + transform: translate3d(0, -5em, 0) scale(0.9); + } + 100% { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0) scale(1); + transform: translate3d(0, 0, 0) scale(1); + } +} +@-moz-keyframes animation-modal { + 0% { + opacity: 0; + -moz-transform: translate3d(0, -5em, 0) scale(0.9); + transform: translate3d(0, -5em, 0) scale(0.9); + } + 100% { + opacity: 1; + -moz-transform: translate3d(0, 0, 0) scale(1); + transform: translate3d(0, 0, 0) scale(1); + } +} +@-o-keyframes animation-modal { + 0% { + opacity: 0; + transform: translate3d(0, -5em, 0) scale(0.9); + } + 100% { + opacity: 1; + transform: translate3d(0, 0, 0) scale(1); + } +} +@keyframes animation-modal { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -5em, 0) scale(0.9); + -moz-transform: translate3d(0, -5em, 0) scale(0.9); + transform: translate3d(0, -5em, 0) scale(0.9); + } + 100% { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0) scale(1); + -moz-transform: translate3d(0, 0, 0) scale(1); + transform: translate3d(0, 0, 0) scale(1); + } +} +@-webkit-keyframes animation-full-poster { + 0% { + -webkit-transform: translate3d(-2em, 0, 0); + transform: translate3d(-2em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes animation-full-poster { + 0% { + -moz-transform: translate3d(-2em, 0, 0); + transform: translate3d(-2em, 0, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes animation-full-poster { + 0% { + transform: translate3d(-2em, 0, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes animation-full-poster { + 0% { + -webkit-transform: translate3d(-2em, 0, 0); + -moz-transform: translate3d(-2em, 0, 0); + transform: translate3d(-2em, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes animation-full-background { + 0% { + -webkit-transform: translate3d(10%, 0, 0); + transform: translate3d(10%, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes animation-full-background { + 0% { + -moz-transform: translate3d(10%, 0, 0); + transform: translate3d(10%, 0, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes animation-full-background { + 0% { + transform: translate3d(10%, 0, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes animation-full-background { + 0% { + -webkit-transform: translate3d(10%, 0, 0); + -moz-transform: translate3d(10%, 0, 0); + transform: translate3d(10%, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes animation-opacity { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-moz-keyframes animation-opacity { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-o-keyframes animation-opacity { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@keyframes animation-opacity { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@-webkit-keyframes animation-opacity-blink { + 0% { + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@-moz-keyframes animation-opacity-blink { + 0% { + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@-o-keyframes animation-opacity-blink { + 0% { + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes animation-opacity-blink { + 0% { + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@-webkit-keyframes animation-zoom-down { + 0% { + -webkit-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@-moz-keyframes animation-zoom-down { + 0% { + -moz-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -moz-transform: scale(1); + transform: scale(1); + } +} +@-o-keyframes animation-zoom-down { + 0% { + -o-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -o-transform: scale(1); + transform: scale(1); + } +} +@keyframes animation-zoom-down { + 0% { + -webkit-transform: scale(1.2); + -moz-transform: scale(1.2); + -o-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes animation-activity { + 0% { + -webkit-transform: translate3d(0, 14%, 0); + transform: translate3d(0, 14%, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes animation-activity { + 0% { + -moz-transform: translate3d(0, 14%, 0); + transform: translate3d(0, 14%, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes animation-activity { + 0% { + transform: translate3d(0, 14%, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes animation-activity { + 0% { + -webkit-transform: translate3d(0, 14%, 0); + -moz-transform: translate3d(0, 14%, 0); + transform: translate3d(0, 14%, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes animation-from-below { + 0% { + -webkit-transform: translate3d(0, 50%, 0); + transform: translate3d(0, 50%, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-moz-keyframes animation-from-below { + 0% { + -moz-transform: translate3d(0, 50%, 0); + transform: translate3d(0, 50%, 0); + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-o-keyframes animation-from-below { + 0% { + transform: translate3d(0, 50%, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} +@keyframes animation-from-below { + 0% { + -webkit-transform: translate3d(0, 50%, 0); + -moz-transform: translate3d(0, 50%, 0); + transform: translate3d(0, 50%, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +@-webkit-keyframes animation-down { + 0% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } + 100% { + -webkit-transform: translate3d(0, 50%, 0); + transform: translate3d(0, 50%, 0); + opacity: 0; + } +} +@-moz-keyframes animation-down { + 0% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } + 100% { + -moz-transform: translate3d(0, 50%, 0); + transform: translate3d(0, 50%, 0); + opacity: 0; + } +} +@-o-keyframes animation-down { + 0% { + transform: translate3d(0, 0, 0); + opacity: 1; + } + 100% { + transform: translate3d(0, 50%, 0); + opacity: 0; + } +} +@keyframes animation-down { + 0% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } + 100% { + -webkit-transform: translate3d(0, 50%, 0); + -moz-transform: translate3d(0, 50%, 0); + transform: translate3d(0, 50%, 0); + opacity: 0; + } +} +@-webkit-keyframes animation-up { + 0% { + -webkit-transform: translate3d(0, -50%, 0); + transform: translate3d(0, -50%, 0); + opacity: 0; + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} +@-moz-keyframes animation-up { + 0% { + -moz-transform: translate3d(0, -50%, 0); + transform: translate3d(0, -50%, 0); + opacity: 0; + } + 100% { + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} +@-o-keyframes animation-up { + 0% { + transform: translate3d(0, -50%, 0); + opacity: 0; + } + 100% { + transform: translate3d(0, 0, 0); + opacity: 1; + } +} +@keyframes animation-up { + 0% { + -webkit-transform: translate3d(0, -50%, 0); + -moz-transform: translate3d(0, -50%, 0); + transform: translate3d(0, -50%, 0); + opacity: 0; + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} +body.advanced--animation:not(.no--animation) .card:not(.card--wide).focus .card__view, body.advanced--animation:not(.no--animation) .card:not(.card--wide).hover .card__view { + -webkit-animation: animation-card-focus 0.2s; + -moz-animation: animation-card-focus 0.2s; + -o-animation: animation-card-focus 0.2s; + animation: animation-card-focus 0.2s; +} +body.advanced--animation:not(.no--animation) .card:not(.card--wide).animate-trigger-enter .card__view { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +body.advanced--animation:not(.no--animation) .card-episode.focus .full-episode, body.advanced--animation:not(.no--animation) .card-episode.hover .full-episode { + -webkit-animation: animation-card-focus 0.2s; + -moz-animation: animation-card-focus 0.2s; + -o-animation: animation-card-focus 0.2s; + animation: animation-card-focus 0.2s; +} +body.advanced--animation:not(.no--animation) .card-episode.animate-trigger-enter .full-episode { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +body.advanced--animation:not(.no--animation) .explorer-card__head-img.focus, body.advanced--animation:not(.no--animation) .explorer-card__head-img.hover { + -webkit-animation: animation-card-focus 0.2s; + -moz-animation: animation-card-focus 0.2s; + -o-animation: animation-card-focus 0.2s; + animation: animation-card-focus 0.2s; +} +body.advanced--animation:not(.no--animation) .explorer-card__head-img.animate-trigger-enter { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +body.advanced--animation:not(.no--animation) .torrent-item.focus, body.advanced--animation:not(.no--animation) .torrent-item.hover { + -webkit-animation: animation-file-focus 0.2s; + -moz-animation: animation-file-focus 0.2s; + -o-animation: animation-file-focus 0.2s; + animation: animation-file-focus 0.2s; +} +body.advanced--animation:not(.no--animation) .torrent-item.animate-trigger-enter { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +body.advanced--animation:not(.no--animation) .head .head__action.focus, body.advanced--animation:not(.no--animation) .head .head__action.hover, +body.advanced--animation:not(.no--animation) .menu .menu__item.focus, +body.advanced--animation:not(.no--animation) .menu .menu__item.hover, +body.advanced--animation:not(.no--animation) .full-start__button.focus, +body.advanced--animation:not(.no--animation) .full-start__button.hover, +body.advanced--animation:not(.no--animation) .simple-button.focus, +body.advanced--animation:not(.no--animation) .simple-button.hover, +body.advanced--animation:not(.no--animation) .full-descr__tag.focus, +body.advanced--animation:not(.no--animation) .full-descr__tag.hover, +body.advanced--animation:not(.no--animation) .tag-count.focus, +body.advanced--animation:not(.no--animation) .tag-count.hover, +body.advanced--animation:not(.no--animation) .full-review.focus, +body.advanced--animation:not(.no--animation) .full-review.hover, +body.advanced--animation:not(.no--animation) .full-review-add.focus, +body.advanced--animation:not(.no--animation) .full-review-add.hover { + -webkit-animation: animation-button-focus 0.2s; + -moz-animation: animation-button-focus 0.2s; + -o-animation: animation-button-focus 0.2s; + animation: animation-button-focus 0.2s; +} +body.advanced--animation:not(.no--animation) .head .head__action.animate-trigger-enter:not([data-action]), +body.advanced--animation:not(.no--animation) .menu .menu__item.animate-trigger-enter:not([data-action]), +body.advanced--animation:not(.no--animation) .full-start__button.animate-trigger-enter:not([data-action]), +body.advanced--animation:not(.no--animation) .simple-button.animate-trigger-enter:not([data-action]), +body.advanced--animation:not(.no--animation) .full-descr__tag.animate-trigger-enter:not([data-action]), +body.advanced--animation:not(.no--animation) .tag-count.animate-trigger-enter:not([data-action]), +body.advanced--animation:not(.no--animation) .full-review.animate-trigger-enter:not([data-action]), +body.advanced--animation:not(.no--animation) .full-review-add.animate-trigger-enter:not([data-action]) { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +body.advanced--animation:not(.no--animation) .full-person.focus .full-person__photo, body.advanced--animation:not(.no--animation) .full-person.hover .full-person__photo { + -webkit-animation: animation-button-focus 0.2s; + -moz-animation: animation-button-focus 0.2s; + -o-animation: animation-button-focus 0.2s; + animation: animation-button-focus 0.2s; +} +body.advanced--animation:not(.no--animation) .full-person.animate-trigger-enter .full-person__photo { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +body.advanced--animation:not(.no--animation) .settings-folder.focus .settings-folder__icon, body.advanced--animation:not(.no--animation) .settings-folder.hover .settings-folder__icon { + -webkit-animation: animation-button-focus 0.2s; + -moz-animation: animation-button-focus 0.2s; + -o-animation: animation-button-focus 0.2s; + animation: animation-button-focus 0.2s; +} +body.advanced--animation:not(.no--animation) .settings-folder.animate-trigger-enter .settings-folder__icon { + -webkit-animation: animation-trigger-enter 0.2s forwards; + -moz-animation: animation-trigger-enter 0.2s forwards; + -o-animation: animation-trigger-enter 0.2s forwards; + animation: animation-trigger-enter 0.2s forwards; +} +body.advanced--animation:not(.no--animation) .modal.animate .modal__content { + -webkit-animation: animation-modal 0.3s; + -moz-animation: animation-modal 0.3s; + -o-animation: animation-modal 0.3s; + animation: animation-modal 0.3s; +} +body.advanced--animation:not(.no--animation) .modal.modal--full.animate .modal__content { + -webkit-animation: animation-from-below 0.3s; + -moz-animation: animation-from-below 0.3s; + -o-animation: animation-from-below 0.3s; + animation: animation-from-below 0.3s; +} +body.advanced--animation:not(.no--animation) .full-start__background.loaded { + -webkit-animation: animation-full-background 0.3s; + -moz-animation: animation-full-background 0.3s; + -o-animation: animation-full-background 0.3s; + animation: animation-full-background 0.3s; +} +body.advanced--animation:not(.no--animation) .activity:not(.activity--load) .activity__body { + -webkit-animation: animation-activity 0.2s; + -moz-animation: animation-activity 0.2s; + -o-animation: animation-activity 0.2s; + animation: animation-activity 0.2s; +} +body.advanced--animation:not(.no--animation) .animate-opacity { + -webkit-animation: animation-opacity 0.3s; + -moz-animation: animation-opacity 0.3s; + -o-animation: animation-opacity 0.3s; + animation: animation-opacity 0.3s; +} +body.advanced--animation:not(.no--animation) .animate-up-content { + -webkit-animation: animation-activity 0.2s; + -moz-animation: animation-activity 0.2s; + -o-animation: animation-activity 0.2s; + animation: animation-activity 0.2s; +} + +@media screen and (max-width: 480px) { + .selectbox.animate .selectbox__content, +.settings.animate .settings__content { + -webkit-animation: animation-from-below 0.3s forwards; + -moz-animation: animation-from-below 0.3s forwards; + -o-animation: animation-from-below 0.3s forwards; + animation: animation-from-below 0.3s forwards; + } + + .selectbox.animate-down .selectbox__content, +.settings.animate-down .settings__content { + -webkit-animation: animation-down 0.3s forwards; + -moz-animation: animation-down 0.3s forwards; + -o-animation: animation-down 0.3s forwards; + animation: animation-down 0.3s forwards; + } + + .modal.animate .modal__content { + -webkit-animation: animation-from-below 0.3s !important; + -moz-animation: animation-from-below 0.3s !important; + -o-animation: animation-from-below 0.3s !important; + animation: animation-from-below 0.3s !important; + } + + .modal.animate-down .modal__content { + -webkit-animation: animation-down 0.3s !important; + -moz-animation: animation-down 0.3s !important; + -o-animation: animation-down 0.3s !important; + animation: animation-down 0.3s !important; + } +} +@media screen and (min-width: 767px) { + body.light--version .wrap__left { + position: static; + background: transparent; + margin-left: 0; + width: 13.5em; + } + body.light--version .background { + display: none; + } + body.light--version .card--category { + width: 20%; + } + body.light--version .files__left { + font-size: 0.7em; + } + body.light--version .files__body { + max-width: inherit; + } + body.light--version .timetable__item { + width: 16.66%; + } + body.light--version .card--small .card__title { + margin-top: 0.5em; + } +} +@media screen and (max-width: 767px) { + body.light--version.menu--open .wrap__content { + -webkit-transform: translate3d(15em, 0, 0); + -moz-transform: translate3d(15em, 0, 0); + transform: translate3d(15em, 0, 0); + } +} +body.light--version .card__img, +body.light--version .card__quality, +body.light--version .card__vote, +body.light--version .items-line__more, +body.light--version .card-more__box, +body.light--version .card__type, +body.light--version .card__promo, +body.light--version .torrent-item, +body.light--version .explorer-card__head-img > img, +body.light--version .full-start__img, +body.light--version .full-start-new__poster.loaded img, +body.light--version .full-episode__img img, +body.light--version .full-episode__body, +body.light--version .register, +body.light--version .full-episode--next .full-episode__img:after, +body.light--version .season-episode, +body.light--version .season-episode__img > img, +body.light--version .card__textbox, +body.light--version .ad-bot__content, +body.light--version .ad-bot__marker, +body.light--version .full-review, +body.light--version .full-review-add, +body.light--version .bookmarks-folder__layer { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +body.light--version .card .card__view::after, +body.light--version .torrent-item::after, +body.light--version .explorer-card__head-img::after, +body.light--version .full-episode.focus::after, +body.light--version .card-more .card-more__box::after, +body.light--version .card-episode.focus .full-episode::after, +body.light--version .feed-item__poster-img, +body.light--version .feed-item__poster-box, +body.light--version .feed-item__image-box, +body.light--version .feed-item__image-img, +body.light--version .register::after, +body.light--version .season-episode::after, +body.light--version .ad-bot.focus .ad-bot__content::after, +body.light--version .full-review-add::after { + -webkit-border-radius: 0.4em; + -moz-border-radius: 0.4em; + border-radius: 0.4em; +} +body.light--version .full-start__button, +body.light--version .info__icon, +body.light--version .full-start__tag, +body.light--version .full-start__tag.tag--quality, +body.light--version .full-descr__tag, +body.light--version .full-start .info__rate, +body.light--version .explorer__files .torrent-filter .simple-button, +body.light--version .card-watched, +body.light--version .feed-item__buttons .simple-button { + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; +} +body.light--version .torrent-item__details { + font-size: 0.95em; +} + +body.glass--style .selectbox__content, +body.glass--style .settings__content, +body.glass--style .settings-input__content, +body.glass--style .modal__content, +body.glass--style .settings-input--free, +body.glass--style .navigation-bar__body, +body.glass--style .discuss-rules, +body.glass--style .bell__item, +body.glass--style .media-loading__status { + background-color: rgba(70, 70, 70, 0.3); + -webkit-backdrop-filter: blur(1.6em); + backdrop-filter: blur(1.6em); +} +@media screen and (max-width: 480px) { + body.glass--style .selectbox__content, +body.glass--style .modal__content, +body.glass--style .settings__content { + background-color: #262829; + } +} +body.glass--style .selectbox-item.focus, +body.glass--style .settings-folder.focus, +body.glass--style .settings-param.focus { + background-color: #fff; + color: #000; +} +body.glass--style .selectbox-item.focus .settings-folder__icon, +body.glass--style .selectbox-item.focus .selectbox-item__checkbox, +body.glass--style .settings-folder.focus .settings-folder__icon, +body.glass--style .settings-folder.focus .selectbox-item__checkbox, +body.glass--style .settings-param.focus .settings-folder__icon, +body.glass--style .settings-param.focus .selectbox-item__checkbox { + -webkit-filter: invert(1); + filter: invert(1); +} +body.glass--style .selectbox-item.focus::after { + border-color: #000; +} +body.glass--style .settings-param-title > span { + color: rgba(255, 255, 255, 0.4); +} +body.glass--style .settings-input__links { + background: rgba(221, 221, 221, 0.06); +} +body.glass--style .settings-input__input { + border: 0; +} +body.glass--style .settings-input--free .settings-input__content { + background: transparent; + -webkit-backdrop-filter: none; + backdrop-filter: none; +} +body.glass--style .torrent-serial { + background: rgba(132, 135, 137, 0.15); +} +body.glass--style .torrent-serial.focus { + background: rgba(255, 255, 255, 0.35); +} +body.glass--style .card-more__box, +body.glass--style .bookmarks-folder__layer { + background: rgba(0, 0, 0, 0.3); +} +body.glass--style-opacity--medium .selectbox__content, +body.glass--style-opacity--medium .settings__content, +body.glass--style-opacity--medium .settings-input__content, +body.glass--style-opacity--medium .modal__content, +body.glass--style-opacity--medium .settings-input--free, +body.glass--style-opacity--medium .navigation-bar__body, +body.glass--style-opacity--medium .bell__item { + background-color: rgba(70, 70, 70, 0.45); +} +@media screen and (max-width: 480px) { + body.glass--style-opacity--medium .selectbox__content, +body.glass--style-opacity--medium .modal__content, +body.glass--style-opacity--medium .settings__content { + background-color: #262829; + } +} +body.glass--style-opacity--blacked .selectbox__content, +body.glass--style-opacity--blacked .settings__content, +body.glass--style-opacity--blacked .settings-input__content, +body.glass--style-opacity--blacked .modal__content, +body.glass--style-opacity--blacked .settings-input--free, +body.glass--style-opacity--blacked .navigation-bar__body, +body.glass--style-opacity--blacked .bell__item { + background-color: rgba(56, 56, 56, 0.7); +} +@media screen and (max-width: 480px) { + body.glass--style-opacity--blacked .selectbox__content, +body.glass--style-opacity--blacked .modal__content, +body.glass--style-opacity--blacked .settings__content { + background-color: #262829; + } +} +body.glass--style.platform--browser .card .card__icons-inner, +body.glass--style.platform--browser .card .card__marker, +body.glass--style.platform--browser .card .card__vote, +body.glass--style.platform--browser .card .card-watched, +body.glass--style.platform--browser .head__action:not(.focus), body.glass--style.platform--nw .card .card__icons-inner, +body.glass--style.platform--nw .card .card__marker, +body.glass--style.platform--nw .card .card__vote, +body.glass--style.platform--nw .card .card-watched, +body.glass--style.platform--nw .head__action:not(.focus), body.glass--style.platform--apple .card .card__icons-inner, +body.glass--style.platform--apple .card .card__marker, +body.glass--style.platform--apple .card .card__vote, +body.glass--style.platform--apple .card .card-watched, +body.glass--style.platform--apple .head__action:not(.focus) { + background-color: rgba(70, 70, 70, 0.3); + -webkit-backdrop-filter: blur(1em); + backdrop-filter: blur(1em); +} +body.glass--style.platform--browser .card-watched__item, body.glass--style.platform--nw .card-watched__item, body.glass--style.platform--apple .card-watched__item { + color: #fff; +} +body.glass--style.platform--browser .card-watched__item:nth-child(2), body.glass--style.platform--nw .card-watched__item:nth-child(2), body.glass--style.platform--apple .card-watched__item:nth-child(2) { + opacity: 0.8; +} +body.glass--style.platform--browser .card-watched__item:nth-child(3), body.glass--style.platform--nw .card-watched__item:nth-child(3), body.glass--style.platform--apple .card-watched__item:nth-child(3) { + opacity: 0.6; +} +body.glass--style.platform--browser .card-watched__item:nth-child(4), body.glass--style.platform--nw .card-watched__item:nth-child(4), body.glass--style.platform--apple .card-watched__item:nth-child(4) { + opacity: 0.4; +} +body.glass--style.platform--browser .card-watched__item:nth-child(5), body.glass--style.platform--nw .card-watched__item:nth-child(5), body.glass--style.platform--apple .card-watched__item:nth-child(5) { + opacity: 0.2; +} + +body.platform--browser .player:not(.iptv) .player-panel__box-buttons, +body.platform--browser .player:not(.iptv) .player-panel__playpause:not(.focus), +body.platform--browser .player:not(.iptv) .player-info__values .value--size span, +body.platform--nw .player:not(.iptv) .player-panel__box-buttons, +body.platform--nw .player:not(.iptv) .player-panel__playpause:not(.focus), +body.platform--nw .player:not(.iptv) .player-info__values .value--size span, +body.true--mobile .player:not(.iptv) .player-panel__box-buttons, +body.true--mobile .player:not(.iptv) .player-panel__playpause:not(.focus), +body.true--mobile .player:not(.iptv) .player-info__values .value--size span, +body.glass--style.platform--apple .player:not(.iptv) .player-panel__box-buttons, +body.glass--style.platform--apple .player:not(.iptv) .player-panel__playpause:not(.focus), +body.glass--style.platform--apple .player:not(.iptv) .player-info__values .value--size span, +body.glass--style.platform--apple_tv .player:not(.iptv) .player-panel__box-buttons, +body.glass--style.platform--apple_tv .player:not(.iptv) .player-panel__playpause:not(.focus), +body.glass--style.platform--apple_tv .player:not(.iptv) .player-info__values .value--size span, +body.glass--style.platform--android .player:not(.iptv) .player-panel__box-buttons, +body.glass--style.platform--android .player:not(.iptv) .player-panel__playpause:not(.focus), +body.glass--style.platform--android .player:not(.iptv) .player-info__values .value--size span { + -webkit-backdrop-filter: blur(1em); + backdrop-filter: blur(1em); +} +body.platform--browser .normalization, +body.platform--browser .player-video__paused, +body.platform--browser .player-video__loader, +body.platform--browser .player-video__noise-text, +body.platform--browser .player-panel__time, +body.platform--browser .player-skip, +body.platform--browser .player-chat__body, +body.platform--nw .normalization, +body.platform--nw .player-video__paused, +body.platform--nw .player-video__loader, +body.platform--nw .player-video__noise-text, +body.platform--nw .player-panel__time, +body.platform--nw .player-skip, +body.platform--nw .player-chat__body, +body.true--mobile .normalization, +body.true--mobile .player-video__paused, +body.true--mobile .player-video__loader, +body.true--mobile .player-video__noise-text, +body.true--mobile .player-panel__time, +body.true--mobile .player-skip, +body.true--mobile .player-chat__body, +body.glass--style.platform--apple .normalization, +body.glass--style.platform--apple .player-video__paused, +body.glass--style.platform--apple .player-video__loader, +body.glass--style.platform--apple .player-video__noise-text, +body.glass--style.platform--apple .player-panel__time, +body.glass--style.platform--apple .player-skip, +body.glass--style.platform--apple .player-chat__body, +body.glass--style.platform--apple_tv .normalization, +body.glass--style.platform--apple_tv .player-video__paused, +body.glass--style.platform--apple_tv .player-video__loader, +body.glass--style.platform--apple_tv .player-video__noise-text, +body.glass--style.platform--apple_tv .player-panel__time, +body.glass--style.platform--apple_tv .player-skip, +body.glass--style.platform--apple_tv .player-chat__body, +body.glass--style.platform--android .normalization, +body.glass--style.platform--android .player-video__paused, +body.glass--style.platform--android .player-video__loader, +body.glass--style.platform--android .player-video__noise-text, +body.glass--style.platform--android .player-panel__time, +body.glass--style.platform--android .player-skip, +body.glass--style.platform--android .player-chat__body { + -webkit-backdrop-filter: blur(1em); + backdrop-filter: blur(1em); +} \ No newline at end of file diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Bold.eot b/lampa-main/fonts/SegoeUI/SegoeUI-Bold.eot new file mode 100644 index 0000000..b0691b8 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Bold.eot differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Bold.ttf b/lampa-main/fonts/SegoeUI/SegoeUI-Bold.ttf new file mode 100644 index 0000000..1b609f8 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Bold.ttf differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Bold.woff b/lampa-main/fonts/SegoeUI/SegoeUI-Bold.woff new file mode 100644 index 0000000..e4ffe34 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Bold.woff differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.eot b/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.eot new file mode 100644 index 0000000..6a5567a Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.eot differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.ttf b/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.ttf new file mode 100644 index 0000000..6f8b400 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.ttf differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.woff b/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.woff new file mode 100644 index 0000000..0cc5e56 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-BoldItalic.woff differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Italic.eot b/lampa-main/fonts/SegoeUI/SegoeUI-Italic.eot new file mode 100644 index 0000000..f01b3af Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Italic.eot differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Italic.ttf b/lampa-main/fonts/SegoeUI/SegoeUI-Italic.ttf new file mode 100644 index 0000000..831f98f Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Italic.ttf differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Italic.woff b/lampa-main/fonts/SegoeUI/SegoeUI-Italic.woff new file mode 100644 index 0000000..8d213fa Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Italic.woff differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Light.eot b/lampa-main/fonts/SegoeUI/SegoeUI-Light.eot new file mode 100644 index 0000000..65e51f8 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Light.eot differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Light.ttf b/lampa-main/fonts/SegoeUI/SegoeUI-Light.ttf new file mode 100644 index 0000000..949fa7b Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Light.ttf differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-Light.woff b/lampa-main/fonts/SegoeUI/SegoeUI-Light.woff new file mode 100644 index 0000000..71b225a Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-Light.woff differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.eot b/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.eot new file mode 100644 index 0000000..da794cd Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.eot differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.ttf b/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.ttf new file mode 100644 index 0000000..a899102 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.ttf differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.woff b/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.woff new file mode 100644 index 0000000..ce946f9 Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI-SemiBold.woff differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI.eot b/lampa-main/fonts/SegoeUI/SegoeUI.eot new file mode 100644 index 0000000..910475b Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI.eot differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI.ttf b/lampa-main/fonts/SegoeUI/SegoeUI.ttf new file mode 100644 index 0000000..92276cf Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI.ttf differ diff --git a/lampa-main/fonts/SegoeUI/SegoeUI.woff b/lampa-main/fonts/SegoeUI/SegoeUI.woff new file mode 100644 index 0000000..019931c Binary files /dev/null and b/lampa-main/fonts/SegoeUI/SegoeUI.woff differ diff --git a/lampa-main/fonts/SegoeUI/demo.html b/lampa-main/fonts/SegoeUI/demo.html new file mode 100644 index 0000000..6b4d6de --- /dev/null +++ b/lampa-main/fonts/SegoeUI/demo.html @@ -0,0 +1,342 @@ + + + + + + + + Transfonter demo + + + + +
    +
    +

    Segoe UI Light

    +
    .your-style {
    +    font-family: 'Segoe UI';
    +    font-weight: 300;
    +    font-style: normal;
    +}
    +
    +

    + абвгдеёжзийклмнопрстуфхцчшщъыьэюя
    + АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
    + abcdefghijklmnopqrstuvwxyz
    + ABCDEFGHIJKLMNOPQRSTUVWXYZ
    0123456789.:,;()*!?'@#<>$%&^+-=~ +

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +
    +
    +
    +

    Segoe UI Bold Italic

    +
    .your-style {
    +    font-family: 'Segoe UI';
    +    font-weight: bold;
    +    font-style: italic;
    +}
    +
    +

    + абвгдеёжзийклмнопрстуфхцчшщъыьэюя
    + АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
    + abcdefghijklmnopqrstuvwxyz
    + ABCDEFGHIJKLMNOPQRSTUVWXYZ
    0123456789.:,;()*!?'@#<>$%&^+-=~ +

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +
    +
    +
    +

    Segoe UI Semibold

    +
    .your-style {
    +    font-family: 'Segoe UI';
    +    font-weight: 600;
    +    font-style: normal;
    +}
    +
    +

    + абвгдеёжзийклмнопрстуфхцчшщъыьэюя
    + АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
    + abcdefghijklmnopqrstuvwxyz
    + ABCDEFGHIJKLMNOPQRSTUVWXYZ
    0123456789.:,;()*!?'@#<>$%&^+-=~ +

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +
    +
    +
    +

    Segoe UI

    +
    .your-style {
    +    font-family: 'Segoe UI';
    +    font-weight: normal;
    +    font-style: normal;
    +}
    +
    +

    + абвгдеёжзийклмнопрстуфхцчшщъыьэюя
    + АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
    + abcdefghijklmnopqrstuvwxyz
    + ABCDEFGHIJKLMNOPQRSTUVWXYZ
    0123456789.:,;()*!?'@#<>$%&^+-=~ +

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +
    +
    +
    +

    Segoe UI Bold

    +
    .your-style {
    +    font-family: 'Segoe UI';
    +    font-weight: bold;
    +    font-style: normal;
    +}
    +
    +

    + абвгдеёжзийклмнопрстуфхцчшщъыьэюя
    + АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
    + abcdefghijklmnopqrstuvwxyz
    + ABCDEFGHIJKLMNOPQRSTUVWXYZ
    0123456789.:,;()*!?'@#<>$%&^+-=~ +

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +
    +
    +
    +

    Segoe UI Italic

    +
    .your-style {
    +    font-family: 'Segoe UI';
    +    font-weight: normal;
    +    font-style: italic;
    +}
    +
    +

    + абвгдеёжзийклмнопрстуфхцчшщъыьэюя
    + АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
    + abcdefghijklmnopqrstuvwxyz
    + ABCDEFGHIJKLMNOPQRSTUVWXYZ
    0123456789.:,;()*!?'@#<>$%&^+-=~ +

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +

    Съешь же ещё этих мягких французских булок, да выпей чаю.

    +
    +
    +
    + + \ No newline at end of file diff --git a/lampa-main/fonts/SegoeUI/stylesheet.css b/lampa-main/fonts/SegoeUI/stylesheet.css new file mode 100644 index 0000000..8b9c5f0 --- /dev/null +++ b/lampa-main/fonts/SegoeUI/stylesheet.css @@ -0,0 +1,67 @@ +/* This stylesheet generated by Transfonter (https://transfonter.org) on August 23, 2017 4:44 PM */ + +@font-face { + font-family: 'Segoe UI'; + src: url('SegoeUI-Light.eot'); + src: local('Segoe UI Light'), local('SegoeUI-Light'), + url('SegoeUI-Light.eot?#iefix') format('embedded-opentype'), + url('SegoeUI-Light.woff') format('woff'), + url('SegoeUI-Light.ttf') format('truetype'); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: 'Segoe UI'; + src: url('SegoeUI-BoldItalic.eot'); + src: local('Segoe UI Bold Italic'), local('SegoeUI-BoldItalic'), + url('SegoeUI-BoldItalic.eot?#iefix') format('embedded-opentype'), + url('SegoeUI-BoldItalic.woff') format('woff'), + url('SegoeUI-BoldItalic.ttf') format('truetype'); + font-weight: bold; + font-style: italic; +} + +@font-face { + font-family: 'Segoe UI'; + src: url('SegoeUI-SemiBold.eot'); + src: local('Segoe UI Semibold'), local('SegoeUI-SemiBold'), + url('SegoeUI-SemiBold.eot?#iefix') format('embedded-opentype'), + url('SegoeUI-SemiBold.woff') format('woff'), + url('SegoeUI-SemiBold.ttf') format('truetype'); + font-weight: 600; + font-style: normal; +} + +@font-face { + font-family: 'Segoe UI'; + src: url('SegoeUI.eot'); + src: local('Segoe UI'), local('SegoeUI'), + url('SegoeUI.eot?#iefix') format('embedded-opentype'), + url('SegoeUI.woff') format('woff'), + url('SegoeUI.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'Segoe UI'; + src: url('SegoeUI-Bold.eot'); + src: local('Segoe UI Bold'), local('SegoeUI-Bold'), + url('SegoeUI-Bold.eot?#iefix') format('embedded-opentype'), + url('SegoeUI-Bold.woff') format('woff'), + url('SegoeUI-Bold.ttf') format('truetype'); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'Segoe UI'; + src: url('SegoeUI-Italic.eot'); + src: local('Segoe UI Italic'), local('SegoeUI-Italic'), + url('SegoeUI-Italic.eot?#iefix') format('embedded-opentype'), + url('SegoeUI-Italic.woff') format('woff'), + url('SegoeUI-Italic.ttf') format('truetype'); + font-weight: normal; + font-style: italic; +} diff --git a/lampa-main/icons/android-chrome-192x192.png b/lampa-main/icons/android-chrome-192x192.png new file mode 100644 index 0000000..06c4391 Binary files /dev/null and b/lampa-main/icons/android-chrome-192x192.png differ diff --git a/lampa-main/icons/android-chrome-384x384.png b/lampa-main/icons/android-chrome-384x384.png new file mode 100644 index 0000000..c11e57d Binary files /dev/null and b/lampa-main/icons/android-chrome-384x384.png differ diff --git a/lampa-main/icons/apple-touch-icon.png b/lampa-main/icons/apple-touch-icon.png new file mode 100644 index 0000000..9e76d8d Binary files /dev/null and b/lampa-main/icons/apple-touch-icon.png differ diff --git a/lampa-main/icons/browserconfig.xml b/lampa-main/icons/browserconfig.xml new file mode 100644 index 0000000..9ee98ad --- /dev/null +++ b/lampa-main/icons/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #1d1f20 + + + diff --git a/lampa-main/icons/favicon-16x16.png b/lampa-main/icons/favicon-16x16.png new file mode 100644 index 0000000..3ebec9f Binary files /dev/null and b/lampa-main/icons/favicon-16x16.png differ diff --git a/lampa-main/icons/favicon-32x32.png b/lampa-main/icons/favicon-32x32.png new file mode 100644 index 0000000..c8b538c Binary files /dev/null and b/lampa-main/icons/favicon-32x32.png differ diff --git a/lampa-main/icons/favicon.ico b/lampa-main/icons/favicon.ico new file mode 100644 index 0000000..398a389 Binary files /dev/null and b/lampa-main/icons/favicon.ico differ diff --git a/lampa-main/icons/mstile-150x150.png b/lampa-main/icons/mstile-150x150.png new file mode 100644 index 0000000..36bcf6b Binary files /dev/null and b/lampa-main/icons/mstile-150x150.png differ diff --git a/lampa-main/icons/safari-pinned-tab.svg b/lampa-main/icons/safari-pinned-tab.svg new file mode 100644 index 0000000..a9d4d87 --- /dev/null +++ b/lampa-main/icons/safari-pinned-tab.svg @@ -0,0 +1,39 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + + + + diff --git a/lampa-main/icons/site.webmanifest b/lampa-main/icons/site.webmanifest new file mode 100644 index 0000000..c3048a6 --- /dev/null +++ b/lampa-main/icons/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "android-chrome-384x384.png", + "sizes": "384x384", + "type": "image/png" + } + ], + "theme_color": "#1d1f20", + "background_color": "#1d1f20", + "display": "standalone" +} diff --git a/lampa-main/img/actor.svg b/lampa-main/img/actor.svg new file mode 100644 index 0000000..5f0cb3d --- /dev/null +++ b/lampa-main/img/actor.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lampa-main/img/bokeh-h/1.png b/lampa-main/img/bokeh-h/1.png new file mode 100644 index 0000000..8e67d1b Binary files /dev/null and b/lampa-main/img/bokeh-h/1.png differ diff --git a/lampa-main/img/bokeh-h/2.png b/lampa-main/img/bokeh-h/2.png new file mode 100644 index 0000000..256c5bd Binary files /dev/null and b/lampa-main/img/bokeh-h/2.png differ diff --git a/lampa-main/img/bokeh-h/3.png b/lampa-main/img/bokeh-h/3.png new file mode 100644 index 0000000..7ee0345 Binary files /dev/null and b/lampa-main/img/bokeh-h/3.png differ diff --git a/lampa-main/img/bokeh-h/4.png b/lampa-main/img/bokeh-h/4.png new file mode 100644 index 0000000..d6114c5 Binary files /dev/null and b/lampa-main/img/bokeh-h/4.png differ diff --git a/lampa-main/img/bokeh-h/5.png b/lampa-main/img/bokeh-h/5.png new file mode 100644 index 0000000..392a901 Binary files /dev/null and b/lampa-main/img/bokeh-h/5.png differ diff --git a/lampa-main/img/bokeh-h/6.png b/lampa-main/img/bokeh-h/6.png new file mode 100644 index 0000000..c288091 Binary files /dev/null and b/lampa-main/img/bokeh-h/6.png differ diff --git a/lampa-main/img/bokeh/1.png b/lampa-main/img/bokeh/1.png new file mode 100644 index 0000000..140e001 Binary files /dev/null and b/lampa-main/img/bokeh/1.png differ diff --git a/lampa-main/img/bokeh/2.png b/lampa-main/img/bokeh/2.png new file mode 100644 index 0000000..5b90693 Binary files /dev/null and b/lampa-main/img/bokeh/2.png differ diff --git a/lampa-main/img/bokeh/3.png b/lampa-main/img/bokeh/3.png new file mode 100644 index 0000000..382c1f7 Binary files /dev/null and b/lampa-main/img/bokeh/3.png differ diff --git a/lampa-main/img/bokeh/4.png b/lampa-main/img/bokeh/4.png new file mode 100644 index 0000000..1b357e0 Binary files /dev/null and b/lampa-main/img/bokeh/4.png differ diff --git a/lampa-main/img/bokeh/5.png b/lampa-main/img/bokeh/5.png new file mode 100644 index 0000000..d690eb2 Binary files /dev/null and b/lampa-main/img/bokeh/5.png differ diff --git a/lampa-main/img/bokeh/6.png b/lampa-main/img/bokeh/6.png new file mode 100644 index 0000000..70978dd Binary files /dev/null and b/lampa-main/img/bokeh/6.png differ diff --git a/lampa-main/img/empty.svg b/lampa-main/img/empty.svg new file mode 100644 index 0000000..ff916dd --- /dev/null +++ b/lampa-main/img/empty.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/error.svg b/lampa-main/img/error.svg new file mode 100644 index 0000000..7a58fc0 --- /dev/null +++ b/lampa-main/img/error.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/lampa-main/img/icons/add.svg b/lampa-main/img/icons/add.svg new file mode 100644 index 0000000..5cb3321 --- /dev/null +++ b/lampa-main/img/icons/add.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/android/android-launchericon-144-144.png b/lampa-main/img/icons/android/android-launchericon-144-144.png new file mode 100644 index 0000000..6d70581 Binary files /dev/null and b/lampa-main/img/icons/android/android-launchericon-144-144.png differ diff --git a/lampa-main/img/icons/android/android-launchericon-192-192.png b/lampa-main/img/icons/android/android-launchericon-192-192.png new file mode 100644 index 0000000..b0ea843 Binary files /dev/null and b/lampa-main/img/icons/android/android-launchericon-192-192.png differ diff --git a/lampa-main/img/icons/android/android-launchericon-48-48.png b/lampa-main/img/icons/android/android-launchericon-48-48.png new file mode 100644 index 0000000..06f7f3e Binary files /dev/null and b/lampa-main/img/icons/android/android-launchericon-48-48.png differ diff --git a/lampa-main/img/icons/android/android-launchericon-512-512.png b/lampa-main/img/icons/android/android-launchericon-512-512.png new file mode 100644 index 0000000..c4e7bd9 Binary files /dev/null and b/lampa-main/img/icons/android/android-launchericon-512-512.png differ diff --git a/lampa-main/img/icons/android/android-launchericon-72-72.png b/lampa-main/img/icons/android/android-launchericon-72-72.png new file mode 100644 index 0000000..38a1066 Binary files /dev/null and b/lampa-main/img/icons/android/android-launchericon-72-72.png differ diff --git a/lampa-main/img/icons/android/android-launchericon-96-96.png b/lampa-main/img/icons/android/android-launchericon-96-96.png new file mode 100644 index 0000000..e4d85c3 Binary files /dev/null and b/lampa-main/img/icons/android/android-launchericon-96-96.png differ diff --git a/lampa-main/img/icons/check_dark.svg b/lampa-main/img/icons/check_dark.svg new file mode 100644 index 0000000..6bc4c06 --- /dev/null +++ b/lampa-main/img/icons/check_dark.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/film.svg b/lampa-main/img/icons/film.svg new file mode 100644 index 0000000..b7d4801 --- /dev/null +++ b/lampa-main/img/icons/film.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/ios/100.png b/lampa-main/img/icons/ios/100.png new file mode 100644 index 0000000..a85e3fc Binary files /dev/null and b/lampa-main/img/icons/ios/100.png differ diff --git a/lampa-main/img/icons/ios/1024.png b/lampa-main/img/icons/ios/1024.png new file mode 100644 index 0000000..63bc43c Binary files /dev/null and b/lampa-main/img/icons/ios/1024.png differ diff --git a/lampa-main/img/icons/ios/114.png b/lampa-main/img/icons/ios/114.png new file mode 100644 index 0000000..4ab94a6 Binary files /dev/null and b/lampa-main/img/icons/ios/114.png differ diff --git a/lampa-main/img/icons/ios/120.png b/lampa-main/img/icons/ios/120.png new file mode 100644 index 0000000..cb84150 Binary files /dev/null and b/lampa-main/img/icons/ios/120.png differ diff --git a/lampa-main/img/icons/ios/128.png b/lampa-main/img/icons/ios/128.png new file mode 100644 index 0000000..c808b44 Binary files /dev/null and b/lampa-main/img/icons/ios/128.png differ diff --git a/lampa-main/img/icons/ios/152.png b/lampa-main/img/icons/ios/152.png new file mode 100644 index 0000000..aeef135 Binary files /dev/null and b/lampa-main/img/icons/ios/152.png differ diff --git a/lampa-main/img/icons/ios/16.png b/lampa-main/img/icons/ios/16.png new file mode 100644 index 0000000..0cdbf8e Binary files /dev/null and b/lampa-main/img/icons/ios/16.png differ diff --git a/lampa-main/img/icons/ios/167.png b/lampa-main/img/icons/ios/167.png new file mode 100644 index 0000000..e14f88d Binary files /dev/null and b/lampa-main/img/icons/ios/167.png differ diff --git a/lampa-main/img/icons/ios/180.png b/lampa-main/img/icons/ios/180.png new file mode 100644 index 0000000..8066515 Binary files /dev/null and b/lampa-main/img/icons/ios/180.png differ diff --git a/lampa-main/img/icons/ios/20.png b/lampa-main/img/icons/ios/20.png new file mode 100644 index 0000000..a9d5ee8 Binary files /dev/null and b/lampa-main/img/icons/ios/20.png differ diff --git a/lampa-main/img/icons/ios/256.png b/lampa-main/img/icons/ios/256.png new file mode 100644 index 0000000..f2c6717 Binary files /dev/null and b/lampa-main/img/icons/ios/256.png differ diff --git a/lampa-main/img/icons/ios/29.png b/lampa-main/img/icons/ios/29.png new file mode 100644 index 0000000..ad42e86 Binary files /dev/null and b/lampa-main/img/icons/ios/29.png differ diff --git a/lampa-main/img/icons/ios/32.png b/lampa-main/img/icons/ios/32.png new file mode 100644 index 0000000..4852096 Binary files /dev/null and b/lampa-main/img/icons/ios/32.png differ diff --git a/lampa-main/img/icons/ios/40.png b/lampa-main/img/icons/ios/40.png new file mode 100644 index 0000000..98936c1 Binary files /dev/null and b/lampa-main/img/icons/ios/40.png differ diff --git a/lampa-main/img/icons/ios/50.png b/lampa-main/img/icons/ios/50.png new file mode 100644 index 0000000..69d920e Binary files /dev/null and b/lampa-main/img/icons/ios/50.png differ diff --git a/lampa-main/img/icons/ios/57.png b/lampa-main/img/icons/ios/57.png new file mode 100644 index 0000000..e5b3686 Binary files /dev/null and b/lampa-main/img/icons/ios/57.png differ diff --git a/lampa-main/img/icons/ios/58.png b/lampa-main/img/icons/ios/58.png new file mode 100644 index 0000000..b304821 Binary files /dev/null and b/lampa-main/img/icons/ios/58.png differ diff --git a/lampa-main/img/icons/ios/60.png b/lampa-main/img/icons/ios/60.png new file mode 100644 index 0000000..3108177 Binary files /dev/null and b/lampa-main/img/icons/ios/60.png differ diff --git a/lampa-main/img/icons/ios/64.png b/lampa-main/img/icons/ios/64.png new file mode 100644 index 0000000..b746d37 Binary files /dev/null and b/lampa-main/img/icons/ios/64.png differ diff --git a/lampa-main/img/icons/ios/76.png b/lampa-main/img/icons/ios/76.png new file mode 100644 index 0000000..3094ddc Binary files /dev/null and b/lampa-main/img/icons/ios/76.png differ diff --git a/lampa-main/img/icons/ios/80.png b/lampa-main/img/icons/ios/80.png new file mode 100644 index 0000000..c4c2ef1 Binary files /dev/null and b/lampa-main/img/icons/ios/80.png differ diff --git a/lampa-main/img/icons/ios/87.png b/lampa-main/img/icons/ios/87.png new file mode 100644 index 0000000..a3b33e9 Binary files /dev/null and b/lampa-main/img/icons/ios/87.png differ diff --git a/lampa-main/img/icons/keyboard/abc.svg b/lampa-main/img/icons/keyboard/abc.svg new file mode 100644 index 0000000..d11583f --- /dev/null +++ b/lampa-main/img/icons/keyboard/abc.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lampa-main/img/icons/keyboard/bksp.svg b/lampa-main/img/icons/keyboard/bksp.svg new file mode 100644 index 0000000..8d0b237 --- /dev/null +++ b/lampa-main/img/icons/keyboard/bksp.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lampa-main/img/icons/keyboard/enter.svg b/lampa-main/img/icons/keyboard/enter.svg new file mode 100644 index 0000000..0c58367 --- /dev/null +++ b/lampa-main/img/icons/keyboard/enter.svg @@ -0,0 +1,3 @@ + + + diff --git a/lampa-main/img/icons/keyboard/lang.svg b/lampa-main/img/icons/keyboard/lang.svg new file mode 100644 index 0000000..06b1d72 --- /dev/null +++ b/lampa-main/img/icons/keyboard/lang.svg @@ -0,0 +1,3 @@ + + + diff --git a/lampa-main/img/icons/keyboard/space.svg b/lampa-main/img/icons/keyboard/space.svg new file mode 100644 index 0000000..a869af9 --- /dev/null +++ b/lampa-main/img/icons/keyboard/space.svg @@ -0,0 +1,3 @@ + + + diff --git a/lampa-main/img/icons/keyboard/sym.svg b/lampa-main/img/icons/keyboard/sym.svg new file mode 100644 index 0000000..68b85fe --- /dev/null +++ b/lampa-main/img/icons/keyboard/sym.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lampa-main/img/icons/keyboard/up.svg b/lampa-main/img/icons/keyboard/up.svg new file mode 100644 index 0000000..6fc36bd --- /dev/null +++ b/lampa-main/img/icons/keyboard/up.svg @@ -0,0 +1,3 @@ + + + diff --git a/lampa-main/img/icons/menu/bookmark.svg b/lampa-main/img/icons/menu/bookmark.svg new file mode 100644 index 0000000..f3cedc5 --- /dev/null +++ b/lampa-main/img/icons/menu/bookmark.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/browse.svg b/lampa-main/img/icons/menu/browse.svg new file mode 100644 index 0000000..6bb9f0c --- /dev/null +++ b/lampa-main/img/icons/menu/browse.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/catalog.svg b/lampa-main/img/icons/menu/catalog.svg new file mode 100644 index 0000000..08dc6bc --- /dev/null +++ b/lampa-main/img/icons/menu/catalog.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/home.svg b/lampa-main/img/icons/menu/home.svg new file mode 100644 index 0000000..4b7da5c --- /dev/null +++ b/lampa-main/img/icons/menu/home.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/hourglass.svg b/lampa-main/img/icons/menu/hourglass.svg new file mode 100644 index 0000000..f71a1be --- /dev/null +++ b/lampa-main/img/icons/menu/hourglass.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/info.svg b/lampa-main/img/icons/menu/info.svg new file mode 100644 index 0000000..32ec8ab --- /dev/null +++ b/lampa-main/img/icons/menu/info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lampa-main/img/icons/menu/like.svg b/lampa-main/img/icons/menu/like.svg new file mode 100644 index 0000000..0a2bbfc --- /dev/null +++ b/lampa-main/img/icons/menu/like.svg @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/movie.svg b/lampa-main/img/icons/menu/movie.svg new file mode 100644 index 0000000..626f1ee --- /dev/null +++ b/lampa-main/img/icons/menu/movie.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/settings.svg b/lampa-main/img/icons/menu/settings.svg new file mode 100644 index 0000000..098c4ee --- /dev/null +++ b/lampa-main/img/icons/menu/settings.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/time.svg b/lampa-main/img/icons/menu/time.svg new file mode 100644 index 0000000..f7d6a3f --- /dev/null +++ b/lampa-main/img/icons/menu/time.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/menu/tv.svg b/lampa-main/img/icons/menu/tv.svg new file mode 100644 index 0000000..b847f8d --- /dev/null +++ b/lampa-main/img/icons/menu/tv.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/more.svg b/lampa-main/img/icons/more.svg new file mode 100644 index 0000000..2ea2cfb --- /dev/null +++ b/lampa-main/img/icons/more.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/player/next.svg b/lampa-main/img/icons/player/next.svg new file mode 100644 index 0000000..41607a7 --- /dev/null +++ b/lampa-main/img/icons/player/next.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lampa-main/img/icons/player/pause.svg b/lampa-main/img/icons/player/pause.svg new file mode 100644 index 0000000..bcea028 --- /dev/null +++ b/lampa-main/img/icons/player/pause.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lampa-main/img/icons/player/play.svg b/lampa-main/img/icons/player/play.svg new file mode 100644 index 0000000..3a0aa87 --- /dev/null +++ b/lampa-main/img/icons/player/play.svg @@ -0,0 +1,3 @@ + + + diff --git a/lampa-main/img/icons/player/playlist.svg b/lampa-main/img/icons/player/playlist.svg new file mode 100644 index 0000000..b762dde --- /dev/null +++ b/lampa-main/img/icons/player/playlist.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lampa-main/img/icons/player/prev.svg b/lampa-main/img/icons/player/prev.svg new file mode 100644 index 0000000..219bcf1 --- /dev/null +++ b/lampa-main/img/icons/player/prev.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lampa-main/img/icons/player/size.svg b/lampa-main/img/icons/player/size.svg new file mode 100644 index 0000000..d80a9e0 --- /dev/null +++ b/lampa-main/img/icons/player/size.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lampa-main/img/icons/player/subs.svg b/lampa-main/img/icons/player/subs.svg new file mode 100644 index 0000000..da6c58f --- /dev/null +++ b/lampa-main/img/icons/player/subs.svg @@ -0,0 +1,3 @@ + + + diff --git a/lampa-main/img/icons/pulse.svg b/lampa-main/img/icons/pulse.svg new file mode 100644 index 0000000..f22dc5b --- /dev/null +++ b/lampa-main/img/icons/pulse.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/lampa-main/img/icons/settings/more.svg b/lampa-main/img/icons/settings/more.svg new file mode 100644 index 0000000..8ee8850 --- /dev/null +++ b/lampa-main/img/icons/settings/more.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/settings/panel.svg b/lampa-main/img/icons/settings/panel.svg new file mode 100644 index 0000000..fa99976 --- /dev/null +++ b/lampa-main/img/icons/settings/panel.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/settings/parser.svg b/lampa-main/img/icons/settings/parser.svg new file mode 100644 index 0000000..c654110 --- /dev/null +++ b/lampa-main/img/icons/settings/parser.svg @@ -0,0 +1,2 @@ + + diff --git a/lampa-main/img/icons/settings/player.svg b/lampa-main/img/icons/settings/player.svg new file mode 100644 index 0000000..63e7d5b --- /dev/null +++ b/lampa-main/img/icons/settings/player.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/lampa-main/img/icons/settings/server.svg b/lampa-main/img/icons/settings/server.svg new file mode 100644 index 0000000..93bc3ae --- /dev/null +++ b/lampa-main/img/icons/settings/server.svg @@ -0,0 +1,2 @@ + + diff --git a/lampa-main/img/icons/split.svg b/lampa-main/img/icons/split.svg new file mode 100644 index 0000000..7afba26 --- /dev/null +++ b/lampa-main/img/icons/split.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lampa-main/img/icons/time.svg b/lampa-main/img/icons/time.svg new file mode 100644 index 0000000..cb99c04 --- /dev/null +++ b/lampa-main/img/icons/time.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/lampa-main/img/icons/view.svg b/lampa-main/img/icons/view.svg new file mode 100644 index 0000000..4acbfb3 --- /dev/null +++ b/lampa-main/img/icons/view.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/lampa-main/img/ili/bookmarks.png b/lampa-main/img/ili/bookmarks.png new file mode 100644 index 0000000..ec2d178 Binary files /dev/null and b/lampa-main/img/ili/bookmarks.png differ diff --git a/lampa-main/img/ili/search.png b/lampa-main/img/ili/search.png new file mode 100644 index 0000000..42e42ca Binary files /dev/null and b/lampa-main/img/ili/search.png differ diff --git a/lampa-main/img/ili/tv.png b/lampa-main/img/ili/tv.png new file mode 100644 index 0000000..492a999 Binary files /dev/null and b/lampa-main/img/ili/tv.png differ diff --git a/lampa-main/img/img_broken.svg b/lampa-main/img/img_broken.svg new file mode 100644 index 0000000..82bcfcf --- /dev/null +++ b/lampa-main/img/img_broken.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lampa-main/img/img_load.svg b/lampa-main/img/img_load.svg new file mode 100644 index 0000000..b481cbd --- /dev/null +++ b/lampa-main/img/img_load.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lampa-main/img/loader.svg b/lampa-main/img/loader.svg new file mode 100644 index 0000000..5c9ad94 --- /dev/null +++ b/lampa-main/img/loader.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lampa-main/img/logo-icon.svg b/lampa-main/img/logo-icon.svg new file mode 100644 index 0000000..448be96 --- /dev/null +++ b/lampa-main/img/logo-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/lampa-main/img/logo.svg b/lampa-main/img/logo.svg new file mode 100644 index 0000000..1b1906a --- /dev/null +++ b/lampa-main/img/logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lampa-main/img/video_poster.png b/lampa-main/img/video_poster.png new file mode 100644 index 0000000..8ff4e71 Binary files /dev/null and b/lampa-main/img/video_poster.png differ diff --git a/lampa-main/img/welcome.jpg b/lampa-main/img/welcome.jpg new file mode 100644 index 0000000..7949a8c Binary files /dev/null and b/lampa-main/img/welcome.jpg differ diff --git a/lampa-main/index.html b/lampa-main/index.html new file mode 100644 index 0000000..4fb1ed7 --- /dev/null +++ b/lampa-main/index.html @@ -0,0 +1,167 @@ + + + + + + Lampa - Каталог фильмов и сериалов + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    +
    Ошибка
    +
    Не удалось загрузить файл:
    +
    + + + + + + + + + + + \ No newline at end of file diff --git a/lampa-main/lang/be.js b/lampa-main/lang/be.js new file mode 100644 index 0000000..ae6b803 --- /dev/null +++ b/lampa-main/lang/be.js @@ -0,0 +1,1379 @@ +export default { + lang_choice_title: 'Сардэчна запрашаем', + lang_choice_subtitle: 'Выберыце сваю мову', + + more: 'Яшчэ', + show_more: 'Паказаць яшчэ', + more_results: 'Паказаць больш вынікаў', + loading: 'Загрузка', + nofind_movie: 'Не атрымалася знайсці фільм.', + noname: 'Без назвы', + nochoice: 'Не абрана', + cancel: 'Адмяніць', + confirm: 'Сцвярджаю', + sure: 'Вы ўпэўненыя?', + nodata: 'Няма дадзеных', + back: 'Назад', + ready: 'Гатова', + close_app_modal: 'Вы ўпэўненыя, што хочаце пакінуць дадатак?', + connected_seeds: 'злуч.', + + search: 'Пошук', + search_input: 'Увядзіце тэкст', + search_empty: 'Гісторыя пошуку пустая.', + search_delete: 'Налева - выдаліць', + search_start_typing: 'Пачніце ўводзіць тэкст для пошуку.', + search_searching: 'Ідзе пошук...', + search_start: 'Пачаць пошук', + search_nofound: 'Па вашым запыце нічога не знойдзена.', + global_search: 'Сусветны пошук', + + full_genre: 'Жанр', + full_production: 'Вытворчасць', + full_date_of_release: 'Дата рэлізу', + full_budget: 'Бюджэт', + full_countries: 'Краіны', + full_like: 'Падабаецца', + full_torrents: 'Торэнты', + full_trailers: 'Трэйлеры', + full_detail: 'Падрабязна', + full_notext: 'Без апісання.', + full_series_release: 'Выхад серый', + full_next_episode: 'Наступная', + full_episode_days_left: 'Засталося дзён', + full_trailer_official: 'Афіцыйны', + full_trailer_no_official: 'Неафіцыйны', + full_season: 'Сезон', + full_episode: 'Эпізод', + full_directing: 'Рэжысура', + + + settings_cub_sync: 'Сінхранізацыя', + settings_cub_sync_descr: 'Сінхранізацыя з сэрвісам CUB: сінхранізацыя вашых закладак, гісторыі праглядаў, пазнак і тайм-кодаў.', + settings_cub_account: 'Акаўнт', + settings_cub_logged_in_as: 'Увайшлі як', + settings_cub_profile: 'Профіль', + settings_cub_sync_btn: 'Сінхранізаваць', + settings_cub_sync_btn_descr: 'Захаваць лакальныя закладкі ў рахунак CUB', + settings_cub_backup: 'Бэкап', + settings_cub_backup_descr: 'Захаваць або загрузіць бэкап дадзеных', + settings_cub_logout: 'Выйсці з акаўнта', + settings_cub_signin: 'аўтарызацыя', + settings_cub_not_specified: 'Не паказаны', + settings_cub_password: 'Пароль', + settings_cub_status: 'Статус', + settings_cub_backup_import: 'Імпарт', + settings_cub_backup_export: 'Экспарт', + settings_cub_sync_filters: 'Сінхранізацыя фільтраў', + settings_cub_sync_calendar: 'Сінхранізацыя календара', + settings_cub_sync_quality: 'Сінхранізацыя адзнак (якасць)', + settings_cub_sync_search: 'Сінхранізацыя гісторыі пошуку', + settings_cub_sync_recomends: 'Сінхранізацыя рэкамендацый', + settings_cub_sync_timecodes: 'Сінхранізацыя тайм-кодаў', + + settings_input_links: 'Выбранае', + + settings_interface_type: 'Аблегчаная версія', + settings_interface_size: 'Памер інтэрфейсу', + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: 'Фон', + settings_interface_background_use: 'Паказваць фон', + settings_interface_background_type: 'Тып фону', + settings_interface_performance: 'Хуткадзейнасць', + settings_interface_animation: 'Анімацыя', + settings_interface_animation_descr: 'Анімацыя картак і кантэнту', + settings_interface_attenuation: 'Згасанне', + settings_interface_attenuation_descr: 'Плыўнае згасанне картак знізу і зверху', + settings_interface_scroll: 'Тып скролінга', + settings_interface_view_card: 'Тып прагляду картак', + settings_interface_view_card_descr: 'Па меры скралінга стужкі карткі будуць падгружацца паступова або загружацца ўсё', + settings_interface_lang: 'Мова інтэрфейсу', + settings_interface_lang_reload: 'Неабходна перазагрузіць дадатак, націсніце "OK" для перазагрузкі.', + + settings_main_account: 'Акаўнт', + settings_main_interface: 'Інтэрфейс', + settings_main_player: 'Плэер', + settings_main_parser: 'Парсер', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Пашырэння', + settings_main_rest: 'Астатняе', + + settings_rest_start: 'Стартавая старонка', + settings_rest_start_descr: 'З якой старонкі пачынаць пры запуску', + settings_rest_source: 'Крыніца', + settings_rest_source_use: 'Асноўная крыніца', + settings_rest_source_descr: 'Адкуль браць інфармацыю пра фільмы', + settings_rest_tmdb_lang: 'На якой мове адлюстроўваць дадзеныя з TMDB', + settings_rest_tmdb_prox: 'Праксіраваць TMDB', + settings_rest_tmdb_prox_auto: 'Уключыць проксі аўтаматычна', + settings_rest_tmdb_posters: 'Разрозненне постэраў TMDB', + settings_rest_screensaver: 'Скрынсэйвер', + settings_rest_screensaver_use: 'Паказваць застаўку пры бяздзейнасці', + settings_rest_screensaver_type: 'Тып застаўкі', + settings_rest_helper: 'Падказкі', + settings_rest_helper_use: 'Паказваць падказкі', + settings_rest_helper_reset: 'Паказаць падказкі зноў', + settings_rest_pages: 'Колькі старонак захоўваць у памяці', + settings_rest_pages_descr: 'Захоўвае старонкі ў тым стане, у якім вы іх пакінулі', + settings_rest_time: 'Зрушыць час', + settings_rest_navigation: 'Тып навігацыі', + settings_rest_keyboard: 'Тып клавіятуры', + settings_rest_device: 'Назва прылады', + settings_rest_device_placeholder: 'Напрыклад: Мая Лямпа', + settings_rest_cache: 'Ачысціць кэш', + settings_rest_cache_descr: 'Будуць ачышчаны ўсе налады і дадзеныя', + settings_rest_tmdb_example: 'Напрыклад:', + settings_rest_tmdb_api_descr: 'Для атрымання дадзеных', + settings_rest_tmdb_image_descr: 'Для атрымання малюнкаў', + settings_rest_card_quality: 'Адзнакі якасці', + settings_rest_card_quality_descr: 'Адлюстроўваць адзнакі якасці на картках', + settings_rest_card_episodes: 'Адзнакі эпізодаў', + settings_rest_card_episodes_descr: 'Адлюстроўваць адзнакі эпізодаў на картках', + + settings_parser_use: 'Выкарыстоўваць парсер', + settings_parser_use_descr: 'Тым самым, вы згаджаецеся прыняць на сябе ўсю адказнасць за выкарыстанне публічных спасылак для прагляду торэнт і анлайн кантэнту.', + settings_parser_type: 'Тып парсера для торэнтаў', + settings_parser_jackett_placeholder: 'Напрыклад: 192.168.х', + settings_parser_jackett_link: 'спасылка', + settings_parser_jackett_link_descr: 'Укажыце спасылку на скрыпт Jackett', + settings_parser_jackett_key_placeholder: 'Напрыклад: sa0sk83d..', + settings_parser_jackett_key: 'Api ключ', + settings_parser_jackett_key_descr: 'Знаходзіцца ў Jackett', + settings_parser_torlook_type: 'Метад парсінгу сайта TorLook', + settings_parser_scraperapi_placeholder: 'Напрыклад: scraperapi.com', + settings_parser_scraperapi_link: 'Спасылка на парсер сайтаў', + settings_parser_scraperapi_descr: 'Зарэгіструйцеся на сайце scraperapi.com, увядзіце спасылку api.scraperapi.com?api_key=...&url={q}
    У {q} будзе пастаўляцца сайт w41.torlook.info', + settings_parser_search: 'Пошук', + settings_parser_search_descr: 'На якой мове рабіць пошук?', + settings_parser_in_search: 'Парсер у пошуку', + settings_parser_in_search_descr: 'Паказваць вынікі ў пошуку?', + settings_parser_timeout_title: 'Таймаўт парсера', + settings_parser_timeout_descr: 'Час у секундах, які будзе чакацца адказу ад сервера', + + settings_player_type: 'Тып плэера', + settings_player_type_descr: 'Якім плэерам прайграваць', + settings_infuse_launch_mode: 'Запуск у Infuse', + settings_infuse_launch_mode_descr: 'Што рабіць пры адкрыцці відэа ў Infuse. Для торэнтаў заўжды адразу прайграванне', + settings_infuse_launch_ask: 'Пытаць пры запуску', + settings_infuse_launch_play: 'Гуляць', + settings_infuse_launch_save_and_play: 'Захаваць і гуляць', + settings_player_iptv_type: 'Тып плэера для IPTV', + settings_player_iptv_type_descr: 'Якім плэерам прайграваць IPTV каналы', + settings_player_reset: 'Скінуць плэер па змаўчанні', + settings_player_reset_descr: 'Скідае абраны Android плэер у дадатку', + settings_player_path: 'Шлях да плэера', + settings_player_path_descr: 'Укажыце шлях да плэера .exe', + settings_player_external_header: 'Знешні плэер', + settings_player_external_fullscreen: 'Запускать у поўнаэкранным рэжыме', + settings_player_normalization: 'Нармалізацыя гуку', + settings_player_normalization_descr: 'Нармалізуе гук у адзін узровень, паніжае гучныя гукі і павялічвае ціхія.', + settings_player_next_episode: 'Наступная серыя', + settings_player_next_episode_descr: 'Аўтаматычна пераключаць на наступную серыю пасля заканчэння бягучай', + settings_player_timecode: 'Тайм-код', + settings_player_timecode_descr: 'Працягнуць з апошняга месца прагляду', + settings_player_scale: 'Метад маштабавання', + settings_player_scale_descr: 'Якім чынам рабіць вылічэнні для маштабавання відэа', + settings_player_subs: 'Субтытры', + settings_player_subs_use: 'Уключыць', + settings_player_subs_use_descr: 'Заўсёды ўключаць субтытры пасля запуску відэа', + settings_player_subs_lang: 'Мова субтытраў', + settings_player_subs_lang_descr: 'Якія субтытры ўключаць аўтаматычна, калі даступна некалькі моў', + settings_param_subtitles_lang_auto: 'Мова інтэрфейсу', + settings_player_subs_size: 'Памер', + settings_player_subs_size_descr: 'Памер субтытраў на экране', + settings_player_subs_stroke_use: 'Выкарыстоўваць акантоўку', + settings_player_subs_stroke_use_descr: 'Субтытры будуць абведзены чорным колерам для паляпшэння чытальнасці', + settings_player_subs_backdrop_use: 'Выкарыстоўваць падкладку', + settings_player_subs_backdrop_use_descr: 'Субтытры будуць адлюстроўвацца на напаўпразрыстай падкладцы для паляпшэння чытальнасці', + settings_player_quality: 'Якасць відэа па змаўчанні', + settings_player_quality_descr: 'Пераважная якасць відэа для прагляду', + settings_player_hls_title: 'Апрацоўка патоку .m3u8', + settings_player_hls_descr: 'Не чапайце гэты параметр калі не ведаеце навошта ён.', + + settings_plugins_notice: 'Для прымянення плагіна неабходна перазагрузіць дадатак', + settings_plugins_add: 'Дадаць плагін', + settings_plugins_add_descr: 'Для выдалення дададзенага плагіна ўтрымлівайце ці націсніце двойчы клавішу (OK) на ім', + settings_plugins_install: 'Усталяваць плагін', + settings_plugins_install_descr: 'Усталяваць плагін са спісу даступных', + + settings_server_link: 'Выкарыстоўваць спасылку', + settings_server_links: 'Спасылкі', + settings_server_placeholder: 'Напрыклад: 192.168.х', + settings_server_link_one: 'Асноўная спасылка', + settings_server_link_one_descr: 'Укажыце асноўную спасылку на скрыпт TorrServer', + settings_server_link_two: 'Дадатковая спасылка', + settings_server_link_two_descr: 'Укажыце дадатковую спасылку на скрыпт TorrServer', + settings_server_additionally: 'Дадаткова', + settings_server_client: 'Убудаваны кліент', + settings_server_client_descr: 'Выкарыстоўваць убудаваны JS-кліент TorrServer, інакш запускаецца сістэмны.', + settings_server_base: 'Захаваць у базу', + settings_server_base_descr: 'Торэнт будзе дададзены ў базу TorrServer', + settings_server_preload: 'Выкарыстоўваць буфер перад.загрузкі', + settings_server_preload_descr: 'Чакаць запаўнення буфера папярэдняй загрузкі TorrServer перад прайграваннем', + settings_server_auth: 'аўтарызацыя', + settings_server_password_use: 'Уваход па паролі', + settings_server_login: 'Лагін', + settings_server_password: 'Пароль', + settings_server_not_specified: 'Не паказаны', + settings_server_search_type: 'Тып пошуку', + settings_server_search_type_descr: 'Дзе шукаць тарэнты: убудаваны rutor, Torznab-індэксары ў TorrServer, або абодва крыніцы.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + settings_server_not_specified: 'Не паказаны', + + + torent_nohash_reasons: 'Прычыны', + torent_nohash_reason_one: 'TorServer не змог спампаваць торэнт файл', + torent_nohash_reason_two: 'Адказ ад TorServer', + torent_nohash_reason_three: 'Спасылка', + torent_nohash_do: 'Што рабіць?', + torent_nohash_do_one: 'Праверце ці правільна вы наладзілі Jackett', + torent_nohash_do_two: 'Прыватныя крыніцы могуць не выдаваць спасылку на файл', + torent_nohash_do_three: 'Пераканайцеся, што Jackett таксама можа спампаваць файл', + torent_nohash_do_four: 'Напісаць у нашу тэлеграм групу: @lampa_group', + torent_nohash_do_five: 'Пакажыце які фільм, якая раздача і па магчымасці фота гэтай раздачы', + + torrent_error_text: 'Немагчыма падлучыцца да TorrServer. Давайце хутка пройдземся па спісе магчымых праблем і ўсё праверым.', + torrent_error_step_1: 'Ці запушчаны TorrServer', + torrent_error_step_2: 'Дынамічны IP-адрас', + torrent_error_step_3: 'Пратакол і порт', + torrent_error_step_4: 'Блакіроўка антывірусамі', + torrent_error_step_5: 'Праверце на даступнасць', + torrent_error_step_6: 'Усё роўна не працуе', + torrent_error_info_1: 'Упэўніцеся, што вы запусцілі TorrServer на прыладзе, дзе ён усталяваны.', + torrent_error_info_2: 'Частая памылка, змяніўся IP-адрас прылады з TorrServer. Упэўніцеся, што IP-адрас, які вы ўвялі - {ip}, супадае з адрасам прылады, на якім усталяваны TorrServer.', + torrent_error_info_3: 'Для падключэння да TorrServer, неабходна пазначыць пратакол http:// у пачатку і порт :8090 у канцы адрасу. Пераканайцеся, што пасля IP-адрасы паказаны порт, ваш бягучы адрас - {ip}', + torrent_error_info_4: 'Частая з\'ява, антывірус ці брандмаўэр можа блакаваць доступ па IP-адрасу, паспрабуйце адключыць антывірус і брандмаўэр.', + torrent_error_info_5: 'На любой іншай прыладзе ў гэтай жа сетцы, адкрыйце ў браўзэры адрас {ip} і праверце, ці даступны вэб-інтэрфейс TorrServer.', + torrent_error_info_6: 'Калі пасля ўсіх праверак усё роўна ўзнікае памылка падлучэння, паспрабуйце перазагрузіць TorrServer і інтэрнэт-адаптар.', + torrent_error_info_7: 'Калі праблема не ўхіленая, пішыце ў Telegram-групу @lampa_group з тэкстам (Lampa не падлучаецца да TorrServer пасля ўсіх праверак, бягучы адрас {ip})', + torrent_error_start: 'Пачаць праверку', + torrent_error_nomatrix: 'Не атрымалася пацвердзіць версію Matrix', + torrent_error_made: 'Выканана', + torrent_error_from: 'з', + torrent_error_next: 'Далей', + torrent_error_complite: 'Завяршыць', + torrent_error_connect: 'Памылка падключэння', + + torrent_install_need: 'Неабходны TorrServer', + torrent_install_text: 'TorrServer – дадатак, якое дазваляе праглядаць кантэнт з торэнт-файлаў у анлайн рэжыме.

    Больш дэталёвую інфармацыю па ўстаноўцы вы знойдзеце ў Telegram-групах, указаных ніжэй.', + torrent_install_contact: 'Telegram-групы', + + torrent_item_bitrate: 'Бітрэйт', + torrent_item_seeds: 'Раздаюць', + torrent_item_grabs: 'пампуюць', + torrent_item_mb: 'Мбіт/с', + + torrent_serial_episode: 'Серыя', + torrent_serial_season: 'Сезон', + torrent_serial_date: 'Выхад', + + torrent_get_magnet: 'Запытваю magnet спасылку', + torrent_remove_title: 'Выдаліць', + torrent_remove_descr: 'Торэнт будзе выдалены з вашага спісу', + + torrent_parser_any_one: 'Любое', + torrent_parser_any_two: 'Любы', + torrent_parser_no_choice: 'Не абрана', + torrent_parser_yes: 'Так', + torrent_parser_no: 'Не', + torrent_parser_quality: 'Якасць', + torrent_parser_subs: 'Субтытры', + torrent_parser_voice: 'Пераклад', + torrent_parser_tracker: 'Трэкер', + torrent_parser_year: 'Год', + torrent_parser_season: 'Сезон', + torrent_parser_sort_by_seeders: 'Па раздавальных', + torrent_parser_sort_by_size: 'Па памеры', + torrent_parser_sort_by_name: 'Па назве', + torrent_parser_sort_by_tracker: 'Па крыніцы', + torrent_parser_sort_by_date: 'Па даце', + torrent_parser_sort_by_viewed: 'Па прагледжаным', + torrent_parser_voice_dubbing: 'Дубляж', + torrent_parser_voice_polyphonic: 'Шматгалосы', + torrent_parser_voice_two: 'Двухгалосы', + torrent_parser_voice_amateur: 'Любіцельскі', + torrent_parser_reset: 'Скінуць фільтр', + torrent_parser_empty: 'Немагчыма атрымаць вынікаў', + torrent_parser_no_hash: 'Не атрымалася атрымаць HASH, паспрабуйце перезагрузить TorrServer', + torrent_parser_added_to_mytorrents: 'дададзена ў «Мае торэнты»', + torrent_parser_add_to_mytorrents: 'Дадаць у «Мае торэнты»', + torrent_parser_label_title: 'Пазначыць', + torrent_parser_label_descr: 'Пазначыць раздачу са сцягам (прагледжана)', + torrent_parser_label_cancel_title: 'Зняць адзнаку', + torrent_parser_label_cancel_descr: 'Зняць адзнаку з раздачы (прагледжана)', + torrent_parser_timeout: 'Час чакання скончыўся', + torrent_parser_nofiles: 'Немагчыма атрымаць патрэбныя файлы', + torrent_parser_set_link: 'Пазначце спасылку для парсінгу', + torrent_parser_request_error: 'Памылка ў запыце', + torrent_parser_magnet_error: 'Не ўдалося атрымаць magnet спасылку', + torrent_parser_no_responce: 'Парсер не адказвае на запыт', + torrent_parser_torlook_fallback_search_notification: 'Парсэр Jackett не даступны або налады падлучэння не дакладныя. Ажыццяўляецца пошук у Torlook...', + + about_text: 'Дадатак цалкам бясплатны і выкарыстоўвае публічныя спасылкі для атрымання інфармацыі пра відэа, навінкі, папулярныя фільмы і г.д. Уся даступная інфармацыя выкарыстоўваецца выключна ў пазнавальных мэтах, прыкладанне не выкарыстоўвае свае ўласныя серверы для распаўсюджвання інфармацыі.', + about_channel: 'Наш канал', + about_group: 'Група', + about_version: 'Версія', + about_donate: 'Данат', + + title_watched: 'Вы глядзелі', + title_settings: 'Налады', + title_collections: 'Падборкі', + title_company: 'Кампанія', + title_actors: 'Акцёры', + title_actor: 'Акцёр', + title_actress: 'Актрыса', + title_person: 'Персона', + title_persons: 'Персоны', + title_comments: 'Каментары', + title_torrents: 'Торэнты', + title_trailers: 'Трэйлеры', + title_watch: 'Глядзець', + title_error: 'Памылка', + title_links: 'Спасылкі', + title_choice: 'Выбраць', + title_main: 'Галоўная', + title_book: 'Закладкі', + title_like: 'Падабаецца', + title_wath: 'Пазней', + title_history: 'Гісторыя праглядаў', + title_mytorrents: 'Мае торэнты', + title_last: 'Апошняя', + title_action: 'Дзеянне', + title_action_infuse: 'Дзеянне Infuse', + title_producer: 'Рэжысёр', + title_collection: 'Калекцыя', + title_recomendations: 'Рэкамендацыі', + title_similar: 'Падобныя', + title_about: 'Пра прыкладанне', + title_timetable: 'Расклад', + title_relises: 'Лічбавыя рэлізы', + title_catalog: 'Каталог', + title_category: 'Катэгорыя', + title_parser: 'Парсер', + title_type: 'Тып', + title_rating: 'Рэйтынг', + title_country: 'Краіна', + title_year: 'Год', + title_genre: 'Жанр', + title_filter: 'Фільтр', + title_notice: 'Апавяшчэнні', + title_files: 'Файлы', + title_now_watch: 'Глядзяць зараз', + title_latest: 'Апошняе даданне', + title_continue: 'Працягнуць прагляд', + title_recomend_watch: 'Рэкамендуем паглядзець', + title_new_episodes: 'Новыя серыі', + title_popular: 'Папулярнае', + title_popular_movie: 'Папулярныя фільмы', + title_popular_tv: 'Папулярныя серыялы', + title_new_this_year: 'Навінкі гэтага года', + title_hight_voite: 'З высокім рэйтынгам', + title_new: 'Навінкі', + title_trend_day: 'Сёння ў трэндзе', + title_trend_week: 'У трэндзе за тыдзень', + title_upcoming: 'Глядзіце ў кіназалах', + title_top_movie: 'Топ фільмы', + title_top_tv: 'Топ серыялы', + title_tv_today: 'Сёння ў эфіры', + title_this_week: 'На гэтым тыдні', + title_in_top: 'У топе', + title_out: 'Выхад', + title_out_confirm: 'Так, выйсці', + title_continue_two: 'Працягнуць', + title_choice_language: 'Выберыце мову', + title_subscribe: 'Падпісацца', + title_subscribes: 'Падпіскі', + title_unsubscribe: 'Адпісацца', + title_language: 'Арыгінальная мова', + + subscribe_success: 'Вы паспяхова падпісаліся', + subscribe_error: 'Узнікла памылка пры падпісцы, паспрабуйце пазней', + subscribe_noinfo: 'Не ўдалося атрымаць інфармацыю, паспрабуйце пазней', + + company_headquarters: 'Штаб', + company_homepage: 'Сайт', + company_country: 'Краіна', + + country_ad: 'Андора', + country_ae: 'ААЭ', + country_af: 'Афганістан', + country_al: 'Албанія', + country_am: 'Арменія', + country_ao: 'Ангола', + country_ar: 'Аргенціна', + country_at: 'Аўстрыя', + country_au: 'Аўстралія', + country_aw: 'Аруба', + country_az: 'Азербайджан', + country_bа: 'Боснія і Герцагавіна', + country_bd: 'Бангладэш', + country_be: 'Бельгія', + country_bg: 'Балгарыя', + country_bh: 'Бахрэйн', + country_bi: 'Бурунды', + country_bj: 'Бенін', + country_bo: 'Балівія', + country_br: 'Бразілія', + country_bs: 'Багамскія а-вы', + country_bt: 'Бутан', + country_bw: 'Батсвана', + country_by: 'Беларусь', + country_ca: 'Канада', + country_ch: 'Швейцарыя', + country_cl: 'Чылі', + country_cm: 'Камерун', + country_cn: 'Кітай', + country_co: 'Калумбія', + country_cr: 'Коста-Рыка', + country_cu: 'Куба', + country_cv: 'Каба-Вэрдэ', + country_cy: 'Кіпр', + country_cz: 'Чэхія', + country_de: 'Германія', + country_dj: 'Джыбуці', + country_dk: 'Данія', + country_do: 'Дамінікана', + country_dz: 'Алжыр', + country_ec: 'Эквадор', + country_ee: 'Эстонія', + country_eg: 'Егіпет', + country_es: 'Іспанія', + country_et: 'Эфіопія', + country_fi: 'Фінляндыя', + country_fo: 'Фарэрскія а-вы', + country_fr: 'Францыя', + country_ga: 'Габон', + country_gb: 'Вялікабрытанія', + country_ge: 'Грузія', + country_gh: 'Гана', + country_gl: 'Грэнландыя', + country_gp: 'Гвадэлупа', + country_gr: 'Грэцыя', + country_gt: 'Гватэмала', + country_hk: 'Ганконг', + country_hr: 'Харватыя', + country_ht: 'Гаіці', + country_hu: 'Венгрыя', + country_id: 'Інданезія', + country_ie: 'Ірландыя', + country_il: 'Ізраіль', + country_in: 'Індыя', + country_iq: 'Ірак', + country_ir: 'Іран', + country_is: 'Ісландыя', + country_it: 'Італія', + country_jm: 'Ямайка', + country_jo: 'Іарданія', + country_jp: 'Японія', + country_ke: 'Кенія', + country_kg: 'Кіргізія', + country_kh: 'Камбоджа', + country_kp: 'Паўночная Карэя', + country_kr: 'Паўднёвая Карэя', + country_kz: 'Казахстан', + country_kw: 'Кувейт', + country_la: 'Лаос', + country_lb: 'Ліван', + country_li: 'Ліхтэнштэйн', + country_lk: 'Шры-Ланка', + country_lr: 'Ліберыя', + country_lt: 'Літва', + country_lu: 'Люксембург', + country_lv: 'Латвія', + country_ly: 'Лівія', + country_ma: 'Марока', + country_mc: 'Манака', + country_md: 'Малдова', + country_me: 'Чарнагорыя', + country_mk: 'Македонія', + country_mm: 'М\'янма', + country_mn: 'Манголія', + country_mo: 'Макаа', + country_mt: 'Мальта', + country_mu: 'Маўрыкій', + country_mv: 'Мальдывы', + country_mw: 'Малаві', + country_mx: 'Мексіка', + country_my: 'Малайзія', + country_mz: 'Мазамбік', + country_na: 'Намібія', + country_ne: 'Нігер', + country_ng: 'Нігерыя', + country_ni: 'Нікарагуа', + country_nl: 'Нідэрланды', + country_no: 'Нарвегія', + country_np: 'Непал', + country_nz: 'Новая Зеландыя', + country_om: 'Аман', + country_pa: 'Панама', + country_pe: 'Пяру', + country_pg: 'Папуа - Новая Гвінея', + country_ph: 'Філіпіны', + country_pk: 'Пакістан', + country_pl: 'Польшча', + country_pr: 'Пуэрта-Рыка', + country_ps: 'Палестына', + country_pt: 'Партугалія', + country_py: 'Парагвай', + country_qa: 'Катар', + country_ro: 'Румынія', + country_rs: 'Сербія', + country_ru: 'Расія', + country_rw: 'Руанда', + country_sa: 'Саудаўская Аравія', + country_sd: 'Судан', + country_se: 'Швецыя', + country_sg: 'Сінгапур', + country_si: 'Славенія', + country_sk: 'Славакія', + country_sn: 'Сенегал', + country_su: 'СССР', + country_sv: 'Сальвадор', + country_sy: 'Сірыя', + country_th: 'Тайланд', + country_tj: 'Таджыкістан', + country_tm: 'Туркменістан', + country_tn: 'Туніс', + country_tr: 'Турцыя', + country_tw: 'Тайвань', + country_tz: 'Танзанія', + country_ua: 'Украіна', + country_ug: 'Уганда', + country_us: 'ЗША', + country_uy: 'Уругвай', + country_uz: 'Узбекістан', + country_ve: 'Венесуэла', + country_vn: 'В\'етнам', + country_ws: 'Самаа', + country_xk: 'Косава', + country_ye: 'Емен', + country_yu: 'Югаславія', + country_za: 'ПАР', + country_zm: 'Замбія', + country_zw: 'Зімбабвэ', + + filter_clarify: 'Удакладніць', + filter_clarify_two: 'Удакладніць пошук', + filter_set_name: 'Указаць назву', + filter_sorted: 'Сартаваць', + filter_filtred: 'Фільтр', + filter_any: 'Любы', + filter_combinations: 'Камбінацыі', + filter_alt_names: 'Іншыя назвы', + filter_rating_from: 'ад', + filter_rating_to: 'да', + + filter_lang_af: 'Афрыкаанс', + filter_lang_ar: 'Арабская', + filter_lang_az: 'Азербайджанская', + filter_lang_ba: 'Башкірская', + filter_lang_be: 'Беларуская', + filter_lang_bg: 'Балгарская', + filter_lang_bn: 'Бенгальская', + filter_lang_bs: 'Баснійская', + filter_lang_ca: 'Каталанская', + filter_lang_ce: 'Чачэнская', + filter_lang_cs: 'Чэшская', + filter_lang_da: 'Дацкая', + filter_lang_de: 'Нямецкая', + filter_lang_el: 'Грэчаская', + filter_lang_en: 'Англійская', + filter_lang_es: 'Іспанская', + filter_lang_et: 'Эстонская', + filter_lang_fa: 'Персідская', + filter_lang_fi: 'Фінская', + filter_lang_fr: 'Французская', + filter_lang_ga: 'Ірландская', + filter_lang_gl: 'Галісійская', + filter_lang_gn: 'Гуарані', + filter_lang_he: 'Іўрыт', + filter_lang_hi: 'Хіндзі', + filter_lang_hr: 'Харвацкая', + filter_lang_hu: 'Венгерская', + filter_lang_hy: 'Армянская', + filter_lang_id: 'Інданезійская', + filter_lang_is: 'Ісландская', + filter_lang_it: 'Італьянская', + filter_lang_ja: 'Японская', + filter_lang_ka: 'Грузінская', + filter_lang_kk: 'Казахская', + filter_lang_ko: 'Карэйская', + filter_lang_ks: 'Кашміры', + filter_lang_ku: 'Курдская', + filter_lang_ky: 'Кіргізская', + filter_lang_lt: 'Літоўская', + filter_lang_lv: 'Латышская', + filter_lang_mi: 'Маоры', + filter_lang_mk: 'Македонская', + filter_lang_mn: 'Мангольская', + filter_lang_mt: 'Мальтыйская', + filter_lang_ne: 'Непальская', + filter_lang_nl: 'Нідэрландская', + filter_lang_no: 'Нарвежская', + filter_lang_pa: 'Панджабі', + filter_lang_pl: 'Польская', + filter_lang_ps: 'Пушту', + filter_lang_pt: 'Партугальская', + filter_lang_ro: 'Румынская', + filter_lang_ru: 'Руская', + filter_lang_si: 'Сінгальская', + filter_lang_sk: 'Славацкі', + filter_lang_sl: 'Славенская', + filter_lang_sm: 'Самаанская', + filter_lang_so: 'Самалійская', + filter_lang_sq: 'Албанская', + filter_lang_sr: 'Сербская', + filter_lang_sv: 'Шведская', + filter_lang_sw: 'Суахілі', + filter_lang_ta: 'Тамільская', + filter_lang_tg: 'Таджыкская', + filter_lang_th: 'Тайская', + filter_lang_tk: 'Туркменская', + filter_lang_tr: 'Турэцкая', + filter_lang_tt: 'Татарская', + filter_lang_ur: 'Урду', + filter_lang_uk: 'Украінская', + filter_lang_uz: 'Узбекская', + filter_lang_vi: 'В\'етнамская', + filter_lang_yi: 'Ідыш', + filter_lang_zh: 'Кітайская', + + filter_genre_ac: 'Баявік', + filter_genre_ad: 'Прыгоды', + filter_genre_mv: 'Мультфільм', + filter_genre_cm: 'Камедыя', + filter_genre_cr: 'Крымінал', + filter_genre_dc: 'Дакументальны', + filter_genre_dr: 'Драма', + filter_genre_fm: 'Сямейны', + filter_genre_fe: 'Фэнтэзі', + filter_genre_hi: 'Гісторыя', + filter_genre_ho: 'Жахі', + filter_genre_mu: 'Музыка', + filter_genre_de: 'Дэтэктыў', + filter_genre_md: 'Меладрама', + filter_genre_fa: 'Фантастыка', + filter_genre_tv: 'Тэлевізійны фільм', + filter_genre_tr: 'Трылер', + filter_genre_mi: 'Ваенны', + filter_genre_ve: 'Вэстэрн', + filter_genre_aa: 'Баявік і Прыгоды', + filter_genre_ch: 'Дзіцячы', + filter_genre_nw: 'Навіны', + filter_genre_rs: 'Рэаліці-шоў', + filter_genre_hf: 'НФ і Фэнтэзі', + filter_genre_op: 'Мыльная опера', + filter_genre_tc: 'Ток-шоу', + filter_genre_mp: 'Вайна і Палітыка', + + empty_title: 'Пуста', + empty_text: 'Па вашым фільтры нічога не знайшлося, удакладніце фільтр.', + empty_title_two: 'Тут пуста', + empty_text_two: 'На дадзены момант спіс пусты', + + menu_main: 'Галоўная', + menu_movies: 'Фільмы', + menu_tv: 'Серыялы', + menu_catalog: 'Каталог', + menu_filter: 'Фільтр', + menu_collections: 'Падборкі', + menu_relises: 'Рэлізы', + menu_anime: 'Анімэ', + menu_bookmark: 'Закладкі', + menu_like: 'Падабаецца', + menu_time: 'Пазней', + menu_history: 'Гісторыя', + menu_timeline: 'Расклад', + menu_torrents: 'Торэнты', + menu_settings: 'Налады', + menu_about: 'Інфармацыя', + menu_console: 'Кансоль', + menu_multmovie: 'Мультфільмы', + menu_multtv: 'Мультсерыялы', + menu_feed: 'Стужка', + lampa_movie_title: 'Лямпавае кіно', + lampa_movie_descr: 'Сачыце за навінкамі на сваім смартфоне.
    Тэлеграм: @lampa_movie', + + plugins_catalog_work: 'Працаздольныя плагіны', + plugins_catalog_work_descr: 'Плагіны, якія сапраўды працуюць у лямпе.', + plugins_catalog_popular: 'Папулярныя плагіны сярод карыстальнікаў', + plugins_catalog_popular_descr: 'Усталяванне з невядомых крыніц можа прывесці да некарэктнай працы прыкладання.', + plugins_online: 'Прагляд анлайн', + plugins_check_fail: 'Немагчыма праверыць працаздольнасць плагіна. Аднак гэта не азначае, што плягін не працуе. Перазагрузіце прыкладанне для высвятлення, ці загружаецца плягін.', + plugins_need_reload: 'Для прымянення плагіна неабходна перазагрузіць дадатак', + plugins_install: 'Усталяваць', + plugins_install_ready: 'Гэты плагін ужо ўсталяваны.', + plugins_installed: 'Усталёвак', + plugins_load_from: 'Загружана з CUB', + plugins_ok_for_check: 'Націсніце (OK) для праверкі плагіна', + plugins_no_loaded: 'Пры загрузцы прыкладання, частка плагінаў не атрымалася загрузіць', + + time_viewed: 'Прагледжана', + time_from: 'з', + time_reset: 'Скінуць тайм-код', + + settings_clear_cache: 'Кэш і дадзеныя ачышчаны', + settings_user_links: 'Карыстацкая спасылка', + settings_for_local: 'Для лакальнага TorrServer', + settings_add: 'Дадаць', + settings_remove: 'Выдаліць', + settings_this_value: 'бягучае значэнне', + settings_added: 'Дададзена', + settings_removed: 'Выдалена', + + settings_param_player_inner: 'Убудаваны', + settings_param_player_outside: 'Вонкавы', + settings_param_player_inner_tvos: 'Внутршній', + settings_param_yes: 'Так', + settings_param_no: 'Не', + settings_param_interface_size_small: 'Менш', + settings_param_interface_size_normal: 'Нармальны', + settings_param_interface_size_bigger: 'Больш', + settings_param_poster_quality_low: 'Нізкае', + settings_param_poster_quality_average: 'Сярэдняе', + settings_param_poster_quality_high: 'Высокае', + settings_param_parse_directly: 'Напрамую', + settings_param_parse_api: 'Праз API сайта', + settings_param_background_complex: 'Складаны', + settings_param_background_simple: 'Просты', + settings_param_background_image: 'Малюнак', + settings_param_link_use_one: 'Асноўную', + settings_param_link_use_two: 'Дадатковую', + settings_param_link_use_both: 'Абедзве', + settings_param_subtitles_size_small: 'Маленькія', + settings_param_subtitles_size_normal: 'Звычайныя', + settings_param_subtitles_size_bigger: 'Вялікія', + settings_param_screensaver_nature: 'Прырода', + settings_param_torrent_lang_orig: 'Арыгінал', + settings_param_torrent_lang_ru: 'Рускі', + settings_param_player_timecode_again: 'Пачаць з пачатку', + settings_param_player_timecode_continue: 'Працягнуць', + settings_param_player_timecode_ask: 'Пытаць', + settings_param_player_scale_method: 'Разлічыць', + settings_param_player_hls_app: 'Сістэмны', + settings_param_player_hls_js: 'Праграмны', + settings_param_card_view_load: 'Падгружаць', + settings_param_card_view_all: 'Паказаць усё', + settings_param_navigation_remote: 'Пульт', + settings_param_navigation_mouse: 'Пульт з мышкай', + settings_param_keyboard_lampa: 'Убудаваная', + settings_param_keyboard_system: 'Сістэмная', + + helper_keyboard: 'Пасля ўводу значэння націсніце кнопку "Назад" для захавання', + helper_torrents: 'Утрымлівайце клавішу (ОК) для выкліку кантэкстнага меню', + helper_cleared: 'Паспяхова, падказкі будуць паказаны нанава.', + helper_torrents_view: 'Для скіду тайм-кода і выкліку меню ўтрымлівайце клавішу (ОК)', + + fav_sync_title: 'Сінхранізацыя закладак', + fav_sync_text: 'Вашыя любімыя закладкі разам з Вамі. Падлучыце сінхранізацыю і праглядайце на любой прыладзе.

    Для гэтага зарэгіструйцеся на сайце {site}, стварыце профіль і аўтарызуйцеся ў дадатак.', + fav_sync_site: 'Сайт', + fav_remove_title: 'Выдаліць з гісторыі', + fav_remove_descr: 'Выдаліць выдзеленую картку', + fav_clear_title: 'Ачысціць гісторыю', + fav_clear_descr: 'Выдаліць усе карткі з гісторыі', + fav_clear_label_title: 'Ачысціць пазнакі', + fav_clear_label_descr: 'Ачысціць пазнакі аб праглядах', + fav_clear_time_title: 'Ачысціць тайм-коды', + fav_clear_time_descr: 'Ачысціць усе тайм-коды', + fav_label_cleared: 'Пазнакі ачышчаны', + fav_time_cleared: 'Тайм-коды ачышчаны', + + timetable_empty: 'У гэтым раздзеле будуць адлюстроўвацца даты выхаду новых серый', + + player_quality: 'Якасць', + player_flow: 'Струмень', + player_tracks: 'Аўдыёдарожкі', + player_disabled: 'Адключана', + player_unknown: 'Невядома', + player_subs: 'Субтытры', + player_size_default_title: 'Па змаўчанні', + player_size_default_descr: 'Памер відэа па змаўчанні', + player_size_cover_title: 'Пашырыць', + player_size_cover_descr: 'Пашырае відэа на ўвесь экран', + player_size_fill_title: 'Запоўніць', + player_size_fill_descr: 'Змясціць відэа на ўвесь экран', + player_size_s115_title: 'Павялічыць 115%', + player_size_s115_descr: 'Павялічыць відэа на 115%', + player_size_s130_title: 'Павялічыць 130%', + player_size_s130_descr: 'Павялічыць відэа на 130%', + player_size_v115_title: 'Па вертыкалі 115%', + player_size_v115_descr: 'Павялічыць відэа на 115%', + player_size_v130_title: 'Па вертыкалі 130%', + player_size_v130_descr: 'Павялічыць відэа на 130%', + player_video_size: 'Памер відэа', + player_playlist: 'Плэйліст', + player_error_one: 'Не атрымалася дэкадаваць відэа', + player_error_two: 'Відэа не знойдзена ці пашкоджана', + player_start_from: 'Працягнуць прагляд з', + player_not_found: 'Плэер не знойдзены', + player_lauch: 'Запусціць плэер', + player_speed_default_title: 'Звычайная', + player_speed_two_descr: 'Прайграваць без гуку', + player_video_speed: 'Хуткасць прайгравання', + player_share_title: 'Падзеліцца', + player_share_descr: 'Запусціць гэтае відэа на іншай прыладзе', + player_normalization_power_title: 'Сіла нармалізацыі', + player_normalization_smooth_title: 'Хуткасць нармалізацыі', + player_normalization_step_low: 'Нізкае', + player_normalization_step_medium: 'Сярэдняе', + player_normalization_step_hight: 'Высокае', + player_youtube_no_played: 'Нажаль, гэта відэа не даступна ў вашым рэгіёне, магчыма, яно было заблакавана ці выдаленае.', + player_youtube_start_play: 'Для пачатку прайгравання відэа, націсніце кнопку "Плэй"', + + broadcast_open: 'Адкрыць картку на іншай прыладзе', + broadcast_play: 'Абярыце прыладу на якой глядзець', + + card_new_episode: 'Новая серыя', + card_book_remove: 'Прыбраць з закладак', + card_book_add: 'У закладкі', + card_book_descr: 'Глядзіце ў меню (Закладкі)', + card_like_remove: 'Прыбраць з упадабаных', + card_like_add: 'Падабаецца', + card_like_descr: 'Глядзіце ў меню (Падабаецца)', + card_wath_remove: 'Прыбраць з чаканых', + card_wath_add: 'Глядзець пазней', + card_wath_descr: 'Глядзіце ў меню (Пазлей)', + card_history_remove: 'Прыбраць з гісторыі', + card_history_add: 'У гісторыю', + card_history_descr: 'Глядзіце ў меню (Гісторыя)', + + keyboard_listen: 'Гаварыце, я слухаю...', + keyboard_nomic: 'Няма доступу да мікрафона', + + notice_new_quality: 'Даступна новая якасць', + notice_quality: 'Якасць', + notice_new_episode: 'Новая серыя', + notice_none: 'У вас яшчэ няма ніякіх апавяшчэнняў, зарэгіструйцеся на сайце {site}, каб сачыць за новымі серыямі і рэлізамі.', + notice_in_quality: 'У якасці', + + copy_link: 'Капіяваць спасылку на відэа', + copy_secuses: 'Спасылка скапіявана ў буфер абмену', + copy_error: 'Памылка пры капіраванні спасылкі', + + account_sync_to_profile: 'Усе закладкі будуць перанесеныя ў профіль', + account_sync_secuses: 'Усе закладкі паспяхова перанесены', + account_profiles: 'Профілі', + account_profiles_empty: 'Немагчыма атрымаць спіс профіляў', + account_authorized: 'Аўтарызаваны', + account_logged_in: 'Вы ўвайшлі пад акаўнтам', + account_login_failed: 'Уваход не выкананы', + account_login_wait: 'Чакаем уваходу ў акаўнт', + account_profile_main: 'агульны', + account_export_secuses: 'Экспарт паспяхова завершаны', + account_export_fail: 'Памылка пры экспарце', + account_import_secuses: 'Імпарт паспяхова завершаны', + account_import_fail: 'Памылка пры імпарце', + account_imported: 'імпартавана', + account_reload_after: 'перазагрузка праз 5 сек.', + account_create: 'Адкрыйце больш магчымасцяў з акаўнтам CUB. Зарэгіструйцеся на сайце і атрымайце доступ да сінхранізацыі вашых закладак, тайм-кодаў і іншых магчымасцяў акаўнта CUB.', + account_premium: 'Раскрыйце новыя гарызонты з акаўнтам CUB Premium! Атрымлівайце асалоду ад павялічанымі лімітамі і ўзбагачаным функцыяналам сэрвісу. Перайдзіце на сайт і даведайцеся больш пра перавагі прэміум акаўнта.', + account_premium_more: 'Больш падрабязна пра CUB Premium', + account_limited: 'Вы дасягнулі максімальнага ліміту. Павялічце ліміт з акаўнтам CUB Premium. Падрабязней на сайце ', + account_premium_include_1: 'Павелічэнне колькасць закладак', + account_premium_include_2: 'Павелічэнне гісторыі праглядаў', + account_premium_include_3: 'Павелічэнне колькасць тайм-кодаў', + account_premium_include_4: 'Колькасць профіляў на рахунак', + account_premium_include_5: 'Апавяшчэнні', + account_premium_include_6: 'Сінхранізацыя дадзеных', + account_premium_include_text_1: 'Больш закладак - больш магчымасцяў! Захоўвайце свае любімыя фільмы і серыялы, стварайце спісы прагляду і атрымлівайце асалоду ад прагляду ў любы зручны час.', + account_premium_include_text_2: 'Павялічце гісторыю праглядаў у дадатку і сачыце за тым, што ўжо паглядзелі. Лёгка знаходзіце і пераглядайце свае любімыя фільмы і серыялы.', + account_premium_include_text_3: 'Не бойцеся прапусціць ніводнай важнай сцэны! Павялічце колькасць тайм-кодаў у дадатку і лёгка адсочвайце, дзе спыніліся ў праглядзе любімых фільмаў і серыялаў.', + account_premium_include_text_4: 'Атрымайце больш свабоды з нашым прэміум доступам! Павялічце колькасць профіляў на акаўнце і дазвольце сваім сябрам і блізкім атрымліваць асалоду ад фільмамі і серыяламі разам з вамі. Ніякіх абмежаванняў - атрымлівайце асалоду ад прагляду з каханымі людзьмі.', + account_premium_include_text_5: 'Не прапусціце ніводнай новай серыі або перакладу! Атрымлівайце апавяшчэння своечасова і будзьце ў курсе ўсіх абнаўленняў. Павялічце свой кінаструмень разам з намі і атрымлівайце апавяшчэнні аб выхадзе новых серый і перакладаў прама на свой смартфон.', + account_premium_include_text_6: 'Сінхранізуйце свае дадзеныя паміж прыладамі з прэміум доступам! Больш не трэба марнаваць час на пошук апошняга эпізоду, на якім вы спыніліся. З нашым прэміум доступам вы можаце сінхранізаваць свае дадзеныя паміж прыладамі, каб працягваць прагляд з месца, дзе вы спыніліся, на любой прыладзе, дзе ўстаноўлена прыкладанне.', + + account_code_enter: 'Калі ласка, увядзіце шэсцізначны код', + account_code_error: 'Магчыма, вы ўвялі няправільны ці старэлы код', + account_code_wrong: 'Магчыма, вы ўказалі няправільны фармат', + account_code_where: 'Перайдзіце на сайт і ўвядзіце там указаны код.', + account_code_input: 'Увесці код', + settings_cub_signin_button: 'Увайсці', + + network_noconnect: 'Няма падлучэння да сеткі', + network_404: 'Запытаная старонка не знойдзена. [404]', + network_401: 'Аўтарызацыя не ўдалася', + network_500: 'Унутраная памылка сервера. [500]', + network_parsererror: 'Запытаны сінтаксічны аналіз JSON завяршыўся няўдала.', + network_timeout: 'Час запыту скончыўся.', + network_abort: 'Запыт быў перарваны.', + network_error: 'Невядомая памылка', + + size_zero: '0 Байт', + size_byte: 'Байт', + size_kb: 'КБ', + size_mb: 'МБ', + size_gb: 'ГБ', + size_tb: 'ТБ', + size_pp: 'ПБ', + + speed_bit: 'біт/c', + speed_kb: 'Кбіт/c', + speed_mb: 'Мбіт/c', + speed_gb: 'Гбіт/c', + speed_tb: 'Тбіт/c', + speed_pp: 'Пбіт/c', + + month_1: 'Студзень', + month_2: 'Люты', + month_3: 'Сакавік', + month_4: 'Красавік', + month_5: 'Май', + month_6: 'Чэрвень', + month_7: 'Ліпень', + month_8: 'Жнівень', + month_9: 'Верасень', + month_10: 'Кастрычнік', + month_11: 'Лістапад', + month_12: 'Снежань', + + day_1: 'Панядзелак', + day_2: 'Аўторак', + day_3: 'Серада', + day_4: 'Чацвер', + day_5: 'Пятніца', + day_6: 'Субота', + day_7: 'Нядзеля', + + month_1_e: 'Студзеня', + month_2_e: 'Лютага', + month_3_e: 'Сакавіка', + month_4_e: 'Красавіка', + month_5_e: 'Мая', + month_6_e: 'Чэрвеня', + month_7_e: 'Ліпеня', + month_8_e: 'Жніўня', + month_9_e: 'Верасня', + month_10_e: 'Кастрычніка', + month_11_e: 'Лістапада', + month_12_e: 'Снежня', + + week_1: 'Пн', + week_2: 'Аў', + week_3: 'Ср', + week_4: 'Чц', + week_5: 'Пт', + week_6: 'Сб', + week_7: 'Нд', + + notice_none_account: 'У вас яшчэ няма ніякіх апавяшчэнняў, дадайце серыялы ў закладкі і чакайце апавяшчэння аб новых серыях.', + notice_none_system: 'На дадзены момант у вас адсутнічаюць апавяшчэння. Мы абавязкова апавясцім вас, калі з\'явяцца новыя апавяшчэнні.', + + extensions_enable: 'Уключыць', + extensions_disable: 'Адключыць', + extensions_check: 'Праверыць статус', + extensions_install: 'Усталяваць', + extensions_info: 'Інфармацыя', + extensions_edit: 'рэдагаваць', + extensions_change_name: 'Змяніць назву', + extensions_change_link: 'Змяніць спасылку', + extensions_remove: 'Выдаліць', + extensions_set_name: 'Увядзіце назву плагіна', + extensions_set_url: 'Увядзіце адрас плагіна', + extensions_ready: 'Гэты плагін ужо ўсталяваны', + extensions_no_info: 'Без інфармацыі', + extensions_no_name: 'Без назвы', + extensions_worked: 'Працаздольны', + extensions_no_plugin: 'Плагін не пацверджаны ', + extensions_add: 'Дадаць плагін', + extensions_from_memory: 'Устаноўленыя ў памяць ', + extensions_from_cub: 'Устаноўленыя з CUB', + extensions_from_popular: 'Папулярныя плагіны', + extensions_from_lib: 'Бібліятэка плагінаў', + extensions_from_connected: 'Падлучаныя плагіны', + + settings_webos_launcher: 'Запуск прыкладання', + settings_webos_launcher_add_device: 'Усталяваць як стартавае', + settings_webos_launcher_remove_device: 'Прыбраць са стартавых прыкладанняў', + player_normalization: 'Нармалізацыя', + change_source_on_cub: 'Змяніць крыніцу на CUB', + settings_param_jackett_interview_all: 'Усё', + settings_param_jackett_interview_healthy: 'Толькі даступныя', + settings_parser_jackett_interview: 'Апытваць трэкеры', + title_ongoing: 'Ангоінгі', + title_pgrating: 'Узроставае абмежаванне', + + settings_interface_card_interfice: 'Інтэрфейс картак', + settings_interface_card_poster: 'Паказаць постэр', + title_card: 'Картка', + settings_param_card_interface_old: 'Стары', + settings_param_card_interface_new: 'Новы', + title_seasons: 'Сезоны', + title_episodes: 'Серыі', + title_rewiews: 'Водгукі', + settings_interface_glass: 'Шкло', + settings_interface_glass_descr: 'Паказваць інтэрфейс у шклопадобным стылі', + settings_interface_black_style: 'Чорны стыль', + + plugins_remove: 'Выдаліць плагіны', + plugins_add_success: 'Убудова паспяхова падлучаны', + settings_reset: 'Скід налад', + title_channel: 'Канал', + + input_detection_touch: 'Жадаеце пераключыць на сэнсарнае кіраванне?', + input_detection_mouse: 'Жадаеце пераключыць на кіраванне мышшу?', + input_detection_remote: 'Жадаеце пераключыць на кіраванне пультам?', + + settings_interface_hide_outside_the_screen: 'Хаваць карткі за межамі экрана', + settings_interface_hide_outside_the_screen_descr: 'Гэта паскорыць рэндэр інтэрфейсу і палепшыць прадукцыйнасць', + + https_text: 'Вы выкарыстоўвайце HTTPS пратакол, у гэтым пратаколе лямпа працуе некарэктна. Для карэктнай працы лямпы, выкарыстоўвайце адрас з пратаколам HTTP', + + extensions_hpu_best: 'Папулярныя', + extensions_hpu_recomend: 'Рэкамендуем', + extensions_hpu_theme: 'Тэмы', + extensions_hpu_screensaver: 'Скрынсэйвер', + extensions_hpu_video: 'Відэа', + extensions_hpu_control: 'Упраўленне', + extensions_hpu_other: 'Рознае', + extensions_hpu_: 'Астатняе', + + title_author: 'Аўтар', + + title_buffer: 'Буфер', + settings_rest_screensaver_time: 'Праз колькі хвілін запусціць скрынсэйвер', + + time_h: 'г.', + time_m: 'х.', + time_s: 'с.', + + settings_param_glass_easy: 'Празрыстая', + settings_param_glass_medium: 'Напаўпразрыстая', + settings_param_glass_blacked: 'Зацемненая', + + settings_interface_glass_opacity: 'Празрыстасць шкла', + torrent_error_check_no_auth: 'Сервер адказаў на запыт, але не ўдалося прайсці аўтарызацыю', + settings_interface_card_cover: 'Паказаць вокладку', + + title_upcoming_episodes: 'Бліжэйшыя выхады эпізодаў', + title_recent_episodes: 'Нядаўнія выхады эпізодаў', + settings_rest_cache_images: 'Кэш малюнкаў', + settings_rest_cache_images_descr: 'Кэшаваць постэры і фоны ў лакальнае сховішча', + + settings_player_rewind_title: 'Перамотка', + settings_player_rewind_descr: 'Інтэрвал перамоткі ў секундах', + + settings_interface_card_reactions: 'Паказаць рэакцыі', + title_look: 'Гляджу', + title_scheduled: 'Запланавана', + title_viewed: 'Прагледжана', + title_thrown: 'Выбрасена', + title_reactions: 'Рэакцыі', + reactions_none: 'Няма рэакцый', + reactions_fire: 'Выдатна', + reactions_nice: 'Добра', + reactions_think: 'Цікава', + reactions_bore: 'Нудна', + reactions_shit: 'Пагана', + reactions_ready: 'Вы ўжо пакінулі рэакцыю', + settings_player_launch_trailers: 'Плэер для трэйлераў', + title_continued: 'Працяг будзе', + title_language_short: 'Мова', + + speedtest_connect: 'падлучэнне', + speedtest_test: 'тэставанне', + speedtest_ready: 'гатова', + speedtest_button: 'Тэставаць хуткасць', + + settings_rest_protocol_use: 'Бяспечнае злучэнне', + settings_rest_protocol_descr: 'Выкарыстоўваць пратакол HTTPS', + install_app_apk_title: 'Як усталяваць Lampa на Android', + install_app_apk_text: 'Мы заўважылі, што для запуску Lampa на Android вы карыстаецеся MediaStationX. Мы рэкамендуем вам усталяваць Lampa у выглядзе APK-прыкладанні. Гэта забяспечыць больш стабільную працу і доступ да ўсіх функцый прыкладання.

    Перайдзіце ў групу у Тэлеграме, каб спампаваць апошнюю версію APK і інструкцыі па ўстаноўцы.', + install_app_apk_qr: 'Адскануйце QR-код, каб спампаваць Lampa APK', + copy_link_buffer: 'Скапіяваць спасылку', + + tv_status_returning_series: 'Працягваецца', + tv_status_planned: 'Плануецца', + tv_status_in_production: 'У вырабніцтве', + tv_status_ended: 'Завершана', + tv_status_canceled: 'Скасавана', + tv_status_pilot: 'Пілотны', + + tv_status_released: 'Выпушчаны', + tv_status_rumored: 'Па слыхам', + tv_status_post_production: 'Хутка', + + full_keywords: 'Тэгі', + title_last_year: 'Мінулы год', + + title_reset: 'Перазагрузіць', + back_to_card: 'Вярнуцца ў картку', + + premiere_author_recomend_1: 'Замовіце піцу і падрыхтуйцеся да драйву.', + premiere_author_recomend_2: 'Вечарынка толькі пачынаецца.', + premiere_author_recomend_3: 'Прыгатуйцеся да адрэналіну.', + premiere_author_recomend_4: 'Гатовыя да нязабыўнага вечара?', + premiere_author_recomend_5: 'Я рэкамендую гэта праглядзець.', + premiere_title: 'Прем’ера', + + settings_clear_cache_only: 'Кеш ачышчаны', + settings_rest_cache_only: 'Толькі кеш', + settings_rest_cache_only_descr: 'Асноўныя налады застануцца', + settings_rest_cache_all: 'Кеш і дадзеныя', + settings_rest_cache_all_descr: 'Будуць ачышчаныя ўсе налады і дадзеныя', + settings_rest_cache_calculate: 'Колькі засталося памяці', + + title_left:'Засталося', + + account_export_fail_500: 'Невядомая памылка', + account_export_fail_610: 'Вы выйшлі за мяжу ліміту на сёння', + account_export_fail_200: 'Памылка базы даных, паспрабуйце пазней', + account_export_fail_600: 'Памылка, не атрымалася загрузіць файл', + account_export_fail_620: 'Памылка, файл не перададзены', + + title_parental_control: 'Кантроль бацькіў', + settings_parental_control_param_time_always: 'Заўсёды', + settings_parental_control_param_time_once: 'Адзін раз', + settings_parental_control_param_time_10: 'Праз 10 хвілін', + settings_parental_control_param_time_20: 'Праз 20 хвілін', + settings_parental_control_param_time_30: 'Праз 30 хвілін', + settings_parental_control_param_time_60: 'Праз 1 гадзіну', + settings_parental_control_param_time_120: 'Праз 2 гадзіны', + settings_parental_control_change_pin: 'Змяніць PIN-код', + settings_parental_control_demand_title: 'Калі запытаць', + settings_parental_control_demand_descr: 'Праз які час запытваць PIN-код', + settings_parental_control_enabled: 'Уключаны', + settings_parental_control_disabled: 'Адключаны', + parental_control_input_new_code: 'Увядзіце новы PIN-код', + parental_control_confirm_new_code: 'Паўтарыце PIN-код', + parental_control_no_match_code: 'PIN-код не супадае з папярэднім кодам', + parental_control_input_code: 'Увядзіце PIN-код', + parental_control_input_error: 'Вы ўвялі няправільны PIN-код', + title_worth_rewatch: 'Варта перагледзець', + + ad_disable: 'Падпісаўшыся на CUB Premium, вы забудзецеся аб рэкламе.', + ad_after: 'Рэклама праз', + ad: 'Рэклама', + ad_skip: 'Прапусціць', + ad_continue_after: 'Прагляд пачнецца праз', + + settings_parser_prowlarr_link_descr: 'Пазначце спасылку на сервер Prowlarr', + settings_parser_prowlarr_key_descr: 'Знаходзіцца ва ўкладцы налад Prowlarr у катэгорыі асноўнае', + settings_player_torrent_type: 'Тып плэера для торэнтаў', + settings_player_torrent_type_descr: 'Якім плэерам прайграваць торэнты', + + full_crew: 'Яшчэ', + full_editing: 'Рэдагаванне', + full_creator: 'Стваральнік', + player_normalization_step_none: 'Нулявая', + + settings_cub_backup_export_descr: 'Захаваць наладкі ў воблака', + settings_cub_backup_import_descr: 'Аднавіць налады з аблокі', + + settings_interface_sound: 'Сістэмныя гукі', + settings_interface_sound_play: 'Пераходы', + settings_interface_sound_level: 'Узровень гучнасці', + settings_interface_advanced_animation: 'Продвинутая анимация', + + discuss_rules_title: 'Сачыце за правіламі і паважайце іншых — ствараем камфорт разам!', + discuss_rules_rule_1: 'Не выкарыстоўвайце словы, якія складаюцца толькі з лічбаў.', + discuss_rules_rule_2: 'Пішыце на адной мове, выкарыстоўвайце словы з 5 і больш літараў.', + discuss_rules_rule_3: 'Выкарыстоўвайце знакі прыпынку і завяршайце сказы кропкамі.', + discuss_rules_rule_4: 'Аднайцеся ад незразумелых сімвалаў !?#%', + discuss_rules_rule_5: 'Пішыце поўныя сказы, выкарыстоўвайце сказы з 5 і больш слоў.', + discuss_rules_rule_6: 'Не выкарыстоўвайце занадта доўгія словы.', + discuss_rules_rule_7: 'Старайцеся ўпісацца ў 300 сімвалаў.', + discuss_voited: 'Дзякуй за вашу адзнаку! Ваш голас дапамагае паляпшаць кантэнт.', + + confirm_open_player: 'Іншая прылада запытвае доступ да плэера. Жадаеце прайграць відэа?', + + pincode_use_remote: 'Выкарыстоўвайце пульт для ўводу кода, націскаючы стрэлкі для выбару патрэбнай лічбы.', + pincode_use_toggle: 'Націсніце і ўтрымлівайце кнопку OK, каб змяніць раскладку.', + + settings_parental_control_where: 'Дзе запытваць PIN-код', + title_fire: 'Агонь!', + title_top_100: 'Топ 100', + + storage_quota_exceeded: 'Перавышаны ліміт сховішча. Выдаліце кэш і паспрабуйце зноў.', + player_normalization_type_title: 'Тып нармалізацыі', + player_normalization_type_all: 'Усе', + player_normalization_type_up: 'Толькі павышэнне', + player_normalization_type_down: 'Толькі паніжэнне', + settings_cub_domain: 'Асноўны дамен', + + title_ai_assistant: 'AI-асістэнт', + title_facts: 'Цікавыя факты', + ai_search_start_typing: 'Запытайце ў AI-асістэнта, якія фільмы вы хочаце знайсці. Напрыклад: "Фільмы пра космас"', + ai_search_limit: 'Ліміт запытаў перавышаны. Паспрабуйце паўтарыць запыт пазней. З падпіскай CUB Premium ліміты будуць павялічаны, і вам не давядзецца чакаць!', + ai_subscribe_title: 'Адкрыйце больш магчымасцяў з AI', + ai_subscribe_descr: 'Аформіце падпіску CUB Premium і павялічце колькасць запытаў да AI. Разам з AI мы падбяром для вас найлепшыя фільмы, якія толькі зможам.', + + dmca_title: 'Кантэнт заблакаваны', + dmca_descr: 'Гэты матэрыял недаступны для прагляду. Ён быў заблакаваны па просьбе праваўладальніка ў адпаведнасці з заканадаўствам аб аўтарскіх правах.', + + loading_progress_step_0: 'Падрыхтоўка', + loading_progress_step_1: 'Загрузка моў', + loading_progress_step_2: 'Пошук люстэркаў', + loading_progress_step_3: 'Падрыхтоўка пашырэнняў', + loading_progress_step_4: 'Засталося крыху', + loading_progress_step_5: 'Ужо хутка', + + install_extension_rule_1: 'Устаноўка старонняга плагіна', + install_extension_rule_2: 'Плагіны ствараюцца незалежнымі распрацоўшчыкамі, і LAMPA не правярае іх змесціва. Усталёўваючы іх, вы згаджаецеся з тым, што:', + install_extension_rule_3: '- Некаторыя плагіны могуць запытваць доступ да вашых дадзеных або працаваць з непраўеранымі крыніцамі.', + install_extension_rule_4: '- Калі ўсталяваны вамі плагін парушае аўтарскія правы або іншыя законы, уся адказнасць за яго выкарыстанне ляжыць на вас.', + install_extension_rule_5: '- Усталёўвайце толькі плагіны з давераных крыніц. Калі вы сумняваецеся ў бяспецы або законнасці плагіна, лепш адмовіцца ад яго ўсталёўкі.', + install_extension_rule_6: 'LAMPA не падтрымлівае і не ўхваляе плагіны, звязаныя з пірацкім кантэнтам.', + install_extension_rule_7: 'Працягваючы, вы пацвярджаеце, што разумееце гэтыя рызыкі.', + ad_plugin: 'Рэклама ад плагіна', + + terminal_title: 'Тэрмінал', + terminal_no_access: 'Без доступу', + terminal_confirm: 'Дазволіць', + terminal_deny: 'Забараніць', + terminal_update: 'Абнавіць', + terminal_code: 'Код доступу', + terminal_text: 'Вы запытваеце доступ да тэрміналу. Распрацоўшчыкі могуць атрымаць доступ да вашай прылады і кіраваць ёй. Гэта можа быць карысна для дыягностыкі і ліквідацыі праблем, але таксама можа ўяўляць рызыку бяспекі. Калі ласка, пераканайцеся, што вы давяраеце распрацоўшчыкам, перш чым даваць доступ.

    Вы можаце ў любы момант адключыць гэтую функцыю, націснуўшы кнопку "Забараніць".', + + title_anons: 'Анонс', + title_developer: 'Распрацоўшчык', + title_navigation: 'Навігацыя', + title_page: 'Старонка', + title_person_about: 'Пра чалавека', + account_qr_premium: 'Адскануйце QR-код, каб даведацца больш пра CUB Premium', + account_qr_code: 'Адскануйце QR-код, каб атрымаць код для прывязкі прылады', + account_qr_create: 'Адскануйце QR-код, каб стварыць уліковы запіс', + account_add_device_title: 'Дадаць прыладу', + account_add_device_text: 'Перайдзіце на , каб атрымаць код для дадання прылады.', + account_none_title: 'Яшчэ няма ўліковага запісу?', + account_none_include_1: 'Закладкі і гісторыя праглядаў захоўваюцца ў воблаку', + account_none_include_2: 'Сінхранізацыя паміж прыладамі', + account_none_include_3: 'Апавяшчэнні пра новыя серыі і рэлізы', + account_none_include_4: 'Стварайце некалькі профіляў у адным уліковым запісе', + account_premium_include_1: 'Павялічаная колькасць закладак', + account_premium_include_2: 'Пашыраная гісторыя праглядаў', + account_premium_include_3: 'Больш даступных таймкодаў', + account_premium_include_4: 'Колькасць профіляў на адзін уліковы запіс', + empty_subscribes_title: 'Вашы падпіскі на пераклады', + empty_subscribes_text: 'Проста падпішыцеся на ўлюбёны пераклад, і мы паведамім вам, калі выйдзе новая серыя.', + empty_history_title: 'Ваша гісторыя праглядаў', + empty_history_text: 'Ваша гісторыя праглядаў з’явіцца тут.', + empty_bookmark_title: 'Вашы абраныя', + empty_bookmark_text: 'Дадавайце фільмы і серыялы, якія вам падабаюцца, у абраныя, каб хутка знаходзіць іх у гэтым раздзеле.', + empty_mytorrents_title: 'Вашы торэнты', + empty_mytorrents_text: 'Торэнты, загружаныя праз TorServer, з’явяцца тут.', + developer_param_enabled: 'Рэжым распрацоўшчыка', + developer_param_nopremium: 'Адключыць CUB Premium', + developer_param_nodemo: 'Адключыць дэма-рэжым', + developer_param_ads: 'Паказваць рэкламу', + developer_param_fps: 'Паказваць FPS', + developer_trigger_help_1: 'Амаль адгадалі :)', + developer_trigger_help_2: 'Яшчэ крыху :)', + developer_trigger_help_3: 'Вы ўпэўнены, што хочаце ўвайсці ў рэжым распрацоўшчыка?', + developer_trigger_help_4: 'Рэжым распрацоўшчыка актываваны', + settings_param_navigation_touch: 'Сэнсар', + account_discuss_add_qr: 'Адскануйце QR-код', + account_discuss_add_title: 'Хочаце пакінуць каментар?', + account_discuss_add_text: 'Адскануйце QR-код, каб перайсці ў дадатак і пакінуць каментар да гэтага фільма ці серыяла.

    - Вазьміце тэлефон або планшэт
    - Адкрыйце камеру
    - Навядзіце на QR-код
    - Перайдзіце па спасылцы, якая з’явіцца на экране', + account_discuss_added: 'Дзякуй за ваш каментар!', + account_discuss_added_ready: 'Вы ўжо пакідалі каментар да гэтага фільма ці серыяла.', + remote_helper_long: 'Утрымлівайце кнопку (OK), каб адкрыць меню', + account_premium: 'Адкрыйце новыя гарызонты з уліковым запісам CUB Premium! Атрымлівайце асалоду ад павялічаных лімітаў і пашыраных магчымасцей сэрвісу. Наведайце , каб даведацца больш пра перавагі прэміум-акаўнта.', + player_segments_title: 'Сегменты', + player_segments_descr: 'Прапуск уступу і іншых частак відэа', + player_segments_ad_title: 'Рэклама', + player_segments_skip_title: 'Уступ і іншае', + player_segments_value_none: 'Не прапускаць', + player_segments_value_auto: 'Аўтапрапуск', + player_segments_value_user: 'Карыстальніцкі', + player_segments_skiped: 'Сегмент прапушчаны', + player_segments_skip_now: 'Прапусціць', + player_segments_skip_in: 'Прапуск праз', + player_segments_skip_intro: 'Прапусціць застаўку', + player_segments_next: 'Наступная серыя', + player_segments_next_in: 'Наступная серыя праз', + subscribe_info: 'У раздзеле «Падпіскі» вы ўбачыце ўсе свае падпіскі на пераклады. Вы атрымаеце апавяшчэнне, калі выйдзе новая серыя з выбраным перакладам.', + no_watch_history: 'Няма гісторыі прагляду', + + settings_request_caching_use: 'Кэшаванне запытаў', + settings_request_caching_descr: 'Захоўваць вынікі запытаў для паскарэння працы прыкладання', + + account_profile_child: 'Дзіцячы', + account_profile_add: 'Дадаць профіль', + account_profile_name: 'Імя профілю', + account_profile_created: 'Профіль паспяхова створаны', + account_profile_limited: 'Дасягнуты максімальны ліміт профіляў: {count}', + account_profile_info: 'Вы можаце кіраваць профілямі ў наладах акаўнта, для гэтага перайдзіце на сайт ', + player_youtube_no_support: 'Вашае прылада не падтрымлівае прайграванне відэа YouTube, праверце інтэрнэт-злучэнне.', + title_channels: 'Каналы', + title_best_of_2000: 'Залатыя 2000-я', + title_best_of_2010: 'Хіты 2010-х', + title_best_of_2015: 'Сучасная класіка', + title_comedy_of_2000: 'Смех 2000-х', + title_comedy_of_2010: 'Гумар 2010-х', + title_comedy_of_2015: 'Сучасныя камедыі', + + filter_keyword_sequel: 'Сіквел', + filter_keyword_based_comic: 'Па коміксах', + filter_keyword_space: 'Космас', + filter_keyword_survival: 'Выжыванне', + filter_keyword_zombie: 'Зомбі', + filter_keyword_school: 'Школа', + filter_keyword_revenge: 'Помста', + filter_keyword_detective: 'Дэтэктыў', + filter_keyword_robots: 'Робаты', + filter_keyword_vampires: 'Вампіры', + filter_keyword_aliens: 'Іншапланецяне', + filter_keyword_police: 'Паліцыя', + filter_keyword_reincarnation: 'Перараджэнне', + filter_keyword_spy: 'Шпіён', + filter_keyword_disaster: 'Катастрофа', + filter_keyword_christmas: 'Каляды', + + dmca_title_lgbt: 'Кантэнт абмежаваны', + dmca_descr_lgbt: 'Прагляд недаступны ў вашым рэгіёне, так як магчыма змяшчае ЛГБТ-кантэнт. У некаторых краінах такія матэрыялы могуць быць забаронены ці абмежаваны.', + + settings_lgbt_content_block: 'Блокіроўка ЛГБТ-контента', + + // todo: + adult_content_title: 'Кантэнт для дарослых', + adult_content_text_warning: 'Кантэнт можа змяшчаць матэрыялы для дарослых, якія могуць быць непрыдатнымі для некаторых гледачоў.', + adult_content_text_modal: 'Гэты фільм або серыял пазначаны як той, які змяшчае кантэнт для дарослых. Для прагляду гэтага матэрыялу вам павінна быць 18 гадоў ці болей. Калі ласка, пацвердзіце, што вы дасягнулі паўналецця, каб працягнуць прагляд.', + + adult_content_confirm: 'Мне 18 гадоў ці болей', + adult_content_deny: 'Мне менш за 18 гадоў', + + inner_player_disclaimer_title: 'Дысклеймер плэера', + inner_player_disclaimer_text: 'Я разумею, што запускаю плэер з няпоўнай падтрымкай, і разумею, што гэта можа выклікаць нетыповыя паводзіны прылады. Аптымальна перайсці на плэеры сямейства tvOS або іншыя альтэрнатывы.', + + inner_player_disclaimer_change_player: 'Змяніць плэер', + remote_configuration_settings_title: 'Аддалёная канфігурацыя', + remote_configuration_registration_text: 'Аддалёная канфігурацыя забяспечвае часовы доступ да вашага прыкладання, іншае прыкладанне зможа ўсталёўваць пашырэнні і наладжваць параметры.', + remote_configuration_waite_text: 'Цяпер вы можаце перадаць гэты код іншаму прыкладанню, каб даць доступ да налад.', + remote_configuration_open_button: 'Адкрыць доступ', + remote_configuration_code_life: 'Код сапраўдны', + remote_configuration_notice_nocode: 'Не ўдалося адкрыць доступ', + + settings_server_gts: 'Перакадаванне', + settings_server_gts_descr: 'Аўтаматычна канвертаваць відэа ў сумяшчальны фармат пры неабходнасці.', + settings_server_tracktimecode: 'Уключыць TrackTimecode', + settings_server_tracktimecode_descr: 'Захоўвае прагрэс прайгравання фільмаў і серыялаў на серверы TorrServer. Для працы гэтую опцыю таксама неабходна ўключыць у TorrServer.', + + title_metadata: 'Метаданыя', + title_moods: 'Настроі', + title_meta_violence: 'Гвалт', + title_meta_fear: 'Страх', + title_meta_profanity: 'Лексіка', + title_meta_sadness: 'Сум', + title_meta_sex: 'Сексуальнасць', + player_pip: 'Паменшыць', + player_volume: 'Гучнасць', + player_time_end: 'Канец у', + player_ai_agent_info: 'Хочаце даведацца больш пра відэа? Спытайцеся ў AI-асістэнта, і ён прадаставіць вам графік настрояў, кароткі сюжэт і цікавыя моманты.', + player_ai_agent_ask_plot: 'Коратка пра сюжэт', + player_ai_agent_ask_moods: 'Паказаць графік', + player_ai_agent_ask_highlights: 'Цікавыя моманты', + player_ai_agent_ask: 'Спытаць', + player_ai_agent_processing: 'Аналізую...', + player_ai_agent_no_data: 'Няма дадзеных для паказу.', + player_ai_agent_no_analysis: 'Не ўдалося правесці аналіз відэа.', + player_ai_agent_quota: 'Ліміт запытаў перавышаны. Паспрабуйце паўтарыць запыт пазней.', + player_ai_agent_working: 'Я яшчэ працую над гэтым...', + title_meta_humor: 'Гумар', + title_meta_tension: 'Напружанне', + title_meta_romance: 'Раманты', + title_meta_pace: 'Тэмп', + title_meta_importance: 'Важныя сцэны', + title_meta_action: 'Экшн' +} diff --git a/lampa-main/lang/bg.js b/lampa-main/lang/bg.js new file mode 100644 index 0000000..29a4172 --- /dev/null +++ b/lampa-main/lang/bg.js @@ -0,0 +1,1364 @@ +export default { + lang_choice_title: 'Здравейте', + lang_choice_subtitle: 'Изберете вашият език', + + more: 'Още', + show_more: 'Покажи още', + more_results: 'Още резултати', + loading: 'Зареждане', + nofind_movie: 'Филмът не е намерен.', + noname: 'Неозаглавен', + nochoice: 'Не е избран', + cancel: 'Отказ', + confirm: 'Потвърждавам', + sure: 'Сигурни ли сте?', + nodata: 'Няма данни', + back: 'Назад', + ready: 'Готов', + close_app_modal: 'Сигурни ли сте, че искате да излезете?', + connected_seeds: 'свързани', + + search: 'Търсене', + search_input: 'Въведете текст', + search_empty: 'Историята на търсенията е празна.', + search_delete: 'Ляво - изтриване', + search_start_typing: 'Напишете търсеният текст.', + search_searching: 'Търсенето е в ход...', + search_start: 'За да започнете търсене', + search_nofound: 'Нищо не беше намерено според вашата заявка.', + global_search: 'Глобално търсене', + + full_genre: 'Жанр', + full_production: 'Продукция', + full_date_of_release: 'дата на пускане', + full_budget: 'Бюджет', + full_countries: 'Страни', + full_like: 'Като', + full_torrents: 'Торенти', + full_trailers: 'Трейлъри', + full_detail: 'Подробно', + full_notext: 'Без описание.', + full_series_release: 'Излъчване на серия', + full_next_episode: 'Следващ', + full_episode_days_left: 'Дни остават', + full_trailer_official: 'Официален', + full_trailer_no_official: 'Неформален', + full_season: 'Сезон', + full_episode: 'Епизод', + full_directing: 'Режисура', + full_writing: 'Сценарии', + + settings_cub_sync: 'Синхронизация', + settings_cub_sync_descr: 'Синхронизация с CUB сървиза: Синхронизиране на вашите отметки, история на сърфиране, тагове и времеви кодове.', + settings_cub_account: 'Акаунт', + settings_cub_logged_in_as: 'Влезли сте като', + settings_cub_profile: 'Профил', + settings_cub_sync_btn: 'Синхронизация', + settings_cub_sync_btn_descr: 'Запишете локалните отметки в CUB акаунта', + settings_cub_backup: 'Архив', + settings_cub_backup_descr: 'Запиши или възстанови данните от архив', + settings_cub_logout: 'Отписване', + settings_cub_signin: 'Оторизация', + settings_cub_not_specified: 'Неопределено', + settings_cub_password: 'Парола', + settings_cub_status: 'Статус', + settings_cub_backup_import: 'Внасяне', + settings_cub_backup_export: 'Изнасяне', + settings_cub_sync_filters: 'Синхронизация на филтри', + settings_cub_sync_calendar: 'Синхронизация на календар', + settings_cub_sync_quality: 'Синхронизация на качеството', + settings_cub_sync_search: 'Синхронизация на историята на търсене', + settings_cub_sync_recomends: 'Синхронизация на препоръки', + settings_cub_sync_timecodes: 'Синхронизация на времевия код', + + settings_input_links: 'Любими', + + settings_interface_type: 'Олекотена версия', + settings_interface_size: 'Размер на интерфейса', + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: 'Фон', + settings_interface_background_use: 'Покажи фон', + settings_interface_background_type: 'Тип фон', + settings_interface_performance: 'Производителност', + settings_interface_animation: 'Анимация', + settings_interface_animation_descr: 'Анимация на карти и съдържание', + settings_interface_attenuation: 'Смекчаване', + settings_interface_attenuation_descr: 'Плавно избледняване на картите отдолу и отгоре', + settings_interface_scroll: 'Тип превъртане', + settings_interface_view_card: 'Тип изглед на карта', + settings_interface_view_card_descr: 'Докато превъртате емисията, картите да се зареждат постепенно или всички', + settings_interface_lang: 'Език на интерфейса', + settings_interface_lang_reload: 'Трябва да рестартирате приложението, изберете "OK", за да рестартирате.', + + settings_main_account: 'Акаунт', + settings_main_interface: 'Интерфейс', + settings_main_player: 'Плеър', + settings_main_parser: 'Парсър/Анализатор', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Разширения', + settings_main_rest: 'Други', + + settings_rest_start: 'Стартова страница', + settings_rest_start_descr: 'Коя страница да се показва при старт', + settings_rest_source: 'Източник', + settings_rest_source_use: 'Главен източник', + settings_rest_source_descr: 'От къде да се получава информация за филмите', + settings_rest_tmdb_lang: 'На какъв език да се показват данните от TMDB', + settings_rest_tmdb_prox: 'Прокси TMDB', + settings_rest_tmdb_prox_auto: 'Автоматично активиране на прокси', + settings_rest_tmdb_posters: 'Резолюция на TMDB постери', + settings_rest_screensaver: 'Скрийнсейвър', + settings_rest_screensaver_use: 'Показване на началния екран при неактивност', + settings_rest_screensaver_type: 'Тип скрийнсейвър', + settings_rest_helper: 'Съвети', + settings_rest_helper_use: 'Покажи съвети', + settings_rest_helper_reset: 'Покажи съветите отново', + settings_rest_pages: 'Колко страници да се пазят в паметта', + settings_rest_pages_descr: 'Пази страниците в състоянието, в което сте ги оставили', + settings_rest_time: 'Време за смяна', + settings_rest_navigation: 'Тип навигация', + settings_rest_keyboard: 'Тип клавиатура', + settings_rest_device: 'Име на устройството', + settings_rest_device_placeholder: 'Например: Моята Лампа', + settings_rest_cache: 'Изчисти кеша', + settings_rest_cache_descr: 'Всички настройки и данни ще бъдат изчистени', + settings_rest_tmdb_example: 'Например:', + settings_rest_tmdb_api_descr: 'За да получите данни', + settings_rest_tmdb_image_descr: 'За да получите изображения', + settings_rest_card_quality: 'Знаци за качество', + settings_rest_card_quality_descr: 'Покажи знаци за качеството върху картите', + settings_rest_card_episodes: 'Индекс за епизоди', + settings_rest_card_episodes_descr: 'Покажи индекс за епизодите върху картите', + + settings_parser_use: 'Използвай анализатор', + settings_parser_use_descr: 'С настоящото вие се съгласявате да поемете цялата отговорност за използването на публични връзки за гледане на торент и онлайн съдържание.', + settings_parser_type: 'Тип анализатор за торенти', + settings_parser_jackett_placeholder: 'Например: 192.168.x', + settings_parser_jackett_link: 'Връзка', + settings_parser_jackett_link_descr: 'Връзка към скрипта Jackett', + settings_parser_jackett_key_placeholder: 'Например: sa0sk83d..', + settings_parser_jackett_key: 'Api ключ', + settings_parser_jackett_key_descr: 'намиращ се в Jackett', + settings_parser_torlook_type: 'Метод за обхождане на TorLook', + settings_parser_scraperapi_placeholder: 'Например: scraperapi.com', + settings_parser_scraperapi_link: 'Връзка към анализатор на сайта', + settings_parser_scraperapi_descr: 'Регистрирайте се в сайта scraperapi.com, въведете връзката на api.scraperapi.com?api_key=...&url={q}
    W41.torlook.info ще бъдат доставени до {q}', + settings_parser_search: 'Търсене', + settings_parser_search_descr: 'На какъв език да търся?', + settings_parser_in_search: 'Анализатор при търсене', + settings_parser_in_search_descr: 'Показване на резултатите от търсенето?', + settings_parser_timeout_title: 'Таймаут', + settings_parser_timeout_descr: 'Време в секудни, през което да се чака отговор от сървъра', + + settings_player_type: 'Тип плейър', + settings_player_type_descr: 'Кой плейър да се използва', + settings_infuse_launch_mode: 'Стартиране в Infuse', + settings_infuse_launch_mode_descr: 'Какво да прави при отваряне на видео в Infuse. За торенти винаги веднага възпроизвеждане', + settings_infuse_launch_ask: 'Питай при стартиране', + settings_infuse_launch_play: 'Пусни', + settings_infuse_launch_save_and_play: 'Запази и пусни', + settings_player_iptv_type: 'Тип плеър за IPTV', + settings_player_iptv_type_descr: 'Кой плейър да се използва за IPTV канали', + settings_player_reset: 'Нулирай плейъра по подразбиране', + settings_player_reset_descr: 'Нулира избрания Android плейър в приложението', + settings_player_path: 'Път до плейъра', + settings_player_path_descr: 'Укажете пътя до плейър.exe', + settings_player_external_header: 'Външен плейър', + settings_player_external_fullscreen: 'Стартиране в пълен екран', + settings_player_normalization: 'Нормализация на звука', + settings_player_normalization_descr: 'Нормализира звука до едно ниво, понижава силните звуци и усилва тихите.', + settings_player_next_episode: 'Следващ епизод', + settings_player_next_episode_descr: 'Автоматично превключване към следващата серия след краят на текущата', + settings_player_timecode: 'Времеви код', + settings_player_timecode_descr: 'Продължи от последното преглеждано место', + settings_player_scale: 'Метод за мащабиране', + settings_player_scale_descr: 'Как да се изчисли мащабирането на видеото', + settings_player_subs: 'Субтитри', + settings_player_subs_use: 'Включи', + settings_player_subs_use_descr: 'Винаги да се включват субтитри след стартиране на видеото', + settings_player_subs_lang: 'Език на субтитрите', + settings_player_subs_lang_descr: 'Кои субтитри да се включват автоматично, когато има няколко езика', + settings_param_subtitles_lang_auto: 'Език на интерфейса', + settings_player_subs_size: 'Размер', + settings_player_subs_size_descr: 'Размерът на субтитрите върху екрана', + settings_player_subs_stroke_use: 'Обкантване', + settings_player_subs_stroke_use_descr: 'Субтитрите ще бъдат обкантени в черно за по-добра четимост', + settings_player_subs_backdrop_use: 'Фон', + settings_player_subs_backdrop_use_descr: 'Субтитрите ще бъдат изобразени на полупрозрачна основа за подобряване на четливостта', + settings_player_quality: 'Видео качество по подразбиране', + settings_player_quality_descr: 'Предпочитаното видео качество при преглед', + settings_player_hls_title: 'Обработка на .m3u8 поток', + settings_player_hls_descr: 'Не променяйте този параметър, ако не знаете какво правите.', + + settings_plugins_notice: 'За да приложите плъгина, трябва да рестартирате приложението', + settings_plugins_add: 'Добави плъгин', + settings_plugins_add_descr: 'За да изтриете добавен плъгин, задръжте или двукратно щракнете (OK) бутона, когато сте на него', + settings_plugins_install: 'Инсталирай плъгин', + settings_plugins_install_descr: 'Инсталирай плъгин от наличният лист', + + settings_server_link: 'Използвай връзка', + settings_server_links: 'Връзки', + settings_server_placeholder: 'Например: 192.168.X', + settings_server_link_one: 'Главна връзка', + settings_server_link_one_descr: 'Укажете главната връзка към TorrServer-а', + settings_server_link_two: 'Допълнителна връзка', + settings_server_link_two_descr: 'Укажете допълнителна връзка към TorrServer-а', + settings_server_additionally: 'Допълнително', + settings_server_client: 'Вграден клиент', + settings_server_client_descr: 'Използване на вграденият TorrServe JS клиент, в противен случай ще се стартира системният клиент.', + settings_server_base: 'Запис в базата данни', + settings_server_base_descr: 'Торентът ще бъде добавен в базата данни на TorrServer', + settings_server_preload: 'Използвай предварителен буфер', + settings_server_preload_descr: 'Да се изчака предварителният буфер на TorrServer да се запълни, преди възпроизвеждане', + settings_server_auth: 'Оторизация', + settings_server_password_use: 'Вход с парола', + settings_server_login: 'Вход', + settings_server_password: 'Парола', + settings_server_not_specified: 'Неопределено', + settings_server_search_type: 'Тип търсене', + settings_server_search_type_descr: 'Къде да се търсят торенти: вграденият rutor, Torznab индексатори в TorrServer, или и двата източника.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + torent_nohash_reasons: 'Причината', + torent_nohash_reason_one: 'TorServer не можа да зареди торент файла', + torent_nohash_reason_two: 'Отговор от TorServer', + torent_nohash_reason_three: 'Връзка', + torent_nohash_do: 'Какво да правя?', + torent_nohash_do_one: 'Проверете дали сте настроили Jackett коректно', + torent_nohash_do_two: 'Частни източници може да не предоставят връзка към файлът', + torent_nohash_do_three: 'Уверете се, че Jackett може да сваля файлът също', + torent_nohash_do_four: 'Пишете в нашата група в Телеграм: @lampa_group', + torent_nohash_do_five: 'Посочете кой филм, кое издание и по възможност снимка на това издание', + + torrent_error_text: 'Пропадна връзката към TorrServer. Нека набързо минем през списък с възможните проблеми и да проверим всичко.', + torrent_error_step_1: 'TorrServer-а работи ли', + torrent_error_step_2: 'Динамичен IP адрес', + torrent_error_step_3: 'Протокол и порт', + torrent_error_step_4: 'Блокиране от антивирусна програма', + torrent_error_step_5: 'Проверете за наличност', + torrent_error_step_6: 'Все още не работи', + torrent_error_info_1: 'Уверете се, че сте стартирали TorrServer на устройството, на което е инсталиран.', + torrent_error_info_2: 'Често срещана грешка е, че IP адресът на устройството с TorrServer е променен. Уверете се, че IP адресът, който сте въвели - {ip} - съвпада с адреса на устройството, на което е инсталиран TorrServer.', + torrent_error_info_3: 'За да се свържете с TorrServer, трябва да посочите протокола http:// в началото и порт :8090 в края на адреса. Уверете се, че има порт след IP адреса, текущият ви адрес е {ip}', + torrent_error_info_4: 'Често срещано явление, антивирусната програма или защитната стена могат да блокират достъпа по IP адрес, опитайте да деактивирате антивирусната програма и защитната стена.', + torrent_error_info_5: 'На друго устройство, в същата мрежа, отворете {ip} адреса в браузър и проверете дали уеб интерфейсът TorrServer е наличен.', + torrent_error_info_6: 'Ако след всички проверки все още възниква грешка при свързване, опитайте да рестартирате TorrServer и интернет адаптера.', + torrent_error_info_7: 'Ако проблемът продължава, пишете на групата на Telegram @lampa_group с текста (Lampa не се свързва с TorrServer след всички проверки, текущият адрес е {ip})', + torrent_error_start: 'Стартирайте проверката', + torrent_error_nomatrix: 'Неуспешна проверка на версията на Matrix', + torrent_error_made: 'Извършено', + torrent_error_from: 'от', + torrent_error_next: 'Допълнително', + torrent_error_complite: 'За да завършите', + torrent_error_connect: 'Грешка при свързване', + + torrent_install_need: 'Изисква се TorrServer', + torrent_install_text: 'TorrServer е приложение, което ви позволява да видите съдържание от торент файлове онлайн.

    По-подробна информация за инсталацията можете да намерите в групите на Telegram по-долу', + torrent_install_contact: 'Телеграм групи', + + torrent_item_bitrate: 'Битрейт', + torrent_item_seeds: 'Раздаващи', + torrent_item_grabs: 'Свалящи', + torrent_item_mb: 'Mbps', + + torrent_serial_episode: 'Серии', + torrent_serial_season: 'Сезон', + torrent_serial_date: 'Изход', + + torrent_get_magnet: 'Искане на магнитна връзка', + torrent_remove_title: 'Изтрий', + torrent_remove_descr: 'Торентът ще бъде премахнат от вашата листа', + + torrent_parser_any_one: 'Всеки', + torrent_parser_any_two: 'Всеки', + torrent_parser_no_choice: 'Не е избрано', + torrent_parser_yes: 'Да', + torrent_parser_no: 'Не', + torrent_parser_quality: 'Качество', + torrent_parser_subs: 'Субтитри', + torrent_parser_voice: 'Дублаж', + torrent_parser_tracker: 'източник', + torrent_parser_year: 'Година', + torrent_parser_season: 'Сезон', + torrent_parser_sort_by_seeders: 'По дистрибутори', + torrent_parser_sort_by_size: 'По размер', + torrent_parser_sort_by_name: 'По име', + torrent_parser_sort_by_tracker: 'По източник', + torrent_parser_sort_by_date: 'По дата', + torrent_parser_sort_by_viewed: 'По гледания', + torrent_parser_voice_dubbing: 'Гласов дублаж', + torrent_parser_voice_polyphonic: 'Полифонични', + torrent_parser_voice_two: 'Два гласа', + torrent_parser_voice_amateur: 'Аматьорски', + torrent_parser_reset: 'Нулиране на филтъра', + torrent_parser_empty: 'Неуспешно получаване на резултати', + torrent_parser_no_hash: 'Неуспешно получаване на HASH, опитайте да перезагрузите TorrServer', + torrent_parser_added_to_mytorrents: 'Добавен в "Моите торенти"', + torrent_parser_add_to_mytorrents: 'Добави в "Моите торенти"', + torrent_parser_label_title: 'Флаг', + torrent_parser_label_descr: 'Маркиране ръчно с флаг (прегледано)', + torrent_parser_label_cancel_title: 'Размаркиране', + torrent_parser_label_cancel_descr: 'Размаркиране на изданието (прегледано)', + torrent_parser_timeout: 'Времето за изчакване изтече', + torrent_parser_nofiles: 'Неуспешно извличане на нужните файлове', + torrent_parser_set_link: 'Посочете връзка за анализиране', + torrent_parser_request_error: 'Грешка в заявката', + torrent_parser_magnet_error: 'Неуспешно получаване на магнитна връзка', + torrent_parser_no_responce: 'Анализаторът не отговаря на заявката', + torrent_parser_torlook_fallback_search_notification: 'Jackett анализаторът не е наличен или настройките за връзка са неправилни. Търся през Torlook...', + + about_text: 'Приложението е напълно безплатно и използва публични връзки за получаване на информация за видеоклипове, нови издания, популярни филми и т.н. Цялата налична информация се използва само за образователни цели, приложението не използва собствени сървъри за разпространение на информация.', + about_channel: 'Нашият канал', + about_group: 'Група', + about_version: 'Версия', + about_donate: 'Дарете', + + title_watched: 'Гледахте', + title_settings: 'Настройки', + title_collections: 'Колекции', + title_company: 'Компания', + title_actors: 'Актьори', + title_actor: 'Актьор', + title_actress: 'Актриси', + title_person: 'Човек', + title_persons: 'Човеки', + title_comments: 'Коментари', + title_torrents: 'Торенти', + title_trailers: 'Трейлъри', + title_watch: 'Гледайте', + title_error: 'Грешка', + title_links: 'Връзки', + title_choice: 'Избор', + title_main: 'Главна', + title_book: 'Отметки', + title_like: 'Харесвам', + title_wath: 'По-късно', + title_history: 'История сърфиране', + title_mytorrents: 'Моите торенти', + title_last: 'Последен', + title_action: 'Действие', + title_action_infuse: 'Действие Infuse', + title_producer: 'Продуцент', + title_collection: 'Колекция', + title_recomendations: 'Препоръки', + title_similar: 'Подобни', + title_about: 'Относно приложението', + title_timetable: 'Разписание', + title_relises: 'Дигитални издания', + title_catalog: 'Каталог', + title_category: 'Категория', + title_parser: 'Парсър', + title_type: 'Тип', + title_rating: 'Оценка', + title_country: 'Държава', + title_year: 'Година', + title_genre: 'Жанр', + title_filter: 'Филтър', + title_notice: 'Известия', + title_files: 'Файлове', + title_now_watch: 'Гледани сега', + title_latest: 'Последно добавени', + title_continue: 'Продължете да разглеждате', + title_recomend_watch: 'Препоръчваме ви', + title_new_episodes: 'Нови епизоди', + title_popular: 'Популярни', + title_popular_movie: 'Популярни филми', + title_popular_tv: 'Популярни сериали', + title_new_this_year: 'Нови тази година', + title_hight_voite: 'Най-високо оценени', + title_new: 'Нов', + title_trend_day: 'Нашумели днес', + title_trend_week: 'Нашумели тази седмица', + title_upcoming: 'В кината', + title_top_movie: 'Топ филми', + title_top_tv: 'Топ сериали', + title_tv_today: 'Премиери днес', + title_this_week: 'Тази седмица', + title_in_top: 'Топ', + title_out: 'Изход', + title_out_confirm: 'Да, излез!', + title_continue_two: 'Продължи', + title_choice_language: 'Избери език', + title_subscribe: 'Абонамент', + title_subscribes: 'Абонаменти', + title_unsubscribe: 'Отмяна на абонамент', + title_language: 'Оригинален език', + + subscribe_success: 'Вие успешно се абонирахте', + subscribe_error: 'Възникна грешка при абонирането, моля, опитайте отново по-късно', + subscribe_noinfo: 'Неуспешно извличане на информация, моля, опитайте отново по-късно', + + company_headquarters: 'Щаб', + company_homepage: 'Уебсайт', + company_country: 'Държава', + + country_ad: 'Андора', + country_ae: 'ОАЕ', + country_af: 'Афганистан', + country_al: 'Албания', + country_am: 'Армения', + country_ao: 'Ангола', + country_ar: 'Аржентина', + country_at: 'Австрия', + country_au: 'Австралия', + country_aw: 'Аруба', + country_az: 'Азербайджан', + country_ba: 'Босна и Херцеговина', + country_bd: 'Бангладеш', + country_be: 'Белгия', + country_bg: 'България', + country_bh: 'Бахрейн', + country_bi: 'Бурунди', + country_bj: 'Бенин', + country_bo: 'Боливия', + country_br: 'Бразилия', + country_bs: 'Бахамски острови', + country_bt: 'Бутан', + country_bw: 'Ботсвана', + country_by: 'Беларус', + country_ca: 'Канада', + country_ch: 'Швейцария', + country_cl: 'Чили', + country_cm: 'Камерун', + country_cn: 'Китай', + country_co: 'Колумбия', + country_cr: 'Коста Рика', + country_cu: 'Куба', + country_cv: 'Кабо Верде', + country_cy: 'Кипър', + country_cz: 'Чехия', + country_de: 'Германия', + country_dj: 'Джибути', + country_dk: 'Дания', + country_do: 'Доминиканска република', + country_dz: 'Алжир', + country_ec: 'Еквадор', + country_ee: 'Естония', + country_eg: 'Египет', + country_es: 'Испания', + country_et: 'Етиопия', + country_fi: 'Финландия', + country_fo: 'Фарьорски острови', + country_fr: 'Франция', + country_ga: 'Габон', + country_gb: 'Обединено кралство', + country_ge: 'Грузия', + country_gh: 'Гана', + country_gl: 'Гренландия', + country_gp: 'Гваделупа', + country_gr: 'Гърция', + country_gt: 'Гватемала', + country_hk: 'Хонконг', + country_hr: 'Хърватия', + country_ht: 'Хаити', + country_hu: 'Унгария', + country_id: 'Индонезия', + country_ie: 'Ирландия', + country_il: 'Израел', + country_in: 'Индия', + country_iq: 'Ирак', + country_ir: 'Иран', + country_is: 'Исландия', + country_it: 'Италия', + country_jm: 'Ямайка', + country_jo: 'Йордания', + country_jp: 'Япония', + country_ke: 'Кения', + country_kg: 'Киргизстан', + country_kh: 'Камбоджа', + country_kp: 'Северна Корея', + country_kr: 'Южна Корея', + country_kz: 'Казахстан', + country_kw: 'Кувейт', + country_la: 'Лаос', + country_lb: 'Ливан', + country_li: 'Лихтенщайн', + country_lk: 'Шри Ланка', + country_lr: 'Либерия', + country_lt: 'Литва', + country_lu: 'Люксембург', + country_lv: 'Латвия', + country_ly: 'Либия', + country_ma: 'Мароко', + country_mc: 'Монако', + country_md: 'Молдова', + country_me: 'Черна гора', + country_mk: 'Северна Македония', + country_mm: 'Мианмар', + country_mn: 'Монголия', + country_mo: 'Макао', + country_mt: 'Малта', + country_mu: 'Мавриций', + country_mv: 'Малдиви', + country_mw: 'Малави', + country_mx: 'Мексико', + country_my: 'Малайзия', + country_mz: 'Мозамбик', + country_na: 'Намибия', + country_ne: 'Нигер', + country_ng: 'Нигерия', + country_ni: 'Никарагуа', + country_nl: 'Нидерландия', + country_no: 'Норвегия', + country_np: 'Непал', + country_nz: 'Нова Зеландия', + country_om: 'Оман', + country_pa: 'Панама', + country_pe: 'Перу', + country_pg: 'Папуа Нова Гвинея', + country_ph: 'Филипини', + country_pk: 'Пакистан', + country_pl: 'Полша', + country_pr: 'Пуерто Рико', + country_ps: 'Палестинска територия', + country_pt: 'Португалия', + country_py: 'Парагвай', + country_qa: 'Катар', + country_ro: 'Румъния', + country_rs: 'Сърбия', + country_ru: 'Русия', + country_rw: 'Руанда', + country_sa: 'Саудитска Арабия', + country_sd: 'Судан', + country_se: 'Швеция', + country_sg: 'Сингапур', + country_si: 'Словения', + country_sk: 'Словакия', + country_sn: 'Сенегал', + country_su: 'СССР', + country_sv: 'Салвадор', + country_sy: 'Сирия', + country_th: 'Тайланд', + country_tj: 'Таджикистан', + country_tm: 'Туркменистан', + country_tn: 'Тунис', + country_tr: 'Турция', + country_tw: 'Тайван', + country_tz: 'Танзания', + country_ua: 'Украйна', + country_ug: 'Уганда', + country_us: 'САЩ', + country_uy: 'Уругвай', + country_uz: 'Узбекистан', + country_ve: 'Венецуела', + country_vn: 'Виетнам', + country_xk: 'Косово', + country_ws: 'Самоа', + country_ye: 'Йемен', + country_yu: 'Югославия', + country_za: 'Южна Африка', + country_zm: 'Замбия', + country_zw: 'Зимбабве', + + filter_clarify: 'Изяснете', + filter_clarify_two: 'Уточнете търсенето', + filter_set_name: 'Определено заглавие', + filter_sorted: 'Сортиране', + filter_filtred: 'Филтър', + filter_any: 'Всеки', + filter_combinations: 'Комбинации', + filter_alt_names: 'Други имена', + filter_rating_from: 'от', + filter_rating_to: 'до', + + filter_lang_af: 'африкаанс', + filter_lang_ar: 'арабски', + filter_lang_az: 'азербайджански', + filter_lang_ba: 'башкирски', + filter_lang_be: 'беларуски', + filter_lang_bg: 'български', + filter_lang_bn: 'бенгалски', + filter_lang_bs: 'босненски', + filter_lang_ca: 'каталонски', + filter_lang_ce: 'чеченски', + filter_lang_cs: 'чешки', + filter_lang_da: 'датски', + filter_lang_de: 'немски', + filter_lang_el: 'гръцки', + filter_lang_en: 'английски', + filter_lang_es: 'испански', + filter_lang_et: 'естонски', + filter_lang_fa: 'персийски', + filter_lang_fi: 'фински', + filter_lang_fr: 'френски', + filter_lang_ga: 'ирландски', + filter_lang_gl: 'галисийски', + filter_lang_gn: 'гуарани', + filter_lang_he: 'иврит', + filter_lang_hi: 'хинди', + filter_lang_hr: 'хърватски', + filter_lang_hu: 'унгарски', + filter_lang_hy: 'арменски', + filter_lang_id: 'индонезийски', + filter_lang_is: 'исландски', + filter_lang_it: 'италиански', + filter_lang_ja: 'японски', + filter_lang_ka: 'грузински', + filter_lang_kk: 'казахски', + filter_lang_ko: 'корейски', + filter_lang_ks: 'кашмирски', + filter_lang_ku: 'кюрдски', + filter_lang_ky: 'киргизки', + filter_lang_lt: 'литовски', + filter_lang_lv: 'латвийски', + filter_lang_mi: 'маорски', + filter_lang_mk: 'македонски', + filter_lang_mn: 'монголски', + filter_lang_mt: 'малтийски', + filter_lang_ne: 'непалски', + filter_lang_nl: 'нидерландски', + filter_lang_no: 'норвежки', + filter_lang_pa: 'панджабски', + filter_lang_pl: 'полски', + filter_lang_ps: 'пущу', + filter_lang_pt: 'португалски', + filter_lang_ro: 'румънски', + filter_lang_ru: 'руски', + filter_lang_si: 'синхалски', + filter_lang_sk: 'словашки', + filter_lang_sl: 'словенски', + filter_lang_sm: 'самоански', + filter_lang_so: 'сомалийски', + filter_lang_sq: 'албански', + filter_lang_sr: 'сръбски', + filter_lang_sv: 'шведски', + filter_lang_sw: 'суахили', + filter_lang_ta: 'тамилски', + filter_lang_tg: 'таджикски', + filter_lang_th: 'тайландски', + filter_lang_tk: 'туркменски', + filter_lang_tr: 'турски', + filter_lang_tt: 'татарски', + filter_lang_ur: 'урду', + filter_lang_uk: 'украински', + filter_lang_uz: 'узбекски', + filter_lang_vi: 'виетнамски', + filter_lang_yi: 'идиш', + filter_lang_zh: 'китайски', + + + filter_genre_ac: 'Екшън', + filter_genre_ad: 'Приключения', + filter_genre_mv: 'Анимация', + filter_genre_cm: 'Комедия', + filter_genre_cr: 'Криминален', + filter_genre_dc: 'Документален', + filter_genre_dr: 'Драма', + filter_genre_fm: 'Семеен', + filter_genre_fe: 'Фантазия', + filter_genre_hi: 'Разказ', + filter_genre_ho: 'Ужас', + filter_genre_mu: 'Музика', + filter_genre_de: 'Детектив', + filter_genre_md: 'Мелодрама', + filter_genre_fa: 'Фикция', + filter_genre_tv: 'ТВ филм', + filter_genre_tr: 'Трилър', + filter_genre_mi: 'Военен', + filter_genre_ve: 'Уестърн', + filter_genre_aa: 'Екшън & Приключение', + filter_genre_ch: 'Детски', + filter_genre_nw: 'Новини', + filter_genre_rs: 'Риалити шоу', + filter_genre_hf: 'Научна фантастика и фентъзи', + filter_genre_op: 'Сапунена опера', + filter_genre_tc: 'Толк шоу', + filter_genre_mp: 'Война и политика', + + empty_title: 'Празно', + empty_text: 'Нищо не е намерено за вашия филтър, моля, прецизирайте филтъра си.', + empty_title_two: 'Тук е празно', + empty_text_two: 'Списъкът в момента е празен.', + + menu_main: 'Главна', + menu_movies: 'Филми', + menu_tv: 'Сериали', + menu_catalog: 'Каталог', + menu_filter: 'Филтър', + menu_collections: 'Колекции', + menu_relises: 'Релийзи', + menu_anime: 'Аниме', + menu_bookmark: 'Отметки', + menu_like: 'Харесвам', + menu_time: 'По-късно', + menu_history: 'История', + menu_timeline: 'Разписание', + menu_torrents: 'Торенти', + menu_settings: 'Настройки', + menu_about: 'Информация', + menu_console: 'Конзола', + menu_multmovie: 'Анимации', + menu_multtv: 'Анимационни сериали', + + plugins_catalog_work: 'Работещи добавки', + plugins_catalog_work_descr: 'Добавки, които работят в Лампата.', + plugins_catalog_popular: 'Популярни сред потребителите добавки', + plugins_catalog_popular_descr: 'Инсталиране на добавки от непознати източници могат да причинят неправилна работа на приложението.', + plugins_online: 'Виж онлайн', + plugins_check_fail: 'Неуспешно тестване на добавка. Това обаче не означава, че добавката не работи. Презаредете приложението, за да видите дали добавката се зарежда.', + plugins_need_reload: 'За да приложите добавка, трябва да рестартирате приложението', + plugins_install: 'Инсталирай', + plugins_install_ready: 'Тази добавка е вече инсталирана.', + plugins_installed: 'Инсталации', + plugins_load_from: 'Заредени от CUB', + plugins_ok_for_check: 'Натиснете (OK) за да се тества добавката', + plugins_no_loaded: 'При зареждане на приложението някои добавки не можаха да бъдат заредени', + + time_viewed: 'Изгледано', + time_from: 'от', + time_reset: 'Нулирай времевия код', + + settings_clear_cache: 'Кешът и данните са изчистени', + settings_user_links: 'Връзка по избор', + settings_for_local: 'За локален TorrServer', + settings_add: 'Добави', + settings_remove: 'Изтрий', + settings_this_value: 'настояща стойност', + settings_added: 'Добавен', + settings_removed: 'Изтрит', + + settings_param_player_inner: 'Lampa', + settings_param_player_outside: 'Външен', + settings_param_player_inner_tvos: 'Вътрешен', + settings_param_yes: 'Да', + settings_param_no: 'Не', + settings_param_interface_size_small: 'По-малък', + settings_param_interface_size_normal: 'Нормален', + settings_param_interface_size_bigger: 'По-голям', + settings_param_poster_quality_low: 'Ниско', + settings_param_poster_quality_average: 'Средно', + settings_param_poster_quality_high: 'Високо', + settings_param_parse_directly: 'Директно', + settings_param_parse_api: 'Чрез API на уебсайта', + settings_param_background_complex: 'Комплексен', + settings_param_background_simple: 'Прост', + settings_param_background_image: 'Картина', + settings_param_link_use_one: 'Главна', + settings_param_link_use_two: 'Допълнителна', + settings_param_link_use_both: 'И двете', + settings_param_subtitles_size_small: 'малки', + settings_param_subtitles_size_normal: 'нормални', + settings_param_subtitles_size_bigger: 'големи', + settings_param_screensaver_nature: 'Природа', + settings_param_torrent_lang_orig: 'Оригинал', + settings_param_torrent_lang_ru: 'Руски', + settings_param_player_timecode_again: 'Стартирай отначало', + settings_param_player_timecode_continue: 'Продължи', + settings_param_player_timecode_ask: 'Питай', + settings_param_player_scale_method: 'Пресмятане', + settings_param_player_hls_app: 'Системен', + settings_param_player_hls_js: 'Програмен', + settings_param_card_view_load: 'Качени', + settings_param_card_view_all: 'Покажи всички', + settings_param_navigation_remote: 'Дистанционно управление', + settings_param_navigation_mouse: 'Управление с мишка', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: 'Системна', + + helper_keyboard: 'След като въведете стойността, натиснете бутона "Назад", за да запазите', + helper_torrents: 'Задръжте натиснат клавиша (OK), за да изведете контекстното меню', + helper_cleared: 'Успешно, подсказки ще бъдат показани отново.', + helper_torrents_view: 'Задръжте натиснат клавиша (OK), за да нулирате времевия код и да покажете менюто', + + fav_sync_title: 'Синхронизация отметки', + fav_sync_text: 'Любимите ви отметки с вас. Свързване на синхронизация и преглед на всяко устройство.

    За да направите това, регистрирайте се на сайта {site}, създайте профил и влезте в приложението.', + fav_sync_site: 'Уебсайт', + fav_remove_title: 'Премахни от историята', + fav_remove_descr: 'Изтрий избраната карта', + fav_clear_title: 'Изчистване на историята', + fav_clear_descr: 'Изтриване на всички карти от историята', + fav_clear_label_title: 'Изчисти отметките', + fav_clear_label_descr: 'Изчисти отметките за прегледани', + fav_clear_time_title: 'Изчисти времеви кодове', + fav_clear_time_descr: 'Изчисти всички времеви кодове', + fav_label_cleared: 'Маркировките са изчистени', + fav_time_cleared: 'Времевите кодове са изчистени', + + timetable_empty: 'Този раздел ще покаже датите на пускане на нови епизоди.', + + player_quality: 'Качество', + player_flow: 'Поток', + player_tracks: 'Аудио пътчеки', + player_disabled: 'Забранено', + player_unknown: 'Непознат', + player_subs: 'Субтитри', + player_size_default_title: 'По подразбиране', + player_size_default_descr: 'Видео размер по подразбиране', + player_size_cover_title: 'Разширено', + player_size_cover_descr: 'Разшири видеото до цял екран', + player_size_fill_title: 'Запълнено', + player_size_fill_descr: 'Побери видеото на цял екран', + player_size_s115_title: 'Увеличение 115%', + player_size_s115_descr: 'Увеличи видеото с 115%', + player_size_s130_title: 'Увеличение 130%', + player_size_s130_descr: 'Увеличи видеото с 130%', + player_size_v115_title: 'Вертикално 115%', + player_size_v115_descr: 'Увеличи видеото с 115%', + player_size_v130_title: 'Вертикално 130%', + player_size_v130_descr: 'Увеличи видеото с 130%', + player_video_size: 'Видео размер', + player_playlist: 'Плейлиста', + player_error_one: 'Неуспешно декодиране на видео', + player_error_two: 'Видеото не е намерено или повредено', + player_start_from: 'Продължете да разглеждате от', + player_not_found: 'Плейърът не е намерен', + player_lauch: 'Стартиране на плейъра', + player_speed_default_title: 'Обичайна', + player_speed_two_descr: 'Възпроизвеждане без звук', + player_video_speed: 'Скорост на възпроизвеждане', + player_share_title: 'Споделяне ', + player_share_descr: 'Възпроизвеждане на това видео на друго устройство', + player_normalization_power_title: 'Нормализация на силата', + player_normalization_smooth_title: 'Нормализация на скоростта', + player_normalization_step_low: 'Ниско', + player_normalization_step_medium: 'Средно', + player_normalization_step_hight: 'Високо', + player_youtube_no_played: 'За съжаление това видео не е налично във вашия регион и може да е блокирано или премахнато.', + player_youtube_start_play: 'За да започнете да възпроизвеждате видеоклипа, кликнете върху бутона "Play".', + + broadcast_open: 'Отваряне заглавието на друго устройство', + broadcast_play: 'Изберете устройството, на което да гледате', + + card_new_episode: 'Нови сериали', + card_book_remove: 'Премахни от отметките', + card_book_add: 'В отметките', + card_book_descr: 'Погледнете в менюто (Отметки)', + card_like_remove: 'Премахване от Предпочитани', + card_like_add: 'Харесвам', + card_like_descr: 'Виж менюто (Харесвам)', + card_wath_remove: 'Премахни от очаквани', + card_wath_add: 'Гледай по-късно', + card_wath_descr: 'Виж менюто (По-късно)', + card_history_remove: 'Премахни от историята', + card_history_add: 'В историята', + card_history_descr: 'Виж менюто (История)', + + keyboard_listen: 'Говори, аз слушам...', + keyboard_nomic: 'Няма достъп до микрофона', + + notice_new_quality: 'Налично ново качество', + notice_quality: 'Качество', + notice_new_episode: 'Нови серии', + notice_none: 'Все още нямате известия, регистрирайте се на {site}, за да следите за нови епизоди и издания.', + notice_in_quality: 'В качество', + notice_none_account: 'Все още нямате известия, маркирайте поредицата и изчакайте известия за нови епизоди.', + notice_none_system: 'В момента нямате известия. Със сигурност ще Ви уведомим, когато се появят нови известия.', + + copy_link: 'Копиране на връзката към видеото', + copy_secuses: 'Линка е копиран в клипборда', + copy_error: 'Грешка при копиране на връзката', + + account_sync_to_profile: 'Всички отметки ще бъдат преместени в профила', + account_sync_secuses: 'Всички отметки са прехвърлени успешно', + account_profiles: 'Профили', + account_profiles_empty: 'Неуспешно получаване на списък с профили', + account_authorized: 'Оторизиран', + account_logged_in: 'Вие сте влезли', + account_login_failed: 'Неуспешно влизане', + account_login_wait: 'Изчакване за влизане', + account_profile_main: 'Общ', + account_export_secuses: 'Експортирането завърши успешно', + account_export_fail: 'Грешка при експортиране', + account_import_secuses: 'Импортирането завърши успешно', + account_import_fail: 'Грешка при импортиране', + account_imported: 'импортирано', + account_reload_after: 'рестарт след 5 сек.', + account_create: 'Открийте повече възможности с CUB акаунт. Регистрирайте се на и получете достъп за синхронизиране на вашите отметки, времеви кодове и други функции на CUB акаунта.', + account_premium: 'Отключете нови хоризонти с CUB Premium акаунт! Възползвайте се от увеличени лимити и подобрена функционалност на услугата. Посетете и научете повече за предимствата на премиум акаунта.', + account_premium_more: 'Научете повече за CUB Premium', + account_limited: 'Достигнали сте максималния лимит. Увеличете лимита с CUB Premium акаунт. Научете повече на ', + + account_code_enter: 'Въведете шестцифрен код', + account_code_error: 'Може би сте въвели неправилен или остарял код', + account_code_wrong: 'Може би сте въвели неправилен формат', + account_code_where: 'Отидете на website и въведете предоставения там код.', + account_code_input: 'Въведете кода', + settings_cub_signin_button: 'Влизане', + + network_noconnect: 'Няма мрежова връзка', + network_404: 'Заявената страница не бе намерена. [404]', + network_401: 'Неуспешно удостоверяване', + network_500: 'Вътрешна грешка на сървъра. [500]', + network_parsererror: 'Исканият JSON анализ е неуспешен.', + network_timeout: 'Времето за изчакване на заявката изтече.', + network_abort: 'Искането е прекратено.', + network_error: 'Неизвестна грешка', + + size_zero: '0 Byte', + size_byte: 'Byte', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'TB', + size_pp: 'PB', + + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + + month_1: 'Януари', + month_2: 'Февруари', + month_3: 'Март', + month_4: 'Април', + month_5: 'Май', + month_6: 'Юни', + month_7: 'Юли', + month_8: 'Август', + month_9: 'Септември', + month_10: 'Октомври', + month_11: 'Ноември', + month_12: 'Декември', + + day_1: 'Понеделник', + day_2: 'Вторник', + day_3: 'Сряда', + day_4: 'Четвъртък', + day_5: 'Петък', + day_6: 'Събота', + day_7: 'Неделя', + + month_1_e: 'Януари', + month_2_e: 'Февруари', + month_3_e: 'Март', + month_4_e: 'Април', + month_5_e: 'Май', + month_6_e: 'Юни', + month_7_e: 'Юли', + month_8_e: 'Август', + month_9_e: 'Септември', + month_10_e: 'Октомври', + month_11_e: 'Ноември', + month_12_e: 'Декември', + + week_1: 'Пон', + week_2: 'Вто', + week_3: 'Сря', + week_4: 'Чет', + week_5: 'Пет', + week_6: 'Съб', + week_7: 'Нед', + + extensions_enable: 'Включи', + extensions_disable: 'Забрани', + extensions_check: 'Провери състоянието', + extensions_install: 'Инсталирай', + extensions_info: 'Информация', + extensions_edit: 'Редакция', + extensions_change_name: 'Смяна на име', + extensions_change_link: 'Смяна на линк', + extensions_remove: 'Изтрий', + extensions_set_name: 'Въведете име на добавка', + extensions_set_url: 'Въведете адрес на добавка', + extensions_ready: 'Тази добавка вече е инсталирана', + extensions_no_info: 'Без информация', + extensions_no_name: 'Без заглавие', + extensions_worked: 'Работи', + extensions_no_plugin: 'Добавката не е проверена', + extensions_add: 'Добави', + extensions_from_memory: 'Инсталиране от паметта', + extensions_from_cub: 'Инсталирана от CUB', + extensions_from_popular: 'Популярни добавки', + extensions_from_lib: 'Библиотека добавки', + extensions_from_connected: 'Свързани добавки', + + settings_webos_launcher: 'Стартиране на приложение', + settings_webos_launcher_add_device: 'Инсталирайте като стартово приложение', + settings_webos_launcher_remove_device: 'Премахване от стартиращи приложения', + player_normalization: 'Нормализация', + change_source_on_cub: 'Променете източника на CUB', + settings_param_jackett_interview_all: 'Всички', + settings_param_jackett_interview_healthy: 'Само налични', + settings_parser_jackett_interview: 'Запитване на източници', + title_ongoing: 'Текущи', + title_pgrating: 'Възрастова граница', + + settings_interface_card_interfice: 'Картов интерфейс', + settings_interface_card_poster: 'Покажи постери', + title_card: 'Карта', + settings_param_card_interface_old: 'Стар', + settings_param_card_interface_new: 'Нов', + title_seasons: 'Сезони', + title_episodes: 'Епизоди', + title_rewiews: 'Отзиви', + settings_interface_glass: 'Стъклен', + settings_interface_glass_descr: 'Покажи интерфейса в стил стъкло', + settings_interface_black_style: 'Черен стил', + + plugins_remove: 'Премахване на добавките', + plugins_add_success: 'Добавката е свързана успешно', + settings_reset: 'Нулиране', + title_channel: 'Канал', + + input_detection_touch: 'Искате ли да превключите на тъч управление?', + input_detection_mouse: 'Искате ли да превключите на управление с мишка?', + input_detection_remote: 'Искате ли да превключите на управление с дистанционно?', + + settings_interface_hide_outside_the_screen: 'Скриване на картите извън екрана', + settings_interface_hide_outside_the_screen_descr: 'Това ще ускори рендирането на потребителския интерфейс и ще подобри производителността', + + https_text: 'Използвате протокола HTTPS, в този протокол лампата не работи правилно. За правилната работа на лампата използвайте адреса с HTTP протокола', + + extensions_hpu_best: 'Популярни', + extensions_hpu_recomend: 'Препоръчани', + extensions_hpu_theme: 'Теми', + extensions_hpu_screensaver: 'Скрийнсейвъри', + extensions_hpu_video: 'Видео', + extensions_hpu_control: 'Контрол', + extensions_hpu_other: 'Разни', + extensions_hpu_: 'Други', + + title_author: 'Автор', + + title_buffer: 'Буфер', + settings_rest_screensaver_time: 'След колко минути да се стартира скрийнсейвъра', + + time_h: 'ч.', + time_m: 'м.', + time_s: 'с.', + + settings_param_glass_easy: 'Прозрачен', + settings_param_glass_medium: 'Полупрозрачен', + settings_param_glass_blacked: 'Затъмнен', + + settings_interface_glass_opacity: 'Прозрачност', + torrent_error_check_no_auth: 'Сървърът отговори на искането, но упълномощаването беше неуспешно', + settings_interface_card_cover: 'Показване на корицата', + + title_upcoming_episodes: 'Предстоящи епизоди', + title_recent_episodes: 'Наскоро излезли епизоди', + settings_rest_cache_images: 'Кеш на изображения', + settings_rest_cache_images_descr: 'Кеширане на плакати и фонове в локалното хранилище', + + settings_player_rewind_title: 'Назад', + settings_player_rewind_descr: 'Интервал Назад в секунди', + + settings_interface_card_reactions: 'Показване на реакциите', + title_look: 'Гледащи', + title_scheduled: 'Планирани', + title_viewed: 'Изгледани', + title_thrown: 'Отхвърлени', + title_reactions: 'Реакции', + reactions_none: 'Без реакции', + reactions_fire: 'Чудесно', + reactions_nice: 'Хубаво', + reactions_think: 'Интересно', + reactions_bore: 'Скучно', + reactions_shit: 'Лош', + reactions_ready: 'Вече сте оставили реакция', + settings_player_launch_trailers: 'Трейлър плейър', + title_continued: 'Следва продължение', + title_language_short: 'Език', + speedtest_connect: 'връзка', + speedtest_test: 'тестване', + speedtest_ready: 'готов', + speedtest_button: 'Тест Скорост', + + termsofuse_t_01: 'Условия за ползване', + termsofuse_t_02: 'Lampa е удобен инструмент за разглеждане на най-новите новини в киноиндустрията, включително филми, телевизионни сериали, анимации и друга информация. За получаване на информация за филми се използва уебсайт с отворен код – themoviedb.org.', + termsofuse_t_03: 'Съдържание', + termsofuse_t_04: 'Lampa използва API (интерфейс за програмиране на приложения) на каталога themoviedb.org, за да извлича информация за филми и телевизионни сериали, както и за преглед на свързани медийни файлове като плакати, трейлъри и други.', + termsofuse_t_05: 'API на themoviedb.org позволява на приложението Lampa достъп до база данни с филми и телевизионни сериали, осигурявайки възможност за търсене и преглед на информация за медийни файлове.', + termsofuse_t_06: 'Взаимодействието между приложението Lampa и themoviedb.org се осъществява чрез API заявки, които се изпращат от приложението Lampa към сървърите на themoviedb.org за получаване на информация и медийни файлове. Themoviedb.org обработва заявките и изпраща поисканите данни обратно към приложението Lampa.', + termsofuse_t_07: 'Така, благодарение на използването на API на themoviedb.org, приложението Lampa предоставя на потребителите достъп до обширна база данни с филми и телевизионни сериали, като същевременно спазва условията за ползване и ограниченията, определени от носителя на авторските права.', + termsofuse_t_08: 'Разширения', + termsofuse_t_09: 'Разширенията са мощен инструмент, предоставен за приложението Lampa, който позволява на потребителите да разширят неговите възможности, да добавят допълнителни функции и да модифицират съдържанието според техните нужди.', + termsofuse_t_10: 'Важно е да се отбележи, че потребителите инсталират разширения на свой собствен риск. Всички последици от използването на разширения са отговорност на потребителя. Препоръчва се потребителите да бъдат внимателни при инсталиране и използване на разширения, като внимателно оценяват тяхната надеждност и сигурност.', + termsofuse_t_11: 'Нарушения на авторските права', + termsofuse_t_12: 'Ако откриете нарушение на авторските права в приложението Lampa, трябва да се свържете с разработчиците на приложението Lampa. Можете да използвате контактите, предоставени в приложението Lampa, за тази цел. Важно е обаче да се отбележи, че приложението Lampa използва API от каталога themoviedb.org, който предоставя открит достъп до информация за филми и телевизионни сериали. Това означава, че информацията, показвана в приложението Lampa, е публично достъпна и не нарушава авторските права.', + termsofuse_t_13: 'Ако смятате, че приложението Lampa все още съдържа съдържание, което нарушава вашите авторски права, можете да се свържете с носителя на авторските права на това съдържание и да поискате неговото премахване от уебсайта themoviedb.org. От своя страна, приложението Lampa може да премахне съдържание при получаване на надлежно уведомление за нарушение на авторските права.', + + settings_rest_protocol_use: 'Сигурна връзка', + settings_rest_protocol_descr: 'Използвайте HTTPS протокол', + install_app_apk_title: 'Как да инсталирате Lampa на Android', + install_app_apk_text: 'Забелязахме, че използвате MediaStationX, за да стартирате Lampa на Android. Препоръчваме да инсталирате Lampa като APK приложение. Това ще осигури по-стабилна работа и достъп до всички функции на приложението.

    Отидете в Telegram групата , за да изтеглите най-новия APK файл и инструкции за инсталиране.', + install_app_apk_qr: 'Сканирайте QR кода, за да изтеглите APK файла на Lampa', + copy_link_buffer: 'Копиране на връзката', + + tv_status_returning_series: 'Предстоящ', + tv_status_planned: 'Планирано', + tv_status_in_production: 'В продукция', + tv_status_ended: 'Приключил', + tv_status_canceled: 'Отменен', + tv_status_pilot: 'Пилотен', + + tv_status_released: 'Излъчен', + tv_status_rumored: 'Слухове', + tv_status_post_production: 'Скоро', + + full_keywords: 'Тагове', + title_last_year: 'Миналата година', + + title_reset: 'Рестартирайте', + back_to_card: 'Връщане към картата', + + premiere_author_recomend_1: 'Поръчайте пица и се пригответе за забава', + premiere_author_recomend_2: 'Вечеринката тъкмо започва', + premiere_author_recomend_3: 'Бъдете готови за адреналина.', + premiere_author_recomend_4: 'Готови ли сте за една незабравима вечер?', + premiere_author_recomend_5: 'Препоръчвам ви да гледате', + premiere_title: 'Премиера', + + settings_clear_cache_only: 'Изчисти кеш', + settings_rest_cache_only: 'Само кеш', + settings_rest_cache_only_descr: 'Основните настройки ще бъдат запазени', + settings_rest_cache_all: 'Кеш и данни', + settings_rest_cache_all_descr: 'Ще бъдат изчистени всички настройки и данни', + settings_rest_cache_calculate: 'Колко памет остава', + + title_left:'Остават', + + account_export_fail_500: 'Непозната грешка', + account_export_fail_610: 'Изчерпахте лимита за днес', + account_export_fail_200: 'Грешка в базата данни, опитайте отново по-късно', + account_export_fail_600: 'Грешка, неуспешно качване на файл', + account_export_fail_620: 'Грешка, файлът не е предаден', + + title_parental_control: 'Родителски контрол', + settings_parental_control_param_time_always: 'Винаги', + settings_parental_control_param_time_once: 'Един път', + settings_parental_control_param_time_10: 'След 10 минути', + settings_parental_control_param_time_20: 'След 20 минути', + settings_parental_control_param_time_30: 'След 30 минути', + settings_parental_control_param_time_60: 'След 1 час', + settings_parental_control_param_time_120: 'След 2 часа', + settings_parental_control_change_pin: 'Промяна на PIN-кода', + settings_parental_control_demand_title: 'Кога да изисква', + settings_parental_control_demand_descr: 'След колко време да се изисква PIN-код', + settings_parental_control_enabled: 'Включено', + settings_parental_control_disabled: 'Изключено', + parental_control_input_new_code: 'Въведете нов PIN-код', + parental_control_confirm_new_code: 'Повторете PIN-код', + parental_control_no_match_code: 'PIN-кода не съвпада с предишния код', + parental_control_input_code: 'Въведете PIN-код', + parental_control_input_error: 'Въвели сте неправилен PIN-код', + title_worth_rewatch: 'Заслужава си повторно гледане', + + ad_disable: 'Като се абонирате за CUB Premium, ще забравите за рекламата.', + ad_after: 'Реклама чрез', + ad: 'Реклама', + ad_skip: 'Пропускане', + ad_continue_after: 'Гледането ще започне в', + settings_parser_prowlarr_link_descr: 'Предоставете връзка към сървъра Prowlarr', + settings_parser_prowlarr_key_descr: 'Намира се в раздела с настройки на Prowlarr в общата категория', + settings_player_torrent_type: 'Тип плеър за торенти', + settings_player_torrent_type_descr: 'На кой плеър да пускате торенти', + + full_crew: 'Още', + full_editing: 'Редакция', + full_creator: 'Създател', + player_normalization_step_none: 'Нула', + + settings_cub_backup_export_descr: 'Запазете настройките в облака', + settings_cub_backup_import_descr: 'Възстановете настройките от облака', + + settings_interface_sound: 'Системни звуци', + settings_interface_sound_play: 'Преходи', + settings_interface_sound_level: 'Ниво на звука', + settings_interface_advanced_animation: 'Разширена анимация', + + confirm_open_player: 'Друго устройство иска достъп до плейъра. Искате ли да пуснете видеоклипа?', + + pincode_use_remote: 'Използвайте дистанционното управление, за да въведете кода, като натиснете стрелките, за да изберете желания номер.', + pincode_use_toggle: 'Натиснете и задръжте бутона OK, за да промените оформлението.', + + settings_parental_control_where: 'Къде да поискате ПИН код', + title_fire: 'Огън!', + title_top_100: 'Топ 100', + + player_normalization_type_title: 'Тип нормализация', + player_normalization_type_all: 'Всички', + player_normalization_type_up: 'Само увеличаване', + player_normalization_type_down: 'Само намаляване', + storage_quota_exceeded: 'Надхвърлен е лимитът за съхранение. Изтрийте кеша и опитайте отново.', + settings_cub_domain: 'Основен домейн', + + title_ai_assistant: 'AI-асистент', + title_facts: 'Интересни факти', + ai_search_start_typing: 'Попитайте AI-асистента кои филми искате да намерите. Например: "Филми за космоса"', + ai_search_limit: 'Лимитът на заявките е надвишен. Опитайте отново по-късно. С абонамент за CUB Premium лимитите ще бъдат увеличени и няма да се налага да чакате!', + ai_subscribe_title: 'Отключете повече възможности с AI', + ai_subscribe_descr: 'Абонирайте се за CUB Premium и увеличете броя на заявките към AI. С AI ще ви предложим най-добрите филми, които можем да намерим.', + + dmca_title: 'Съдържанието е блокирано', + dmca_descr: 'Този материал не е достъпен за гледане. Беше блокиран по искане на притежателя на авторските права в съответствие със закона за авторското право.', + + loading_progress_step_0: 'Подготовка', + loading_progress_step_1: 'Зареждане на езици', + loading_progress_step_2: 'Търсене на огледала', + loading_progress_step_3: 'Подготовка на разширения', + loading_progress_step_4: 'Остава още малко', + loading_progress_step_5: 'Скоро ще е готово', + + install_extension_rule_1: 'Инсталиране на външен плъгин', + install_extension_rule_2: 'Плъгините са създадени от независими разработчици и LAMPA не проверява тяхното съдържание. С инсталирането им вие се съгласявате, че:', + install_extension_rule_3: '- Някои плъгини може да изискват достъп до вашите данни или да работят с непроверени източници.', + install_extension_rule_4: '- Ако инсталираният от вас плъгин нарушава авторски права или други закони, цялата отговорност за неговото използване е ваша.', + install_extension_rule_5: '- Инсталирайте само плъгини от надеждни източници. Ако се съмнявате в сигурността или законността на даден плъгин, по-добре се въздържайте от инсталирането му.', + install_extension_rule_6: 'LAMPA не поддържа и не одобрява плъгини, свързани с пиратско съдържание.', + install_extension_rule_7: 'Продължавайки, вие потвърждавате, че разбирате тези рискове.', + ad_plugin: 'Реклама от плъгина', + + terminal_title: 'Терминал', + terminal_no_access: 'Без достъп', + terminal_confirm: 'Разреши', + terminal_deny: 'Забрани', + terminal_update: 'Обнови', + terminal_code: 'Код за достъп', + terminal_text: 'Заявявате достъп до терминала. Разработчиците могат да получат достъп до вашето устройство и да го управляват. Това може да е полезно за диагностика и отстраняване на проблеми, но също така може да представлява риск за сигурността. Моля, уверете се, че имате доверие на разработчиците, преди да предоставите достъп.

    Можете да изключите тази функция по всяко време, като натиснете бутона "Забрани".', + + title_anons: 'Съобщение', + title_developer: 'Разработчик', + title_navigation: 'Навигация', + title_page: 'Страница', + title_person_about: 'За актьора', + account_qr_premium: 'Сканирайте QR кода, за да научите повече за CUB Premium', + account_qr_code: 'Сканирайте QR кода, за да получите код за свързване на устройство', + account_qr_create: 'Сканирайте QR кода, за да създадете акаунт', + account_add_device_title: 'Добавяне на устройство', + account_add_device_text: 'Отидете на , за да получите код за добавяне на устройство.', + account_none_title: 'Все още нямате акаунт?', + account_none_include_1: 'Отметките и историята на гледане се съхраняват в облака', + account_none_include_2: 'Синхронизация между устройства', + account_none_include_3: 'Известия за нови епизоди и издания', + account_none_include_4: 'Създавайте няколко профила под един акаунт', + account_premium_include_1: 'Повече отметки', + account_premium_include_2: 'Разширена история на гледане', + account_premium_include_3: 'Повече налични таймкодове', + account_premium_include_4: 'Брой профили на акаунт', + empty_subscribes_title: 'Вашите абонаменти за преводи', + empty_subscribes_text: 'Просто се абонирайте за любимия си превод и ще ви уведомим, когато излезе нов епизод.', + empty_history_title: 'Вашата история на гледане', + empty_history_text: 'Историята на гледане ще се появи тук.', + empty_bookmark_title: 'Вашите любими', + empty_bookmark_text: 'Добавете филми и сериали, които харесвате, в „Любими“, за да ги намирате бързо в този раздел.', + empty_mytorrents_title: 'Вашите торенти', + empty_mytorrents_text: 'Торентите, които сте изтеглили чрез TorServer, ще се появят тук.', + developer_param_enabled: 'Режим за разработчици', + developer_param_nopremium: 'Деактивиране на CUB Premium', + developer_param_nodemo: 'Деактивиране на демо режим', + developer_param_ads: 'Показване на реклами', + developer_param_fps: 'Показване на FPS', + developer_trigger_help_1: 'Почти познахте :)', + developer_trigger_help_2: 'Още малко :)', + developer_trigger_help_3: 'Сигурни ли сте, че искате да влезете в режим за разработчици?', + developer_trigger_help_4: 'Режимът за разработчици е активиран', + settings_param_navigation_touch: 'Сензор', + account_discuss_add_qr: 'Сканирайте QR кода', + account_discuss_add_title: 'Искате да оставите коментар?', + account_discuss_add_text: 'Сканирайте QR кода, за да отворите приложението и да добавите коментар за този филм или сериал.

    - Вземете телефона или таблета си
    - Отворете камерата
    - Насочете я към QR кода
    - Следвайте връзката, която ще се появи на екрана', + account_discuss_added: 'Благодарим за вашия коментар!', + account_discuss_added_ready: 'Вече сте оставили коментар за този филм или сериал.', + remote_helper_long: 'Задръжте бутона (OK), за да отворите менюто', + account_premium: 'Отключете нови хоризонти с акаунт CUB Premium! Насладете се на увеличени лимити и разширени функции на услугата. Посетете , за да научите повече за предимствата на премиум акаунта.', + player_segments_title: 'Сегменти', + player_segments_descr: 'Прескачайте интрото и други части на видеото', + player_segments_ad_title: 'Реклами', + player_segments_skip_title: 'Интро и други', + player_segments_value_none: 'Без прескачане', + player_segments_value_auto: 'Автоматично прескачане', + player_segments_value_user: 'Персонализирано', + player_segments_skiped: 'Сегментът е пропуснат', + player_segments_skip_now: 'Прескочи', + player_segments_skip_in: 'Прескачане след', + player_segments_skip_intro: 'Пропусни въведението', + player_segments_next: 'Следващ епизод', + player_segments_next_in: 'Следващ епизод след', + subscribe_info: 'В раздела „Абонаменти“ ще видите всички ваши абонаменти за преводи. Ще получите известие, когато излезе нов епизод с избрания от вас превод.', + no_watch_history: 'Няма история на сърфиране', + + settings_request_caching_use: 'Кеширане на заявки', + settings_request_caching_descr: 'Кеширане на резултатите от заявките за по-бърз достъп при повторни заявки', + + account_profile_child: 'Дете', + account_profile_add: 'Добавяне на профил', + account_profile_name: 'Име на профил', + account_profile_created: 'Профилът е създаден успешно', + account_profile_limited: 'Достигнат е максималният брой профили: {count}', + account_profile_info: 'Можете да управлявате профилите в настройките на профила си. За да направите това, отидете на ', + player_youtube_no_support: 'Вашето устройство не поддържа възпроизвеждане на YouTube видеоклипове, проверете интернет връзката.', + title_channels: 'Канали', + title_best_of_2000: 'Златните 2000-те', + title_best_of_2010: 'Хитовете на 2010-те', + title_best_of_2015: 'Съвременни класики', + title_comedy_of_2000: 'Смяхът на 2000-те', + title_comedy_of_2010: 'Хуморът на 2010-те', + title_comedy_of_2015: 'Съвременни комедии', + + filter_keyword_sequel: 'Продължение', + filter_keyword_based_comic: 'Базирано на комикси', + filter_keyword_space: 'Космос', + filter_keyword_survival: 'Оцеляване', + filter_keyword_zombie: 'Зомби', + filter_keyword_school: 'Училище', + filter_keyword_revenge: 'Отмъщение', + filter_keyword_detective: 'Детектив', + filter_keyword_robots: 'Роботи', + filter_keyword_vampires: 'Вампири', + filter_keyword_aliens: 'Извънземни', + filter_keyword_police: 'Полиция', + filter_keyword_reincarnation: 'Прераждане', + filter_keyword_spy: 'Шпионин', + filter_keyword_disaster: 'Катастрофа', + filter_keyword_christmas: 'Коледа', + + dmca_title_lgbt: 'Съдържание с ограничен достъп', + dmca_descr_lgbt: 'Преглеждането не е възможно във вашия регион, тъй като е възможно да съдържа ЛГБТ съдържание. Такива материали може да са забранени или ограничени в някои страни.', + + settings_lgbt_content_block: 'Блокиране на ЛГБТ съдържание', + + // todo: + adult_content_title: 'Съдържание за възрастни', + adult_content_text_warning: 'Съдържанието може да включва материали за възрастни, които може да са неподходящи за някои зрители.', + adult_content_text_modal: 'Този филм или сериал е маркиран като съдържащ съдържание за възрастни. Трябва да сте на 18 или повече години, за да гледате този материал. Моля, потвърдете, че сте навършили законовата възраст, за да продължите да гледате.', + + adult_content_confirm: 'На 18 съм или повече', + adult_content_deny: 'Под 18 съм', + + inner_player_disclaimer_title: 'Дисклеймър за плейъра', + inner_player_disclaimer_text: 'Разбирам, че стартирам плейър с непълна поддръжка, и разбирам, че това може да доведе до нетипично поведение на устройството. Оптимално е да преминете към плейъри от семейството tvOS или други алтернативи.', + + inner_player_disclaimer_change_player: 'Смени плеъра', + remote_configuration_settings_title: 'Дистанционна конфигурация', + remote_configuration_registration_text: 'Дистанционната конфигурация предоставя временен достъп до вашето приложение, друго приложение ще може да инсталира разширения и да конфигурира параметри.', + remote_configuration_waite_text: 'Вече можете да предадете този код на друго приложение, за да му предоставите достъп до настройките.', + remote_configuration_open_button: 'Отвори достъп', + remote_configuration_code_life: 'Кодът е валиден', + remote_configuration_notice_nocode: 'Неуспешно отваряне на достъп', + + settings_server_gts: 'Прекодиране', + settings_server_gts_descr: 'Автоматично конвертиране на видеото в съвместим формат при необходимост.', + settings_server_tracktimecode: 'Активирай TrackTimecode', + settings_server_tracktimecode_descr: 'Запазва прогреса на възпроизвеждане на филми и сериали на сървъра TorrServer. За да работи, тази опция трябва да бъде активирана и в TorrServer.', + + title_metadata: 'Метаданни', + title_moods: 'Настроения', + title_meta_violence: 'Насилие', + title_meta_fear: 'Страх', + title_meta_profanity: 'Лексика', + title_meta_sadness: 'Тъга', + title_meta_sex: 'Сексуалност', + player_pip: 'Намали', + player_volume: 'Сила на звука', + player_time_end: 'Край в', + player_ai_agent_info: 'Искате ли да научите повече за видеото? Попитайте AI асистента, и той ще ви предостави графика на настроенията, кратко резюме и интересни моменти.', + player_ai_agent_ask_plot: 'Накратко за сюжета', + player_ai_agent_ask_moods: 'Покажи графика', + player_ai_agent_ask_highlights: 'Интересни моменти', + player_ai_agent_ask: 'Попитай', + player_ai_agent_processing: 'Анализирам...', + player_ai_agent_no_data: 'Няма данни за показване.', + player_ai_agent_no_analysis: 'Не успя да анализира видеото.', + player_ai_agent_quota: 'Лимитът на заявки е надвишен. Моля, опитайте по-късно.', + player_ai_agent_working: 'Все още работя върху това...', + title_meta_humor: 'Хумор', + title_meta_tension: 'Напрежение', + title_meta_romance: 'Романтика', + title_meta_pace: 'Темпо', + title_meta_importance: 'Ключови сцени', + title_meta_action: 'Екшън' +} diff --git a/lampa-main/lang/cs.js b/lampa-main/lang/cs.js new file mode 100644 index 0000000..4cd4732 --- /dev/null +++ b/lampa-main/lang/cs.js @@ -0,0 +1,1373 @@ +export default { + lang_choice_title: "Vítejte", + lang_choice_subtitle: "Vyberte svůj jazyk", + + more: "Více", + show_more: "Zobrazit více", + more_results: "Zobrazit více výsledků", + loading: "Načítání", + nofind_movie: "Film nebyl nalezen.", + noname: "Bez názvu", + nochoice: "Není vybráno", + cancel: "Zrušit", + confirm: "Potvrdit", + sure: "Jste si jisti?", + nodata: "Žádná data", + back: "Zpět", + ready: "Připraveno", + close_app_modal: "Opravdu chcete opustit aplikaci?", + connected_seeds: "připojeno", + + search: "Hledat", + search_input: "Zadejte text", + search_empty: "Historie hledání je prázdná.", + search_delete: "Doleva - smazat", + search_start_typing: "Začněte psát pro hledání.", + search_searching: "Probíhá hledání...", + search_start: "Začít hledat", + search_nofound: "Podle vašeho dotazu nebylo nic nalezeno.", + global_search: 'Globální vyhledávání', + + full_genre: "Žánr", + full_production: "Produkce", + full_date_of_release: "Datum vydání", + full_budget: "Rozpočet", + full_countries: "Země", + full_like: "Líbí se", + full_torrents: "Torrenty", + full_trailers: "Trailery", + full_detail: "Podrobnosti", + full_notext: "Bez popisu.", + full_series_release: "Vydání série", + full_next_episode: "Další epizoda", + full_episode_days_left: "Zbývá dní", + full_trailer_official: "Oficiální", + full_trailer_no_official: "Neoficiální", + full_season: "Série", + full_episode: "Epizoda", + full_directing: "Režie", + full_writing: "Scénář", + full_keywords: "Klíčová slova", + full_crew: "Více", + full_editing: "Střih", + full_creator: "Tvůrce", + + settings_cub_sync: "Synchronizace", + settings_cub_sync_descr: "Synchronizace se službou CUB: synchronizace vašich záložek, historie sledování, značek a časových kódů.", + settings_cub_account: "Účet", + settings_cub_logged_in_as: "Přihlášen jako", + settings_cub_profile: "Profil", + settings_cub_sync_btn: "Synchronizovat", + settings_cub_sync_btn_descr: "Uložit místní záložky do účtu CUB", + settings_cub_backup: "Záloha", + settings_cub_backup_descr: "Uložit nebo načíst zálohu dat", + settings_cub_logout: "Odhlásit se z účtu", + settings_cub_signin: "Přihlášení", + settings_cub_not_specified: "Není uvedeno", + settings_cub_password: "Heslo", + settings_cub_status: "Stav", + settings_cub_backup_import: "Import", + settings_cub_backup_export: "Export", + settings_cub_backup_export_descr: "Uložit nastavení do cloudu", + settings_cub_backup_import_descr: "Obnovit nastavení z cloudu", + settings_cub_sync_filters: "Synchronizace filtrů", + settings_cub_sync_calendar: "Synchronizace kalendáře", + settings_cub_sync_quality: "Synchronizace značek (kvalita)", + settings_cub_sync_search: "Synchronizace historie hledání", + settings_cub_sync_recomends: "Synchronizace doporučení", + settings_cub_sync_timecodes: "Synchronizace časových kódů", + settings_cub_signin_button: "Přihlásit se", + + settings_input_links: "Oblíbené", + + settings_interface_type: "Zjednodušená verze", + settings_interface_size: "Velikost rozhraní", + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: "Pozadí", + settings_interface_background_use: "Zobrazit pozadí", + settings_interface_background_type: "Typ pozadí", + settings_interface_performance: "Výkon", + settings_interface_animation: "Animace", + settings_interface_advanced_animation: "Pokročilá animace", + settings_interface_animation_descr: "Animace karet a obsahu", + settings_interface_attenuation: "Útlum", + settings_interface_attenuation_descr: "Plynulé útlum karet shora a zdola", + settings_interface_scroll: "Typ posouvání", + settings_interface_view_card: "Typ zobrazení karet", + settings_interface_view_card_descr: "Při posouvání se karty budou načítat postupně nebo se načtou všechny", + settings_interface_lang: "Jazyk rozhraní", + settings_interface_lang_reload: "Je nutné restartovat aplikaci, stiskněte (OK) pro restart", + settings_interface_card_interfice: "Rozhraní karet", + settings_interface_card_poster: "Zobrazit plakát", + settings_interface_card_cover: "Zobrazit obal", + settings_interface_card_reactions: "Zobrazit reakce", + settings_interface_glass: "Sklo", + settings_interface_glass_descr: "Zobrazit rozhraní ve skleněném stylu", + settings_interface_glass_opacity: "Průhlednost skla", + settings_interface_black_style: "Černý styl", + settings_interface_hide_outside_the_screen: "Skrýt karty mimo obrazovku", + settings_interface_hide_outside_the_screen_descr: "To urychlí vykreslování rozhraní a zlepší výkon", + + settings_interface_sound: "Systémové zvuky", + settings_interface_sound_play: "Přechody", + settings_interface_sound_level: "Úroveň hlasitosti", + + settings_main_account: "Účet", + settings_main_interface: "Rozhraní", + settings_main_player: "Přehrávač", + settings_main_parser: "Parser", + settings_main_torrserver: "TorrServer", + settings_main_plugins: "Rozšíření", + settings_main_rest: "Ostatní", + + settings_rest_start: "Úvodní stránka", + settings_rest_start_descr: "Z jaké stránky začít při spuštění", + settings_rest_source: "Zdroj", + settings_rest_source_use: "Hlavní zdroj", + settings_rest_source_descr: "Odkud brát informace o filmech", + settings_rest_tmdb_lang: "V jakém jazyce zobrazovat data z TMDB", + settings_rest_tmdb_prox: "Proxy TMDB", + settings_rest_tmdb_prox_auto: "Automaticky zapnout proxy", + settings_rest_tmdb_posters: "Rozlišení plakátů TMDB", + settings_rest_screensaver: "Spořič obrazovky", + settings_rest_screensaver_use: "Zobrazit spořič při nečinnosti", + settings_rest_screensaver_type: "Typ spořiče", + settings_rest_screensaver_time: "Po kolika minutách spustit spořič", + settings_rest_helper: "Nápověda", + settings_rest_helper_use: "Zobrazit nápovědu", + settings_rest_helper_reset: "Zobrazit nápovědu znovu", + settings_rest_pages: "Kolik stránek uchovávat v paměti", + settings_rest_pages_descr: "Uchovává stránky ve stavu, ve kterém jste je opustili.", + settings_rest_time: "Posunout čas", + settings_rest_navigation: "Typ navigace", + settings_rest_keyboard: "Typ klávesnice", + settings_rest_device: "Název zařízení", + settings_rest_device_placeholder: "Například: Moje Lampa", + settings_rest_cache: "Vymazat cache", + settings_rest_tmdb_example: "Například:", + settings_rest_tmdb_api_descr: "Pro získání dat", + settings_rest_tmdb_image_descr: "Pro získání obrázků", + settings_rest_card_quality: "Značky kvality", + settings_rest_card_quality_descr: "Zobrazit značky kvality na kartách", + settings_rest_card_episodes: "Značky epizod", + settings_rest_card_episodes_descr: "Zobrazit značky epizod na kartách", + settings_rest_cache_images: "Cache obrázků", + settings_rest_cache_images_descr: "Cache plakátů a pozadí do lokálního úložiště", + settings_rest_protocol_use: "Bezpečné připojení", + settings_rest_protocol_descr: "Použít protokol HTTPS", + settings_rest_cache_only: "Pouze cache", + settings_rest_cache_only_descr: "Hlavní nastavení budou uložena", + settings_rest_cache_all: "Cache a data", + settings_rest_cache_all_descr: "Budou vymazána všechna nastavení a data", + settings_rest_cache_calculate: "Kolik paměti zbývá", + + settings_parser_use: "Použít parser", + settings_parser_use_descr: "Tímto souhlasíte s převzetím veškeré odpovědnosti za používání veřejných odkazů pro sledování torrentu a online obsahu.", + settings_parser_type: "Typ parseru pro torrenty", + settings_parser_jackett_placeholder: "Například: 192.168.x", + settings_parser_jackett_link: "Odkaz", + settings_parser_jackett_link_descr: "Uveďte odkaz na skript Jackett", + settings_parser_prowlarr_link_descr: "Uveďte odkaz na server Prowlarr", + settings_parser_jackett_key_placeholder: "Například: sa0sk83d..", + settings_parser_jackett_key: "Api-klíč", + settings_parser_jackett_key_descr: "Nachází se v Jackett", + settings_parser_prowlarr_key_descr: "Nachází se v nastavení Prowlarr v kategorii hlavní", + settings_parser_torlook_type: "Metoda parsování webu TorLook", + settings_parser_scraperapi_placeholder: "Například: scraperapi.com", + settings_parser_scraperapi_link: "Odkaz na parser webů", + settings_parser_scraperapi_descr: "Zaregistrujte se na webu scraperapi.com, zadejte odkaz api.scraperapi.com?api_key=...&url={q}
    V {q} bude dodán web w41.torlook.info", + settings_parser_search: "Hledat", + settings_parser_search_descr: "V jakém jazyce provádět hledání?", + settings_parser_in_search: "Parser ve vyhledávání", + settings_parser_in_search_descr: "Zobrazit výsledky ve vyhledávání?", + settings_parser_timeout_title: "Timeout parseru", + settings_parser_timeout_descr: "Čas (v sekundách) čekání na odpověď serveru", + + settings_player_type: "Typ přehrávače", + settings_player_type_descr: "Jakým přehrávačem přehrávat video", + settings_infuse_launch_mode: "Spuštění v Infuse", + settings_infuse_launch_mode_descr: "Co dělat při otevření videa v Infuse. U torrentů vždy okamžité přehrání", + settings_infuse_launch_ask: "Zeptat se při spuštění", + settings_infuse_launch_play: "Přehrát", + settings_infuse_launch_save_and_play: "Uložit a přehrát", + settings_player_iptv_type: "Typ přehrávače pro IPTV", + settings_player_iptv_type_descr: "Jakým přehrávačem přehrávat IPTV kanály", + settings_player_torrent_type: "Typ přehrávače pro torrenty", + settings_player_torrent_type_descr: "Jakým přehrávačem přehrávat torrenty", + settings_player_reset: "Resetovat přehrávač na výchozí", + settings_player_reset_descr: "Resetuje vybraný Android přehrávač v aplikaci", + settings_player_path: "Cesta k přehrávači", + settings_player_path_descr: "Uveďte cestu k spustitelnému souboru přehrávače", + settings_player_external_header: 'Externí přehrávač', + settings_player_external_fullscreen: 'Spustit v režimu celé obrazovky', + settings_player_normalization: "Normalizace zvuku", + settings_player_normalization_descr: "Normalizuje zvuk na jednu úroveň, snižuje hlasité zvuky a zvyšuje tiché.", + settings_player_next_episode: "Další epizoda", + settings_player_next_episode_descr: "Automaticky přepnout na další epizodu po skončení aktuální", + settings_player_timecode: "Časový kód", + settings_player_timecode_descr: "Pokračovat z posledního místa sledování", + settings_player_scale: "Metoda škálování", + settings_player_scale_descr: "Jakým způsobem provádět výpočty pro škálování videa", + settings_player_subs: "Titulky", + settings_player_subs_use: "Zapnout", + settings_player_subs_use_descr: "Vždy zapnout titulky po spuštění videa", + settings_player_subs_lang: "Jazyk titulků", + settings_player_subs_lang_descr: "Které titulky automaticky zapnout, když je k dispozici více jazyků", + settings_param_subtitles_lang_auto: "Jazyk rozhraní", + settings_player_subs_size: "Velikost", + settings_player_subs_size_descr: "Velikost titulků na obrazovce", + settings_player_subs_stroke_use: "Použít obrys", + settings_player_subs_stroke_use_descr: "Titulky budou obtaženy černou barvou pro zlepšení čitelnosti", + settings_player_subs_backdrop_use: "Použít podklad", + settings_player_subs_backdrop_use_descr: "Titulky budou zobrazeny na poloprůhledném podkladu pro zlepšení čitelnosti", + settings_player_quality: "Výchozí kvalita videa", + settings_player_quality_descr: "Preferovaná kvalita videa pro sledování", + settings_player_hls_title: "Zpracování streamu .m3u8", + settings_player_hls_descr: "Nedotýkejte se tohoto nastavení, pokud nevíte, k čemu slouží.", + settings_player_rewind_title: "Přetáčení", + settings_player_rewind_descr: "Interval přetáčení v sekundách", + settings_player_launch_trailers: "Přehrávač pro trailery", + + settings_plugins_notice: "Pro použití pluginu je nutné restartovat aplikaci", + settings_plugins_add: "Přidat plugin", + settings_plugins_add_descr: "Pro odstranění přidaného pluginu podržte nebo dvakrát stiskněte tlačítko (OK) na něm", + settings_plugins_install: "Nainstalovat plugin", + settings_plugins_install_descr: "Nainstalovat plugin ze seznamu dostupných", + + settings_server_link: "Použít odkaz", + settings_server_links: "Odkazy", + settings_server_placeholder: "Například: 192.168.x", + settings_server_link_one: "Hlavní odkaz", + settings_server_link_one_descr: "Uveďte hlavní odkaz na TorrServer", + settings_server_link_two: "Doplňkový odkaz", + settings_server_link_two_descr: "Uveďte doplňkový odkaz na TorrServer", + settings_server_additionally: "Doplňkově", + settings_server_client: "Vestavěný klient", + settings_server_client_descr: "Použít vestavěný JS klient TorrServer, jinak se spustí systémový.", + settings_server_base: "Uložit do databáze", + settings_server_base_descr: "Torrent bude přidán do databáze TorrServer", + settings_server_preload: "Použít buffer předběžného načítání", + settings_server_preload_descr: "Čekat na naplnění bufferu předběžného načítání TorrServer před přehráváním", + settings_server_auth: "Autorizace", + settings_server_password_use: "Přihlášení pomocí hesla", + settings_server_login: "Přihlášení", + settings_server_password: "Heslo", + settings_server_not_specified: "Není uvedeno", + settings_server_search_type: "Typ vyhledávání", + settings_server_search_type_descr: "Kde hledat torrenty: vestavěný rutor, Torznab indexery v TorrServer, nebo oba zdroje.", + settings_param_torrserver_search_rutor: "Rutor", + settings_param_torrserver_search_torznab: "Torznab", + settings_param_torrserver_search_both: "Rutor + Torznab", + + settings_webos_launcher: "Spuštění aplikace", + settings_webos_launcher_add_device: "Nastavit jako startovací", + settings_webos_launcher_remove_device: "Odebrat ze startovacích aplikací", + + settings_parental_control_param_time_always: "Vždy", + settings_parental_control_param_time_once: "Jednou", + settings_parental_control_param_time_10: "Za 10 minut", + settings_parental_control_param_time_20: "Za 20 minut", + settings_parental_control_param_time_30: "Za 30 minut", + settings_parental_control_param_time_60: "Za 1 hodinu", + settings_parental_control_param_time_120: "Za 2 hodiny", + settings_parental_control_change_pin: "Změnit PIN kód", + settings_parental_control_demand_title: "Kdy vyžadovat", + settings_parental_control_demand_descr: "Po jaké době vyžadovat PIN kód", + settings_parental_control_enabled: "Zapnuto", + settings_parental_control_disabled: "Vypnuto", + settings_parental_control_where: "Kde vyžadovat PIN kód", + + parental_control_input_new_code: "Zadejte nový PIN kód", + parental_control_confirm_new_code: "Zopakujte PIN kód", + parental_control_no_match_code: "PIN kód se neshoduje s předchozím kódem", + parental_control_input_code: "Zadejte PIN kód", + parental_control_input_error: "Zadali jste nesprávný PIN kód", + + torent_nohash_reasons: "Důvody", + torent_nohash_reason_one: "TorServer nemohl stáhnout torrent soubor", + torent_nohash_reason_two: "Odpověď od TorServer", + torent_nohash_reason_three: "Odkaz", + torent_nohash_do: "Co dělat?", + torent_nohash_do_one: "Zkontrolujte, zda jste správně nastavili Jackett", + torent_nohash_do_two: "Soukromé zdroje nemusí poskytovat odkaz na soubor", + torent_nohash_do_three: "Ujistěte se, že Jackett také může stáhnout soubor", + torent_nohash_do_four: "Napište do naší Telegram skupiny: @lampa_group", + torent_nohash_do_five: "Uveďte, jaký film, jaké vydání a pokud možno foto tohoto vydání", + + torrent_error_text: "Nepodařilo se připojit k TorrServer. Pojďme rychle projít seznam možných problémů a vše zkontrolovat.", + torrent_error_step_1: "Je TorrServer spuštěn", + torrent_error_step_2: "Dynamická IP adresa", + torrent_error_step_3: "Protokol a port", + torrent_error_step_4: "Blokování antiviry", + torrent_error_step_5: "Zkontrolujte dostupnost", + torrent_error_step_6: "Stále nefunguje", + torrent_error_info_1: "Ujistěte se, že jste spustili TorrServer na zařízení, kde je nainstalován.", + torrent_error_info_2: "Častá chyba, změnila se IP adresa zařízení s TorrServer. Ujistěte se, že IP adresa, kterou jste zadali - {ip}, se shoduje s adresou zařízení, na kterém je nainstalován TorrServer.", + torrent_error_info_3: "Pro připojení k TorrServer je nutné uvést protokol http:// na začátku a port :8090 na konci adresy. Ujistěte se, že po IP adrese je uveden port, vaše aktuální adresa - {ip}", + torrent_error_info_4: "Častý jev, antivirus nebo firewall může blokovat přístup podle IP adresy, zkuste vypnout antivirus a firewall.", + torrent_error_info_5: "Na jakémkoli jiném zařízení v této síti otevřete v prohlížeči adresu {ip} a zkontrolujte, zda je dostupné webové rozhraní TorrServer.", + torrent_error_info_6: "Pokud po všech kontrolách stále dochází k chybě připojení, zkuste restartovat TorrServer a internetový adaptér.", + torrent_error_info_7: "Pokud problém není odstraněn, pište do Telegram skupiny @lampa_group s textem (Lampa se nepřipojuje k TorrServer po všech kontrolách, aktuální adresa {ip})", + torrent_error_start: "Začít kontrolu", + torrent_error_nomatrix: "Nepodařilo se potvrdit verzi Matrix", + torrent_error_made: "Hotovo", + torrent_error_from: "z", + torrent_error_next: "Dále", + torrent_error_complite: "Dokončit", + torrent_error_connect: "Chyba připojení", + torrent_error_check_no_auth: "Server odpověděl na požadavek, ale nepodařilo se projít autorizací", + + torrent_install_need: "Je potřeba TorrServer", + torrent_install_text: "TorrServer je aplikace, která umožňuje sledovat obsah z torrent souborů online.

    Podrobnější informace o instalaci najdete v Telegram skupinách uvedených níže.", + torrent_install_contact: "Telegram skupiny", + + torrent_item_bitrate: "Bitrate", + torrent_item_seeds: "Sdílejí", + torrent_item_grabs: "Stahují", + torrent_item_mb: "Mbit/s", + + torrent_serial_episode: "Epizoda", + torrent_serial_season: "Série", + torrent_serial_date: "Vydání", + + torrent_get_magnet: "Žádám magnet odkaz", + torrent_remove_title: "Odstranit", + torrent_remove_descr: "Torrent bude odstraněn z vašeho seznamu", + + torrent_parser_any_one: "Jakýkoli", + torrent_parser_any_two: "Jakýkoli", + torrent_parser_no_choice: "Není vybráno", + torrent_parser_yes: "Ano", + torrent_parser_no: "Ne", + torrent_parser_quality: "Kvalita", + torrent_parser_subs: "Titulky", + torrent_parser_voice: "Dabing", + torrent_parser_tracker: "Tracker", + torrent_parser_year: "Rok", + torrent_parser_season: "Série", + torrent_parser_sort_by_seeders: "Podle sdílejících", + torrent_parser_sort_by_size: "Podle velikosti", + torrent_parser_sort_by_name: "Podle názvu", + torrent_parser_sort_by_tracker: "Podle zdroje", + torrent_parser_sort_by_date: "Podle data", + torrent_parser_sort_by_viewed: "Podle zhlédnutých", + torrent_parser_voice_dubbing: "Dabing", + torrent_parser_voice_polyphonic: "Vícehlasý", + torrent_parser_voice_two: "Dvouhlasý", + torrent_parser_voice_amateur: "Amatérský", + torrent_parser_reset: "Resetovat filtr", + torrent_parser_empty: "Nepodařilo se získat výsledky", + torrent_parser_no_hash: "Nepodařilo se získat HASH", + torrent_parser_added_to_mytorrents: "přidáno do «Moje torrenty»", + torrent_parser_add_to_mytorrents: "Přidat do «Moje torrenty»", + torrent_parser_label_title: "Označit", + torrent_parser_label_descr: "Označit torrent s vlajkou (zhlédnuto)", + torrent_parser_label_cancel_title: "Zrušit označení", + torrent_parser_label_cancel_descr: "Zrušit označení torrentu (zhlédnuto)", + torrent_parser_timeout: "Časový limit vypršel", + torrent_parser_nofiles: "Nepodařilo se extrahovat vhodné soubory", + torrent_parser_set_link: "Uveďte odkaz pro parsování", + torrent_parser_request_error: "Chyba v požadavku", + torrent_parser_magnet_error: "Nepodařilo se získat magnet odkaz", + torrent_parser_no_responce: "Parser neodpovídá na požadavek", + torrent_parser_torlook_fallback_search_notification: "Parser Jackett není dostupný nebo nastavení připojení nejsou správná. Probíhá hledání v Torlook...", + + about_text: "Aplikace je zcela zdarma a používá veřejné odkazy pro získání informací o videích, novinkách, populárních filmech atd. Veškeré dostupné informace jsou používány výhradně pro vzdělávací účely, aplikace nepoužívá své vlastní servery pro šíření informací.", + about_channel: "Náš kanál", + about_group: "Skupina", + about_version: "Verze", + about_donate: "Darovat", + + title_watched: "Sledovali jste", + title_settings: "Nastavení", + title_collections: "Kolekce", + title_company: "Společnost", + title_actors: "Herci", + title_actor: "Herec", + title_actress: "Herečka", + title_person: "Osoba", + title_persons: "Osoby", + title_comments: "Komentáře", + title_torrents: "Torrenty", + title_trailers: "Trailery", + title_watch: "Sledovat", + title_error: "Chyba", + title_links: "Odkazy", + title_choice: "Vybrat", + title_main: "Hlavní", + title_book: "Záložky", + title_like: "Líbí se", + title_wath: "Později", + title_look: "Sleduji", + title_scheduled: "Naplánováno", + title_viewed: "Zhlédnuto", + title_thrown: "Odloženo", + title_continued: "Pokračování", + title_history: "Historie sledování", + title_mytorrents: "Moje torrenty", + title_last: "Poslední", + title_action: "Akce", + title_action_infuse: "Akce Infuse", + title_producer: "Režisér", + title_collection: "Kolekce", + title_recomendations: "Doporučení", + title_similar: "Podobné", + title_about: "O aplikaci", + title_timetable: "Rozvrh", + title_relises: "Digitální vydání", + title_catalog: "Katalog", + title_category: "Kategorie", + title_parser: "Parser", + title_type: "Typ", + title_rating: "Hodnocení", + title_country: "Země", + title_year: "Rok", + title_genre: "Žánr", + title_filter: "Filtr", + title_notice: "Upozornění", + title_files: "Soubory", + title_now_watch: "Nyní sledují", + title_latest: "Poslední přidání", + title_continue: "Pokračovat ve sledování", + title_recomend_watch: "Doporučujeme sledovat", + title_new_episodes: "Nové epizody", + title_popular: "Populární", + title_popular_movie: "Populární filmy", + title_popular_tv: "Populární seriály", + title_new_this_year: "Novinky tohoto roku", + title_hight_voite: "S vysokým hodnocením", + title_new: "Novinky", + title_trend_day: "Dnes v trendu", + title_trend_week: "V trendu za týden", + title_upcoming: "Sledujte v kinech", + title_top_movie: "Top filmy", + title_top_tv: "Top seriály", + title_tv_today: "Dnes v televizi", + title_this_week: "Tento týden", + title_in_top: "V topu", + title_out: "Odchod", + title_out_confirm: "Ano, odejít", + title_continue_two: "Pokračovat", + title_choice_language: "Vybrat jazyk", + title_subscribe: "Přihlásit se", + title_subscribes: "Předplatné", + title_unsubscribe: "Odhlásit se", + title_language: "Jazyk originálu", + title_language_short: "Jazyk", + title_ongoing: "Probíhající", + title_pgrating: "Věkové omezení", + title_card: "Karta", + title_seasons: "Série", + title_episodes: "Epizody", + title_rewiews: "Recenze", + title_channel: "Kanál", + title_in_high_quality: "Ve vysoké kvalitě", + title_author: "Autor", + title_buffer: "Buffer", + title_upcoming_episodes: "Nadcházející epizody", + title_recent_episodes: "Nedávno vydané epizody", + title_reactions: "Reakce", + title_last_year: "Minulý rok", + title_reset: "Restartovat", + title_left: "Zbývá", + title_parental_control: "Rodičovská kontrola", + title_worth_rewatch: "Stojí za zhlédnutí znovu", + + reactions_none: "Žádné reakce", + reactions_fire: "Super", + reactions_nice: "Dobré", + reactions_think: "Sledovatelné", + reactions_bore: "Nuda", + reactions_shit: "Špatné", + reactions_ready: "Již jste zanechali reakci", + + subscribe_success: "Úspěšně jste se přihlásili", + subscribe_error: "Při přihlášení došlo k chybě, zkuste to později", + subscribe_noinfo: "Nepodařilo se získat informace, zkuste to později", + + company_headquarters: "Sídlo", + company_homepage: "Web", + company_country: "Země", + + country_ad: "Andorra", + country_ae: "SAE", + country_af: "Afghánistán", + country_al: "Albánie", + country_am: "Arménie", + country_ao: "Angola", + country_ar: "Argentina", + country_at: "Rakousko", + country_au: "Austrálie", + country_aw: "Aruba", + country_az: "Ázerbájdžán", + country_bа: "Bosna a Hercegovina", + country_bd: "Bangladéš", + country_be: "Belgie", + country_bg: "Bulharsko", + country_bh: "Bahrajn", + country_bi: "Burundi", + country_bj: "Benin", + country_bo: "Bolívie", + country_br: "Brazílie", + country_bs: "Bahamy", + country_bt: "Bhútán", + country_bw: "Botswana", + country_by: "Bělorusko", + country_ca: "Kanada", + country_ch: "Švýcarsko", + country_cl: "Chile", + country_cm: "Kamerun", + country_cn: "Čína", + country_co: "Kolumbie", + country_cr: "Kostarika", + country_cu: "Kuba", + country_cv: "Kapverdy", + country_cy: "Kypr", + country_cz: "Česko", + country_de: "Německo", + country_dj: "Džibutsko", + country_dk: "Dánsko", + country_do: "Dominikánská republika", + country_dz: "Alžírsko", + country_ec: "Ekvádor", + country_ee: "Estonsko", + country_eg: "Egypt", + country_es: "Španělsko", + country_et: "Etiopie", + country_fi: "Finsko", + country_fo: "Faerské ostrovy", + country_fr: "Francie", + country_ga: "Gabon", + country_gb: "Velká Británie", + country_ge: "Gruzie", + country_gh: "Ghana", + country_gl: "Grónsko", + country_gp: "Guadeloupe", + country_gr: "Řecko", + country_gt: "Guatemala", + country_hk: "Hongkong", + country_hr: "Chorvatsko", + country_ht: "Haiti", + country_hu: "Maďarsko", + country_id: "Indonésie", + country_ie: "Irsko", + country_il: "Izrael", + country_in: "Indie", + country_iq: "Irák", + country_ir: "Írán", + country_is: "Island", + country_it: "Itálie", + country_jm: "Jamajka", + country_jo: "Jordánsko", + country_jp: "Japonsko", + country_ke: "Keňa", + country_kg: "Kyrgyzstán", + country_kh: "Kambodža", + country_kp: "Severní Korea", + country_kr: "Jižní Korea", + country_kz: "Kazachstán", + country_kw: "Kuvajt", + country_la: "Laos", + country_lb: "Libanon", + country_li: "Lichtenštejnsko", + country_lk: "Srí Lanka", + country_lr: "Libérie", + country_lt: "Litva", + country_lu: "Lucembursko", + country_lv: "Lotyšsko", + country_ly: "Libye", + country_ma: "Maroko", + country_mc: "Monako", + country_md: "Moldavsko", + country_me: "Černá Hora", + country_mk: "Makedonie", + country_mm: "Myanmar", + country_mn: "Mongolsko", + country_mo: "Macao", + country_mt: "Malta", + country_mu: "Mauricius", + country_mv: "Maledivy", + country_mw: "Malawi", + country_mx: "Mexiko", + country_my: "Malajsie", + country_mz: "Mosambik", + country_na: "Namibie", + country_ne: "Niger", + country_ng: "Nigérie", + country_ni: "Nikaragua", + country_nl: "Nizozemsko", + country_no: "Norsko", + country_np: "Nepál", + country_nz: "Nový Zéland", + country_om: "Omán", + country_pa: "Panama", + country_pe: "Peru", + country_pg: "Papua-Nová Guinea", + country_ph: "Filipíny", + country_pk: "Pákistán", + country_pl: "Polsko", + country_pr: "Portoriko", + country_ps: "Palestina", + country_pt: "Portugalsko", + country_py: "Paraguay", + country_qa: "Katar", + country_ro: "Rumunsko", + country_rs: "Srbsko", + country_ru: "Rusko", + country_rw: "Rwanda", + country_sa: "Saúdská Arábie", + country_sd: "Súdán", + country_se: "Švédsko", + country_sg: "Singapur", + country_si: "Slovinsko", + country_sk: "Slovensko", + country_sn: "Senegal", + country_su: "SSSR", + country_sv: "Salvador", + country_sy: "Sýrie", + country_th: "Thajsko", + country_tj: "Tádžikistán", + country_tm: "Turkmenistán", + country_tn: "Tunisko", + country_tr: "Turecko", + country_tw: "Tchaj-wan", + country_tz: "Tanzanie", + country_ua: "Ukrajina", + country_ug: "Uganda", + country_us: "USA", + country_uy: "Uruguay", + country_uz: "Uzbekistán", + country_ve: "Venezuela", + country_vn: "Vietnam", + country_ws: "Samoa", + country_xk: "Kosovo", + country_ye: "Jemen", + country_yu: "Jugoslávie", + country_za: "JAR", + country_zm: "Zambie", + country_zw: "Zimbabwe", + + filter_clarify: "Upřesnit", + filter_clarify_two: "Upřesnit hledání", + filter_set_name: "Uveďte název", + filter_sorted: "Seřadit", + filter_filtred: "Filtr", + filter_any: "Jakýkoli", + filter_combinations: "Kombinace", + filter_alt_names: "Další názvy", + filter_rating_from: "od", + filter_rating_to: "do", + + filter_lang_af: "Afrikánština", + filter_lang_ar: "Arabština", + filter_lang_az: "Ázerbájdžánština", + filter_lang_ba: "Baškirština", + filter_lang_be: "Běloruština", + filter_lang_bg: "Bulharština", + filter_lang_bn: "Bengálština", + filter_lang_bs: "Bosenština", + filter_lang_ca: "Katalánština", + filter_lang_ce: "Čečenština", + filter_lang_cs: "Čeština", + filter_lang_da: "Dánština", + filter_lang_de: "Němčina", + filter_lang_el: "Řečtina", + filter_lang_en: "Angličtina", + filter_lang_es: "Španělština", + filter_lang_et: "Estonština", + filter_lang_fa: "Perština", + filter_lang_fi: "Finština", + filter_lang_fr: "Francouzština", + filter_lang_ga: "Irština", + filter_lang_gl: "Galicijština", + filter_lang_gn: "Guaraní", + filter_lang_he: "Hebrejština", + filter_lang_hi: "Hindština", + filter_lang_hr: "Chorvatština", + filter_lang_hu: "Maďarština", + filter_lang_hy: "Arménština", + filter_lang_id: "Indonéština", + filter_lang_is: "Islandština", + filter_lang_it: "Italština", + filter_lang_ja: "Japonština", + filter_lang_ka: "Gruzínština", + filter_lang_kk: "Kazaština", + filter_lang_ko: "Korejština", + filter_lang_ks: "Kašmírština", + filter_lang_ku: "Kurdština", + filter_lang_ky: "Kyrgyzština", + filter_lang_lt: "Litevština", + filter_lang_lv: "Lotyština", + filter_lang_mi: "Maorština", + filter_lang_mk: "Makedonština", + filter_lang_mn: "Mongolština", + filter_lang_mt: "Maltština", + filter_lang_ne: "Nepálština", + filter_lang_nl: "Nizozemština", + filter_lang_no: "Norština", + filter_lang_pa: "Paňdžábština", + filter_lang_pl: "Polština", + filter_lang_ps: "Paštština", + filter_lang_pt: "Portugalština", + filter_lang_ro: "Rumunština", + filter_lang_ru: "Ruština", + filter_lang_si: "Sinhálština", + filter_lang_sk: "Slovenština", + filter_lang_sl: "Slovinština", + filter_lang_sm: "Samoánština", + filter_lang_so: "Somálština", + filter_lang_sq: "Albánština", + filter_lang_sr: "Srbština", + filter_lang_sv: "Švédština", + filter_lang_sw: "Svahilština", + filter_lang_ta: "Tamilština", + filter_lang_tg: "Tádžičtina", + filter_lang_th: "Thajština", + filter_lang_tk: "Turkmenština", + filter_lang_tr: "Turečtina", + filter_lang_tt: "Tatarština", + filter_lang_ur: "Urdština", + filter_lang_uk: "Ukrajinština", + filter_lang_uz: "Uzbečtina", + filter_lang_vi: "Vietnamština", + filter_lang_yi: "Jidiš", + filter_lang_zh: "Čínština", + + filter_genre_ac: "Akční", + filter_genre_ad: "Dobrodružný", + filter_genre_mv: "Animovaný", + filter_genre_cm: "Komedie", + filter_genre_cr: "Krimi", + filter_genre_dc: "Dokumentární", + filter_genre_dr: "Drama", + filter_genre_fm: "Rodinný", + filter_genre_fe: "Fantasy", + filter_genre_hi: "Historický", + filter_genre_ho: "Horor", + filter_genre_mu: "Hudební", + filter_genre_de: "Detektivní", + filter_genre_md: "Romantický", + filter_genre_fa: "Sci-Fi", + filter_genre_tv: "Televizní film", + filter_genre_tr: "Thriller", + filter_genre_mi: "Válečný", + filter_genre_ve: "Western", + filter_genre_aa: "Akční a Dobrodružný", + filter_genre_ch: "Dětský", + filter_genre_nw: "Zprávy", + filter_genre_rs: "Reality show", + filter_genre_hf: "Sci-Fi a Fantasy", + filter_genre_op: "Soap opera", + filter_genre_tc: "Talk show", + filter_genre_mp: "Válka a Politika", + + empty_title: "Prázdné", + empty_text: "Podle vašeho filtru nebylo nic nalezeno, upřesněte filtr.", + empty_title_two: "Zde je prázdno", + empty_text_two: "Momentálně je seznam prázdný", + + back_to_card: "Vrátit se na kartu", + + menu_main: "Hlavní", + menu_movies: "Filmy", + menu_tv: "Seriály", + menu_catalog: "Katalog", + menu_filter: "Filtr", + menu_collections: "Kolekce", + menu_relises: "Vydání", + menu_anime: "Anime", + menu_bookmark: "Záložky", + menu_like: "Líbí se", + menu_time: "Později", + menu_history: "Historie", + menu_timeline: "Rozvrh", + menu_torrents: "Torrenty", + menu_settings: "Nastavení", + menu_about: "Informace", + menu_console: "Konzole", + menu_multmovie: "Animované filmy", + menu_multtv: "Animované seriály", + menu_feed: "Kanál", + + lampa_movie_title: "Lampa film", + lampa_movie_descr: "Sledujte novinky na svém smartphonu.
    Telegram: @lampa_movie", + + plugins_catalog_work: "Funkční pluginy", + plugins_catalog_work_descr: "Pluginy, které určitě fungují v lampě.", + plugins_catalog_popular: "Populární pluginy mezi uživateli", + plugins_catalog_popular_descr: "Instalace z neznámých zdrojů může vést k nesprávné funkci aplikace.", + plugins_online: "Sledování online", + plugins_check_fail: "Nepodařilo se ověřit funkčnost pluginu. To však neznamená, že plugin nefunguje. Restartujte aplikaci pro zjištění, zda se plugin načítá.", + plugins_need_reload: "Pro použití pluginu je nutné restartovat aplikaci", + plugins_install: "Nainstalovat", + plugins_install_ready: "Tento plugin je již nainstalován.", + plugins_installed: "Instalace", + plugins_load_from: "Načteno z CUB", + plugins_ok_for_check: "Stiskněte (OK) pro kontrolu pluginu", + plugins_no_loaded: "Při načítání aplikace se nepodařilo načíst některé pluginy", + plugins_remove: "Odstranit pluginy", + plugins_add_success: "Plugin úspěšně připojen", + + time_viewed: "Zhlédnuto", + time_from: "z", + time_reset: "Resetovat časový kód", + + settings_clear_cache: "Cache a data vymazána", + settings_clear_cache_only: "Cache vymazána", + settings_user_links: "Uživatelský odkaz", + settings_for_local: "Pro lokální TorrServer", + settings_add: "Přidat", + settings_remove: "Odstranit", + settings_this_value: "aktuální hodnota", + settings_added: "Přidáno", + settings_removed: "Odstraněno", + settings_reset: "Resetovat nastavení", + + settings_param_player_inner: "Vestavěný", + settings_param_player_outside: "Externí", + settings_param_player_inner_tvos: 'Vnitřní', + settings_param_yes: "Ano", + settings_param_no: "Ne", + settings_param_interface_size_small: "Menší", + settings_param_interface_size_normal: "Normální", + settings_param_interface_size_bigger: "Větší", + settings_param_poster_quality_low: "Nízké", + settings_param_poster_quality_average: "Střední", + settings_param_poster_quality_high: "Vysoké", + settings_param_parse_directly: "Přímo", + settings_param_parse_api: "Přes API webu", + settings_param_background_complex: "Komplexní", + settings_param_background_simple: "Jednoduchý", + settings_param_background_image: "Obrázek", + settings_param_link_use_one: "Hlavní", + settings_param_link_use_two: "Doplňkovou", + settings_param_link_use_both: "Obě", + settings_param_subtitles_size_small: "Malé", + settings_param_subtitles_size_normal: "Obvyklé", + settings_param_subtitles_size_bigger: "Velké", + settings_param_screensaver_nature: "Příroda", + settings_param_torrent_lang_orig: "Originál", + settings_param_player_timecode_again: "Začít od začátku", + settings_param_player_timecode_continue: "Pokračovat", + settings_param_player_timecode_ask: "Ptát se", + settings_param_player_scale_method: "Vypočítat", + settings_param_player_hls_app: "Systémový", + settings_param_player_hls_js: "Softwarový", + settings_param_card_view_load: "Načítat", + settings_param_card_view_all: "Zobrazit vše", + settings_param_navigation_remote: "Dálkový ovladač", + settings_param_navigation_mouse: "Dálkový ovladač s myší", + settings_param_keyboard_lampa: "Vestavěná", + settings_param_keyboard_system: "Systémová", + settings_param_card_interface_old: "Starý", + settings_param_card_interface_new: "Nový", + + settings_param_glass_easy: "Průhledná", + settings_param_glass_medium: "Poloprůhledná", + settings_param_glass_blacked: "Ztmavená", + + settings_param_jackett_interview_all: "Vše", + settings_param_jackett_interview_healthy: "Pouze dostupné", + settings_parser_jackett_interview: "Dotazovat se na trackery", + + helper_keyboard: "Po zadání hodnoty stiskněte tlačítko «Zpět» pro uložení", + helper_torrents: "Podržte tlačítko (OK) pro vyvolání kontextového menu", + helper_cleared: "Úspěšně, nápovědy budou zobrazeny znovu.", + helper_torrents_view: "Pro resetování časového kódu a vyvolání menu podržte tlačítko (OK)", + + fav_sync_title: "Synchronizace záložek", + fav_sync_text: "Vaše oblíbené záložky s vámi. Připojte synchronizaci a sledujte na jakémkoli zařízení.

    Pro to se zaregistrujte na webu {site}, vytvořte profil a přihlaste se do aplikace.", + fav_sync_site: "Web", + fav_remove_title: "Odstranit z historie", + fav_remove_descr: "Odstranit vybranou kartu", + fav_clear_title: "Vymazat historii", + fav_clear_descr: "Odstranit všechny karty z historie", + fav_clear_label_title: "Vymazat značky", + fav_clear_label_descr: "Vymazat značky o sledování", + fav_clear_time_title: "Vymazat časové kódy", + fav_clear_time_descr: "Vymazat všechny časové kódy", + fav_label_cleared: "Značky vymazány", + fav_time_cleared: "Časové kódy vymazány", + + timetable_empty: "V této sekci budou zobrazeny data vydání nových epizod", + + player_quality: "Kvalita", + player_flow: 'Tok', + player_tracks: "Zvukové stopy", + player_disabled: "Zakázáno", + player_unknown: "Neznámé", + player_subs: "Titulky", + player_size_default_title: "Výchozí", + player_size_default_descr: "Výchozí velikost videa", + player_size_cover_title: "Rozšířit", + player_size_cover_descr: "Rozšíří video na celou obrazovku", + player_size_fill_title: "Vyplnit", + player_size_fill_descr: "Přizpůsobit video na celou obrazovku", + player_size_s115_title: "Zvětšit 115%", + player_size_s115_descr: "Zvětšit video na 115%", + player_size_s130_title: "Zvětšit 130%", + player_size_s130_descr: "Zvětšit video na 130%", + player_size_v115_title: "Vertikálně 115%", + player_size_v115_descr: "Zvětšit video na 115%", + player_size_v130_title: "Vertikálně 130%", + player_size_v130_descr: "Zvětšit video na 130%", + player_video_size: "Velikost videa", + player_playlist: "Playlist", + player_error_one: "Nepodařilo se dekódovat video", + player_error_two: "Video nebylo nalezeno nebo je poškozeno", + player_start_from: "Pokračovat ve sledování od", + player_not_found: "Přehrávač nebyl nalezen", + player_lauch: "Spustit přehrávač", + player_speed_default_title: "Obvyklá", + player_speed_two_descr: "Přehrává se bez zvuku", + player_video_speed: "Rychlost přehrávání", + player_share_title: "Sdílet", + player_share_descr: "Spustit toto video na jiném zařízení", + player_normalization_power_title: "Síla normalizace", + player_normalization_smooth_title: "Rychlost normalizace", + player_normalization_step_none: "Žádná", + player_normalization_step_low: "Nízká", + player_normalization_step_medium: "Střední", + player_normalization_step_hight: "Vysoká", + player_normalization: "Normalizace", + player_youtube_no_played: "Bohužel, toto video není dostupné ve vaší oblasti, možná bylo zablokováno nebo odstraněno.", + player_youtube_start_play: 'Pro spuštění přehrávání videa stiskněte tlačítko "Přehrát"', + + broadcast_open: "Otevřít kartu na jiném zařízení", + broadcast_play: "Vyberte zařízení pro sledování", + + card_new_episode: "Nová epizoda", + card_book_remove: "Odebrat ze záložek", + card_book_add: "Do záložek", + card_book_descr: "Sledujte v menu (Záložky)", + card_like_remove: "Odebrat z oblíbených", + card_like_add: "Líbí se", + card_like_descr: "Sledujte v menu (Líbí se)", + card_wath_remove: "Odebrat z očekávaných", + card_wath_add: "Sledovat později", + card_wath_descr: "Sledujte v menu (Později)", + card_history_remove: "Odebrat z historie", + card_history_add: "Do historie", + card_history_descr: "Sledujte v menu (Historie)", + + keyboard_listen: "Mluvte, poslouchám...", + keyboard_nomic: "Není přístup k mikrofonu", + + notice_new_quality: "Dostupná nová kvalita", + notice_quality: "Kvalita", + notice_new_episode: "Nová epizoda", + notice_none: "Ještě nemáte žádná upozornění, zaregistrujte se na webu {site}, abyste sledovali nové epizody a vydání.", + notice_in_quality: "V kvalitě", + notice_none_account: "Ještě nemáte žádná upozornění, přidejte seriály do záložek a očekávejte upozornění o nových epizodách.", + notice_none_system: "Momentálně nemáte žádná upozornění. Určitě vás upozorníme, když se objeví nová upozornění.", + + copy_link: "Kopírovat odkaz na video", + copy_secuses: "Odkaz zkopírován do schránky", + copy_error: "Chyba při kopírování odkazu", + + account_sync_to_profile: "Všechny záložky budou přeneseny do profilu", + account_sync_secuses: "Všechny záložky úspěšně přeneseny", + account_profiles: "Profily", + account_profiles_empty: "Nepodařilo se získat seznam profilů", + account_authorized: "Autorizováno", + account_logged_in: "Jste přihlášeni pod účtem", + account_login_failed: "Přihlášení se nezdařilo", + account_login_wait: "Čekáme na přihlášení do účtu", + account_profile_main: "Hlavní", + account_export_secuses: "Export úspěšně dokončen", + account_export_fail: "Chyba při exportu", + account_export_fail_500: "Neznámá chyba", + account_export_fail_610: "Vyčerpali jste limit na dnešek", + account_export_fail_200: "Chyba databáze, zkuste to později", + account_export_fail_600: "Chyba, nepodařilo se načíst soubor", + account_export_fail_620: "Chyba, soubor nebyl předán", + account_import_secuses: "Import úspěšně dokončen", + account_import_fail: "Chyba při importu", + account_imported: "importováno", + account_reload_after: "restart za 5 sek.", + account_create: 'Otevřete více možností s účtem CUB. Zaregistrujte se na webu a získejte přístup k synchronizaci vašich záložek, časových kódů a dalších možností účtu CUB.', + account_premium: 'Odemkněte nové obzory s prémiovým účtem CUB! Využijte zvýšené limity a vylepšené funkce služeb. Navštivte a dozvíte se více o výhodách prémiového účtu.', + account_premium_more: "Více o CUB Premium", + account_limited: 'Dosáhli jste maximálního limitu. Zvýšte limit s účtem CUB Premium. Více na webu ', + account_premium_include_1: "Zvýšení počtu záložek", + account_premium_include_2: "Zvýšení historie sledování", + account_premium_include_3: "Zvýšení počtu časových kódů", + account_premium_include_4: "Počet profilů na účet", + account_premium_include_5: "Upozornění", + account_premium_include_6: "Synchronizace dat", + account_premium_include_text_1: "Více záložek - více možností! Ukládejte své oblíbené filmy a seriály, vytvářejte seznamy sledování a užívejte si sledování kdykoli.", + account_premium_include_text_2: "Zvyšte historii sledování v aplikaci a sledujte, co jste již viděli. Snadno najděte a znovu sledujte své oblíbené filmy a seriály.", + account_premium_include_text_3: "Nebojte se, že přijdete o důležitou scénu! Zvyšte počet časových kódů v aplikaci a snadno sledujte, kde jste přestali ve sledování oblíbených filmů a seriálů.", + account_premium_include_text_4: "Získejte více svobody s naším prémiovým přístupem! Zvyšte počet profilů na účtu a umožněte svým přátelům a blízkým užívat si filmy a seriály spolu s vámi. Žádná omezení - užívejte si sledování s milovanými lidmi.", + account_premium_include_text_5: "Nezmeškejte žádnou novou epizodu nebo překlad! Dostávejte upozornění včas a buďte v obraze všech aktualizací. Zvyšte svůj filmový proud s námi a dostávejte upozornění o vydání nových epizod a překladů přímo na svůj smartphone.", + account_premium_include_text_6: "Synchronizujte svá data mezi zařízeními s prémiovým přístupem! Už nemusíte ztrácet čas hledáním poslední epizody, na které jste přestali. S naším prémiovým přístupem můžete synchronizovat svá data mezi zařízeními, abyste mohli pokračovat ve sledování z místa, kde jste přestali, na jakémkoli zařízení, kde je aplikace nainstalována.", + account_code_enter: "Zadejte šestimístný kód", + account_code_error: "Možná jste zadali nesprávný nebo zastaralý kód", + account_code_wrong: "Možná jste zadali nesprávný formát", + account_code_where: 'řejděte na web a zadejte tam uvedený kód.', + account_code_input: "Zadejte kód", + + network_noconnect: "Žádné připojení k síti", + network_404: "Požadovaná stránka nebyla nalezena. [404]", + network_401: "Autorizace se nezdařila", + network_500: "Interní chyba serveru. [500]", + network_parsererror: "Požadovaný syntaktický rozbor JSON se nezdařil.", + network_timeout: "Čas požadavku vypršel.", + network_abort: "Požadavek byl přerušen.", + network_error: "Neznámá chyba", + + size_zero: "0 Bajtů", + size_byte: "Bajt", + size_kb: "KB", + size_mb: "MB", + size_gb: "GB", + size_tb: "TB", + size_pp: "PB", + + speed_bit: "bit/s", + speed_kb: "Kbit/s", + speed_mb: "Mbit/s", + speed_gb: "Gbit/s", + speed_tb: "Tbit/s", + speed_pp: "Pbit/s", + + month_1: "Leden", + month_2: "Únor", + month_3: "Březen", + month_4: "Duben", + month_5: "Květen", + month_6: "Červen", + month_7: "Červenec", + month_8: "Srpen", + month_9: "Září", + month_10: "Říjen", + month_11: "Listopad", + month_12: "Prosinec", + + day_1: "Pondělí", + day_2: "Úterý", + day_3: "Středa", + day_4: "Čtvrtek", + day_5: "Pátek", + day_6: "Sobota", + day_7: "Neděle", + + month_1_e: "Ledna", + month_2_e: "Února", + month_3_e: "Března", + month_4_e: "Dubna", + month_5_e: "Května", + month_6_e: "Června", + month_7_e: "Července", + month_8_e: "Srpna", + month_9_e: "Září", + month_10_e: "Října", + month_11_e: "Listopadu", + month_12_e: "Prosince", + + week_1: "Po", + week_2: "Út", + week_3: "St", + week_4: "Čt", + week_5: "Pá", + week_6: "So", + week_7: "Ne", + + time_h: "h.", + time_m: "m.", + time_s: "s.", + + extensions_enable: "Povolit", + extensions_disable: "Zakázat", + extensions_check: "Zkontrolovat stav", + extensions_install: "Nainstalovat", + extensions_info: "Informace", + extensions_edit: "Upravit", + extensions_change_name: "Změnit název", + extensions_change_link: "Změnit odkaz", + extensions_remove: "Odstranit", + extensions_set_name: "Zadejte název pluginu", + extensions_set_url: "Zadejte adresu pluginu", + extensions_ready: "Tento plugin je již nainstalován", + extensions_no_info: "Bez informací", + extensions_no_name: "Bez názvu", + extensions_worked: "Funkční", + extensions_no_plugin: "Plugin není potvrzen", + extensions_add: "Přidat plugin", + extensions_from_memory: "Nainstalováno do paměti", + extensions_from_cub: "Nainstalováno z CUB", + extensions_from_popular: "Populární pluginy", + extensions_from_lib: "Knihovna pluginů", + extensions_from_connected: "Připojené pluginy", + extensions_hpu_best: "Populární", + extensions_hpu_recomend: "Doporučujeme", + extensions_hpu_theme: "Témata", + extensions_hpu_screensaver: "Spořič obrazovky", + extensions_hpu_video: "Video", + extensions_hpu_control: "Ovládání", + extensions_hpu_other: "Různé", + extensions_hpu_: "Ostatní", + + speedtest_connect: "připojení", + speedtest_test: "testování", + speedtest_ready: "připraveno", + speedtest_button: "Testovat rychlost", + + change_source_on_cub: "Změnit zdroj na CUB", + + tv_status_returning_series: "Probíhající", + tv_status_planned: "Naplánováno", + tv_status_in_production: "Ve výrobě", + tv_status_ended: "Ukončeno", + tv_status_canceled: "Zrušeno", + tv_status_pilot: "Pilotní", + tv_status_released: "Vydáno", + tv_status_rumored: "Podle pověstí", + tv_status_post_production: "Brzy", + + input_detection_touch: "Chcete přepnout na dotykové ovládání?", + input_detection_mouse: "Chcete přepnout na ovládání myší?", + input_detection_remote: "Chcete přepnout na ovládání dálkovým ovladačem?", + + https_text: "Používáte protokol HTTPS, se kterým Lampa nefunguje správně. Pro správnou funkci aplikace použijte adresu s protokolem HTTP", + + premiere_author_recomend_1: "Objednejte si pizzu a připravte se na jízdu.", + premiere_author_recomend_2: "Párty teprve začíná.", + premiere_author_recomend_3: "Připravte se na adrenalin.", + premiere_author_recomend_4: "Připraveni na nezapomenutelný večer?", + premiere_author_recomend_5: "Doporučuji ke sledování.", + premiere_title: "Premiéra", + + termsofuse_t_01: "Pravidla používání", + termsofuse_t_02: "Lampa je užitečný nástroj pro seznámení s novinkami filmového průmyslu, včetně filmů, seriálů, animovaných filmů a dalších informací. Pro získání informací o filmech se používá otevřený zdroj - web themoviedb.org", + termsofuse_t_03: "Obsah", + termsofuse_t_04: "Lampa používá API (Application Programming Interface) z katalogu themoviedb.org pro získání informací o filmech a televizních seriálech, stejně jako pro prohlížení souvisejících mediálních souborů, jako jsou plakáty, trailery a další.", + termsofuse_t_05: "API z themoviedb.org umožňuje aplikaci Lampa přístup k databázi filmů a televizních seriálů, poskytující možnost vyhledávání mediálních souborů a prohlížení informací o nich.", + termsofuse_t_06: "Interakce mezi aplikací Lampa a themoviedb.org probíhá prostřednictvím požadavků na API, které jsou odesílány z aplikace Lampa na servery themoviedb.org pro získání informací a mediálních souborů. Themoviedb.org zpracovává požadavky a odesílá zpět do aplikace Lampa požadovaná data.", + termsofuse_t_07: "Díky použití API z themoviedb.org poskytuje aplikace Lampa uživatelům přístup k rozsáhlé databázi filmů a televizních seriálů, přičemž dodržuje podmínky používání a omezení stanovená držitelem práv.", + termsofuse_t_08: "Rozšíření", + termsofuse_t_09: "Rozšíření jsou mocný nástroj poskytovaný pro aplikaci Lampa, který umožňuje uživatelům rozšířit její možnosti, přidat další funkce a změnit obsah podle jejich potřeb.", + termsofuse_t_10: "Je však třeba poznamenat, že uživatelé instalují rozšíření na vlastní nebezpečí. Veškeré důsledky vyplývající z používání rozšíření padají na uživatele. Uživatelům se doporučuje být opatrní při instalaci a používání rozšíření, pečlivě hodnotit jejich spolehlivost a bezpečnost.", + termsofuse_t_11: "Porušení autorských práv", + termsofuse_t_12: "Pokud jste objevili porušení autorských práv v aplikaci Lampa - kontaktujte vývojáře pomocí sekce Kontakty aplikace. Je však důležité vzít v úvahu, že aplikace Lampa používá API z katalogu themoviedb.org, který poskytuje otevřený přístup k informacím o filmech a seriálech. To znamená, že informace, které se zobrazují v aplikaci Lampa, jsou veřejně dostupné a neporušují autorská práva.", + termsofuse_t_13: "Pokud se domníváte, že v aplikaci Lampa je přesto obsah porušující autorská práva - obraťte se na držitele práv tohoto obsahu s žádostí o jeho odstranění ze stránek webu themoviedb.org. Aplikace Lampa může obsah odstranit po obdržení příslušného oznámení o porušení autorských práv.", + + install_app_apk_title: 'Jak nainstalovat Lampu na Android', + install_app_apk_text: 'Všimli jsme si, že k spuštění Lampy na Androidu používáte MediaStationX. Doporučujeme nainstalovat Lampu jako aplikaci APK. Tím zajistíte stabilnější provoz a přístup ke všem funkcím aplikace.

    Přejděte do telegramové skupiny a stáhněte si nejnovější APK a pokyny k instalaci.', + install_app_apk_qr: 'Naskenujte QR kód a stáhněte si APK Lampy', + copy_link_buffer: 'Kopírovat odkaz', + + ad: "Reklama", + ad_disable: "Předplatným CUB Premium zapomenete na reklamu.", + ad_after: "Reklama za", + ad_skip: "Přeskočit", + ad_continue_after: "Sledování začne za", + + discuss_rules_title: "Dodržujte pravidla a respektujte ostatní — vytváříme pohodlí společně!", + discuss_rules_rule_1: "Nepoužívejte slova složená pouze z čísel.", + discuss_rules_rule_2: "Pište v jednom jazyce, používejte slova z 5 a více písmen.", + discuss_rules_rule_3: "Používejte interpunkční znaménka a ukončujte věty tečkami.", + discuss_rules_rule_4: "Vyhněte se nejasným symbolům !?#%", + discuss_rules_rule_5: "Pište celé věty, používejte věty z 5 a více slov.", + discuss_rules_rule_6: "Nepoužívejte příliš dlouhá slova.", + discuss_rules_rule_7: "Snažte se vejít do 300 znaků.", + discuss_voited: "Děkujeme za vaše hodnocení! Váš hlas pomáhá zlepšovat obsah.", + + confirm_open_player: "Jiné zařízení žádá o přístup k přehrávači. Chcete přehrát video?", + + pincode_use_remote: "Použijte dálkový ovladač pro zadání kódu, stiskněte šipky pro výběr požadovaného čísla.", + pincode_use_toggle: "Stiskněte a podržte tlačítko OK pro změnu rozložení.", + title_fire: 'Oheň!', + title_top_100: 'Top 100', + + player_normalization_type_title: 'Typ normalizace', + player_normalization_type_all: 'Vše', + player_normalization_type_up: 'Pouze zvýšení', + player_normalization_type_down: 'Pouze snížení', + storage_quota_exceeded: 'Překročena kvóta úložiště. Vymažte mezipaměť a zkuste to znovu.', + settings_cub_domain: 'Primární doména', + + title_ai_assistant: 'AI asistent', + title_facts: 'Zajímavá fakta', + ai_search_start_typing: 'Zeptejte se AI asistenta, jaké filmy chcete najít. Například: "Filmy o vesmíru"', + ai_search_limit: 'Překročen limit dotazů. Zkuste to prosím znovu později. S předplatným CUB Premium se limity zvýší a nebudete muset čekat!', + ai_subscribe_title: 'Odemkněte více možností s AI', + ai_subscribe_descr: 'Předplaťte si CUB Premium a zvyšte počet dotazů na AI. Společně s AI pro vás vybereme ty nejlepší filmy, jaké můžeme najít.', + + dmca_title: 'Obsah zablokován', + dmca_descr: 'Tento materiál není k nahlédnutí. Byl zablokován na žádost držitele autorských práv v souladu s autorským zákonem.', + + loading_progress_step_0: 'Příprava', + loading_progress_step_1: 'Načítání jazyků', + loading_progress_step_2: 'Hledání zrcadel', + loading_progress_step_3: 'Příprava rozšíření', + loading_progress_step_4: 'Už jen trochu', + loading_progress_step_5: 'Už brzy', + + install_extension_rule_1: 'Instalace externího pluginu', + install_extension_rule_2: 'Pluginy jsou vytvářeny nezávislými vývojáři a LAMPA neověřuje jejich obsah. Instalací souhlasíte s tím, že:', + install_extension_rule_3: '- Některé pluginy mohou požadovat přístup k vašim datům nebo pracovat s neověřenými zdroji.', + install_extension_rule_4: '- Pokud vámi nainstalovaný plugin porušuje autorská práva nebo jiné zákony, veškerá odpovědnost za jeho použití je na vás.', + install_extension_rule_5: '- Instalujte pouze pluginy z důvěryhodných zdrojů. Pokud máte pochybnosti o bezpečnosti nebo legálnosti pluginu, raději jej neinstalujte.', + install_extension_rule_6: 'LAMPA nepodporuje ani neschvaluje pluginy související s pirátským obsahem.', + install_extension_rule_7: 'Pokračováním potvrzujete, že rozumíte těmto rizikům.', + ad_plugin: 'Reklama z pluginu', + + terminal_title: 'Terminál', + terminal_no_access: 'Bez přístupu', + terminal_confirm: 'Povolit', + terminal_deny: 'Zakázat', + terminal_update: 'Aktualizovat', + terminal_code: 'Přístupový kód', + terminal_text: 'Žádáte o přístup k terminálu. Vývojáři mohou získat přístup k vašemu zařízení a ovládat jej. To může být užitečné pro diagnostiku a řešení problémů, ale také to může představovat bezpečnostní riziko. Ujistěte se, že důvěřujete vývojářům, než udělíte přístup.

    Tuto funkci můžete kdykoli vypnout kliknutím na tlačítko "Zakázat".', + + title_anons: 'Oznámení', + title_developer: 'Vývojář', + title_navigation: 'Navigace', + title_page: 'Stránka', + title_person_about: 'O osobě', + account_qr_premium: 'Naskenujte QR kód a zjistěte více o CUB Premium', + account_qr_code: 'Naskenujte QR kód a získejte kód pro propojení zařízení', + account_qr_create: 'Naskenujte QR kód a vytvořte účet', + account_add_device_title: 'Přidat zařízení', + account_add_device_text: 'Přejděte na a získejte kód pro přidání zařízení.', + account_none_title: 'Ještě nemáte účet?', + account_none_include_1: 'Záložky a historie sledování se ukládají do cloudu', + account_none_include_2: 'Synchronizace mezi zařízeními', + account_none_include_3: 'Upozornění na nové epizody a vydání', + account_none_include_4: 'Vytvářejte více profilů pod jedním účtem', + account_premium_include_1: 'Zvětšený počet záložek', + account_premium_include_2: 'Rozšířená historie sledování', + account_premium_include_3: 'Více dostupných časových značek', + account_premium_include_4: 'Počet profilů na jeden účet', + empty_subscribes_title: 'Vaše odběry překladů', + empty_subscribes_text: 'Stačí se přihlásit k odběru oblíbeného překladu a my vás upozorníme, až vyjde nová epizoda.', + empty_history_title: 'Vaše historie sledování', + empty_history_text: 'Vaše historie sledování se zobrazí zde.', + empty_bookmark_title: 'Vaše oblíbené', + empty_bookmark_text: 'Přidejte filmy a seriály, které se vám líbí, do oblíbených, abyste je snadno našli v této sekci.', + empty_mytorrents_title: 'Vaše torrenty', + empty_mytorrents_text: 'Torrenty stažené přes TorServer se zobrazí zde.', + developer_param_enabled: 'Režim vývojáře', + developer_param_nopremium: 'Vypnout CUB Premium', + developer_param_nodemo: 'Vypnout demo režim', + developer_param_ads: 'Zobrazovat reklamy', + developer_param_fps: 'Zobrazovat FPS', + developer_trigger_help_1: 'Téměř jste to uhodli :)', + developer_trigger_help_2: 'Ještě trochu :)', + developer_trigger_help_3: 'Opravdu chcete vstoupit do režimu vývojáře?', + developer_trigger_help_4: 'Režim vývojáře aktivován', + settings_param_navigation_touch: 'Dotykové ovládání', + account_discuss_add_qr: 'Naskenujte QR kód', + account_discuss_add_title: 'Chcete přidat komentář?', + account_discuss_add_text: 'Naskenujte QR kód a otevřete aplikaci, kde můžete přidat komentář k tomuto filmu nebo seriálu.

    - Vezměte telefon nebo tablet
    - Otevřete fotoaparát
    - Namiřte na QR kód
    - Otevřete odkaz, který se objeví na obrazovce', + account_discuss_added: 'Děkujeme za váš komentář!', + account_discuss_added_ready: 'Komentář k tomuto filmu nebo seriálu jste již přidali.', + remote_helper_long: 'Podržte tlačítko (OK) pro otevření menu', + account_premium: 'Odemkněte nové možnosti s účtem CUB Premium! Užijte si vyšší limity a rozšířené funkce služby. Navštivte a zjistěte více o výhodách prémiového účtu.', + player_segments_title: 'Segmenty', + player_segments_descr: 'Přeskočit úvod a další části videa', + player_segments_ad_title: 'Reklamy', + player_segments_skip_title: 'Úvod a další', + player_segments_value_none: 'Nepřeskakovat', + player_segments_value_auto: 'Automaticky přeskočit', + player_segments_value_user: 'Vlastní', + player_segments_skiped: 'Segment přeskočen', + player_segments_skip_now: 'Přeskočit', + player_segments_skip_in: 'Přeskočit za', + player_segments_skip_intro: 'Přeskočit úvod', + player_segments_next: 'Další epizoda', + player_segments_next_in: 'Další epizoda za', + subscribe_info: 'V sekci „Odběry“ uvidíte všechny své odběry překladů. Dostanete upozornění, až vyjde nová epizoda s vaším vybraným překladem.', + no_watch_history: 'Žádná historie prohlížení', + settings_request_caching_use: 'Povolit ukládání do mezipaměti', + settings_request_caching_descr: 'Ukládejte odpovědi z požadavků do mezipaměti pro rychlejší načítání obsahu.', + + account_profile_child: 'Dítě', + account_profile_add: 'Přidat profil', + account_profile_name: 'Název profilu', + account_profile_created: 'Profil byl úspěšně vytvořen', + account_profile_limited: 'Byl dosažen maximální počet profilů: {count}', + account_profile_info: 'Profily můžete spravovat v nastavení účtu. Chcete-li to provést, přejděte na ', + player_youtube_no_support: 'Vaše zařízení nepodporuje přehrávání videí z YouTube, zkontrolujte připojení k internetu.', + title_channels: 'Kanály', + title_best_of_2000: 'Zlatá léta 21. století', + title_best_of_2010: 'Hity 21. století', + title_best_of_2015: 'Moderní klasika', + title_comedy_of_2000: 'Smích 21. století', + title_comedy_of_2010: 'Humor 21. století', + title_comedy_of_2015: 'Moderní komedie', + + filter_keyword_sequel: 'Pokračování', + filter_keyword_based_comic: 'Na motivy komiksu', + filter_keyword_space: 'Vesmír', + filter_keyword_survival: 'Přežití', + filter_keyword_zombie: 'Zombie', + filter_keyword_school: 'Škola', + filter_keyword_revenge: 'Pomsta', + filter_keyword_detective: 'Detektiv', + filter_keyword_robots: 'Roboti', + filter_keyword_vampires: 'Upíři', + filter_keyword_aliens: 'Vetřelci', + filter_keyword_police: 'Policie', + filter_keyword_reincarnation: 'Reinkarnace', + filter_keyword_spy: 'Špion', + filter_keyword_disaster: 'Katastrofa', + filter_keyword_christmas: 'Vánoce', + + dmca_title_lgbt: 'Obsah omezen', + dmca_descr_lgbt: 'Prohlížení není ve vašem regionu možné, protože může obsahovat LGBT obsah. Takový materiál může být v některých zemích zakázán nebo omezen.', + + settings_lgbt_content_block: 'Blokovat LGBT obsah', + + // todo: + adult_content_title: 'Obsah pro dospělé', + adult_content_text_warning: 'Obsah může obsahovat materiál pro dospělé, který může být nevhodný pro některé diváky.', + adult_content_text_modal: 'Tento film nebo seriál je označen jako obsahující obsah pro dospělé. Musíte být starší 18 let, abyste mohli tento materiál sledovat. Potvrďte prosím, že jste dosáhli zákonného věku pro pokračování ve sledování.', + + adult_content_confirm: 'Je mi 18 let nebo více', + adult_content_deny: 'Je mi méně než 18 let', + + inner_player_disclaimer_title: 'Upozornění přehrávače', + inner_player_disclaimer_text: 'Rozumím, že spouštím přehrávač s neúplnou podporou, a rozumím, že to může způsobit netypické chování zařízení. Doporučuje se přejít na přehrávače rodiny tvOS nebo jiné alternativy.', + + inner_player_disclaimer_change_player: 'Změnit přehrávač', + remote_configuration_settings_title: 'Vzdálená konfigurace', + remote_configuration_registration_text: 'Vzdálená konfigurace poskytuje dočasný přístup k vaší aplikaci, jiná aplikace bude moci instalovat rozšíření a konfigurovat parametry.', + remote_configuration_waite_text: 'Nyní můžete předat tento kód jiné aplikaci, abyste jí udělili přístup k nastavení.', + remote_configuration_open_button: 'Otevřít přístup', + remote_configuration_code_life: 'Kód je platný', + remote_configuration_notice_nocode: 'Nepodařilo se otevřít přístup', + + settings_server_gts: 'Překódování', + settings_server_gts_descr: 'Automaticky převést video do kompatibilního formátu v případě potřeby.', + settings_server_tracktimecode: 'Povolit TrackTimecode', + settings_server_tracktimecode_descr: 'Ukládá průběh přehrávání filmů a seriálů na serveru TorrServer. Pro správnou funkci musí být tato možnost povolena také v TorrServeru.', + + title_metadata: 'Metadata', + title_moods: 'Nálady', + title_meta_violence: 'Násilí', + title_meta_fear: 'Strach', + title_meta_profanity: 'Výrazivo', + title_meta_sadness: 'Smutek', + title_meta_sex: 'Sexualita', + player_pip: 'Zmenšit', + player_volume: 'Hlasitost', + player_time_end: 'Konec v', + player_ai_agent_info: 'Chcete se dozvědět více o videu? Zeptejte se AI asistenta a ten vám poskytne graf nálad, krátké shrnutí děje a zajímavé momenty.', + player_ai_agent_ask_plot: 'Krátce o ději', + player_ai_agent_ask_moods: 'Zobrazit graf', + player_ai_agent_ask_highlights: 'Zajímavé momenty', + player_ai_agent_ask: 'Zeptat se', + player_ai_agent_processing: 'Analyzuji...', + player_ai_agent_no_data: 'Žádná data k zobrazení.', + player_ai_agent_no_analysis: 'Analýza videa se nezdařila.', + player_ai_agent_quota: 'Limit požadavků byl překročen. Zkuste to prosím znovu později.', + player_ai_agent_working: 'Stále na tom pracuji...', + title_meta_humor: 'Humor', + title_meta_tension: 'Napětí', + title_meta_romance: 'Romance', + title_meta_pace: 'Tempo', + title_meta_importance: 'Klíčové scény', + title_meta_action: 'Akce' +}; diff --git a/lampa-main/lang/en.js b/lampa-main/lang/en.js new file mode 100644 index 0000000..6d6fff1 --- /dev/null +++ b/lampa-main/lang/en.js @@ -0,0 +1,1363 @@ +export default { + lang_choice_title: 'Welcome', + lang_choice_subtitle: 'Choose your language', + + more: 'More', + show_more: 'Show more', + more_results: 'Show more results', + loading: 'Loading', + nofind_movie: 'The movie could not be found.', + noname: 'Untitled', + nochoice: 'Not chosen', + cancel: 'Cancel', + confirm: 'I confirm', + sure: 'Are you sure?', + nodata: 'No data', + back: 'Back', + ready: 'Ready', + close_app_modal: 'Are you sure you want to leave the app?', + connected_seeds: 'connected', + + search: 'Search', + search_input: 'Enter text', + search_empty: 'Search history is empty.', + search_delete: 'Left - delete', + search_start_typing: 'Start typing search text.', + search_searching: 'Search in progress...', + search_start: 'To start searching', + search_nofound: 'Nothing was found according to your request.', + global_search: 'Global search', + + full_genre: 'Genre', + full_production: 'Production', + full_date_of_release: 'date of release', + full_budget: 'Budget', + full_countries: 'Countries', + full_like: 'Like', + full_torrents: 'Torrents', + full_trailers: 'Trailers', + full_detail: 'In detail', + full_notext: 'No description.', + full_series_release: 'Series release', + full_next_episode: 'Next', + full_episode_days_left: 'Days left', + full_trailer_official: 'Official', + full_trailer_no_official: 'Informal', + full_season: 'Season', + full_episode: 'Episode', + full_directing: 'Directing', + full_writing: 'Writing', + full_keywords: 'Tags', + + settings_cub_sync: 'Synchronization', + settings_cub_sync_descr: 'Synchronization with the CUB service: Synchronization of your bookmarks, browsing history, tags and timecodes.', + settings_cub_account: 'Account', + settings_cub_logged_in_as: 'Logged in as', + settings_cub_profile: 'Profile', + settings_cub_sync_btn: 'Synchronize', + settings_cub_sync_btn_descr: 'Save local bookmarks to CUB account', + settings_cub_backup: 'Backup', + settings_cub_backup_descr: 'Save or load backup data', + settings_cub_logout: 'Sign out', + settings_cub_signin: 'Authorization', + settings_cub_not_specified: 'Not specified', + settings_cub_password: 'Password', + settings_cub_status: 'Status', + settings_cub_backup_import: 'Import', + settings_cub_backup_export: 'Export', + settings_cub_sync_filters: 'Filters sync', + settings_cub_sync_calendar: 'Calendar sync', + settings_cub_sync_quality: 'Quality sync', + settings_cub_sync_search: 'Search history sync', + settings_cub_sync_recomends: 'Recommendations sync', + settings_cub_sync_timecodes: 'Timecode Synchronization', + + settings_input_links: 'Favorites', + + settings_interface_type: 'Lite version', + settings_interface_size: 'Interface size', + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: 'Background', + settings_interface_background_use: 'Show background', + settings_interface_background_type: 'Background type', + settings_interface_performance: 'Performance', + settings_interface_animation: 'Animation', + settings_interface_animation_descr: 'Animation of cards and content', + settings_interface_attenuation: 'Attenuation', + settings_interface_attenuation_descr: 'Smooth fading of cards from below and from above', + settings_interface_scroll: 'Scroll Type', + settings_interface_view_card: 'Card view type', + settings_interface_view_card_descr: 'As you scroll the feed, the cards will load gradually or load all', + settings_interface_lang: 'Interface language', + settings_interface_lang_reload: 'You need to restart the application, click "OK" to restart.', + + settings_main_account: 'Account', + settings_main_interface: 'Interface', + settings_main_player: 'Player', + settings_main_parser: 'Parser', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Extensions', + settings_main_rest: 'Other', + + settings_rest_start: 'Start page', + settings_rest_start_descr: 'Which page to start at startup', + settings_rest_source: 'Source', + settings_rest_source_use: 'Main source', + settings_rest_source_descr: 'Where to get information about films', + settings_rest_tmdb_lang: 'What language to display data from TMDB', + settings_rest_tmdb_prox: 'Proxy TMDB', + settings_rest_tmdb_prox_auto: 'Enable proxy automatically', + settings_rest_tmdb_posters: 'Resolution of TMDB posters', + settings_rest_screensaver: 'Screensaver', + settings_rest_screensaver_use: 'Show splash screen when idle', + settings_rest_screensaver_type: 'Screen saver type', + settings_rest_helper: 'Hints', + settings_rest_helper_use: 'Show hints', + settings_rest_helper_reset: 'Show hints again', + settings_rest_pages: 'How many pages to keep in memory', + settings_rest_pages_descr: 'Keeps pages in the state you left them in', + settings_rest_time: 'Shift time', + settings_rest_navigation: 'Navigation type', + settings_rest_keyboard: 'Keyboard type', + settings_rest_device: 'Device name', + settings_rest_device_placeholder: 'For example: My Lamp', + settings_rest_cache: 'Clear cache', + settings_rest_cache_descr: 'All settings and data will be cleared', + settings_rest_tmdb_example: 'For example:', + settings_rest_tmdb_api_descr: 'To get data', + settings_rest_tmdb_image_descr: 'To get images', + settings_rest_card_quality: 'Quality marks', + settings_rest_card_quality_descr: 'Display quality marks on cards', + settings_rest_card_episodes: 'Episode marks', + settings_rest_card_episodes_descr: 'Display episode markers on cards', + + settings_parser_use: 'Use parser', + settings_parser_use_descr: 'Hereby, you agree to accept all responsibility for the use of public links to view torrent and online content.', + settings_parser_type: 'Parser type for torrents', + settings_parser_jackett_placeholder: 'For example: 192.168.x', + settings_parser_jackett_link: 'Link', + settings_parser_jackett_link_descr: 'Provide a link to the Jackett script', + settings_parser_jackett_key_placeholder: 'For example: sa0sk83d..', + settings_parser_jackett_key: 'Api key', + settings_parser_jackett_key_descr: 'Located in Jackett', + settings_parser_torlook_type: 'TorLook site parsing method', + settings_parser_scraperapi_placeholder: 'For example: scraperapi.com', + settings_parser_scraperapi_link: 'Link to site parser', + settings_parser_scraperapi_descr: 'Register on the site scraperapi.com, enter the link api.scraperapi.com?api_key=...&url={q}
    W41.torlook.info will be delivered to {q}', + settings_parser_search: 'Search', + settings_parser_search_descr: 'What language to search in?', + settings_parser_in_search: 'Parser in search', + settings_parser_in_search_descr: 'Show search results?', + settings_parser_timeout_title: 'Parser timeout', + settings_parser_timeout_descr: 'Time in seconds to wait for a response from the server', + + settings_player_type: 'Player type', + settings_player_type_descr: 'Which player to play', + settings_infuse_launch_mode: 'Launch in Infuse', + settings_infuse_launch_mode_descr: 'What to do when opening video in Infuse. Torrents always play immediately', + settings_infuse_launch_ask: 'Ask on launch', + settings_infuse_launch_play: 'Play', + settings_infuse_launch_save_and_play: 'Save and play', + settings_player_iptv_type: 'Player type for IPTV', + settings_player_iptv_type_descr: 'Which player to play IPTV channels', + settings_player_reset: 'Reset default player', + settings_player_reset_descr: 'Resets the selected Android player in the application', + settings_player_path: 'Path to the player', + settings_player_path_descr: 'Specify the path to the player .exe', + settings_player_external_header: 'External player', + settings_player_external_fullscreen: 'Launch in fullscreen mode', + settings_player_normalization: 'Sound normalization', + settings_player_normalization_descr: 'Normalizes sound to one level, lowers loud sounds and boosts quiet ones.', + settings_player_next_episode: 'Next episode', + settings_player_next_episode_descr: 'Automatically switch to the next series after the end of the current one', + settings_player_timecode: 'Timecode', + settings_player_timecode_descr: 'Continue from last viewed location', + settings_player_scale: 'Scaling Method', + settings_player_scale_descr: 'How to calculate video scaling', + settings_player_subs: 'Subtitles', + settings_player_subs_use: 'Turn on', + settings_player_subs_use_descr: 'Always turn on subtitles after starting a video', + settings_player_subs_lang: 'Subtitle language', + settings_player_subs_lang_descr: 'Which subtitles to turn on automatically when several languages are available', + settings_param_subtitles_lang_auto: 'Interface language', + settings_player_subs_size: 'The size', + settings_player_subs_size_descr: 'Screen size of subtitles', + settings_player_subs_stroke_use: 'Use edging', + settings_player_subs_stroke_use_descr: 'Subtitles will be outlined in black for better readability', + settings_player_subs_backdrop_use: 'Use an underlay', + settings_player_subs_backdrop_use_descr: 'Subtitles will be displayed on a translucent backing to improve readability', + settings_player_quality: 'Default video quality', + settings_player_quality_descr: 'Preferred video quality for viewing', + settings_player_hls_title: 'Processing the .m3u8 stream', + settings_player_hls_descr: 'Do not touch this parameter if you do not know why it is.', + + settings_plugins_notice: 'To apply the plugin, you need to restart the application', + settings_plugins_add: 'Add Plugin', + settings_plugins_add_descr: 'To delete an added plugin, hold or double-click the (OK) key on it', + settings_plugins_install: 'Install Plugin', + settings_plugins_install_descr: 'Install a plugin from the list of available', + + settings_server_link: 'Use link', + settings_server_links: 'Links', + settings_server_placeholder: 'For example: 192.168.X', + settings_server_link_one: 'Main Link', + settings_server_link_one_descr: 'Specify the main link to the TorrServer script', + settings_server_link_two: 'Additional link', + settings_server_link_two_descr: 'Provide an additional link to the TorrServer script', + settings_server_additionally: 'Additionally', + settings_server_client: 'Embedded client', + settings_server_client_descr: 'Use the built-in TorrServer JS client, otherwise the system one starts.', + settings_server_base: 'Save to database', + settings_server_base_descr: 'The torrent will be added to the TorrServer database', + settings_server_preload: 'Use prefetch buffer', + settings_server_preload_descr: 'Wait for TorrServer\'s preload buffer to fill before playing', + settings_server_auth: 'Authorization', + settings_server_password_use: 'Password login', + settings_server_login: 'Login', + settings_server_password: 'Password', + settings_server_not_specified: 'Not specified', + settings_server_search_type: 'Search type', + settings_server_search_type_descr: 'Where to look for torrents: built-in rutor, Torznab indexers in TorrServer, or both sources.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + torent_nohash_reasons: 'The reasons', + torent_nohash_reason_one: 'TorServer was unable to download the torrent file', + torent_nohash_reason_two: 'Reply from TorServer', + torent_nohash_reason_three: 'Link', + torent_nohash_do: 'What to do?', + torent_nohash_do_one: 'Check if you configured Jackett correctly', + torent_nohash_do_two: 'Private sources may not provide a link to the file', + torent_nohash_do_three: 'Make sure Jackett can download the file too', + torent_nohash_do_four: 'Write to our telegram group: @lampa_group', + torent_nohash_do_five: 'Specify which movie, which distribution and, if possible, a photo of this distribution', + + torrent_error_text: 'Failed to connect to TorrServer. Let\'s quickly go through the list of possible problems and check everything.', + torrent_error_step_1: 'Is TorrServer running', + torrent_error_step_2: 'Dynamic IP', + torrent_error_step_3: 'Protocol and Port', + torrent_error_step_4: 'Antivirus blocking', + torrent_error_step_5: 'Check for availability', + torrent_error_step_6: 'Still doesn\'t work', + torrent_error_info_1: 'Make sure you have launched TorrServer on the device where it is installed.', + torrent_error_info_2: 'A common mistake, the IP address of the device with TorrServer has changed. Make sure that the IP address you entered - {ip} - matches the address of the device on which TorrServer is installed.', + torrent_error_info_3: 'To connect to TorrServer, you must specify the protocol http:// at the beginning and port :8090 at the end of the address. Make sure there is a port after the IP address, your current address is {ip}', + torrent_error_info_4: 'Frequent occurrence, antivirus or firewall can block access by IP address, try disabling antivirus and firewall.', + torrent_error_info_5: 'On any other device on the same network, open the {ip} address in a browser and check if the TorrServer web interface is available.', + torrent_error_info_6: 'If, after all the checks, a connection error still occurs, try restarting TorrServer and the Internet adapter.', + torrent_error_info_7: 'If the problem persists, write to the Telegram group @lampa_group with the text (Lampa does not connect to TorrServer after all checks, the current address is {ip})', + torrent_error_start: 'Start verification', + torrent_error_nomatrix: 'Failed to verify Matrix version', + torrent_error_made: 'Performed', + torrent_error_from: 'from', + torrent_error_next: 'Further', + torrent_error_complite: 'To complete', + torrent_error_connect: 'Connection error', + + torrent_install_need: 'Requires TorrServer', + torrent_install_text: 'TorrServer is an application that allows you to view content from torrent files online.

    More detailed information on installation can be found in the Telegram groups below.', + torrent_install_contact: 'Telegram groups', + + torrent_item_bitrate: 'Bitrate', + torrent_item_seeds: 'Seeds', + torrent_item_grabs: 'Leechers', + torrent_item_mb: 'Mbps', + + torrent_serial_episode: 'Series', + torrent_serial_season: 'Season', + torrent_serial_date: 'Exit', + + torrent_get_magnet: 'Requesting a magnet link', + torrent_remove_title: 'Delete', + torrent_remove_descr: 'The torrent will be removed from your list', + + torrent_parser_any_one: 'Any', + torrent_parser_any_two: 'Any', + torrent_parser_no_choice: 'Not chosen', + torrent_parser_yes: 'Yes', + torrent_parser_no: 'No', + torrent_parser_quality: 'Quality', + torrent_parser_subs: 'Subtitles', + torrent_parser_voice: 'Translation', + torrent_parser_tracker: 'tracker', + torrent_parser_year: 'Year', + torrent_parser_season: 'Season', + torrent_parser_sort_by_seeders: 'By distributors', + torrent_parser_sort_by_size: 'To size', + torrent_parser_sort_by_name: 'by name', + torrent_parser_sort_by_tracker: 'By source', + torrent_parser_sort_by_date: 'By date', + torrent_parser_sort_by_viewed: 'Viewed', + torrent_parser_voice_dubbing: 'Dubbing', + torrent_parser_voice_polyphonic: 'Polyphonic', + torrent_parser_voice_two: 'Two-voiced', + torrent_parser_voice_amateur: 'Amateur', + torrent_parser_reset: 'Reset filter', + torrent_parser_empty: 'Failed to get results', + torrent_parser_no_hash: 'Failed to get HASH, try reloading TorrServer', + torrent_parser_added_to_mytorrents: 'added to "My torrents"', + torrent_parser_add_to_mytorrents: 'Add to "My torrents"', + torrent_parser_label_title: 'Flag', + torrent_parser_label_descr: 'Flag a hand with a flag (viewed)', + torrent_parser_label_cancel_title: 'Uncheck', + torrent_parser_label_cancel_descr: 'Remove the mark from the distribution (viewed)', + torrent_parser_timeout: 'Timeout expired', + torrent_parser_nofiles: 'Failed to extract suitable files', + torrent_parser_set_link: 'Specify a link for parsing', + torrent_parser_request_error: 'Request error', + torrent_parser_magnet_error: 'Failed to get magnet link', + torrent_parser_no_responce: 'The parser is not responding to the request', + torrent_parser_torlook_fallback_search_notification: 'Jackett parser is not available or the connection settings are incorrect. Searching Torlook...', + + about_text: 'The application is completely free and uses public links to get information about videos, new releases, popular movies, etc. All available information is used solely for educational purposes, the application does not use its own servers to distribute information.', + about_channel: 'Our channel', + about_group: 'Group', + about_version: 'Version', + about_donate: 'Donat', + + title_watched: 'You watched', + title_settings: 'Settings', + title_collections: 'Collections', + title_company: 'Company', + title_actors: 'Actors', + title_actor: 'Actor', + title_actress: 'Actress', + title_person: 'Person', + title_persons: 'Persons', + title_comments: 'Comments', + title_torrents: 'Torrents', + title_trailers: 'Trailers', + title_watch: 'Watch', + title_error: 'Error', + title_links: 'Links', + title_choice: 'Choose', + title_main: 'Home', + title_book: 'Bookmarks', + title_like: 'Like', + title_wath: 'Later', + title_history: 'Browsing history', + title_mytorrents: 'My torrents', + title_last: 'Last', + title_action: 'Action', + title_action_infuse: 'Infuse action', + title_producer: 'Producer', + title_collection: 'Collection', + title_recomendations: 'Recommendations', + title_similar: 'Similar', + title_about: 'About the application', + title_timetable: 'Schedule', + title_relises: 'Digital releases', + title_catalog: 'Catalog', + title_category: 'Category', + title_parser: 'Parser', + title_type: 'Type of', + title_rating: 'Rating', + title_country: 'Country', + title_year: 'Year', + title_genre: 'Genre', + title_filter: 'Filter', + title_notice: 'Notifications', + title_files: 'Files', + title_now_watch: 'Watching now', + title_latest: 'Last addition', + title_continue: 'Continue browsing', + title_recomend_watch: 'We recommend to see', + title_new_episodes: 'New episodes', + title_popular: 'Popular', + title_popular_movie: 'Popular films', + title_popular_tv: 'Popular TV shows', + title_new_this_year: 'New this year', + title_hight_voite: 'Highly rated', + title_new: 'New', + title_trend_day: 'Today in trend', + title_trend_week: 'Trending for the week', + title_upcoming: 'Watch in cinemas', + title_top_movie: 'Top movies', + title_top_tv: 'Top series', + title_tv_today: 'On air today', + title_this_week: 'This week', + title_in_top: 'Top', + title_out: 'Exit', + title_out_confirm: 'Yes, get out', + title_continue_two: 'Proceed', + title_choice_language: 'Choose a language', + title_subscribe: 'Subscribe', + title_subscribes: 'Subscriptions', + title_unsubscribe: 'Unsubscribe', + title_language: 'Original language', + + subscribe_success: 'You have successfully subscribed', + subscribe_error: 'An error occurred while subscribing, please try again later', + subscribe_noinfo: 'Failed to retrieve information, please try again later', + + company_headquarters: 'Headquarters', + company_homepage: 'Website', + company_country: 'Country', + + country_ad: 'Andorra', + country_ae: 'UAE', + country_af: 'Afghanistan', + country_al: 'Albania', + country_am: 'Armenia', + country_ao: 'Angola', + country_ar: 'Argentina', + country_at: 'Austria', + country_au: 'Australia', + country_aw: 'Aruba', + country_az: 'Azerbaijan', + country_bа: 'Bosnia & Herzegovina', + country_bd: 'Bangladesh', + country_be: 'Belgium', + country_bg: 'Bulgaria', + country_bh: 'Bahrain', + country_bi: 'Burundi', + country_bj: 'Benin', + country_bo: 'Bolivia', + country_br: 'Brazil', + country_bs: 'Bahamas', + country_bt: 'Bhutan', + country_bw: 'Botswana', + country_by: 'Belarus', + country_ca: 'Canada', + country_ch: 'Switzerland', + country_cl: 'Chile', + country_cm: 'Cameroon', + country_cn: 'China', + country_co: 'Colombia', + country_cr: 'Costa Rica', + country_cu: 'Cuba', + country_cv: 'Cape Verde', + country_cy: 'Cyprus', + country_cz: 'Czech Republic', + country_de: 'Germany', + country_dj: 'Djibouti', + country_dk: 'Denmark', + country_do: 'Dominican Republic', + country_dz: 'Algeria', + country_ec: 'Ecuador', + country_ee: 'Estonia', + country_eg: 'Egypt', + country_es: 'Spain', + country_et: 'Ethiopia', + country_fi: 'Finland', + country_fo: 'Faroe Islands', + country_fr: 'France', + country_ga: 'Gabon', + country_gb: 'United Kingdom', + country_ge: 'Georgia', + country_gh: 'Ghana', + country_gl: 'Greenland', + country_gp: 'Guadeloupe', + country_gr: 'Greece', + country_gt: 'Guatemala', + country_hk: 'Hong Kong', + country_hr: 'Croatia', + country_ht: 'Haiti', + country_hu: 'Hungary', + country_id: 'Indonesia', + country_ie: 'Ireland', + country_il: 'Israel', + country_in: 'India', + country_iq: 'Iraq', + country_ir: 'Iran', + country_is: 'Iceland', + country_it: 'Italy', + country_jm: 'Jamaica', + country_jo: 'Jordan', + country_jp: 'Japan', + country_ke: 'Kenya', + country_kg: 'Kyrgyzstan', + country_kh: 'Cambodia', + country_kp: 'North Korea', + country_kr: 'South Korea', + country_kz: 'Kazakhstan', + country_kw: 'Kuwait', + country_la: 'Laos', + country_lb: 'Lebanon', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Liberia', + country_lt: 'Lithuania', + country_lu: 'Luxembourg', + country_lv: 'Latvia', + country_ly: 'Libya', + country_ma: 'Morocco', + country_mc: 'Monaco', + country_md: 'Moldova', + country_me: 'Montenegro', + country_mk: 'Macedonia', + country_mm: 'Myanmar', + country_mn: 'Mongolia', + country_mo: 'Macau', + country_mt: 'Malta', + country_mu: 'Mauritius', + country_mv: 'Maldives', + country_mw: 'Malawi', + country_mx: 'Mexico', + country_my: 'Malaysia', + country_mz: 'Mozambique', + country_na: 'Namibia', + country_ne: 'Niger', + country_ng: 'Nigeria', + country_ni: 'Nicaragua', + country_nl: 'Netherlands', + country_no: 'Norway', + country_np: 'Nepal', + country_nz: 'New Zealand', + country_om: 'Oman', + country_pa: 'Panama', + country_pe: 'Peru', + country_pg: 'Papua New Guinea', + country_ph: 'Philippines', + country_pk: 'Pakistan', + country_pl: 'Poland', + country_pr: 'Puerto Rico', + country_ps: 'Palestinian Territory', + country_pt: 'Portugal', + country_py: 'Paraguay', + country_qa: 'Qatar', + country_ro: 'Romania', + country_rs: 'Serbia', + country_ru: 'Russia', + country_rw: 'Rwanda', + country_sa: 'Saudi Arabia', + country_sd: 'Sudan', + country_se: 'Sweden', + country_sg: 'Singapore', + country_si: 'Slovenia', + country_sk: 'Slovakia', + country_sn: 'Senegal', + country_su: 'USSR', + country_sv: 'El Salvador', + country_sy: 'Syria', + country_th: 'Thailand', + country_tj: 'Tajikistan', + country_tm: 'Turkmenistan', + country_tn: 'Tunisia', + country_tr: 'Turkey', + country_tw: 'Taiwan', + country_tz: 'Tanzania', + country_ua: 'Ukraine', + country_ug: 'Uganda', + country_us: 'USA', + country_uy: 'Uruguay', + country_uz: 'Uzbekistan', + country_ve: 'Venezuela', + country_vn: 'Viet Nam', + country_xk: 'Kosovo', + country_ws: 'Samoa', + country_ye: 'Yemen', + country_yu: 'Yugoslavia', + country_za: 'South Africa', + country_zm: 'Zambia', + country_zw: 'Zimbabwe', + + filter_clarify: 'Clarify', + filter_clarify_two: 'Refine Search', + filter_set_name: 'Specify title', + filter_sorted: 'Sort', + filter_filtred: 'Filter', + filter_any: 'Any', + filter_combinations: 'Combinations', + filter_alt_names: 'Other names', + filter_rating_from: 'from', + filter_rating_to: 'to', + + filter_lang_af: 'Afrikaans', + filter_lang_ar: 'Arabic', + filter_lang_az: 'Azerbaijani', + filter_lang_ba: 'Bashkir', + filter_lang_be: 'Belarusian', + filter_lang_bg: 'Bulgarian', + filter_lang_bn: 'Bengali', + filter_lang_bs: 'Bosnian', + filter_lang_ca: 'Catalan', + filter_lang_ce: 'Chechen', + filter_lang_cs: 'Czech', + filter_lang_da: 'Danish', + filter_lang_de: 'German', + filter_lang_el: 'Greek', + filter_lang_en: 'English', + filter_lang_es: 'Spanish', + filter_lang_et: 'Estonian', + filter_lang_fa: 'Persian', + filter_lang_fi: 'Finnish', + filter_lang_fr: 'French', + filter_lang_ga: 'Irish', + filter_lang_gl: 'Galician', + filter_lang_gn: 'Guarani', + filter_lang_he: 'Hebrew', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Croatian', + filter_lang_hu: 'Hungarian', + filter_lang_hy: 'Armenian', + filter_lang_id: 'Indonesian', + filter_lang_is: 'Icelandic', + filter_lang_it: 'Italian', + filter_lang_ja: 'Japanese', + filter_lang_ka: 'Georgian', + filter_lang_kk: 'Kazakh', + filter_lang_ko: 'Korean', + filter_lang_ks: 'Kashmiri', + filter_lang_ku: 'Kurdish', + filter_lang_ky: 'Kirghiz', + filter_lang_lt: 'Lithuanian', + filter_lang_lv: 'Latvian', + filter_lang_mi: 'Maori', + filter_lang_mk: 'Macedonian', + filter_lang_mn: 'Mongolian', + filter_lang_mt: 'Maltese', + filter_lang_ne: 'Nepali', + filter_lang_nl: 'Dutch (Nederlands)', + filter_lang_no: 'Norwegian', + filter_lang_pa: 'Punjabi', + filter_lang_pl: 'Polish', + filter_lang_ps: 'Pushto', + filter_lang_pt: 'Portuguese', + filter_lang_ro: 'Romanian', + filter_lang_ru: 'Russian', + filter_lang_si: 'Sinhalese', + filter_lang_sk: 'Slovak', + filter_lang_sl: 'Slovenian', + filter_lang_sm: 'Samoan', + filter_lang_so: 'Somali', + filter_lang_sq: 'Albanian', + filter_lang_sr: 'Serbian', + filter_lang_sv: 'Swedish', + filter_lang_sw: 'Swahili', + filter_lang_ta: 'Tamil', + filter_lang_tg: 'Tajik', + filter_lang_th: 'Thai', + filter_lang_tk: 'Turkmen', + filter_lang_tr: 'Turkish', + filter_lang_tt: 'Tatar', + filter_lang_ur: 'Urdu', + filter_lang_uk: 'Ukrainian', + filter_lang_uz: 'Uzbek', + filter_lang_vi: 'Vietnamese', + filter_lang_yi: 'Yiddish', + filter_lang_zh: 'Chinese', + + filter_genre_ac: 'Action', + filter_genre_ad: 'Adventures', + filter_genre_mv: 'Cartoon', + filter_genre_cm: 'Comedy', + filter_genre_cr: 'Crime', + filter_genre_dc: 'Documentary', + filter_genre_dr: 'Drama', + filter_genre_fm: 'Family', + filter_genre_fe: 'Fantasy', + filter_genre_hi: 'Story', + filter_genre_ho: 'Horror', + filter_genre_mu: 'Music', + filter_genre_de: 'Detective', + filter_genre_md: 'Melodrama', + filter_genre_fa: 'Fiction', + filter_genre_tv: 'TV film', + filter_genre_tr: 'Thriller', + filter_genre_mi: 'Military', + filter_genre_ve: 'Western', + filter_genre_aa: 'Action & Adventure', + filter_genre_ch: 'Children\'s', + filter_genre_nw: 'News', + filter_genre_rs: 'Reality show', + filter_genre_hf: 'Sci-Fi and Fantasy', + filter_genre_op: 'Soap opera', + filter_genre_tc: 'Talk show', + filter_genre_mp: 'War and Politics', + + empty_title: 'Empty', + empty_text: 'Nothing found for your filter, please refine your filter.', + empty_title_two: 'It\'s empty here', + empty_text_two: 'The list is currently empty.', + + menu_main: 'Home', + menu_movies: 'Movies', + menu_tv: 'Series', + menu_catalog: 'Catalog', + menu_filter: 'Filter', + menu_collections: 'Collections', + menu_relises: 'Releases', + menu_anime: 'Anime', + menu_bookmark: 'Bookmarks', + menu_like: 'Like', + menu_time: 'Later', + menu_history: 'History', + menu_timeline: 'Schedule', + menu_torrents: 'Torrents', + menu_settings: 'Settings', + menu_about: 'Information', + menu_console: 'Console', + menu_multmovie: 'Cartoons', + menu_multtv: 'Animated series', + + plugins_catalog_work: 'Working plugins', + plugins_catalog_work_descr: 'Plugins that work exactly in the lamp.', + plugins_catalog_popular: 'Popular plugins among users', + plugins_catalog_popular_descr: 'Installation from unknown sources may cause the application to work incorrectly.', + plugins_online: 'View online', + plugins_check_fail: 'Failed to test the functionality of the plugin. However, this does not mean that the plugin does not work. Reload the application to see if the plugin is loading.', + plugins_need_reload: 'To apply the plugin, you need to restart the application', + plugins_install: 'Install', + plugins_install_ready: 'This plugin is already installed.', + plugins_installed: 'Installations', + plugins_load_from: 'Loaded from CUB', + plugins_ok_for_check: 'Click (OK) to test the plugin', + plugins_no_loaded: 'When loading the application, some plugins could not be loaded', + + time_viewed: 'Viewed', + time_from: 'from', + time_reset: 'Reset timecode', + + settings_clear_cache: 'Cache and data cleared', + settings_user_links: 'Custom Link', + settings_for_local: 'For local TorrServer', + settings_add: 'Add', + settings_remove: 'Delete', + settings_this_value: 'present value', + settings_added: 'Added', + settings_removed: 'Removed', + + settings_param_player_inner: 'Lampa', + settings_param_player_outside: 'External', + settings_param_player_inner_tvos: 'Internal', + settings_param_yes: 'Yes', + settings_param_no: 'No', + settings_param_interface_size_small: 'Smaller', + settings_param_interface_size_normal: 'Normal', + settings_param_interface_size_bigger: 'More', + settings_param_poster_quality_low: 'Low', + settings_param_poster_quality_average: 'Average', + settings_param_poster_quality_high: 'High', + settings_param_parse_directly: 'Directly', + settings_param_parse_api: 'Through the website API', + settings_param_background_complex: 'Complex', + settings_param_background_simple: 'Simple', + settings_param_background_image: 'Picture', + settings_param_link_use_one: 'Main', + settings_param_link_use_two: 'Additional', + settings_param_link_use_both: 'Both', + settings_param_subtitles_size_small: 'small', + settings_param_subtitles_size_normal: 'Ordinary', + settings_param_subtitles_size_bigger: 'Large', + settings_param_screensaver_nature: 'Nature', + settings_param_torrent_lang_orig: 'Original', + settings_param_torrent_lang_ru: 'Russian', + settings_param_player_timecode_again: 'Start over', + settings_param_player_timecode_continue: 'Proceed', + settings_param_player_timecode_ask: 'To ask', + settings_param_player_scale_method: 'Calculate', + settings_param_player_hls_app: 'Systemic', + settings_param_player_hls_js: 'Program', + settings_param_card_view_load: 'Upload', + settings_param_card_view_all: 'Show all', + settings_param_navigation_remote: 'Remote controller', + settings_param_navigation_mouse: 'Remote control with mouse', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: 'Systemic', + + helper_keyboard: 'After entering the value, press the "Back" button to save', + helper_torrents: 'Hold down the (OK) key to bring up the context menu', + helper_cleared: 'Success, tooltips will be shown again.', + helper_torrents_view: 'Hold down the (OK) key to reset the timecode and display the menu', + + fav_sync_title: 'Bookmark sync', + fav_sync_text: 'Your favorite bookmarks with you. Connect synchronization and view on any device.

    To do this, register on the site {site}, create a profile and log in to the application.', + fav_sync_site: 'Website', + fav_remove_title: 'Remove from history', + fav_remove_descr: 'Delete selected card', + fav_clear_title: 'Clear the history', + fav_clear_descr: 'Delete all cards from history', + fav_clear_label_title: 'Clear labels', + fav_clear_label_descr: 'Clear View Tags', + fav_clear_time_title: 'Clear Timecodes', + fav_clear_time_descr: 'Clear all timecodes', + fav_label_cleared: 'Marks cleared', + fav_time_cleared: 'Timecodes cleared', + + timetable_empty: 'This section will display the release dates of new episodes.', + + player_quality: 'Quality', + player_flow: 'Flow', + player_tracks: 'Audio tracks', + player_disabled: 'Disabled', + player_unknown: 'Unknown', + player_subs: 'Subtitles', + player_size_default_title: 'Default', + player_size_default_descr: 'Default video size', + player_size_cover_title: 'Expand', + player_size_cover_descr: 'Expands video to full screen', + player_size_fill_title: 'Fill', + player_size_fill_descr: 'Fit video to full screen', + player_size_s115_title: 'Zoom 115%', + player_size_s115_descr: 'Enlarge video by 115%', + player_size_s130_title: 'Zoom 130%', + player_size_s130_descr: 'Enlarge video by 130%', + player_size_v115_title: 'Vertical 115%', + player_size_v115_descr: 'Enlarge video by 115%', + player_size_v130_title: 'Vertical 130%', + player_size_v130_descr: 'Enlarge video by 130%', + player_video_size: 'Video size', + player_playlist: 'Playlist', + player_error_one: 'Failed to decode video', + player_error_two: 'Video not found or corrupted', + player_start_from: 'Continue browsing from', + player_not_found: 'Player not found', + player_lauch: 'Launch player', + player_speed_default_title: 'Plain', + player_speed_two_descr: 'Play without sound', + player_video_speed: 'Playback speed', + player_share_title: 'Share', + player_share_descr: 'Play this video on another device', + player_normalization_power_title: 'Normalization power', + player_normalization_smooth_title: 'Normalization speed', + player_normalization_step_low: 'Low', + player_normalization_step_medium: 'Average', + player_normalization_step_hight: 'High', + player_youtube_no_played: 'Sorry, this video is not available in your region and may have been blocked or removed.', + player_youtube_start_play: 'To start playing the video, click the "Play" button.', + + broadcast_open: 'Open card on another device', + broadcast_play: 'Choose the device to watch on', + + card_new_episode: 'New series', + card_book_remove: 'Remove from bookmarks', + card_book_add: 'To bookmarks', + card_book_descr: 'Look in the menu (Bookmarks)', + card_like_remove: 'Remove from favorites', + card_like_add: 'Like', + card_like_descr: 'Look at the menu (Like)', + card_wath_remove: 'Remove from expected', + card_wath_add: 'Watch Later', + card_wath_descr: 'See the menu (Later)', + card_history_remove: 'Remove from history', + card_history_add: 'Into history', + card_history_descr: 'Look in the menu (History)', + + keyboard_listen: 'Speak, I\'m listening...', + keyboard_nomic: 'No microphone access', + + notice_new_quality: 'New quality available', + notice_quality: 'Quality', + notice_new_episode: 'New series', + notice_none: 'You don\'t have any notifications yet, register at {site} to follow new episodes and releases.', + notice_in_quality: 'As', + notice_none_account: 'You don\'t have any notifications yet, bookmark the series and wait for notifications of new episodes.', + notice_none_system: 'You currently have no notifications. We will be sure to notify you when new notifications become available.', + + copy_link: 'Copy video link', + copy_secuses: 'Link copied to clipboard', + copy_error: 'Error copying link', + + account_sync_to_profile: 'All bookmarks will be moved to the profile', + account_sync_secuses: 'All bookmarks have been successfully transferred', + account_profiles: 'Profiles', + account_profiles_empty: 'Failed to get list of profiles', + account_authorized: 'Authorized', + account_logged_in: 'You are logged in', + account_login_failed: 'Login failed', + account_login_wait: 'Waiting for login', + account_profile_main: 'General', + account_export_secuses: 'Export completed successfully', + account_export_fail: 'Export error', + account_import_secuses: 'Import completed successfully', + account_import_fail: 'Import error', + account_imported: 'imported', + account_reload_after: 'reboot after 5 sec.', + account_create: 'Discover more opportunities with a CUB account. Register at and get access to sync your bookmarks, timecodes and other CUB account features.', + account_premium_more: 'Learn more about CUB Premium', + account_limited: 'You have reached the maximum limit. Increase the limit with a CUB Premium account. Learn more at ', + + account_code_enter: 'Enter a six-digit code', + account_code_error: 'Perhaps you entered an incorrect or outdated code', + account_code_wrong: 'Perhaps you entered an incorrect format', + account_code_where: 'Go to the website and enter the code provided there.', + account_code_input: 'Enter code', + settings_cub_signin_button: 'Sign in', + + network_noconnect: 'No network connection', + network_404: 'The requested page was not found. [404]', + network_401: 'Authorization failed', + network_500: 'Internal Server Error. [500]', + network_parsererror: 'The requested JSON parsing failed.', + network_timeout: 'Request timed out.', + network_abort: 'The request has been aborted.', + network_error: 'Unknown error', + + size_zero: '0 Byte', + size_byte: 'Byte', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'TB', + size_pp: 'PB', + + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + + month_1: 'January', + month_2: 'February', + month_3: 'March', + month_4: 'April', + month_5: 'May', + month_6: 'June', + month_7: 'July', + month_8: 'August', + month_9: 'September', + month_10: 'October', + month_11: 'November', + month_12: 'December', + + day_1: 'Monday', + day_2: 'Tuesday', + day_3: 'Wednesday', + day_4: 'Thursday', + day_5: 'Friday', + day_6: 'Saturday', + day_7: 'Sunday', + + month_1_e: 'January', + month_2_e: 'February', + month_3_e: 'March', + month_4_e: 'April', + month_5_e: 'May', + month_6_e: 'June', + month_7_e: 'July', + month_8_e: 'August', + month_9_e: 'September', + month_10_e: 'October', + month_11_e: 'November', + month_12_e: 'December', + + week_1: 'Mon', + week_2: 'Tue', + week_3: 'Wed', + week_4: 'Thu', + week_5: 'Fri', + week_6: 'Sat', + week_7: 'Sun', + + extensions_enable: 'Turn on', + extensions_disable: 'Disable', + extensions_check: 'Check status', + extensions_install: 'Install', + extensions_info: 'Information', + extensions_edit: 'Edit', + extensions_change_name: 'Change name', + extensions_change_link: 'Change link', + extensions_remove: 'Delete', + extensions_set_name: 'Enter plugin name', + extensions_set_url: 'Enter plugin url', + extensions_ready: 'This plugin is already installed', + extensions_no_info: 'Without information', + extensions_no_name: 'Untitled', + extensions_worked: 'Worker', + extensions_no_plugin: 'Plugin not verified', + extensions_add: 'Add Plugin', + extensions_from_memory: 'Installed in memory', + extensions_from_cub: 'Installed from CUB', + extensions_from_popular: 'Popular plugins', + extensions_from_lib: 'Plugin Library', + extensions_from_connected: 'Connected plugins', + + settings_webos_launcher: 'Application launch', + settings_webos_launcher_add_device: 'Install as starter app', + settings_webos_launcher_remove_device: 'Remove from starter spplications', + player_normalization: 'Normalization', + change_source_on_cub: 'Change source to CUB', + settings_param_jackett_interview_all: 'All', + settings_param_jackett_interview_healthy: 'Available only', + settings_parser_jackett_interview: 'Poll trackers', + title_ongoing: 'Ongoings', + title_pgrating: 'Age limit', + + settings_interface_card_interfice: 'Card interface', + settings_interface_card_poster: 'Show poster', + title_card: 'Card', + settings_param_card_interface_old: 'Old', + settings_param_card_interface_new: 'New', + title_seasons: 'Seasons', + title_episodes: 'Episodes', + title_rewiews: 'Reviews', + settings_interface_glass: 'Glass', + settings_interface_glass_descr: 'Show interface in glassy style', + settings_interface_black_style: 'Black style', + + plugins_remove: 'Remove plugins', + plugins_add_success: 'Plugin connected successfully', + settings_reset: 'Reset', + title_channel: 'Channel', + + input_detection_touch: 'Want to switch to touch control?', + input_detection_mouse: 'Want to switch to mouse control?', + input_detection_remote: 'Want to switch to remote control?', + + settings_interface_hide_outside_the_screen: 'Hide cards off screen', + settings_interface_hide_outside_the_screen_descr: 'This will speed up UI rendering and improve performance', + + https_text: 'You are using the HTTPS protocol, in this protocol the lamp does not work correctly. For the correct operation of the lamp, use the address with the HTTP protocol', + + extensions_hpu_best: 'Popular', + extensions_hpu_recomend: 'Recommended', + extensions_hpu_theme: 'Themes', + extensions_hpu_screensaver: 'Screensaver', + extensions_hpu_video: 'Video', + extensions_hpu_control: 'Control', + extensions_hpu_other: 'Miscellaneous', + extensions_hpu_: 'Other', + + title_author: 'Author', + + title_buffer: 'Buffer', + settings_rest_screensaver_time: 'After how many minutes to start the screensaver', + + time_h: 'h.', + time_m: 'm.', + time_s: 's.', + + settings_param_glass_easy: 'Transparent', + settings_param_glass_medium: 'Semitransparent', + settings_param_glass_blacked: 'Blacked out', + + settings_interface_glass_opacity: 'Glass transparency', + torrent_error_check_no_auth: 'The server responded to the request, but the authorization failed', + settings_interface_card_cover: 'Show cover', + + title_upcoming_episodes: 'Upcoming episode releases', + title_recent_episodes: 'Recent episode releases', + settings_rest_cache_images: 'Image cache', + settings_rest_cache_images_descr: 'Cache posters and backgrounds to local storage', + + settings_player_rewind_title: 'Rewind', + settings_player_rewind_descr: 'Rewind interval in seconds', + + settings_interface_card_reactions: 'Show reactions', + title_look: 'Looking', + title_scheduled: 'Scheduled', + title_viewed: 'Viewed', + title_thrown: 'Thrown', + title_reactions: 'Reactions', + reactions_none: 'No reactions', + reactions_fire: 'Great', + reactions_nice: 'Nice', + reactions_think: 'Interesting', + reactions_bore: 'Boring', + reactions_shit: 'Bad', + reactions_ready: 'You have already left a reaction', + settings_player_launch_trailers: 'Trailer Player', + title_continued: 'To be continued', + title_language_short: 'Language', + + speedtest_connect: 'connection', + speedtest_test: 'testing', + speedtest_ready: 'ready', + speedtest_button: 'Test Speed', + + termsofuse_t_01: 'Terms of Use', + termsofuse_t_02: 'Lampa is a convenient tool for exploring the latest news in the film industry, including movies, TV shows, cartoons, and other information. To obtain information about movies, an open-source website, themoviedb.org, is used.', + termsofuse_t_03: 'Content', + termsofuse_t_04: 'Lampa utilizes the API (application programming interface) from the themoviedb.org catalog to retrieve information about movies and TV shows, as well as to view associated media files such as posters, trailers, and more.', + termsofuse_t_05: 'The themoviedb.org API allows the Lampa application to access a database of movies and TV shows, providing the ability to search and view media file information.', + termsofuse_t_06: 'The interaction between the Lampa application and themoviedb.org occurs through API requests that are sent from the Lampa application to the themoviedb.org servers to obtain information and media files. Themoviedb.org processes the requests and sends the requested data back to the Lampa application.', + termsofuse_t_07: 'Thus, thanks to the use of the themoviedb.org API, the Lampa application provides users with access to an extensive database of movies and TV shows, while complying with the terms of use and restrictions set by the rights holder.', + termsofuse_t_08: 'Extensions', + termsofuse_t_09: 'Extensions are a powerful tool provided for the Lampa application, allowing users to enhance its capabilities, add additional functionality, and modify content according to their needs.', + termsofuse_t_10: 'However, it should be noted that users install extensions at their own risk. All consequences arising from the use of extensions are the responsibility of the user. Users are advised to exercise caution when installing and using extensions, carefully evaluating their reliability and security.', + termsofuse_t_11: 'Copyright Infringements', + termsofuse_t_12: 'If you discover any copyright infringement in the Lampa application, you should contact the developers of the Lampa application. You can use the contacts provided in the Lampa application to do so. However, it is important to note that the Lampa application uses the API from the themoviedb.org catalog, which provides open access to information about movies and TV shows. This means that the information displayed in the Lampa application is publicly available and does not infringe on copyright.', + termsofuse_t_13: 'If you believe that the Lampa application still contains content that violates your copyright, you can contact the rights holder of that content and request its removal from the themoviedb.org website. In turn, the Lampa application can remove content upon receiving a proper copyright infringement notification.', + settings_rest_protocol_use: 'Secure connection', + settings_rest_protocol_descr: 'Use HTTPS protocol', + install_app_apk_title: 'How to install Lampa on Android', + install_app_apk_text: 'We noticed that you use MediaStationX to run Lampa on Android. We recommend installing Lampa as an APK app. This will ensure more stable operation and access to all the app\'s features.

    Go to the Telegram group to download the latest APK and installation instructions.', + install_app_apk_qr: 'Scan the QR code to download the Lampa APK', + copy_link_buffer: 'Copy link', + + tv_status_returning_series: 'Returning series', + tv_status_planned: 'Planned', + tv_status_in_production: 'In Production', + tv_status_ended: 'Ended', + tv_status_canceled: 'Canceled', + tv_status_pilot: 'Pilot', + + tv_status_released:'Released', + tv_status_rumored:'Rumored', + tv_status_post_production:'Post Production', + + title_last_year: 'Last year', + + title_reset: 'Reboot', + back_to_card: 'Return to card', + + premiere_author_recomend_1: 'Order pizza and get ready for some excitement.', + premiere_author_recomend_2: 'The party is just getting started.', + premiere_author_recomend_3: 'Get ready for some adrenaline.', + premiere_author_recomend_4: 'Ready for an unforgettable evening?', + premiere_author_recomend_5: 'I recommend watching it.', + premiere_title: 'Premiere', + + settings_clear_cache_only: 'Cache Cleared', + settings_rest_cache_only: 'Only Cache', + settings_rest_cache_only_descr: 'Basic settings will be preserved', + settings_rest_cache_all: 'Cache and Data', + settings_rest_cache_all_descr: 'All settings and data will be cleared', + settings_rest_cache_calculate: 'How much memory is left', + + title_left:'Left', + + account_export_fail_500: 'Unknown error', + account_export_fail_610: 'You have exceeded the limit for today', + account_export_fail_200: 'Database error, please try again later', + account_export_fail_600: 'Error, failed to upload the file', + account_export_fail_620: 'Error, file not transmitted', + + title_parental_control: 'Parental Control', + settings_parental_control_param_time_always: 'Always', + settings_parental_control_param_time_once: 'Once', + settings_parental_control_param_time_10: 'In 10 minutes', + settings_parental_control_param_time_20: 'In 20 minutes', + settings_parental_control_param_time_30: 'In 30 minutes', + settings_parental_control_param_time_60: 'In 1 hour', + settings_parental_control_param_time_120: 'In 2 hours', + settings_parental_control_change_pin: 'Change PIN', + settings_parental_control_demand_title: 'When to Prompt', + settings_parental_control_demand_descr: 'After how much time to prompt for the PIN', + settings_parental_control_enabled: 'Enabled', + settings_parental_control_disabled: 'Disabled', + parental_control_input_new_code: 'Enter new PIN code', + parental_control_confirm_new_code: 'Confirm PIN code', + parental_control_no_match_code: 'PIN code does not match the previous code', + parental_control_input_code: 'Enter PIN code', + parental_control_input_error: 'You entered an incorrect PIN code', + title_worth_rewatch: 'Worth a rewatch', + + ad_disable: 'By subscribing to CUB Premium, you will forget about advertising.', + ad_after: 'Advertising via', + ad: 'Advertising', + ad_skip: 'Skip', + ad_continue_after: 'Viewing will start in', + settings_parser_prowlarr_link_descr: 'Provide a link to the Prowlarr server', + settings_parser_prowlarr_key_descr: 'Located in the Prowlarr settings tab in the general category', + settings_player_torrent_type: 'Player type for torrents', + settings_player_torrent_type_descr: 'Which player to play torrents', + + full_crew: 'More', + full_editing: 'Editing', + full_creator: 'Creator', + player_normalization_step_none: 'Zero', + + settings_cub_backup_export_descr: 'Save settings to the cloud', + settings_cub_backup_import_descr: 'Restore settings from the cloud', + + settings_interface_sound: 'System sounds', + settings_interface_sound_play: 'Transitions', + settings_interface_sound_level: 'Volume level', + settings_interface_advanced_animation: 'Advanced animation', + + confirm_open_player: 'Another device is requesting access to the player. Do you want to play the video?', + + pincode_use_remote: 'Use the remote control to enter the code by pressing the arrows to select the desired number.', + pincode_use_toggle: 'Press and hold the OK button to change the layout.', + + settings_parental_control_where: 'Where to request a PIN code', + title_fire: 'Fire!', + title_top_100: 'Top 100', + + player_normalization_type_title: 'Normalization Type', + player_normalization_type_all: 'All', + player_normalization_type_up: 'Only Increase', + player_normalization_type_down: 'Only Decrease', + storage_quota_exceeded: 'Storage quota exceeded. Clear cache and try again.', + settings_cub_domain: 'Primary domain', + + title_ai_assistant: 'AI Assistant', + title_facts: 'Interesting Facts', + ai_search_start_typing: 'Ask the AI Assistant what movies you want to find. For example: "Movies about space"', + ai_search_limit: 'Request limit exceeded. Please try again later. With a CUB Premium subscription, limits will be increased, and you won’t have to wait!', + ai_subscribe_title: 'Unlock More Opportunities with AI', + ai_subscribe_descr: 'Subscribe to CUB Premium and increase the number of requests to AI. Together with AI, we’ll find the best movies for you.', + + dmca_title: 'Content blocked', + dmca_descr: 'This material is not available for viewing. It has been blocked at the request of the copyright holder in accordance with copyright law.', + + loading_progress_step_0: 'Preparation', + loading_progress_step_1: 'Loading languages', + loading_progress_step_2: 'Searching for mirrors', + loading_progress_step_3: 'Preparing extensions', + loading_progress_step_4: 'Almost there', + loading_progress_step_5: 'Coming soon', + + install_extension_rule_1: 'Installing a third-party plugin', + install_extension_rule_2: 'Plugins are created by independent developers, and LAMPA does not verify their content. By installing them, you agree that:', + install_extension_rule_3: '- Some plugins may request access to your data or work with unverified sources.', + install_extension_rule_4: '- If the plugin you install violates copyright or other laws, you are fully responsible for its use.', + install_extension_rule_5: '- Install only plugins from trusted sources. If you have any doubts about the security or legality of a plugin, it is better to refrain from installing it.', + install_extension_rule_6: 'LAMPA does not support or endorse plugins related to pirated content.', + install_extension_rule_7: 'By proceeding, you confirm that you understand these risks.', + ad_plugin: 'Advertisement from the plugin', + + terminal_title: 'Terminal', + terminal_no_access: 'No access', + terminal_confirm: 'Allow', + terminal_deny: 'Deny', + terminal_update: 'Update', + terminal_code: 'Access code', + terminal_text: 'You are requesting access to the terminal. Developers may gain access to your device and control it. This can be useful for diagnostics and troubleshooting, but may also pose a security risk. Please make sure you trust the developers before granting access.

    You can disable this feature at any time by clicking the "Deny" button.', + + + title_anons: 'Announcement', + title_developer: 'Developer', + title_navigation: 'Navigation', + title_page: 'Page', + title_person_about: 'About', + account_qr_premium: 'Scan the QR code to learn more about CUB Premium', + account_qr_code: 'Scan the QR code to receive a device linking code', + account_qr_create: 'Scan the QR code to create an account', + account_add_device_title: 'Add Device', + account_add_device_text: 'Go to to get a code for adding a device.', + account_none_title: 'Don’t have an account yet?', + account_none_include_1: 'Bookmarks and watch history are stored in the cloud', + account_none_include_2: 'Sync between devices', + account_none_include_3: 'Notifications about new episodes and releases', + account_none_include_4: 'Create multiple profiles under one account', + account_premium_include_1: 'Increased number of bookmarks', + account_premium_include_2: 'Extended watch history', + account_premium_include_3: 'More timecodes available', + account_premium_include_4: 'Number of profiles per account', + empty_subscribes_title: 'Your translation subscriptions', + empty_subscribes_text: 'Just subscribe to your favorite translation and we’ll notify you when a new episode is released.', + empty_history_title: 'Your watch history', + empty_history_text: 'Your watch history will appear here.', + empty_bookmark_title: 'Your favorites', + empty_bookmark_text: 'Add movies and TV shows you like to favorites to quickly find them in this section.', + empty_mytorrents_title: 'Your torrents', + empty_mytorrents_text: 'Torrents you’ve downloaded via TorServer will appear here.', + developer_param_enabled: 'Developer Mode', + developer_param_nopremium: 'Disable CUB Premium', + developer_param_nodemo: 'Disable Demo Mode', + developer_param_ads: 'Show Ads', + developer_param_fps: 'Show FPS', + developer_trigger_help_1: 'Almost guessed it :)', + developer_trigger_help_2: 'Just a little more :)', + developer_trigger_help_3: 'Are you sure you want to enter Developer Mode?', + developer_trigger_help_4: 'Developer Mode activated', + settings_param_navigation_touch: 'Sensor', + account_discuss_add_qr: 'Scan the QR code', + account_discuss_add_title: 'Want to leave a comment?', + account_discuss_add_text: 'Scan the QR code to go to the app and add a comment on this movie or TV series.

    - Take your phone or tablet
    - Open the camera
    - Point to the QR code
    - Follow the link that appears on the screen', + account_discuss_added: 'Thank you for your comment!', + account_discuss_added_ready: 'You have already left a comment on this movie or TV series.', + remote_helper_long: 'Hold the (OK) button to open the menu', + account_premium: 'Unlock new horizons with a CUB Premium account! Enjoy increased limits and enhanced service functionality. Visit and learn more about the benefits of a premium account.', + player_segments_title: 'Segments', + player_segments_descr: 'Skip intro and other parts of the video', + player_segments_ad_title: 'Ads', + player_segments_skip_title: 'Intro and other', + player_segments_value_none: 'Do not skip', + player_segments_value_auto: 'Auto skip', + player_segments_value_user: 'Custom', + player_segments_skiped: 'Segment skipped', + player_segments_skip_now: 'Skip', + player_segments_skip_in: 'Skip in', + player_segments_skip_intro: 'Skip intro', + player_segments_next: 'Next episode', + player_segments_next_in: 'Next episode in', + subscribe_info: 'In the Subscriptions section, you\'ll see all your translation subscriptions. You\'ll receive a notification when a new episode with your selected translation is released.', + no_watch_history: 'No browsing history', + + settings_request_caching_use: 'Request Caching', + settings_request_caching_descr: 'Cache API requests to speed up the interface and reduce data usage.', + + account_profile_child: 'Child', + account_profile_add: 'Add profile', + account_profile_name: 'Profile name', + account_profile_created: 'Profile successfully created', + account_profile_limited: 'The maximum profile limit has been reached: {count}', + account_profile_info: 'You can manage profiles in your account settings. To do this, go to ', + player_youtube_no_support: 'Your device does not support YouTube video playback, please check your internet connection.', + title_channels: 'Channels', + title_best_of_2000: 'Golden 2000s', + title_best_of_2010: 'Hits of the 2010s', + title_best_of_2015: 'Modern Classics', + title_comedy_of_2000: 'Laughter of the 2000s', + title_comedy_of_2010: 'Humor of the 2010s', + title_comedy_of_2015: 'Modern Comedies', + + filter_keyword_sequel: 'Sequel', + filter_keyword_based_comic: 'Based on Comics', + filter_keyword_space: 'Space', + filter_keyword_survival: 'Survival', + filter_keyword_zombie: 'Zombie', + filter_keyword_school: 'School', + filter_keyword_revenge: 'Revenge', + filter_keyword_detective: 'Detective', + filter_keyword_robots: 'Robots', + filter_keyword_vampires: 'Vampires', + filter_keyword_aliens: 'Aliens', + filter_keyword_police: 'Police', + filter_keyword_reincarnation: 'Reincarnation', + filter_keyword_spy: 'Spy', + filter_keyword_disaster: 'Catastrophe', + filter_keyword_christmas: 'Christmas', + + dmca_title_lgbt: 'Content Restricted', + dmca_descr_lgbt: 'Viewing is unavailable in your region as it may contain LGBT content. Such material may be prohibited or restricted in some countries.', + + settings_lgbt_content_block: 'Block LGBT content', + + // todo: + adult_content_title: 'Adult Content', + adult_content_text_warning: 'Content may contain adult material that may be inappropriate for some viewers.', + adult_content_text_modal: 'This film or series is marked as containing adult content. You must be 18 years of age or older to view this material. Please confirm that you are of legal age to continue viewing.', + + adult_content_confirm: 'I am 18 or older', + adult_content_deny: 'I am under 18', + + inner_player_disclaimer_title: 'Player Disclaimer', + inner_player_disclaimer_text: 'I understand that I am launching a player with incomplete support, and I understand that this may cause atypical behavior on the device. It is recommended to switch to tvOS family players or other alternatives.', + + inner_player_disclaimer_change_player: 'Change player', + remote_configuration_settings_title: 'Remote Configuration', + remote_configuration_registration_text: 'Remote configuration provides temporary access to your application, another application will be able to install extensions and configure parameters.', + remote_configuration_waite_text: 'You can now pass this code to another application to grant access to settings.', + remote_configuration_open_button: 'Open Access', + remote_configuration_code_life: 'Code is valid', + remote_configuration_notice_nocode: 'Failed to open access', + + settings_server_gts: 'Transcoding', + settings_server_gts_descr: 'Automatically convert video to a compatible format when needed.', + settings_server_tracktimecode: 'Enable TrackTimecode', + settings_server_tracktimecode_descr: 'Saves the playback progress of movies and TV shows on the TorrServer. This option must also be enabled in TorrServer for it to work.', + + title_metadata: 'Metadata', + title_moods: 'Moods', + title_meta_violence: 'Violence', + title_meta_fear: 'Fear', + title_meta_profanity: 'Profanity', + title_meta_sadness: 'Sadness', + title_meta_sex: 'Sexuality', + player_pip: 'Minimize', + player_volume: 'Volume', + player_time_end: 'Ends at', + player_ai_agent_info: 'Want to know more about the video? Ask the AI assistant and it will provide you with a mood chart, brief plot summary, and highlights.', + player_ai_agent_ask_plot: 'Brief plot', + player_ai_agent_ask_moods: 'Show chart', + player_ai_agent_ask_highlights: 'Highlights', + player_ai_agent_ask: 'Ask', + player_ai_agent_processing: 'Analyzing...', + player_ai_agent_no_data: 'No data to show.', + player_ai_agent_no_analysis: 'Could not analyze the video.', + player_ai_agent_quota: 'Request limit exceeded. Please try again later.', + player_ai_agent_working: 'Still working on it...', + title_meta_humor: 'Humor', + title_meta_tension: 'Tension', + title_meta_romance: 'Romance', + title_meta_pace: 'Pace', + title_meta_importance: 'Key scenes', + title_meta_action: 'Action' +} diff --git a/lampa-main/lang/es.js b/lampa-main/lang/es.js new file mode 100644 index 0000000..a80b964 --- /dev/null +++ b/lampa-main/lang/es.js @@ -0,0 +1,1369 @@ +export default { + lang_choice_title: 'Bienvenido', + lang_choice_subtitle: 'Elige tu idioma', + + more: 'Más', + show_more: 'Mostrar más', + more_results: 'Mostrar más resultados', + loading: 'Cargando', + nofind_movie: 'No se pudo encontrar la película.', + noname: 'Sin título', + nochoice: 'Sin elegir', + cancel: 'Cancelar', + confirm: 'Confirmo', + sure: '¿Estás seguro?', + nodata: 'Sin datos', + back: 'Atrás', + ready: 'Listo', + close_app_modal: '¿Seguro que quieres salir de la aplicación?', + connected_seeds: 'conectados', + + search: 'Buscar', + search_input: 'Introduce el texto', + search_empty: 'El historial de búsqueda está vacío.', + search_delete: 'Izquierda - eliminar', + search_start_typing: 'Empieza a escribir el texto de búsqueda.', + search_searching: 'Buscando...', + search_start: 'Empezar a buscar', + search_nofound: 'No se encontró nada para tu búsqueda.', + global_search: 'Búsqueda global', + + full_genre: 'Género', + full_production: 'Producción', + full_date_of_release: 'Fecha de estreno', + full_budget: 'Presupuesto', + full_countries: 'Países', + full_like: 'Me gusta', + full_torrents: 'Torrents', + full_trailers: 'Tráileres', + full_detail: 'En detalle', + full_notext: 'Sin descripción.', + full_series_release: 'Emisión de la serie', + full_next_episode: 'Siguiente', + full_episode_days_left: 'Días restantes', + full_trailer_official: 'Oficial', + full_trailer_no_official: 'No oficial', + full_season: 'Temporada', + full_episode: 'Episodio', + full_directing: 'Dirección', + full_writing: 'Guion', + full_keywords: 'Etiquetas', + full_crew: 'Más', + full_editing: 'Montaje', + full_creator: 'Creador', + + settings_cub_sync: 'Sincronización', + settings_cub_sync_descr: 'Sincronización con el servicio CUB: sincroniza tus favoritos, historial de visualización, etiquetas y marcas de tiempo.', + settings_cub_account: 'Cuenta', + settings_cub_logged_in_as: 'Sesión iniciada como', + settings_cub_profile: 'Perfil', + settings_cub_sync_btn: 'Sincronizar', + settings_cub_sync_btn_descr: 'Guardar los favoritos locales en la cuenta CUB', + settings_cub_backup: 'Copia de seguridad', + settings_cub_backup_descr: 'Guardar o cargar una copia de seguridad', + settings_cub_logout: 'Cerrar sesión', + settings_cub_signin: 'Autorización', + settings_cub_not_specified: 'No especificado', + settings_cub_password: 'Contraseña', + settings_cub_status: 'Estado', + settings_cub_backup_import: 'Importar', + settings_cub_backup_export: 'Exportar', + settings_cub_backup_export_descr: 'Guardar los ajustes en la nube', + settings_cub_backup_import_descr: 'Restaurar los ajustes desde la nube', + settings_cub_sync_filters: 'Sincronizar filtros', + settings_cub_sync_calendar: 'Sincronizar calendario', + settings_cub_sync_quality: 'Sincronizar calidad', + settings_cub_sync_search: 'Sincronizar historial de búsqueda', + settings_cub_sync_recomends: 'Sincronizar recomendaciones', + settings_cub_sync_timecodes: 'Sincronizar marcas de tiempo', + settings_cub_signin_button: 'Iniciar sesión', + settings_cub_domain: 'Dominio principal', + + settings_input_links: 'Favoritos', + + settings_interface_type: 'Versión ligera', + settings_interface_size: 'Tamaño de la interfaz', + settings_interface_menu_always: 'Mostrar siempre el menú izquierdo', + settings_interface_background: 'Fondo', + settings_interface_background_use: 'Mostrar fondo', + settings_interface_background_type: 'Tipo de fondo', + settings_interface_performance: 'Rendimiento', + settings_interface_animation: 'Animación', + settings_interface_advanced_animation: 'Animación avanzada', + settings_interface_animation_descr: 'Animación de tarjetas y contenido', + settings_interface_attenuation: 'Atenuación', + settings_interface_attenuation_descr: 'Desvanecimiento suave de las tarjetas por abajo y por arriba', + settings_interface_scroll: 'Tipo de desplazamiento', + settings_interface_view_card: 'Tipo de vista de tarjetas', + settings_interface_view_card_descr: 'Al desplazarte, las tarjetas se cargarán gradualmente o todas a la vez', + settings_interface_lang: 'Idioma de la interfaz', + settings_interface_lang_reload: 'Es necesario reiniciar la aplicación, pulsa "OK" para reiniciar.', + settings_interface_card_interfice: 'Interfaz de la tarjeta', + settings_interface_card_poster: 'Mostrar póster', + settings_interface_card_cover: 'Mostrar portada', + settings_interface_card_reactions: 'Mostrar reacciones', + settings_interface_glass: 'Cristal', + settings_interface_glass_descr: 'Mostrar la interfaz con efecto cristal', + settings_interface_glass_opacity: 'Transparencia del cristal', + settings_interface_black_style: 'Estilo negro', + settings_interface_hide_outside_the_screen: 'Ocultar tarjetas fuera de pantalla', + settings_interface_hide_outside_the_screen_descr: 'Acelera el renderizado de la interfaz y mejora el rendimiento', + + settings_interface_sound: 'Sonidos del sistema', + settings_interface_sound_play: 'Transiciones', + settings_interface_sound_level: 'Nivel de volumen', + + settings_main_account: 'Cuenta', + settings_main_interface: 'Interfaz', + settings_main_player: 'Reproductor', + settings_main_parser: 'Parser', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Extensiones', + settings_main_rest: 'Otros', + + settings_rest_start: 'Página de inicio', + settings_rest_start_descr: 'Página que se abre al iniciar', + settings_rest_source: 'Fuente', + settings_rest_source_use: 'Fuente principal', + settings_rest_source_descr: 'De dónde obtener la información de las películas', + settings_rest_tmdb_lang: 'Idioma de los datos de TMDB', + settings_rest_tmdb_prox: 'Proxy TMDB', + settings_rest_tmdb_prox_auto: 'Activar el proxy automáticamente', + settings_rest_tmdb_posters: 'Resolución de los pósteres de TMDB', + settings_rest_screensaver: 'Salvapantallas', + settings_rest_screensaver_use: 'Mostrar salvapantallas en reposo', + settings_rest_screensaver_type: 'Tipo de salvapantallas', + settings_rest_screensaver_time: 'Minutos de inactividad antes del salvapantallas', + settings_rest_helper: 'Consejos', + settings_rest_helper_use: 'Mostrar consejos', + settings_rest_helper_reset: 'Volver a mostrar los consejos', + settings_rest_pages: 'Cuántas páginas mantener en memoria', + settings_rest_pages_descr: 'Mantiene las páginas en el estado en que las dejaste', + settings_rest_time: 'Desfase horario', + settings_rest_navigation: 'Tipo de navegación', + settings_rest_keyboard: 'Tipo de teclado', + settings_rest_device: 'Nombre del dispositivo', + settings_rest_device_placeholder: 'Por ejemplo: Mi Lampa', + settings_rest_cache: 'Borrar caché', + settings_rest_tmdb_example: 'Por ejemplo:', + settings_rest_tmdb_api_descr: 'Para obtener datos', + settings_rest_tmdb_image_descr: 'Para obtener imágenes', + settings_rest_card_quality: 'Marcas de calidad', + settings_rest_card_quality_descr: 'Mostrar marcas de calidad en las tarjetas', + settings_rest_card_episodes: 'Marcas de episodios', + settings_rest_card_episodes_descr: 'Mostrar marcas de episodios en las tarjetas', + settings_rest_cache_images: 'Caché de imágenes', + settings_rest_cache_images_descr: 'Guardar pósteres y fondos en el almacenamiento local', + settings_rest_protocol_use: 'Conexión segura', + settings_rest_protocol_descr: 'Usar el protocolo HTTPS', + settings_rest_cache_only: 'Solo caché', + settings_rest_cache_only_descr: 'Se conservarán los ajustes básicos', + settings_rest_cache_all: 'Caché y datos', + settings_rest_cache_all_descr: 'Se borrarán todos los ajustes y datos', + settings_rest_cache_calculate: 'Cuánta memoria queda', + settings_request_caching_use: 'Caché de peticiones', + settings_request_caching_descr: 'Guarda en caché las peticiones a la API para acelerar la interfaz y reducir el consumo de datos.', + + settings_parser_use: 'Usar parser', + settings_parser_use_descr: 'Al activarlo, aceptas toda la responsabilidad por el uso de enlaces públicos para ver contenido torrent y en línea.', + settings_parser_type: 'Tipo de parser para torrents', + settings_parser_jackett_placeholder: 'Por ejemplo: 192.168.x', + settings_parser_jackett_link: 'Enlace', + settings_parser_jackett_link_descr: 'Indica el enlace al script de Jackett', + settings_parser_prowlarr_link_descr: 'Indica el enlace al servidor de Prowlarr', + settings_parser_jackett_key_placeholder: 'Por ejemplo: sa0sk83d..', + settings_parser_jackett_key: 'Clave API', + settings_parser_jackett_key_descr: 'Se encuentra en Jackett', + settings_parser_prowlarr_key_descr: 'Se encuentra en la pestaña de ajustes de Prowlarr, en la categoría general', + settings_parser_torlook_type: 'Método de análisis del sitio TorLook', + settings_parser_scraperapi_placeholder: 'Por ejemplo: scraperapi.com', + settings_parser_scraperapi_link: 'Enlace al parser del sitio', + settings_parser_scraperapi_descr: 'Regístrate en scraperapi.com e introduce el enlace api.scraperapi.com?api_key=...&url={q}
    En {q} se pondrá W41.torlook.info', + settings_parser_search: 'Búsqueda', + settings_parser_search_descr: '¿En qué idioma buscar?', + settings_parser_in_search: 'Parser en la búsqueda', + settings_parser_in_search_descr: '¿Mostrar resultados de búsqueda?', + settings_parser_timeout_title: 'Tiempo de espera del parser', + settings_parser_timeout_descr: 'Segundos de espera para la respuesta del servidor', + + settings_player_type: 'Tipo de reproductor', + settings_player_type_descr: 'Con qué reproductor reproducir', + settings_infuse_launch_mode: 'Abrir en Infuse', + settings_infuse_launch_mode_descr: 'Qué hacer al abrir un vídeo en Infuse. Los torrents siempre se reproducen de inmediato', + settings_infuse_launch_ask: 'Preguntar al abrir', + settings_infuse_launch_play: 'Reproducir', + settings_infuse_launch_save_and_play: 'Guardar y reproducir', + settings_player_iptv_type: 'Tipo de reproductor para IPTV', + settings_player_iptv_type_descr: 'Con qué reproductor reproducir los canales IPTV', + settings_player_torrent_type: 'Tipo de reproductor para torrents', + settings_player_torrent_type_descr: 'Con qué reproductor reproducir los torrents', + settings_player_reset: 'Restablecer reproductor predeterminado', + settings_player_reset_descr: 'Restablece el reproductor de Android seleccionado en la aplicación', + settings_player_path: 'Ruta del reproductor', + settings_player_path_descr: 'Indica la ruta al .exe del reproductor', + settings_player_external_header: 'Reproductor externo', + settings_player_external_fullscreen: 'Abrir en pantalla completa', + settings_player_normalization: 'Normalización del sonido', + settings_player_normalization_descr: 'Normaliza el sonido a un mismo nivel, baja los sonidos fuertes y sube los débiles.', + settings_player_next_episode: 'Siguiente episodio', + settings_player_next_episode_descr: 'Pasar automáticamente al siguiente episodio al terminar el actual', + settings_player_timecode: 'Marca de tiempo', + settings_player_timecode_descr: 'Continuar desde el último punto visto', + settings_player_scale: 'Método de escalado', + settings_player_scale_descr: 'Cómo calcular el escalado del vídeo', + settings_player_subs: 'Subtítulos', + settings_player_subs_use: 'Activar', + settings_player_subs_use_descr: 'Activar siempre los subtítulos al iniciar un vídeo', + settings_player_subs_lang: 'Idioma de los subtítulos', + settings_player_subs_lang_descr: 'Qué subtítulos activar automáticamente cuando hay varios idiomas disponibles', + settings_param_subtitles_lang_auto: 'Idioma de la interfaz', + settings_player_subs_size: 'Tamaño', + settings_player_subs_size_descr: 'Tamaño de los subtítulos en pantalla', + settings_player_subs_stroke_use: 'Usar contorno', + settings_player_subs_stroke_use_descr: 'Los subtítulos tendrán un contorno negro para leerse mejor', + settings_player_subs_backdrop_use: 'Usar fondo', + settings_player_subs_backdrop_use_descr: 'Los subtítulos se mostrarán sobre un fondo semitransparente para leerse mejor', + settings_player_quality: 'Calidad de vídeo predeterminada', + settings_player_quality_descr: 'Calidad de vídeo preferida para ver', + settings_player_hls_title: 'Procesamiento del flujo .m3u8', + settings_player_hls_descr: 'No toques este parámetro si no sabes para qué sirve.', + settings_player_rewind_title: 'Avance/retroceso', + settings_player_rewind_descr: 'Intervalo de avance/retroceso en segundos', + settings_player_launch_trailers: 'Reproductor de tráileres', + + settings_plugins_notice: 'Para aplicar el complemento es necesario reiniciar la aplicación', + settings_plugins_add: 'Añadir complemento', + settings_plugins_add_descr: 'Para eliminar un complemento añadido, mantén pulsado o pulsa dos veces (OK) sobre él', + settings_plugins_install: 'Instalar complemento', + settings_plugins_install_descr: 'Instalar un complemento de la lista de disponibles', + + settings_server_link: 'Usar enlace', + settings_server_links: 'Enlaces', + settings_server_placeholder: 'Por ejemplo: 192.168.X', + settings_server_link_one: 'Enlace principal', + settings_server_link_one_descr: 'Indica el enlace principal al script de TorrServer', + settings_server_link_two: 'Enlace adicional', + settings_server_link_two_descr: 'Indica un enlace adicional al script de TorrServer', + settings_server_additionally: 'Adicional', + settings_server_client: 'Cliente integrado', + settings_server_client_descr: 'Usar el cliente JS de TorrServer integrado; si no, se abre el del sistema.', + settings_server_base: 'Guardar en la base de datos', + settings_server_base_descr: 'El torrent se añadirá a la base de datos de TorrServer', + settings_server_preload: 'Usar búfer de precarga', + settings_server_preload_descr: 'Esperar a que se llene el búfer de precarga de TorrServer antes de reproducir', + settings_server_auth: 'Autorización', + settings_server_password_use: 'Acceso con contraseña', + settings_server_login: 'Usuario', + settings_server_password: 'Contraseña', + settings_server_not_specified: 'No especificado', + settings_server_search_type: 'Tipo de búsqueda', + settings_server_search_type_descr: 'Dónde buscar torrents: rutor integrado, indexadores Torznab en TorrServer o ambas fuentes.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + settings_server_gts: 'Transcodificación', + settings_server_gts_descr: 'Convertir automáticamente el vídeo a un formato compatible cuando sea necesario.', + settings_server_tracktimecode: 'Activar TrackTimecode', + settings_server_tracktimecode_descr: 'Guarda el progreso de reproducción de películas y series en TorrServer. Esta opción también debe estar activada en TorrServer para que funcione.', + + settings_webos_launcher: 'Inicio de la aplicación', + settings_webos_launcher_add_device: 'Instalar como aplicación de inicio', + settings_webos_launcher_remove_device: 'Quitar de las aplicaciones de inicio', + + settings_parental_control_param_time_always: 'Siempre', + settings_parental_control_param_time_once: 'Una vez', + settings_parental_control_param_time_10: 'Cada 10 minutos', + settings_parental_control_param_time_20: 'Cada 20 minutos', + settings_parental_control_param_time_30: 'Cada 30 minutos', + settings_parental_control_param_time_60: 'Cada hora', + settings_parental_control_param_time_120: 'Cada 2 horas', + settings_parental_control_change_pin: 'Cambiar PIN', + settings_parental_control_demand_title: 'Cuándo pedirlo', + settings_parental_control_demand_descr: 'Tras cuánto tiempo pedir el PIN', + settings_parental_control_enabled: 'Activado', + settings_parental_control_disabled: 'Desactivado', + settings_parental_control_where: 'Dónde pedir el código PIN', + + settings_lgbt_content_block: 'Bloquear contenido LGBT', + + parental_control_input_new_code: 'Introduce el nuevo código PIN', + parental_control_confirm_new_code: 'Confirma el código PIN', + parental_control_no_match_code: 'El código PIN no coincide con el anterior', + parental_control_input_code: 'Introduce el código PIN', + parental_control_input_error: 'Has introducido un código PIN incorrecto', + + torent_nohash_reasons: 'Motivos', + torent_nohash_reason_one: 'TorrServer no pudo descargar el archivo torrent', + torent_nohash_reason_two: 'Respuesta de TorrServer', + torent_nohash_reason_three: 'Enlace', + torent_nohash_do: '¿Qué hacer?', + torent_nohash_do_one: 'Comprueba que has configurado Jackett correctamente', + torent_nohash_do_two: 'Las fuentes privadas pueden no dar un enlace al archivo', + torent_nohash_do_three: 'Asegúrate de que Jackett también puede descargar el archivo', + torent_nohash_do_four: 'Escribe a nuestro grupo de Telegram: @lampa_group', + torent_nohash_do_five: 'Indica qué película, qué distribución y, si es posible, una foto de esa distribución', + + torrent_error_text: 'No se pudo conectar a TorrServer. Repasemos rápidamente la lista de posibles problemas y comprobemos todo.', + torrent_error_step_1: '¿Está TorrServer en ejecución?', + torrent_error_step_2: 'IP dinámica', + torrent_error_step_3: 'Protocolo y puerto', + torrent_error_step_4: 'Bloqueo del antivirus', + torrent_error_step_5: 'Comprobar disponibilidad', + torrent_error_step_6: 'Sigue sin funcionar', + torrent_error_info_1: 'Asegúrate de haber iniciado TorrServer en el dispositivo donde está instalado.', + torrent_error_info_2: 'Un error habitual: la dirección IP del dispositivo con TorrServer ha cambiado. Asegúrate de que la dirección IP introducida - {ip} - coincide con la del dispositivo donde está instalado TorrServer.', + torrent_error_info_3: 'Para conectarte a TorrServer, debes indicar el protocolo http:// al principio y el puerto :8090 al final de la dirección. Asegúrate de que hay un puerto después de la dirección IP; tu dirección actual es {ip}', + torrent_error_info_4: 'Es frecuente que el antivirus o el cortafuegos bloqueen el acceso por dirección IP; prueba a desactivarlos.', + torrent_error_info_5: 'En cualquier otro dispositivo de la misma red, abre la dirección {ip} en un navegador y comprueba si está disponible la interfaz web de TorrServer.', + torrent_error_info_6: 'Si tras todas las comprobaciones sigue habiendo un error de conexión, prueba a reiniciar TorrServer y el adaptador de red.', + torrent_error_info_7: 'Si el problema continúa, escribe al grupo de Telegram @lampa_group con el texto (Lampa no se conecta a TorrServer tras todas las comprobaciones, la dirección actual es {ip})', + torrent_error_start: 'Iniciar comprobación', + torrent_error_nomatrix: 'No se pudo comprobar la versión Matrix', + torrent_error_made: 'Completado', + torrent_error_from: 'de', + torrent_error_next: 'Siguiente', + torrent_error_complite: 'Terminar', + torrent_error_connect: 'Error de conexión', + torrent_error_check_no_auth: 'El servidor respondió a la petición, pero la autorización falló', + + torrent_install_need: 'Se necesita TorrServer', + torrent_install_text: 'TorrServer es una aplicación que te permite ver en línea el contenido de archivos torrent.

    Encontrarás información más detallada sobre la instalación en los grupos de Telegram de abajo.', + torrent_install_contact: 'Grupos de Telegram', + + torrent_item_bitrate: 'Tasa de bits', + torrent_item_seeds: 'Semillas', + torrent_item_grabs: 'Descargando', + torrent_item_mb: 'Mbps', + + torrent_serial_episode: 'Episodio', + torrent_serial_season: 'Temporada', + torrent_serial_date: 'Estreno', + + torrent_get_magnet: 'Solicitando el enlace magnet', + torrent_remove_title: 'Eliminar', + torrent_remove_descr: 'El torrent se eliminará de tu lista', + + torrent_parser_any_one: 'Cualquiera', + torrent_parser_any_two: 'Cualquiera', + torrent_parser_no_choice: 'Sin seleccionar', + torrent_parser_yes: 'Sí', + torrent_parser_no: 'No', + torrent_parser_quality: 'Calidad', + torrent_parser_subs: 'Subtítulos', + torrent_parser_voice: 'Traducción', + torrent_parser_tracker: 'Tracker', + torrent_parser_year: 'Año', + torrent_parser_season: 'Temporada', + torrent_parser_sort_by_seeders: 'Por semillas', + torrent_parser_sort_by_size: 'Por tamaño', + torrent_parser_sort_by_name: 'Por nombre', + torrent_parser_sort_by_tracker: 'Por fuente', + torrent_parser_sort_by_date: 'Por fecha', + torrent_parser_sort_by_viewed: 'Por vistos', + torrent_parser_voice_dubbing: 'Doblaje', + torrent_parser_voice_polyphonic: 'Voz superpuesta (varias voces)', + torrent_parser_voice_two: 'Voz superpuesta (dos voces)', + torrent_parser_voice_amateur: 'Aficionado', + torrent_parser_reset: 'Restablecer filtro', + torrent_parser_empty: 'No se pudieron obtener resultados', + torrent_parser_no_hash: 'No se pudo obtener el HASH, prueba a reiniciar TorrServer', + torrent_parser_added_to_mytorrents: 'añadido a «Mis torrents»', + torrent_parser_add_to_mytorrents: 'Añadir a «Mis torrents»', + torrent_parser_label_title: 'Marcar', + torrent_parser_label_descr: 'Marcar el torrent con una bandera (visto)', + torrent_parser_label_cancel_title: 'Quitar marca', + torrent_parser_label_cancel_descr: 'Quitar la marca del torrent (visto)', + torrent_parser_timeout: 'Se agotó el tiempo de espera', + torrent_parser_nofiles: 'No se pudieron extraer archivos compatibles', + torrent_parser_set_link: 'Indica un enlace para el parser', + torrent_parser_request_error: 'Error en la solicitud', + torrent_parser_magnet_error: 'No se pudo obtener el enlace magnet', + torrent_parser_no_responce: 'El parser no responde a la solicitud', + torrent_parser_torlook_fallback_search_notification: 'El parser Jackett no está disponible o la configuración de conexión es incorrecta. Buscando en Torlook...', + + about_text: 'La aplicación es totalmente gratuita y utiliza enlaces públicos para obtener información sobre vídeos, novedades, películas populares, etc. Toda la información disponible se usa únicamente con fines educativos; la aplicación no utiliza servidores propios para distribuir información.', + about_channel: 'Nuestro canal', + about_group: 'Grupo', + about_version: 'Versión', + about_donate: 'Donar', + + title_watched: 'Has visto', + title_settings: 'Ajustes', + title_collections: 'Colecciones', + title_company: 'Compañía', + title_actors: 'Actores', + title_actor: 'Actor', + title_actress: 'Actriz', + title_person: 'Persona', + title_persons: 'Personas', + title_person_about: 'Biografía', + title_comments: 'Comentarios', + title_torrents: 'Torrents', + title_trailers: 'Tráileres', + title_watch: 'Ver', + title_error: 'Error', + title_links: 'Enlaces', + title_choice: 'Elegir', + title_main: 'Inicio', + title_book: 'Favoritos', + title_like: 'Me gusta', + title_wath: 'Más tarde', + title_look: 'Viendo', + title_scheduled: 'Planificado', + title_viewed: 'Visto', + title_thrown: 'Abandonado', + title_continued: 'Continuará', + title_history: 'Historial', + title_mytorrents: 'Mis torrents', + title_last: 'Última', + title_action: 'Acción', + title_action_infuse: 'Acción de Infuse', + title_producer: 'Director', + title_collection: 'Colección', + title_recomendations: 'Recomendaciones', + title_similar: 'Similares', + title_about: 'Acerca de la aplicación', + title_timetable: 'Calendario', + title_relises: 'Estrenos digitales', + title_catalog: 'Catálogo', + title_category: 'Categoría', + title_parser: 'Parser', + title_type: 'Tipo', + title_rating: 'Valoración', + title_country: 'País', + title_year: 'Año', + title_genre: 'Género', + title_filter: 'Filtro', + title_notice: 'Notificaciones', + title_files: 'Archivos', + title_now_watch: 'Se está viendo ahora', + title_latest: 'Añadido recientemente', + title_continue: 'Seguir viendo', + title_recomend_watch: 'Te recomendamos ver', + title_new_episodes: 'Nuevos episodios', + title_popular: 'Popular', + title_popular_movie: 'Películas populares', + title_popular_tv: 'Series populares', + title_new_this_year: 'Novedades de este año', + title_hight_voite: 'Mejor valoradas', + title_new: 'Novedades', + title_trend_day: 'Tendencias de hoy', + title_trend_week: 'Tendencias de la semana', + title_upcoming: 'En cines', + title_top_movie: 'Mejores películas', + title_top_tv: 'Mejores series', + title_tv_today: 'Hoy en emisión', + title_this_week: 'Esta semana', + title_in_top: 'En el top', + title_out: 'Salir', + title_out_confirm: 'Sí, salir', + title_continue_two: 'Continuar', + title_choice_language: 'Elegir idioma', + title_subscribe: 'Suscribirse', + title_subscribes: 'Suscripciones', + title_unsubscribe: 'Cancelar suscripción', + title_language: 'Idioma original', + title_language_short: 'Idioma', + title_ongoing: 'En emisión', + title_pgrating: 'Clasificación por edad', + title_card: 'Ficha', + title_seasons: 'Temporadas', + title_episodes: 'Episodios', + title_rewiews: 'Reseñas', + title_channel: 'Canal', + title_in_high_quality: 'En alta calidad', + title_author: 'Autor', + title_buffer: 'Búfer', + title_upcoming_episodes: 'Próximos episodios', + title_recent_episodes: 'Episodios recientes', + title_reactions: 'Reacciones', + title_last_year: 'El año pasado', + title_reset: 'Reiniciar', + title_left: 'Restante', + title_parental_control: 'Control parental', + title_worth_rewatch: 'Vale la pena volver a ver', + title_fire: '¡Fuego!', + title_top_100: 'Top 100', + title_ai_assistant: 'Asistente de IA', + title_facts: 'Datos curiosos', + title_anons: 'Anuncio', + title_developer: 'Desarrollador', + title_navigation: 'Navegación', + title_page: 'Página', + title_channels: 'Canales', + title_best_of_2000: 'Los dorados 2000', + title_best_of_2010: 'Éxitos de los 2010', + title_best_of_2015: 'Clásicos modernos', + title_comedy_of_2000: 'Risas de los 2000', + title_comedy_of_2010: 'Humor de los 2010', + title_comedy_of_2015: 'Comedias modernas', + + title_metadata: 'Metadatos', + title_moods: 'Estados de ánimo', + title_meta_violence: 'Violencia', + title_meta_fear: 'Miedo', + title_meta_profanity: 'Lenguaje soez', + title_meta_sadness: 'Tristeza', + title_meta_sex: 'Sexualidad', + title_meta_humor: 'Humor', + title_meta_tension: 'Tensión', + title_meta_romance: 'Romance', + title_meta_pace: 'Ritmo', + title_meta_importance: 'Escenas clave', + title_meta_action: 'Acción', + + reactions_none: 'Sin reacciones', + reactions_fire: 'Genial', + reactions_nice: 'Bien', + reactions_think: 'Interesante', + reactions_bore: 'Aburrida', + reactions_shit: 'Mala', + reactions_ready: 'Ya has dejado una reacción', + + subscribe_success: 'Te has suscrito correctamente', + subscribe_error: 'Se produjo un error al suscribirte, inténtalo más tarde', + subscribe_noinfo: 'No se pudo obtener la información, inténtalo más tarde', + subscribe_info: 'En la sección Suscripciones verás todas tus suscripciones a traducciones. Recibirás una notificación cuando se publique un nuevo episodio con la traducción seleccionada.', + + company_headquarters: 'Sede', + company_homepage: 'Sitio web', + company_country: 'País', + + country_ad: 'Andorra', + country_ae: 'EAU', + country_af: 'Afganistán', + country_al: 'Albania', + country_am: 'Armenia', + country_ao: 'Angola', + country_ar: 'Argentina', + country_at: 'Austria', + country_au: 'Australia', + country_aw: 'Aruba', + country_az: 'Azerbaiyán', + country_bа: 'Bosnia y Herzegovina', + country_bd: 'Bangladés', + country_be: 'Bélgica', + country_bg: 'Bulgaria', + country_bh: 'Baréin', + country_bi: 'Burundi', + country_bj: 'Benín', + country_bo: 'Bolivia', + country_br: 'Brasil', + country_bs: 'Bahamas', + country_bt: 'Bután', + country_bw: 'Botsuana', + country_by: 'Bielorrusia', + country_ca: 'Canadá', + country_ch: 'Suiza', + country_cl: 'Chile', + country_cm: 'Camerún', + country_cn: 'China', + country_co: 'Colombia', + country_cr: 'Costa Rica', + country_cu: 'Cuba', + country_cv: 'Cabo Verde', + country_cy: 'Chipre', + country_cz: 'República Checa', + country_de: 'Alemania', + country_dj: 'Yibuti', + country_dk: 'Dinamarca', + country_do: 'República Dominicana', + country_dz: 'Argelia', + country_ec: 'Ecuador', + country_ee: 'Estonia', + country_eg: 'Egipto', + country_es: 'España', + country_et: 'Etiopía', + country_fi: 'Finlandia', + country_fo: 'Islas Feroe', + country_fr: 'Francia', + country_ga: 'Gabón', + country_gb: 'Reino Unido', + country_ge: 'Georgia', + country_gh: 'Ghana', + country_gl: 'Groenlandia', + country_gp: 'Guadalupe', + country_gr: 'Grecia', + country_gt: 'Guatemala', + country_hk: 'Hong Kong', + country_hr: 'Croacia', + country_ht: 'Haití', + country_hu: 'Hungría', + country_id: 'Indonesia', + country_ie: 'Irlanda', + country_il: 'Israel', + country_in: 'India', + country_iq: 'Irak', + country_ir: 'Irán', + country_is: 'Islandia', + country_it: 'Italia', + country_jm: 'Jamaica', + country_jo: 'Jordania', + country_jp: 'Japón', + country_ke: 'Kenia', + country_kg: 'Kirguistán', + country_kh: 'Camboya', + country_kp: 'Corea del Norte', + country_kr: 'Corea del Sur', + country_kz: 'Kazajistán', + country_kw: 'Kuwait', + country_la: 'Laos', + country_lb: 'Líbano', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Liberia', + country_lt: 'Lituania', + country_lu: 'Luxemburgo', + country_lv: 'Letonia', + country_ly: 'Libia', + country_ma: 'Marruecos', + country_mc: 'Mónaco', + country_md: 'Moldavia', + country_me: 'Montenegro', + country_mk: 'Macedonia del Norte', + country_mm: 'Myanmar', + country_mn: 'Mongolia', + country_mo: 'Macao', + country_mt: 'Malta', + country_mu: 'Mauricio', + country_mv: 'Maldivas', + country_mw: 'Malaui', + country_mx: 'México', + country_my: 'Malasia', + country_mz: 'Mozambique', + country_na: 'Namibia', + country_ne: 'Níger', + country_ng: 'Nigeria', + country_ni: 'Nicaragua', + country_nl: 'Países Bajos', + country_no: 'Noruega', + country_np: 'Nepal', + country_nz: 'Nueva Zelanda', + country_om: 'Omán', + country_pa: 'Panamá', + country_pe: 'Perú', + country_pg: 'Papúa Nueva Guinea', + country_ph: 'Filipinas', + country_pk: 'Pakistán', + country_pl: 'Polonia', + country_pr: 'Puerto Rico', + country_ps: 'Palestina', + country_pt: 'Portugal', + country_py: 'Paraguay', + country_qa: 'Catar', + country_ro: 'Rumania', + country_rs: 'Serbia', + country_ru: 'Rusia', + country_rw: 'Ruanda', + country_sa: 'Arabia Saudí', + country_sd: 'Sudán', + country_se: 'Suecia', + country_sg: 'Singapur', + country_si: 'Eslovenia', + country_sk: 'Eslovaquia', + country_sn: 'Senegal', + country_su: 'URSS', + country_sv: 'El Salvador', + country_sy: 'Siria', + country_th: 'Tailandia', + country_tj: 'Tayikistán', + country_tm: 'Turkmenistán', + country_tn: 'Túnez', + country_tr: 'Turquía', + country_tw: 'Taiwán', + country_tz: 'Tanzania', + country_ua: 'Ucrania', + country_ug: 'Uganda', + country_us: 'EE. UU.', + country_uy: 'Uruguay', + country_uz: 'Uzbekistán', + country_ve: 'Venezuela', + country_vn: 'Vietnam', + country_ws: 'Samoa', + country_xk: 'Kosovo', + country_ye: 'Yemen', + country_yu: 'Yugoslavia', + country_za: 'Sudáfrica', + country_zm: 'Zambia', + country_zw: 'Zimbabue', + + filter_clarify: 'Precisar', + filter_clarify_two: 'Precisar búsqueda', + filter_set_name: 'Indicar título', + filter_sorted: 'Ordenar', + filter_filtred: 'Filtro', + filter_any: 'Cualquiera', + filter_combinations: 'Combinaciones', + filter_alt_names: 'Otros títulos', + filter_rating_from: 'desde', + filter_rating_to: 'hasta', + + filter_lang_af: 'Afrikáans', + filter_lang_ar: 'Árabe', + filter_lang_az: 'Azerbaiyano', + filter_lang_ba: 'Baskir', + filter_lang_be: 'Bielorruso', + filter_lang_bg: 'Búlgaro', + filter_lang_bn: 'Bengalí', + filter_lang_bs: 'Bosnio', + filter_lang_ca: 'Catalán', + filter_lang_ce: 'Checheno', + filter_lang_cs: 'Checo', + filter_lang_da: 'Danés', + filter_lang_de: 'Alemán', + filter_lang_el: 'Griego', + filter_lang_en: 'Inglés', + filter_lang_es: 'Español', + filter_lang_et: 'Estonio', + filter_lang_fa: 'Persa', + filter_lang_fi: 'Finés', + filter_lang_fr: 'Francés', + filter_lang_ga: 'Irlandés', + filter_lang_gl: 'Gallego', + filter_lang_gn: 'Guaraní', + filter_lang_he: 'Hebreo', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Croata', + filter_lang_hu: 'Húngaro', + filter_lang_hy: 'Armenio', + filter_lang_id: 'Indonesio', + filter_lang_is: 'Islandés', + filter_lang_it: 'Italiano', + filter_lang_ja: 'Japonés', + filter_lang_ka: 'Georgiano', + filter_lang_kk: 'Kazajo', + filter_lang_ko: 'Coreano', + filter_lang_ks: 'Cachemir', + filter_lang_ku: 'Kurdo', + filter_lang_ky: 'Kirguís', + filter_lang_lt: 'Lituano', + filter_lang_lv: 'Letón', + filter_lang_mi: 'Maorí', + filter_lang_mk: 'Macedonio', + filter_lang_mn: 'Mongol', + filter_lang_mt: 'Maltés', + filter_lang_ne: 'Nepalí', + filter_lang_nl: 'Neerlandés', + filter_lang_no: 'Noruego', + filter_lang_pa: 'Panyabí', + filter_lang_pl: 'Polaco', + filter_lang_ps: 'Pastún', + filter_lang_pt: 'Portugués', + filter_lang_ro: 'Rumano', + filter_lang_ru: 'Ruso', + filter_lang_si: 'Cingalés', + filter_lang_sk: 'Eslovaco', + filter_lang_sl: 'Esloveno', + filter_lang_sm: 'Samoano', + filter_lang_so: 'Somalí', + filter_lang_sq: 'Albanés', + filter_lang_sr: 'Serbio', + filter_lang_sv: 'Sueco', + filter_lang_sw: 'Suajili', + filter_lang_ta: 'Tamil', + filter_lang_tg: 'Tayiko', + filter_lang_th: 'Tailandés', + filter_lang_tk: 'Turcomano', + filter_lang_tr: 'Turco', + filter_lang_tt: 'Tártaro', + filter_lang_ur: 'Urdu', + filter_lang_uk: 'Ucraniano', + filter_lang_uz: 'Uzbeko', + filter_lang_vi: 'Vietnamita', + filter_lang_yi: 'Ídish', + filter_lang_zh: 'Chino', + + filter_genre_ac: 'Acción', + filter_genre_ad: 'Aventura', + filter_genre_mv: 'Animación', + filter_genre_cm: 'Comedia', + filter_genre_cr: 'Crimen', + filter_genre_dc: 'Documental', + filter_genre_dr: 'Drama', + filter_genre_fm: 'Familia', + filter_genre_fe: 'Fantasía', + filter_genre_hi: 'Historia', + filter_genre_ho: 'Terror', + filter_genre_mu: 'Música', + filter_genre_de: 'Policíaco', + filter_genre_md: 'Melodrama', + filter_genre_fa: 'Ciencia ficción', + filter_genre_tv: 'Película de TV', + filter_genre_tr: 'Suspense', + filter_genre_mi: 'Bélica', + filter_genre_ve: 'Western', + filter_genre_aa: 'Acción y aventura', + filter_genre_ch: 'Infantil', + filter_genre_nw: 'Noticias', + filter_genre_rs: 'Reality', + filter_genre_hf: 'Ciencia ficción y fantasía', + filter_genre_op: 'Telenovela', + filter_genre_tc: 'Programa de entrevistas', + filter_genre_mp: 'Guerra y política', + + filter_keyword_sequel: 'Secuela', + filter_keyword_based_comic: 'Basado en cómics', + filter_keyword_space: 'Espacio', + filter_keyword_survival: 'Supervivencia', + filter_keyword_zombie: 'Zombis', + filter_keyword_school: 'Escuela', + filter_keyword_revenge: 'Venganza', + filter_keyword_detective: 'Detectives', + filter_keyword_robots: 'Robots', + filter_keyword_vampires: 'Vampiros', + filter_keyword_aliens: 'Extraterrestres', + filter_keyword_police: 'Policía', + filter_keyword_reincarnation: 'Reencarnación', + filter_keyword_spy: 'Espías', + filter_keyword_disaster: 'Catástrofe', + filter_keyword_christmas: 'Navidad', + + empty_title: 'Vacío', + empty_text: 'No se encontró nada con tu filtro. Ajusta el filtro.', + empty_title_two: 'Aquí no hay nada', + empty_text_two: 'La lista está vacía por ahora.', + + empty_subscribes_title: 'Tus suscripciones a doblajes', + empty_subscribes_text: 'Suscríbete a tu doblaje favorito y te avisaremos cuando salga un nuevo episodio.', + empty_history_title: 'Tu historial de reproducción', + empty_history_text: 'Aquí aparecerá tu historial de reproducción.', + empty_bookmark_title: 'Tus favoritos', + empty_bookmark_text: 'Añade a favoritos las películas y series que te gusten para encontrarlas rápidamente en esta sección.', + empty_mytorrents_title: 'Tus torrents', + empty_mytorrents_text: 'Aquí aparecerán los torrents que hayas cargado mediante TorServer.', + + back_to_card: 'Volver a la ficha', + + menu_main: 'Inicio', + menu_movies: 'Películas', + menu_tv: 'Series', + menu_catalog: 'Catálogo', + menu_filter: 'Filtro', + menu_collections: 'Colecciones', + menu_relises: 'Estrenos', + menu_anime: 'Anime', + menu_bookmark: 'Favoritos', + menu_like: 'Me gusta', + menu_time: 'Ver más tarde', + menu_history: 'Historial', + menu_timeline: 'Calendario', + menu_torrents: 'Torrents', + menu_settings: 'Ajustes', + menu_about: 'Información', + menu_console: 'Consola', + menu_multmovie: 'Animación', + menu_multtv: 'Series animadas', + menu_feed: 'Novedades', + + lampa_movie_title: 'Cine Lampa', + lampa_movie_descr: 'Sigue las novedades en tu smartphone.
    Telegram: @lampa_movie', + + plugins_catalog_work: 'Complementos que funcionan', + plugins_catalog_work_descr: 'Complementos que funcionan con seguridad en Lampa.', + plugins_catalog_popular: 'Complementos populares entre los usuarios', + plugins_catalog_popular_descr: 'Instalar desde fuentes desconocidas puede hacer que la aplicación no funcione correctamente.', + plugins_online: 'Ver en línea', + plugins_check_fail: 'No se pudo comprobar el funcionamiento del complemento. Sin embargo, eso no significa que no funcione. Reinicia la aplicación para ver si el complemento se carga.', + plugins_need_reload: 'Para aplicar el complemento, reinicia la aplicación', + plugins_install: 'Instalar', + plugins_install_ready: 'Este complemento ya está instalado.', + plugins_installed: 'Instalaciones', + plugins_load_from: 'Cargado desde CUB', + plugins_ok_for_check: 'Pulsa (OK) para comprobar el complemento', + plugins_no_loaded: 'Al cargar la aplicación no se pudieron cargar algunos complementos', + plugins_remove: 'Eliminar complementos', + plugins_add_success: 'Complemento conectado correctamente', + + time_viewed: 'Visto', + time_from: 'de', + time_reset: 'Restablecer marca de tiempo', + + settings_clear_cache: 'Caché y datos borrados', + settings_clear_cache_only: 'Caché borrada', + settings_user_links: 'Enlace personalizado', + settings_for_local: 'Para TorrServer local', + settings_add: 'Añadir', + settings_remove: 'Eliminar', + settings_this_value: 'valor actual', + settings_added: 'Añadido', + settings_removed: 'Eliminado', + settings_reset: 'Restablecer ajustes', + + settings_param_player_inner: 'Integrado', + settings_param_player_outside: 'Externo', + settings_param_player_inner_tvos: 'Integrado', + settings_param_yes: 'Sí', + settings_param_no: 'No', + settings_param_interface_size_small: 'Más pequeño', + settings_param_interface_size_normal: 'Normal', + settings_param_interface_size_bigger: 'Más grande', + settings_param_poster_quality_low: 'Baja', + settings_param_poster_quality_average: 'Media', + settings_param_poster_quality_high: 'Alta', + settings_param_parse_directly: 'Directamente', + settings_param_parse_api: 'A través de la API del sitio', + settings_param_background_complex: 'Complejo', + settings_param_background_simple: 'Simple', + settings_param_background_image: 'Imagen', + settings_param_link_use_one: 'Principal', + settings_param_link_use_two: 'Adicional', + settings_param_link_use_both: 'Ambos', + settings_param_subtitles_size_small: 'Pequeños', + settings_param_subtitles_size_normal: 'Normales', + settings_param_subtitles_size_bigger: 'Grandes', + settings_param_screensaver_nature: 'Naturaleza', + settings_param_torrent_lang_orig: 'Original', + settings_param_player_timecode_again: 'Empezar desde el principio', + settings_param_player_timecode_continue: 'Continuar', + settings_param_player_timecode_ask: 'Preguntar', + settings_param_player_scale_method: 'Calcular', + settings_param_player_hls_app: 'Del sistema', + settings_param_player_hls_js: 'Por software', + settings_param_card_view_load: 'Cargar más', + settings_param_card_view_all: 'Mostrar todo', + settings_param_navigation_remote: 'Mando a distancia', + settings_param_navigation_mouse: 'Mando con ratón', + settings_param_navigation_touch: 'Táctil', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: 'Del sistema', + settings_param_card_interface_old: 'Antigua', + settings_param_card_interface_new: 'Nueva', + + settings_param_glass_easy: 'Transparente', + settings_param_glass_medium: 'Semitransparente', + settings_param_glass_blacked: 'Oscurecida', + + settings_param_jackett_interview_all: 'Todos', + settings_param_jackett_interview_healthy: 'Solo disponibles', + settings_parser_jackett_interview: 'Consultar trackers', + + helper_keyboard: 'Después de introducir el valor, pulsa el botón "Atrás" para guardar', + helper_torrents: 'Mantén pulsada la tecla (OK) para abrir el menú contextual', + helper_cleared: 'Hecho, las sugerencias se volverán a mostrar.', + helper_torrents_view: 'Mantén pulsada la tecla (OK) para restablecer la marca de tiempo y abrir el menú', + + fav_sync_title: 'Sincronización de favoritos', + fav_sync_text: 'Tus favoritos siempre contigo. Activa la sincronización y míralos en cualquier dispositivo.

    Para ello, regístrate en {site}, crea un perfil e inicia sesión en la aplicación.', + fav_sync_site: 'Sitio web', + fav_remove_title: 'Eliminar del historial', + fav_remove_descr: 'Eliminar la ficha seleccionada', + fav_clear_title: 'Borrar el historial', + fav_clear_descr: 'Eliminar todas las fichas del historial', + fav_clear_label_title: 'Borrar marcas', + fav_clear_label_descr: 'Borrar las marcas de visto', + fav_clear_time_title: 'Borrar marcas de tiempo', + fav_clear_time_descr: 'Borrar todas las marcas de tiempo', + fav_label_cleared: 'Marcas borradas', + fav_time_cleared: 'Marcas de tiempo borradas', + + timetable_empty: 'En esta sección se mostrarán las fechas de estreno de los nuevos episodios.', + + player_quality: 'Calidad', + player_flow: 'Flujo', + player_tracks: 'Pistas de audio', + player_disabled: 'Desactivado', + player_unknown: 'Desconocido', + player_subs: 'Subtítulos', + player_size_default_title: 'Predeterminado', + player_size_default_descr: 'Tamaño de vídeo predeterminado', + player_size_cover_title: 'Ampliar', + player_size_cover_descr: 'Amplía el vídeo a pantalla completa', + player_size_fill_title: 'Rellenar', + player_size_fill_descr: 'Ajusta el vídeo a pantalla completa', + player_size_s115_title: 'Zoom 115%', + player_size_s115_descr: 'Amplía el vídeo un 115%', + player_size_s130_title: 'Zoom 130%', + player_size_s130_descr: 'Amplía el vídeo un 130%', + player_size_v115_title: 'Vertical 115%', + player_size_v115_descr: 'Amplía el vídeo un 115%', + player_size_v130_title: 'Vertical 130%', + player_size_v130_descr: 'Amplía el vídeo un 130%', + player_video_size: 'Tamaño del vídeo', + player_playlist: 'Lista de reproducción', + player_error_one: 'No se pudo decodificar el vídeo', + player_error_two: 'Vídeo no encontrado o dañado', + player_start_from: 'Seguir viendo desde', + player_not_found: 'Reproductor no encontrado', + player_lauch: 'Abrir reproductor', + player_speed_default_title: 'Normal', + player_speed_two_descr: 'Se reproduce sin sonido', + player_video_speed: 'Velocidad de reproducción', + player_share_title: 'Compartir', + player_share_descr: 'Reproducir este vídeo en otro dispositivo', + player_normalization_power_title: 'Intensidad de normalización', + player_normalization_smooth_title: 'Velocidad de normalización', + player_normalization_step_none: 'Nula', + player_normalization_step_low: 'Baja', + player_normalization_step_medium: 'Media', + player_normalization_step_hight: 'Alta', + player_normalization: 'Normalización', + player_normalization_type_title: 'Tipo de normalización', + player_normalization_type_all: 'Todo', + player_normalization_type_up: 'Solo aumentar', + player_normalization_type_down: 'Solo reducir', + player_youtube_no_played: 'Lo sentimos, este vídeo no está disponible en tu región; puede que se haya bloqueado o eliminado.', + player_youtube_start_play: 'Para empezar a reproducir el vídeo, pulsa el botón "Reproducir".', + player_youtube_no_support: 'Tu dispositivo no admite la reproducción de vídeos de YouTube. Comprueba tu conexión a Internet.', + player_segments_title: 'Segmentos', + player_segments_descr: 'Saltar la introducción y otras partes del vídeo', + player_segments_ad_title: 'Anuncios', + player_segments_skip_title: 'Intro y otros', + player_segments_value_none: 'No saltar', + player_segments_value_auto: 'Saltar automáticamente', + player_segments_value_user: 'Personalizado', + player_segments_skiped: 'Segmento omitido', + player_segments_skip_now: 'Saltar', + player_segments_skip_in: 'Saltar en', + player_segments_skip_intro: 'Saltar intro', + player_segments_next: 'Siguiente episodio', + player_segments_next_in: 'Siguiente episodio en', + player_pip: 'Minimizar', + player_volume: 'Volumen', + player_time_end: 'Termina a las', + + broadcast_open: 'Abrir ficha en otro dispositivo', + broadcast_play: 'Elige el dispositivo para ver', + + card_new_episode: 'Nuevo episodio', + card_book_remove: 'Quitar de favoritos', + card_book_add: 'A favoritos', + card_book_descr: 'Consulta el menú (Favoritos)', + card_like_remove: 'Quitar de Me gusta', + card_like_add: 'Me gusta', + card_like_descr: 'Consulta el menú (Me gusta)', + card_wath_remove: 'Quitar de Ver más tarde', + card_wath_add: 'Ver más tarde', + card_wath_descr: 'Consulta el menú (Más tarde)', + card_history_remove: 'Quitar del historial', + card_history_add: 'Al historial', + card_history_descr: 'Consulta el menú (Historial)', + + keyboard_listen: 'Habla, te escucho...', + keyboard_nomic: 'Sin acceso al micrófono', + + notice_new_quality: 'Nueva calidad disponible', + notice_quality: 'Calidad', + notice_new_episode: 'Nuevo episodio', + notice_none: 'Aún no tienes notificaciones. Regístrate en {site} para seguir nuevos episodios y estrenos.', + notice_in_quality: 'En buena calidad', + notice_none_account: 'Aún no tienes notificaciones. Añade la serie a favoritos y espera los avisos de nuevos episodios.', + notice_none_system: 'Ahora mismo no tienes notificaciones. Te avisaremos en cuanto haya nuevas.', + + copy_link: 'Copiar enlace del vídeo', + copy_secuses: 'Enlace copiado al portapapeles', + copy_error: 'Error al copiar el enlace', + copy_link_buffer: 'Copiar enlace', + + account_sync_to_profile: 'Todos los favoritos se moverán al perfil', + account_sync_secuses: 'Todos los favoritos se transfirieron correctamente', + account_profiles: 'Perfiles', + account_profiles_empty: 'No se pudo obtener la lista de perfiles', + account_authorized: 'Autorizado', + account_logged_in: 'Has iniciado sesión', + account_login_failed: 'Error al iniciar sesión', + account_login_wait: 'Esperando inicio de sesión', + account_profile_main: 'General', + account_profile_child: 'Infantil', + account_profile_add: 'Añadir perfil', + account_profile_name: 'Nombre del perfil', + account_profile_created: 'Perfil creado correctamente', + account_profile_limited: 'Se alcanzó el límite máximo de perfiles: {count}', + account_profile_info: 'Puedes gestionar los perfiles en los ajustes de tu cuenta. Para ello, ve a ', + account_export_secuses: 'Exportación completada correctamente', + account_export_fail: 'Error de exportación', + account_export_fail_500: 'Error desconocido', + account_export_fail_610: 'Has superado el límite de hoy', + account_export_fail_200: 'Error de base de datos, inténtalo más tarde', + account_export_fail_600: 'Error, no se pudo subir el archivo', + account_export_fail_620: 'Error, el archivo no se transmitió', + account_import_secuses: 'Importación completada correctamente', + account_import_fail: 'Error de importación', + account_imported: 'importado', + account_reload_after: 'reinicio en 5 s.', + account_create: 'Descubre más posibilidades con una cuenta CUB. Regístrate en y sincroniza tus favoritos, marcas de tiempo y otras funciones de la cuenta CUB.', + account_premium: '¡Abre nuevos horizontes con una cuenta CUB Premium! Disfruta de límites más altos y más funciones del servicio. Visita y descubre las ventajas de una cuenta Premium.', + account_premium_more: 'Más información sobre CUB Premium', + account_limited: 'Has alcanzado el límite máximo. Amplíalo con una cuenta CUB Premium. Más información en ', + account_premium_include_1: 'Más favoritos', + account_premium_include_2: 'Historial de visualización ampliado', + account_premium_include_3: 'Más marcas de tiempo disponibles', + account_premium_include_4: 'Número de perfiles por cuenta', + account_premium_include_5: 'Notificaciones', + account_premium_include_6: 'Sincronización de datos', + account_premium_include_text_1: 'Más favoritos, más posibilidades. Guarda tus películas y series favoritas, crea listas y disfrútalas cuando quieras.', + account_premium_include_text_2: 'Amplía el historial de visualización de la aplicación y lleva el control de lo que ya has visto. Encuentra y vuelve a ver fácilmente tus películas y series favoritas.', + account_premium_include_text_3: 'No te pierdas ninguna escena importante. Aumenta el número de marcas de tiempo y sabe siempre dónde te quedaste en tus películas y series favoritas.', + account_premium_include_text_4: 'Más libertad con el acceso Premium. Aumenta el número de perfiles de tu cuenta y deja que tus amigos y familiares disfruten de películas y series contigo. Sin límites: disfruta viendo con tus seres queridos.', + account_premium_include_text_5: 'No te pierdas ningún episodio ni doblaje nuevo. Recibe notificaciones a tiempo y mantente al día de todas las novedades, directamente en tu teléfono.', + account_premium_include_text_6: 'Sincroniza tus datos entre dispositivos con el acceso Premium. Ya no tendrás que buscar el último episodio en el que te quedaste: continúa la reproducción donde la dejaste en cualquier dispositivo con la aplicación instalada.', + account_code_enter: 'Introduce un código de seis dígitos', + account_code_error: 'Puede que hayas introducido un código incorrecto o caducado', + account_code_wrong: 'Puede que hayas introducido un formato incorrecto', + account_code_where: 'Ve al sitio e introduce el código que aparece allí.', + account_code_input: 'Introduce el código', + account_qr_premium: 'Escanea el código QR para saber más sobre CUB Premium', + account_qr_code: 'Escanea el código QR para recibir un código de vinculación', + account_qr_create: 'Escanea el código QR para crear una cuenta', + account_add_device_title: 'Añadir dispositivo', + account_add_device_text: 'Ve a para obtener un código y añadir un dispositivo.', + account_none_title: '¿Aún no tienes cuenta?', + account_none_include_1: 'Favoritos e historial guardados en la nube', + account_none_include_2: 'Sincronización entre dispositivos', + account_none_include_3: 'Notificaciones de nuevos episodios y estrenos', + account_none_include_4: 'Varios perfiles en una misma cuenta', + account_discuss_add_qr: 'Escanea el código QR', + account_discuss_add_title: '¿Quieres dejar un comentario?', + account_discuss_add_text: 'Escanea el código QR para ir a la aplicación y comentar esta película o serie.

    - Coge tu teléfono o tableta
    - Abre la cámara
    - Apunta al código QR
    - Sigue el enlace que aparece en la pantalla', + account_discuss_added: '¡Gracias por tu comentario!', + account_discuss_added_ready: 'Ya has dejado un comentario sobre esta película o serie.', + + network_noconnect: 'Sin conexión de red', + network_404: 'No se encontró la página solicitada. [404]', + network_401: 'Error de autorización', + network_500: 'Error interno del servidor. [500]', + network_parsererror: 'Error al analizar el JSON solicitado.', + network_timeout: 'Se agotó el tiempo de espera de la solicitud.', + network_abort: 'La solicitud se canceló.', + network_error: 'Error desconocido', + + size_zero: '0 Bytes', + size_byte: 'Bytes', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'TB', + size_pp: 'PB', + + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + + month_1: 'Enero', + month_2: 'Febrero', + month_3: 'Marzo', + month_4: 'Abril', + month_5: 'Mayo', + month_6: 'Junio', + month_7: 'Julio', + month_8: 'Agosto', + month_9: 'Septiembre', + month_10: 'Octubre', + month_11: 'Noviembre', + month_12: 'Diciembre', + + day_1: 'Lunes', + day_2: 'Martes', + day_3: 'Miércoles', + day_4: 'Jueves', + day_5: 'Viernes', + day_6: 'Sábado', + day_7: 'Domingo', + + month_1_e: 'enero', + month_2_e: 'febrero', + month_3_e: 'marzo', + month_4_e: 'abril', + month_5_e: 'mayo', + month_6_e: 'junio', + month_7_e: 'julio', + month_8_e: 'agosto', + month_9_e: 'septiembre', + month_10_e: 'octubre', + month_11_e: 'noviembre', + month_12_e: 'diciembre', + + week_1: 'Lun', + week_2: 'Mar', + week_3: 'Mié', + week_4: 'Jue', + week_5: 'Vie', + week_6: 'Sáb', + week_7: 'Dom', + + time_h: 'h', + time_m: 'min', + time_s: 's', + + extensions_enable: 'Activar', + extensions_disable: 'Desactivar', + extensions_check: 'Comprobar estado', + extensions_install: 'Instalar', + extensions_info: 'Información', + extensions_edit: 'Editar', + extensions_change_name: 'Cambiar nombre', + extensions_change_link: 'Cambiar enlace', + extensions_remove: 'Eliminar', + extensions_set_name: 'Introduce el nombre del complemento', + extensions_set_url: 'Introduce la URL del complemento', + extensions_ready: 'Este complemento ya está instalado', + extensions_no_info: 'Sin información', + extensions_no_name: 'Sin título', + extensions_worked: 'Funciona', + extensions_no_plugin: 'Complemento no verificado', + extensions_add: 'Añadir complemento', + extensions_from_memory: 'Instalados en memoria', + extensions_from_cub: 'Instalados desde CUB', + extensions_from_popular: 'Complementos populares', + extensions_from_lib: 'Biblioteca de complementos', + extensions_from_connected: 'Complementos conectados', + extensions_hpu_best: 'Populares', + extensions_hpu_recomend: 'Recomendados', + extensions_hpu_theme: 'Temas', + extensions_hpu_screensaver: 'Salvapantallas', + extensions_hpu_video: 'Vídeo', + extensions_hpu_control: 'Control', + extensions_hpu_other: 'Varios', + extensions_hpu_: 'Otros', + + speedtest_connect: 'conexión', + speedtest_test: 'probando', + speedtest_ready: 'listo', + speedtest_button: 'Probar velocidad', + + change_source_on_cub: 'Cambiar la fuente a CUB', + + tv_status_returning_series: 'Serie en emisión', + tv_status_planned: 'Planificada', + tv_status_in_production: 'En producción', + tv_status_ended: 'Finalizada', + tv_status_canceled: 'Cancelada', + tv_status_pilot: 'Piloto', + tv_status_released: 'Estrenada', + tv_status_rumored: 'Rumoreada', + tv_status_post_production: 'Posproducción', + + input_detection_touch: '¿Quieres cambiar al control táctil?', + input_detection_mouse: '¿Quieres cambiar al control con ratón?', + input_detection_remote: '¿Quieres cambiar al control remoto?', + + https_text: 'Estás usando el protocolo HTTPS, con el que Lampa no funciona correctamente. Para que Lampa funcione bien, usa la dirección con el protocolo HTTP', + + premiere_author_recomend_1: 'Pide una pizza y prepárate para la emoción.', + premiere_author_recomend_2: 'La fiesta acaba de empezar.', + premiere_author_recomend_3: 'Prepárate para una dosis de adrenalina.', + premiere_author_recomend_4: '¿Listo para una noche inolvidable?', + premiere_author_recomend_5: 'Te recomiendo verla.', + premiere_title: 'Estreno', + + termsofuse_t_01: 'Condiciones de uso', + termsofuse_t_02: 'Lampa es una herramienta práctica para explorar las últimas novedades de la industria del cine, incluidas películas, series, animación y otra información. Para obtener información sobre las películas se utiliza el sitio web abierto themoviedb.org.', + termsofuse_t_03: 'Contenido', + termsofuse_t_04: 'Lampa utiliza la API (interfaz de programación de aplicaciones) del catálogo themoviedb.org para obtener información sobre películas y series, y para mostrar archivos multimedia asociados, como pósteres, tráileres y más.', + termsofuse_t_05: 'La API de themoviedb.org permite a la aplicación Lampa acceder a una base de datos de películas y series, con la posibilidad de buscar y ver información de archivos multimedia.', + termsofuse_t_06: 'La interacción entre la aplicación Lampa y themoviedb.org se realiza mediante solicitudes a la API que la aplicación Lampa envía a los servidores de themoviedb.org para obtener información y archivos multimedia. Themoviedb.org procesa las solicitudes y devuelve los datos solicitados a la aplicación Lampa.', + termsofuse_t_07: 'Así, gracias a la API de themoviedb.org, la aplicación Lampa ofrece a los usuarios acceso a una amplia base de datos de películas y series, respetando las condiciones de uso y las restricciones establecidas por el titular de los derechos.', + termsofuse_t_08: 'Extensiones', + termsofuse_t_09: 'Las extensiones son una herramienta potente de la aplicación Lampa que permite a los usuarios ampliar sus capacidades, añadir funciones y modificar el contenido según sus necesidades.', + termsofuse_t_10: 'Sin embargo, los usuarios instalan las extensiones bajo su propia responsabilidad. Todas las consecuencias derivadas de su uso son responsabilidad del usuario. Se recomienda actuar con precaución al instalar y usar extensiones, evaluando cuidadosamente su fiabilidad y seguridad.', + termsofuse_t_11: 'Infracciones de derechos de autor', + termsofuse_t_12: 'Si detectas alguna infracción de derechos de autor en la aplicación Lampa, ponte en contacto con sus desarrolladores a través de los contactos indicados en la aplicación. No obstante, ten en cuenta que la aplicación Lampa utiliza la API del catálogo themoviedb.org, que ofrece acceso abierto a información sobre películas y series. Esto significa que la información mostrada en Lampa es pública y no infringe derechos de autor.', + termsofuse_t_13: 'Si crees que la aplicación Lampa aún contiene contenido que infringe tus derechos de autor, puedes contactar con el titular de ese contenido y solicitar su retirada del sitio themoviedb.org. A su vez, la aplicación Lampa puede retirar contenido al recibir una notificación de infracción de derechos de autor adecuada.', + + install_app_apk_title: 'Cómo instalar Lampa en Android', + install_app_apk_text: 'Hemos detectado que usas MediaStationX para ejecutar Lampa en Android. Te recomendamos instalar Lampa como aplicación APK. Así funcionará de forma más estable y tendrás acceso a todas sus funciones.

    Ve al grupo de Telegram para descargar el APK más reciente y las instrucciones de instalación.', + install_app_apk_qr: 'Escanea el código QR para descargar el APK de Lampa', + + ad: 'Publicidad', + ad_disable: 'Con una suscripción a CUB Premium te olvidarás de la publicidad.', + ad_plugin: 'Publicidad del complemento', + ad_after: 'Publicidad en', + ad_skip: 'Saltar', + ad_continue_after: 'La reproducción empezará en', + + discuss_rules_title: 'Sigue las normas y respeta a los demás: ¡creemos un buen ambiente juntos!', + discuss_rules_rule_1: 'No uses palabras formadas solo por números.', + discuss_rules_rule_2: 'Escribe en un solo idioma y usa palabras de 5 letras o más.', + discuss_rules_rule_3: 'Usa signos de puntuación y termina las frases con punto.', + discuss_rules_rule_4: 'Evita símbolos incomprensibles !?#%', + discuss_rules_rule_5: 'Escribe frases completas, de 5 palabras o más.', + discuss_rules_rule_6: 'No uses palabras demasiado largas.', + discuss_rules_rule_7: 'Intenta no superar los 300 caracteres.', + discuss_voited: '¡Gracias por tu valoración! Tu voto ayuda a mejorar el contenido.', + + confirm_open_player: 'Otro dispositivo solicita acceso al reproductor. ¿Quieres reproducir el vídeo?', + + pincode_use_remote: 'Usa el mando a distancia para introducir el código pulsando las flechas para elegir el número.', + pincode_use_toggle: 'Mantén pulsado el botón OK para cambiar la distribución.', + + storage_quota_exceeded: 'Se superó la cuota de almacenamiento. Borra la caché e inténtalo de nuevo.', + + ai_search_start_typing: 'Pregunta al asistente de IA qué películas quieres encontrar. Por ejemplo: "Películas sobre el espacio"', + ai_search_limit: 'Se superó el límite de solicitudes. Inténtalo más tarde. Con una suscripción a CUB Premium los límites aumentan y no tendrás que esperar.', + ai_subscribe_title: 'Descubre más posibilidades con la IA', + ai_subscribe_descr: 'Suscríbete a CUB Premium y aumenta el número de solicitudes a la IA. Junto con la IA, encontraremos las mejores películas para ti.', + + dmca_title: 'Contenido bloqueado', + dmca_descr: 'Este material no está disponible. Se ha bloqueado a petición del titular de los derechos de autor, conforme a la legislación de derechos de autor.', + dmca_title_lgbt: 'Contenido restringido', + dmca_descr_lgbt: 'La reproducción no está disponible en tu región porque puede contener contenido LGBT. Este material puede estar prohibido o restringido en algunos países.', + + loading_progress_step_0: 'Preparación', + loading_progress_step_1: 'Cargando idiomas', + loading_progress_step_2: 'Buscando espejos', + loading_progress_step_3: 'Preparando extensiones', + loading_progress_step_4: 'Casi listo', + loading_progress_step_5: 'Ya casi', + + install_extension_rule_1: 'Instalación de un complemento de terceros', + install_extension_rule_2: 'Los complementos los crean desarrolladores independientes y LAMPA no verifica su contenido. Al instalarlos, aceptas que:', + install_extension_rule_3: '- Algunos complementos pueden solicitar acceso a tus datos o trabajar con fuentes no verificadas.', + install_extension_rule_4: '- Si el complemento que instalas infringe derechos de autor u otras leyes, eres totalmente responsable de su uso.', + install_extension_rule_5: '- Instala solo complementos de fuentes de confianza. Si tienes dudas sobre la seguridad o legalidad de un complemento, es mejor no instalarlo.', + install_extension_rule_6: 'LAMPA no apoya ni respalda complementos relacionados con contenido pirata.', + install_extension_rule_7: 'Al continuar, confirmas que entiendes estos riesgos.', + + terminal_title: 'Terminal', + terminal_no_access: 'Sin acceso', + terminal_confirm: 'Permitir', + terminal_deny: 'Denegar', + terminal_update: 'Actualizar', + terminal_code: 'Código de acceso', + terminal_text: 'Estás solicitando acceso al terminal. Los desarrolladores podrán acceder a tu dispositivo y controlarlo. Esto puede ser útil para diagnosticar y resolver problemas, pero también puede suponer un riesgo de seguridad. Asegúrate de confiar en los desarrolladores antes de conceder el acceso.

    Puedes desactivar esta función en cualquier momento pulsando el botón "Denegar".', + + developer_param_enabled: 'Modo desarrollador', + developer_param_nopremium: 'Desactivar CUB Premium', + developer_param_nodemo: 'Desactivar modo demo', + developer_param_ads: 'Mostrar anuncios', + developer_param_fps: 'Mostrar FPS', + + developer_trigger_help_1: 'Casi lo tienes :)', + developer_trigger_help_2: 'Solo un poco más :)', + developer_trigger_help_3: '¿Seguro que quieres entrar en el modo desarrollador?', + developer_trigger_help_4: 'Modo desarrollador activado', + + remote_helper_long: 'Mantén pulsado el botón (OK) para abrir el menú', + no_watch_history: 'No hay historial de visualización', + + adult_content_title: 'Contenido para adultos', + adult_content_text_warning: 'El contenido puede incluir material para adultos no apto para todos los públicos.', + adult_content_text_modal: 'Esta película o serie está marcada como contenido para adultos. Debes tener 18 años o más para ver este material. Confirma que eres mayor de edad para continuar.', + + adult_content_confirm: 'Tengo 18 años o más', + adult_content_deny: 'Soy menor de 18 años', + + inner_player_disclaimer_title: 'Aviso del reproductor', + inner_player_disclaimer_text: 'Entiendo que estoy iniciando un reproductor con soporte incompleto y que esto puede provocar un comportamiento atípico en el dispositivo. Se recomienda cambiar a reproductores de la familia tvOS u otras alternativas.', + + inner_player_disclaimer_change_player: 'Cambiar reproductor', + remote_configuration_settings_title: 'Configuración remota', + remote_configuration_registration_text: 'La configuración remota da acceso temporal a tu aplicación: otra aplicación podrá instalar extensiones y configurar parámetros.', + remote_configuration_waite_text: 'Ahora puedes pasar este código a otra aplicación para darle acceso a los ajustes.', + remote_configuration_open_button: 'Abrir acceso', + remote_configuration_code_life: 'El código es válido', + remote_configuration_notice_nocode: 'No se pudo abrir el acceso', + + player_ai_agent_info: '¿Quieres saber más sobre el vídeo? Pregunta al asistente de IA y te mostrará un gráfico de ambiente, un breve resumen del argumento y los momentos destacados.', + player_ai_agent_ask_plot: 'Argumento breve', + player_ai_agent_ask_moods: 'Mostrar gráfico', + player_ai_agent_ask_highlights: 'Momentos destacados', + player_ai_agent_ask: 'Preguntar', + player_ai_agent_processing: 'Analizando...', + player_ai_agent_no_data: 'No hay datos que mostrar.', + player_ai_agent_no_analysis: 'No se pudo analizar el vídeo.', + player_ai_agent_quota: 'Se superó el límite de solicitudes. Inténtalo más tarde.', + player_ai_agent_working: 'Seguimos trabajando en ello...' +} \ No newline at end of file diff --git a/lampa-main/lang/fr.js b/lampa-main/lang/fr.js new file mode 100644 index 0000000..07329f9 --- /dev/null +++ b/lampa-main/lang/fr.js @@ -0,0 +1,1363 @@ +export default { + lang_choice_title: 'Bienvenue', + lang_choice_subtitle: 'Choisissez votre langue', + + more: 'Plus', + show_more: 'Afficher plus', + more_results: 'Plus de résultats', + loading: 'Chargement...', + nofind_movie: 'Le film est introuvable.', + noname: 'Sans titre', + nochoice: 'Non choisi', + cancel: 'Annuler', + confirm: 'Je confirme', + sure: 'Êtes-vous sûr ?', + nodata: 'Aucune donnée', + back: 'Retour', + ready: 'Prêt', + close_app_modal: 'Voulez-vous vraiment quitter l\'application ?', + connected_seeds: 'connectés', + + search: 'Recherche', + search_input: 'Entrez du texte', + search_empty: 'L\'historique de recherche est vide.', + search_delete: 'Gauche - supprimer', + search_start_typing: 'Commencez à taper pour rechercher.', + search_searching: 'Recherche en cours...', + search_start: 'Pour commencer la recherche', + search_nofound: 'Aucun résultat ne correspond à votre requête.', + global_search: 'Recherche globale', + + full_genre: 'Genre', + full_production: 'Production', + full_date_of_release: 'Date de sortie', + full_budget: 'Budget', + full_countries: 'Pays', + full_like: 'Favoris', + full_torrents: 'Torrents', + full_trailers: 'Bandes-annonces', + full_detail: 'En détail', + full_notext: 'Aucune description.', + full_series_release: 'Sortie de la série', + full_next_episode: 'Suivant', + full_episode_days_left: 'Jours restants', + full_trailer_official: 'Officiel', + full_trailer_no_official: 'Non officiel', + full_season: 'Saison', + full_episode: 'Épisode', + full_directing: 'Réalisation', + full_writing: 'Scénario', + full_keywords: 'Mots-clés', + + settings_cub_sync: 'Synchronisation', + settings_cub_sync_descr: 'Synchronisation avec le service CUB : synchronisation de vos favoris, historique, tags et codes temporels.', + settings_cub_account: 'Compte', + settings_cub_logged_in_as: 'Connecté en tant que', + settings_cub_profile: 'Profil', + settings_cub_sync_btn: 'Synchroniser', + settings_cub_sync_btn_descr: 'Enregistrer les favoris locaux sur le compte CUB', + settings_cub_backup: 'Sauvegarde', + settings_cub_backup_descr: 'Sauvegarder ou charger des données de sauvegarde', + settings_cub_logout: 'Déconnexion', + settings_cub_signin: 'Autorisation', + settings_cub_not_specified: 'Non spécifié', + settings_cub_password: 'Mot de passe', + settings_cub_status: 'Statut', + settings_cub_backup_import: 'Importer', + settings_cub_backup_export: 'Exporter', + settings_cub_sync_filters: 'Sync. des filtres', + settings_cub_sync_calendar: 'Sync. du calendrier', + settings_cub_sync_quality: 'Sync. de la qualité', + settings_cub_sync_search: 'Sync. de l\'historique de recherche', + settings_cub_sync_recomends: 'Sync. des recommandations', + settings_cub_sync_timecodes: 'Sync. des codes temporels', + + settings_input_links: 'Favoris', + + settings_interface_type: 'Version Lite', + settings_interface_size: 'Taille de l\'interface', + settings_interface_menu_always: 'Toujours afficher le menu latéral', + settings_interface_background: 'Arrière-plan', + settings_interface_background_use: 'Afficher l\'arrière-plan', + settings_interface_background_type: 'Type d\'arrière-plan', + settings_interface_performance: 'Performance', + settings_interface_animation: 'Animation', + settings_interface_animation_descr: 'Animation des fiches et du contenu', + settings_interface_attenuation: 'Atténuation', + settings_interface_attenuation_descr: 'Fondu progressif des fiches', + settings_interface_scroll: 'Type de défilement', + settings_interface_view_card: 'Type d\'affichage des fiches', + settings_interface_view_card_descr: 'Chargement progressif ou complet des fiches lors du défilement', + settings_interface_lang: 'Langue de l\'interface', + settings_interface_lang_reload: 'L\'application doit redémarrer, cliquez sur "OK" pour confirmer.', + + settings_main_account: 'Compte', + settings_main_interface: 'Interface', + settings_main_player: 'Lecteur', + settings_main_parser: 'Analyseur (Parser)', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Extensions', + settings_main_rest: 'Divers', + + settings_rest_start: 'Page d\'accueil', + settings_rest_start_descr: 'Page à afficher au démarrage', + settings_rest_source: 'Source', + settings_rest_source_use: 'Source principale', + settings_rest_source_descr: 'Où obtenir les informations sur les films', + settings_rest_tmdb_lang: 'Langue des données TMDB', + settings_rest_tmdb_prox: 'Proxy TMDB', + settings_rest_tmdb_prox_auto: 'Activer le proxy automatiquement', + settings_rest_tmdb_posters: 'Résolution des affiches TMDB', + settings_rest_screensaver: 'Économiseur d\'écran', + settings_rest_screensaver_use: 'Afficher l\'écran de veille en cas d\'inactivité', + settings_rest_screensaver_type: 'Type d\'économiseur d\'écran', + settings_rest_helper: 'Astuces', + settings_rest_helper_use: 'Afficher les astuces', + settings_rest_helper_reset: 'Réinitialiser les astuces', + settings_rest_pages: 'Pages en mémoire', + settings_rest_pages_descr: 'Nombre de pages à conserver dans leur état actuel', + settings_rest_time: 'Décalage horaire', + settings_rest_navigation: 'Type de navigation', + settings_rest_keyboard: 'Type de clavier', + settings_rest_device: 'Nom de l\'appareil', + settings_rest_device_placeholder: 'Exemple : Ma Lampa', + settings_rest_cache: 'Vider le cache', + settings_rest_cache_descr: 'Tous les paramètres et données seront effacés', + settings_rest_tmdb_example: 'Par exemple :', + settings_rest_tmdb_api_descr: 'Pour obtenir des données', + settings_rest_tmdb_image_descr: 'Pour obtenir des images', + settings_rest_card_quality: 'Indicateurs de qualité', + settings_rest_card_quality_descr: 'Afficher la qualité sur les fiches', + settings_rest_card_episodes: 'Indicateurs d\'épisodes', + settings_rest_card_episodes_descr: 'Afficher les marqueurs d\'épisodes sur les fiches', + + settings_parser_use: 'Utiliser l\'analyseur', + settings_parser_use_descr: 'En activant cette option, vous acceptez toute responsabilité quant à l\'utilisation de liens publics pour visionner du contenu.', + settings_parser_type: 'Type d\'analyseur de torrents', + settings_parser_jackett_placeholder: 'Exemple : 192.168.x', + settings_parser_jackett_link: 'Lien', + settings_parser_jackett_link_descr: 'Lien vers le script Jackett', + settings_parser_jackett_key_placeholder: 'Exemple : sa0sk83d..', + settings_parser_jackett_key: 'Clé API', + settings_parser_jackett_key_descr: 'Clé API trouvée dans Jackett', + settings_parser_torlook_type: 'Méthode d\'analyse TorLook', + settings_parser_scraperapi_placeholder: 'Exemple : scraperapi.com', + settings_parser_scraperapi_link: 'Lien vers l\'analyseur de site', + settings_parser_scraperapi_descr: 'Inscrivez-vous sur scraperapi.com et entrez le lien api.scraperapi.com?api_key=...&url={q}', + settings_parser_search: 'Recherche', + settings_parser_search_descr: 'Langue de recherche', + settings_parser_in_search: 'Analyseur dans la recherche', + settings_parser_in_search_descr: 'Afficher les résultats de recherche ?', + settings_parser_timeout_title: 'Délai d\'attente (Timeout)', + settings_parser_timeout_descr: 'Temps d\'attente en secondes pour la réponse du serveur', + + settings_player_type: 'Type de lecteur', + settings_player_type_descr: 'Choisir le lecteur par défaut', + settings_infuse_launch_mode: 'Lancement dans Infuse', + settings_infuse_launch_mode_descr: 'Action à l\'ouverture d\'une vidéo dans Infuse. Les torrents sont toujours lus immédiatement', + settings_infuse_launch_ask: 'Demander au lancement', + settings_infuse_launch_play: 'Lire', + settings_infuse_launch_save_and_play: 'Enregistrer et lire', + settings_player_iptv_type: 'Lecteur pour l\'IPTV', + settings_player_iptv_type_descr: 'Lecteur utilisé pour les chaînes IPTV', + settings_player_reset: 'Réinitialiser le lecteur', + settings_player_reset_descr: 'Réinitialise le lecteur Android sélectionné dans l\'application', + settings_player_path: 'Chemin du lecteur', + settings_player_path_descr: 'Spécifier le chemin vers l\'exécutable du lecteur (.exe)', + settings_player_external_header: 'Lecteur externe', + settings_player_external_fullscreen: 'Lancer en plein écran', + settings_player_normalization: 'Normalisation du son', + settings_player_normalization_descr: 'Équilibre le volume : baisse les sons forts et augmente les sons faibles.', + settings_player_next_episode: 'Épisode suivant', + settings_player_next_episode_descr: 'Passer automatiquement à l\'épisode suivant à la fin du visionnage', + settings_player_timecode: 'Reprise de lecture', + settings_player_timecode_descr: 'Reprendre à partir du dernier emplacement visionné', + settings_player_scale: 'Méthode de mise à l\'échelle', + settings_player_scale_descr: 'Calcul de la mise à l\'échelle vidéo', + settings_player_subs: 'Sous-titres', + settings_player_subs_use: 'Activer', + settings_player_subs_use_descr: 'Toujours activer les sous-titres au démarrage', + settings_player_subs_lang: 'Langue des sous-titres', + settings_player_subs_lang_descr: 'Sous-titres à activer automatiquement lorsque plusieurs langues sont disponibles', + settings_param_subtitles_lang_auto: 'Langue de l\'interface', + settings_player_subs_size: 'Taille', + settings_player_subs_size_descr: 'Taille d\'affichage des sous-titres', + settings_player_subs_stroke_use: 'Bordure', + settings_player_subs_stroke_use_descr: 'Ajoute une bordure noire pour une meilleure lisibilité', + settings_player_subs_backdrop_use: 'Fond opaque', + settings_player_subs_backdrop_use_descr: 'Affiche un fond translucide derrière les sous-titres', + settings_player_quality: 'Qualité vidéo par défaut', + settings_player_quality_descr: 'Qualité vidéo préférée pour le visionnage', + settings_player_hls_title: 'Traitement du flux .m3u8', + settings_player_hls_descr: 'Ne modifiez pas ce paramètre sauf si vous savez ce que vous faites.', + + settings_plugins_notice: 'Vous devez redémarrer l\'application pour appliquer les modifications d\'extensions', + settings_plugins_add: 'Ajouter une extension', + settings_plugins_add_descr: 'Pour supprimer une extension, maintenez la touche (OK) ou double-cliquez dessus', + settings_plugins_install: 'Installer une extension', + settings_plugins_install_descr: 'Installer depuis la liste des extensions disponibles', + + settings_server_link: 'Utiliser le lien', + settings_server_links: 'Liens', + settings_server_placeholder: 'Exemple : 192.168.X', + settings_server_link_one: 'Lien principal', + settings_server_link_one_descr: 'Lien principal vers le script TorrServer', + settings_server_link_two: 'Lien secondaire', + settings_server_link_two_descr: 'Lien supplémentaire vers le script TorrServer', + settings_server_additionally: 'Additionnel', + settings_server_client: 'Client intégré', + settings_server_client_descr: 'Utiliser le client JS TorrServer intégré, sinon le client système sera lancé.', + settings_server_base: 'Enregistrer dans la base de données', + settings_server_base_descr: 'Le torrent sera ajouté à la base de données de TorrServer', + settings_server_preload: 'Utiliser le tampon de préchargement', + settings_server_preload_descr: 'Attendre que le tampon de TorrServer soit plein avant la lecture', + settings_server_auth: 'Authentification', + settings_server_password_use: 'Connexion par mot de passe', + settings_server_login: 'Identifiant', + settings_server_password: 'Mot de passe', + settings_server_not_specified: 'Non spécifié', + settings_server_search_type: 'Type de recherche', + settings_server_search_type_descr: 'Où chercher les torrents : rutor intégré, indexeurs Torznab dans TorrServer, ou les deux.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + torent_nohash_reasons: 'Raisons possibles', + torent_nohash_reason_one: 'TorrServer n\'a pas pu télécharger le fichier torrent', + torent_nohash_reason_two: 'Réponse de TorrServer', + torent_nohash_reason_three: 'Lien', + torent_nohash_do: 'Que faire ?', + torent_nohash_do_one: 'Vérifiez la configuration de Jackett', + torent_nohash_do_two: 'Les sources privées peuvent ne pas fournir de lien direct', + torent_nohash_do_three: 'Vérifiez si Jackett peut télécharger le fichier', + torent_nohash_do_four: 'Contactez notre groupe Telegram : @lampa_group', + torent_nohash_do_five: 'Précisez le film et envoyez une photo de la distribution si possible', + + torrent_error_text: 'Impossible de se connecter à TorrServer. Vérifions ensemble les problèmes courants.', + torrent_error_step_1: 'TorrServer est-il lancé ?', + torrent_error_step_2: 'IP dynamique', + torrent_error_step_3: 'Protocole et Port', + torrent_error_step_4: 'Blocage antivirus', + torrent_error_step_5: 'Vérifier la disponibilité', + torrent_error_step_6: 'Cela ne fonctionne toujours pas', + torrent_error_info_1: 'Vérifiez que TorrServer est actif sur l\'appareil d\'installation.', + torrent_error_info_2: 'L\'adresse IP a peut-être changé. Vérifiez que {ip} correspond à l\'adresse actuelle de l\'appareil.', + torrent_error_info_3: 'L\'adresse doit commencer par http:// et se terminer par :8090. Votre adresse actuelle est {ip}', + torrent_error_info_4: 'Le pare-feu ou l\'antivirus peut bloquer l\'accès. Essayez de les désactiver temporairement.', + torrent_error_info_5: 'Ouvrez {ip} dans un navigateur sur un autre appareil du même réseau pour tester l\'interface web.', + torrent_error_info_6: 'Redémarrez TorrServer et votre routeur si l\'erreur persiste.', + torrent_error_info_7: 'Contactez le groupe Telegram @lampa_group avec le message : (Lampa ne se connecte pas à TorrServer, adresse : {ip})', + torrent_error_start: 'Démarrer la vérification', + torrent_error_nomatrix: 'Échec de la vérification de la version Matrix', + torrent_error_made: 'Effectué', + torrent_error_from: 'sur', + torrent_error_next: 'Suivant', + torrent_error_complite: 'Terminer', + torrent_error_connect: 'Erreur de connexion', + + torrent_install_need: 'TorrServer requis', + torrent_install_text: 'TorrServer est une application permettant de visionner des torrents en ligne.

    Plus d\'infos sur l\'installation dans les groupes Telegram.', + torrent_install_contact: 'Groupes Telegram', + + torrent_item_bitrate: 'Débit', + torrent_item_seeds: 'Sources (Seeds)', + torrent_item_grabs: 'Clients (Leechs)', + torrent_item_mb: 'Mbps', + + torrent_serial_episode: 'Épisode', + torrent_serial_season: 'Saison', + torrent_serial_date: 'Sortie', + + torrent_get_magnet: 'Récupération du lien magnet...', + torrent_remove_title: 'Supprimer', + torrent_remove_descr: 'Le torrent sera retiré de votre liste', + + torrent_parser_any_one: 'Tous', + torrent_parser_any_two: 'Tous', + torrent_parser_no_choice: 'Non choisi', + torrent_parser_yes: 'Oui', + torrent_parser_no: 'Non', + torrent_parser_quality: 'Qualité', + torrent_parser_subs: 'Sous-titres', + torrent_parser_voice: 'Version/Doublage', + torrent_parser_tracker: 'Tracker', + torrent_parser_year: 'Année', + torrent_parser_season: 'Saison', + torrent_parser_sort_by_seeders: 'Par sources', + torrent_parser_sort_by_size: 'Par taille', + torrent_parser_sort_by_name: 'Par nom', + torrent_parser_sort_by_tracker: 'Par source', + torrent_parser_sort_by_date: 'Par date', + torrent_parser_sort_by_viewed: 'Visionné', + torrent_parser_voice_dubbing: 'Doublage', + torrent_parser_voice_polyphonic: 'Polyphonique', + torrent_parser_voice_two: 'Deux voix', + torrent_parser_voice_amateur: 'Amateur', + torrent_parser_reset: 'Réinitialiser le filtre', + torrent_parser_empty: 'Aucun résultat obtenu', + torrent_parser_no_hash: 'Impossible de récupérer le HASH, essayez de recharger TorrServer', + torrent_parser_added_to_mytorrents: 'Ajouté à "Mes torrents"', + torrent_parser_add_to_mytorrents: 'Ajouter à "Mes torrents"', + torrent_parser_label_title: 'Marquer', + torrent_parser_label_descr: 'Marquer comme visionné', + torrent_parser_label_cancel_title: 'Démarquer', + torrent_parser_label_cancel_descr: 'Retirer la marque de visionnage', + torrent_parser_timeout: 'Délai expiré', + torrent_parser_nofiles: 'Aucun fichier compatible trouvé', + torrent_parser_set_link: 'Spécifier un lien pour l\'analyse', + torrent_parser_request_error: 'Erreur de requête', + torrent_parser_magnet_error: 'Impossible de récupérer le lien magnet', + torrent_parser_no_responce: 'L\'analyseur ne répond pas', + torrent_parser_torlook_fallback_search_notification: 'Jackett indisponible ou mal configuré. Recherche sur Torlook...', + + about_text: 'L\'application est gratuite et utilise des liens publics pour obtenir des infos sur les vidéos et nouveautés. Toutes les données sont utilisées à des fins éducatives. L\'application n\'héberge aucun contenu sur ses propres serveurs.', + about_channel: 'Notre canal', + about_group: 'Groupe', + about_version: 'Version', + about_donate: 'Donation', + + title_watched: 'Déjà vu', + title_settings: 'Paramètres', + title_collections: 'Collections', + title_company: 'Société', + title_actors: 'Acteurs', + title_actor: 'Acteur', + title_actress: 'Actrice', + title_person: 'Personne', + title_persons: 'Personnes', + title_comments: 'Commentaires', + title_torrents: 'Torrents', + title_trailers: 'Bandes-annonces', + title_watch: 'Regarder', + title_error: 'Erreur', + title_links: 'Liens', + title_choice: 'Choisir', + title_main: 'Accueil', + title_book: 'Favoris', + title_like: 'J\'aime', + title_wath: 'À regarder', + title_history: 'Historique', + title_mytorrents: 'Mes torrents', + title_last: 'Dernier', + title_action: 'Action', + title_action_infuse: 'Action Infuse', + title_producer: 'Producteur', + title_collection: 'Collection', + title_recomendations: 'Recommandations', + title_similar: 'Similaires', + title_about: 'À propos', + title_timetable: 'Calendrier', + title_relises: 'Sorties numériques', + title_catalog: 'Catalogue', + title_category: 'Catégorie', + title_parser: 'Analyseur', + title_type: 'Type', + title_rating: 'Note', + title_country: 'Pays', + title_year: 'Année', + title_genre: 'Genre', + title_filter: 'Filtre', + title_notice: 'Notifications', + title_files: 'Fichiers', + title_now_watch: 'En cours', + title_latest: 'Ajouts récents', + title_continue: 'Reprendre le visionnage', + title_recomend_watch: 'Nous recommandons', + title_new_episodes: 'Nouveaux épisodes', + title_popular: 'Populaire', + title_popular_movie: 'Films populaires', + title_popular_tv: 'Séries populaires', + title_new_this_year: 'Nouveautés de l\'année', + title_hight_voite: 'Mieux notés', + title_new: 'Nouveautés', + title_trend_day: 'Tendances du jour', + title_trend_week: 'Tendances de la semaine', + title_upcoming: 'Bientôt au cinéma', + title_top_movie: 'Top films', + title_top_tv: 'Top séries', + title_tv_today: 'À la TV aujourd\'hui', + title_this_week: 'Cette semaine', + title_in_top: 'Top', + title_out: 'Sortir', + title_out_confirm: 'Oui, quitter', + title_continue_two: 'Continuer', + title_choice_language: 'Choisir la langue', + title_subscribe: 'S\'abonner', + title_subscribes: 'Abonnements', + title_unsubscribe: 'Se désabonner', + title_language: 'Langue originale', + + subscribe_success: 'Abonnement réussi', + subscribe_error: 'Erreur d\'abonnement, réessayez plus tard', + subscribe_noinfo: 'Impossible de récupérer les infos, réessayez plus tard', + + company_headquarters: 'Siège social', + company_homepage: 'Site web', + company_country: 'Pays', + + country_ad: 'Andorre', + country_ae: 'Émirats Arabes Unis', + country_af: 'Afghanistan', + country_al: 'Albanie', + country_am: 'Arménie', + country_ao: 'Angola', + country_ar: 'Argentine', + country_at: 'Autriche', + country_au: 'Australie', + country_aw: 'Aruba', + country_az: 'Azerbaïdjan', + country_bа: 'Bosnie-Herzégovine', + country_bd: 'Bangladesh', + country_be: 'Belgique', + country_bg: 'Bulgarie', + country_bh: 'Bahreïn', + country_bi: 'Burundi', + country_bj: 'Bénin', + country_bo: 'Bolivie', + country_br: 'Brésil', + country_bs: 'Bahamas', + country_bt: 'Bhoutan', + country_bw: 'Botswana', + country_by: 'Biélorussie', + country_ca: 'Canada', + country_ch: 'Suisse', + country_cl: 'Chili', + country_cm: 'Cameroun', + country_cn: 'Chine', + country_co: 'Colombie', + country_cr: 'Costa Rica', + country_cu: 'Cuba', + country_cv: 'Cap-Vert', + country_cy: 'Chypre', + country_cz: 'République Tchèque', + country_de: 'Allemagne', + country_dj: 'Djibouti', + country_dk: 'Danemark', + country_do: 'République Dominicaine', + country_dz: 'Algérie', + country_ec: 'Équateur', + country_ee: 'Estonie', + country_eg: 'Égypte', + country_es: 'Espagne', + country_et: 'Éthiopie', + country_fi: 'Finlande', + country_fo: 'Îles Féroé', + country_fr: 'France', + country_ga: 'Gabon', + country_gb: 'Royaume-Uni', + country_ge: 'Géorgie', + country_gh: 'Ghana', + country_gl: 'Groenland', + country_gp: 'Guadeloupe', + country_gr: 'Grèce', + country_gt: 'Guatemala', + country_hk: 'Hong Kong', + country_hr: 'Croatie', + country_ht: 'Haïti', + country_hu: 'Hongrie', + country_id: 'Indonésie', + country_ie: 'Irlande', + country_il: 'Israël', + country_in: 'Inde', + country_iq: 'Irak', + country_ir: 'Iran', + country_is: 'Islande', + country_it: 'Italie', + country_jm: 'Jamaïque', + country_jo: 'Jordanie', + country_jp: 'Japon', + country_ke: 'Kenya', + country_kg: 'Kirghizistan', + country_kh: 'Cambodge', + country_kp: 'Corée du Nord', + country_kr: 'Corée du Sud', + country_kz: 'Kazakhstan', + country_kw: 'Koweït', + country_la: 'Laos', + country_lb: 'Liban', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Libéria', + country_lt: 'Lituanie', + country_lu: 'Luxembourg', + country_lv: 'Lettonie', + country_ly: 'Libye', + country_ma: 'Maroc', + country_mc: 'Monaco', + country_md: 'Moldavie', + country_me: 'Monténégro', + country_mk: 'Macédoine', + country_mm: 'Myanmar', + country_mn: 'Mongolie', + country_mo: 'Macao', + country_mt: 'Malte', + country_mu: 'Maurice', + country_mv: 'Maldives', + country_mw: 'Malawi', + country_mx: 'Mexique', + country_my: 'Malaisie', + country_mz: 'Mozambique', + country_na: 'Namibie', + country_ne: 'Niger', + country_ng: 'Nigéria', + country_ni: 'Nicaragua', + country_nl: 'Pays-Bas', + country_no: 'Norvège', + country_np: 'Népal', + country_nz: 'Nouvelle-Zélande', + country_om: 'Oman', + country_pa: 'Panama', + country_pe: 'Pérou', + country_pg: 'Papouasie-Nouvelle-Guinée', + country_ph: 'Philippines', + country_pk: 'Pakistan', + country_pl: 'Pologne', + country_pr: 'Porto Rico', + country_ps: 'Territoire Palestinien', + country_pt: 'Portugal', + country_py: 'Paraguay', + country_qa: 'Qatar', + country_ro: 'Roumanie', + country_rs: 'Serbie', + country_ru: 'Russie', + country_rw: 'Rwanda', + country_sa: 'Arabie Saoudite', + country_sd: 'Soudan', + country_se: 'Suède', + country_sg: 'Singapour', + country_si: 'Slovénie', + country_sk: 'Slovaquie', + country_sn: 'Sénégal', + country_su: 'URSS', + country_sv: 'El Salvador', + country_sy: 'Syrie', + country_th: 'Thaïlande', + country_tj: 'Tadjikistan', + country_tm: 'Turkménistan', + country_tn: 'Tunisie', + country_tr: 'Turquie', + country_tw: 'Taïwan', + country_tz: 'Tanzanie', + country_ua: 'Ukraine', + country_ug: 'Ouganda', + country_us: 'États-Unis', + country_uy: 'Uruguay', + country_uz: 'Ouzbékistan', + country_ve: 'Venezuela', + country_vn: 'Vietnam', + country_xk: 'Kosovo', + country_ws: 'Samoa', + country_ye: 'Yémen', + country_yu: 'Yougoslavie', + country_za: 'Afrique du Sud', + country_zm: 'Zambie', + country_zw: 'Zimbabwe', + + filter_clarify: 'Préciser', + filter_clarify_two: 'Affiner la recherche', + filter_set_name: 'Spécifier le titre', + filter_sorted: 'Trier', + filter_filtred: 'Filtrer', + filter_any: 'Tous', + filter_combinations: 'Combinaisons', + filter_alt_names: 'Autres noms', + filter_rating_from: 'de', + filter_rating_to: 'à', + + filter_lang_af: 'Afrikaans', + filter_lang_ar: 'Arabe', + filter_lang_az: 'Azéri', + filter_lang_ba: 'Bachkir', + filter_lang_be: 'Biélorusse', + filter_lang_bg: 'Bulgare', + filter_lang_bn: 'Bengali', + filter_lang_bs: 'Bosniaque', + filter_lang_ca: 'Catalan', + filter_lang_ce: 'Tchétchène', + filter_lang_cs: 'Tchèque', + filter_lang_da: 'Danois', + filter_lang_de: 'Allemand', + filter_lang_el: 'Grec', + filter_lang_en: 'Anglais', + filter_lang_es: 'Espagnol', + filter_lang_et: 'Estonien', + filter_lang_fa: 'Persan', + filter_lang_fi: 'Finnois', + filter_lang_fr: 'Français', + filter_lang_ga: 'Irlandais', + filter_lang_gl: 'Galicien', + filter_lang_gn: 'Guarani', + filter_lang_he: 'Hébreu', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Croate', + filter_lang_hu: 'Hongrois', + filter_lang_hy: 'Arménien', + filter_lang_id: 'Indonésien', + filter_lang_is: 'Islandais', + filter_lang_it: 'Italien', + filter_lang_ja: 'Japonais', + filter_lang_ka: 'Géorgien', + filter_lang_kk: 'Kazakh', + filter_lang_ko: 'Coréen', + filter_lang_ks: 'Cachemiri', + filter_lang_ku: 'Kurde', + filter_lang_ky: 'Kirghize', + filter_lang_lt: 'Lituanien', + filter_lang_lv: 'Letton', + filter_lang_mi: 'Maori', + filter_lang_mk: 'Macédonien', + filter_lang_mn: 'Mongol', + filter_lang_mt: 'Maltais', + filter_lang_ne: 'Népalais', + filter_lang_nl: 'Néerlandais', + filter_lang_no: 'Norvégien', + filter_lang_pa: 'Pendjabi', + filter_lang_pl: 'Polonais', + filter_lang_ps: 'Pachto', + filter_lang_pt: 'Portugais', + filter_lang_ro: 'Roumain', + filter_lang_ru: 'Russe', + filter_lang_si: 'Cinghalais', + filter_lang_sk: 'Slovaque', + filter_lang_sl: 'Slovène', + filter_lang_sm: 'Samoan', + filter_lang_so: 'Somali', + filter_lang_sq: 'Albanais', + filter_lang_sr: 'Serbe', + filter_lang_sv: 'Suédois', + filter_lang_sw: 'Swahili', + filter_lang_ta: 'Tamoul', + filter_lang_tg: 'Tadjik', + filter_lang_th: 'Thaï', + filter_lang_tk: 'Turkmène', + filter_lang_tr: 'Turc', + filter_lang_tt: 'Tatar', + filter_lang_ur: 'Ourdou', + filter_lang_uk: 'Ukrainien', + filter_lang_uz: 'Ouzbek', + filter_lang_vi: 'Vietnamien', + filter_lang_yi: 'Yiddish', + filter_lang_zh: 'Chinois', + + filter_genre_ac: 'Action', + filter_genre_ad: 'Aventure', + filter_genre_mv: 'Animation', + filter_genre_cm: 'Comédie', + filter_genre_cr: 'Crime', + filter_genre_dc: 'Documentaire', + filter_genre_dr: 'Drame', + filter_genre_fm: 'Famille', + filter_genre_fe: 'Fantastique', + filter_genre_hi: 'Histoire', + filter_genre_ho: 'Horreur', + filter_genre_mu: 'Musique', + filter_genre_de: 'Mystère', + filter_genre_md: 'Mélodrame', + filter_genre_fa: 'Science-Fiction', + filter_genre_tv: 'Téléfilm', + filter_genre_tr: 'Thriller', + filter_genre_mi: 'Guerre', + filter_genre_ve: 'Western', + filter_genre_aa: 'Action & Aventure', + filter_genre_ch: 'Enfants', + filter_genre_nw: 'Nouvelles', + filter_genre_rs: 'Téléréalité', + filter_genre_hf: 'SF & Fantastique', + filter_genre_op: 'Soap', + filter_genre_tc: 'Talk Show', + filter_genre_mp: 'Guerre & Politique', + + empty_title: 'Vide', + empty_text: 'Aucun résultat pour ce filtre, veuillez l\'affiner.', + empty_title_two: 'C\'est vide ici', + empty_text_two: 'La liste est actuellement vide.', + + menu_main: 'Accueil', + menu_movies: 'Films', + menu_tv: 'Séries', + menu_catalog: 'Catalogue', + menu_filter: 'Filtre', + menu_collections: 'Collections', + menu_relises: 'Sorties', + menu_anime: 'Anime', + menu_bookmark: 'Favoris', + menu_like: 'J\'aime', + menu_time: 'Plus tard', + menu_history: 'Historique', + menu_timeline: 'Calendrier', + menu_torrents: 'Torrents', + menu_settings: 'Paramètres', + menu_about: 'Infos', + menu_console: 'Console', + menu_multmovie: 'Dessins animés', + menu_multtv: 'Séries animées', + + plugins_catalog_work: 'Extensions fonctionnelles', + plugins_catalog_work_descr: 'Extensions testées et validées sur Lampa.', + plugins_catalog_popular: 'Extensions populaires', + plugins_catalog_popular_descr: 'L\'installation depuis des sources inconnues peut nuire à l\'application.', + plugins_online: 'Regarder en ligne', + plugins_check_fail: 'Échec du test de l\'extension. Relancez l\'application pour vérifier son statut.', + plugins_need_reload: 'Redémarrez l\'application pour appliquer l\'extension.', + plugins_install: 'Installer', + plugins_install_ready: 'Cette extension est déjà installée.', + plugins_installed: 'Installations', + plugins_load_from: 'Chargé depuis CUB', + plugins_ok_for_check: 'Cliquez (OK) pour tester l\'extension', + plugins_no_loaded: 'Certaines extensions n\'ont pas pu être chargées au démarrage', + + time_viewed: 'Vu', + time_from: 'de', + time_reset: 'Réinitialiser le code temporel', + + settings_clear_cache: 'Cache et données effacés', + settings_user_links: 'Lien personnalisé', + settings_for_local: 'Pour TorrServer local', + settings_add: 'Ajouter', + settings_remove: 'Supprimer', + settings_this_value: 'Valeur actuelle', + settings_added: 'Ajouté', + settings_removed: 'Supprimé', + + settings_param_player_inner: 'Lampa', + settings_param_player_outside: 'Externe', + settings_param_player_inner_tvos: 'Interne', + settings_param_yes: 'Oui', + settings_param_no: 'Non', + settings_param_interface_size_small: 'Petit', + settings_param_interface_size_normal: 'Normal', + settings_param_interface_size_bigger: 'Grand', + settings_param_poster_quality_low: 'Basse', + settings_param_poster_quality_average: 'Moyenne', + settings_param_poster_quality_high: 'Haute', + settings_param_parse_directly: 'Directement', + settings_param_parse_api: 'Via API site', + settings_param_background_complex: 'Complexe', + settings_param_background_simple: 'Simple', + settings_param_background_image: 'Image', + settings_param_link_use_one: 'Principal', + settings_param_link_use_two: 'Secondaire', + settings_param_link_use_both: 'Les deux', + settings_param_subtitles_size_small: 'Petit', + settings_param_subtitles_size_normal: 'Standard', + settings_param_subtitles_size_bigger: 'Grand', + settings_param_screensaver_nature: 'Nature', + settings_param_torrent_lang_orig: 'Originale', + settings_param_torrent_lang_ru: 'Russe', + settings_param_player_timecode_again: 'Recommencer', + settings_param_player_timecode_continue: 'Continuer', + settings_param_player_timecode_ask: 'Demander', + settings_param_player_scale_method: 'Calculer', + settings_param_player_hls_app: 'Système', + settings_param_player_hls_js: 'Programme', + settings_param_card_view_load: 'Charger', + settings_param_card_view_all: 'Tout afficher', + settings_param_navigation_remote: 'Télécommande', + settings_param_navigation_mouse: 'Souris', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: 'Système', + + helper_keyboard: 'Après saisie, appuyez sur "Retour" pour enregistrer', + helper_torrents: 'Maintenez (OK) pour le menu contextuel', + helper_cleared: 'Succès, les astuces seront de nouveau affichées.', + helper_torrents_view: 'Maintenez (OK) pour réinitialiser le temps ou voir le menu', + + fav_sync_title: 'Sync. des favoris', + fav_sync_text: 'Vos favoris partout. Connectez-vous sur {site} pour synchroniser vos données sur tous vos appareils.', + fav_sync_site: 'Site web', + fav_remove_title: 'Retirer de l\'historique', + fav_remove_descr: 'Supprimer la fiche sélectionnée', + fav_clear_title: 'Vider l\'historique', + fav_clear_descr: 'Supprimer toutes les fiches de l\'historique', + fav_clear_label_title: 'Effacer les marques', + fav_clear_label_descr: 'Effacer les indicateurs de visionnage', + fav_clear_time_title: 'Effacer les temps', + fav_clear_time_descr: 'Effacer tous les codes temporels', + fav_label_cleared: 'Marques effacées', + fav_time_cleared: 'Codes temporels effacés', + + timetable_empty: 'Les dates de sortie des nouveaux épisodes apparaîtront ici.', + + player_quality: 'Qualité', + player_flow: 'Flux', + player_tracks: 'Pistes audio', + player_disabled: 'Désactivé', + player_unknown: 'Inconnu', + player_subs: 'Sous-titres', + player_size_default_title: 'Défaut', + player_size_default_descr: 'Taille vidéo par défaut', + player_size_cover_title: 'Étendre', + player_size_cover_descr: 'Étendre la vidéo au plein écran', + player_size_fill_title: 'Remplir', + player_size_fill_descr: 'Adapter la vidéo au plein écran', + player_size_s115_title: 'Zoom 115%', + player_size_s115_descr: 'Agrandir la vidéo de 115%', + player_size_s130_title: 'Zoom 130%', + player_size_s130_descr: 'Agrandir la vidéo de 130%', + player_size_v115_title: 'Vertical 115%', + player_size_v115_descr: 'Agrandir verticalement de 115%', + player_size_v130_title: 'Vertical 130%', + player_size_v130_descr: 'Agrandir verticalement de 130%', + player_video_size: 'Taille de la vidéo', + player_playlist: 'Playlist', + player_error_one: 'Échec du décodage vidéo', + player_error_two: 'Vidéo non trouvée ou corrompue', + player_start_from: 'Reprendre le visionnage à', + player_not_found: 'Lecteur non trouvé', + player_lauch: 'Lancer le lecteur', + player_speed_default_title: 'Normal', + player_speed_two_descr: 'Jouer sans son', + player_video_speed: 'Vitesse de lecture', + player_share_title: 'Partager', + player_share_descr: 'Lire sur un autre appareil', + player_normalization_power_title: 'Force de normalisation', + player_normalization_smooth_title: 'Vitesse de normalisation', + player_normalization_step_low: 'Basse', + player_normalization_step_medium: 'Moyenne', + player_normalization_step_hight: 'Haute', + player_youtube_no_played: 'Cette vidéo n\'est pas disponible dans votre région ou a été supprimée.', + player_youtube_start_play: 'Cliquez sur "Play" pour lancer la vidéo.', + + broadcast_open: 'Ouvrir la fiche sur un autre appareil', + broadcast_play: 'Choisir l\'appareil de lecture', + + card_new_episode: 'Nouvel épisode', + card_book_remove: 'Retirer des favoris', + card_book_add: 'Ajouter aux favoris', + card_book_descr: 'Voir dans le menu (Favoris)', + card_like_remove: 'Retirer de J\'aime', + card_like_add: 'J\'aime', + card_like_descr: 'Voir dans le menu (J\'aime)', + card_wath_remove: 'Retirer de À regarder', + card_wath_add: 'Regarder plus tard', + card_wath_descr: 'Voir dans le menu (Plus tard)', + card_history_remove: 'Retirer de l\'historique', + card_history_add: 'Ajouter à l\'historique', + card_history_descr: 'Voir dans le menu (Historique)', + + keyboard_listen: 'Parlez, j\'écoute...', + keyboard_nomic: 'Aucun accès au microphone', + + notice_new_quality: 'Nouvelle qualité disponible', + notice_quality: 'Qualité', + notice_new_episode: 'Nouvelle série', + notice_none: 'Pas de notifications. Inscrivez-vous sur {site} pour suivre les nouveautés.', + notice_in_quality: 'En', + notice_none_account: 'Pas de notifications. Ajoutez des séries en favoris pour être prévenu.', + notice_none_system: 'Aucune notification disponible actuellement.', + + copy_link: 'Copier le lien vidéo', + copy_secuses: 'Lien copié dans le presse-papiers', + copy_error: 'Erreur lors de la copie', + + account_sync_to_profile: 'Les favoris seront déplacés vers le profil', + account_sync_secuses: 'Synchronisation réussie', + account_profiles: 'Profils', + account_profiles_empty: 'Échec de récupération des profils', + account_authorized: 'Autorisé', + account_logged_in: 'Vous êtes connecté', + account_login_failed: 'Échec de connexion', + account_login_wait: 'En attente de connexion', + account_profile_main: 'Général', + account_export_secuses: 'Exportation réussie', + account_export_fail: 'Erreur d\'exportation', + account_import_secuses: 'Importation réussie', + account_import_fail: 'Erreur d\'importation', + account_imported: 'importé', + account_reload_after: 'redémarrage dans 5 s.', + account_create: 'Découvrez plus d\'options avec un compte CUB. Inscrivez-vous sur pour synchroniser vos favoris et codes temporels.', + account_premium_more: 'En savoir plus sur CUB Premium', + account_limited: 'Limite atteinte. Augmentez la limite avec CUB Premium sur ', + + account_code_enter: 'Entrez le code à six chiffres', + account_code_error: 'Code incorrect ou expiré', + account_code_wrong: 'Format de code invalide', + account_code_where: 'Allez sur et entrez le code affiché.', + account_code_input: 'Entrer le code', + settings_cub_signin_button: 'Se connecter', + + network_noconnect: 'Pas de connexion réseau', + network_404: 'Page non trouvée. [404]', + network_401: 'Échec d\'autorisation', + network_500: 'Erreur interne du serveur. [500]', + network_parsererror: 'Échec de l\'analyse JSON.', + network_timeout: 'Délai de requête dépassé.', + network_abort: 'Requête annulée.', + network_error: 'Erreur inconnue', + + size_zero: '0 Octet', + size_byte: 'Octet', + size_kb: 'Ko', + size_mb: 'Mo', + size_gb: 'Go', + size_tb: 'To', + size_pp: 'Po', + + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + + month_1: 'Janvier', + month_2: 'Février', + month_3: 'Mars', + month_4: 'Avril', + month_5: 'Mai', + month_6: 'Juin', + month_7: 'Juillet', + month_8: 'Août', + month_9: 'Septembre', + month_10: 'Octobre', + month_11: 'Novembre', + month_12: 'Décembre', + + day_1: 'Lundi', + day_2: 'Mardi', + day_3: 'Mercredi', + day_4: 'Jeudi', + day_5: 'Vendredi', + day_6: 'Samedi', + day_7: 'Dimanche', + + month_1_e: 'Janvier', + month_2_e: 'Février', + month_3_e: 'Mars', + month_4_e: 'Avril', + month_5_e: 'Mai', + month_6_e: 'Juin', + month_7_e: 'Juillet', + month_8_e: 'Août', + month_9_e: 'Septembre', + month_10_e: 'Octobre', + month_11_e: 'Novembre', + month_12_e: 'Décembre', + + week_1: 'Lun', + week_2: 'Mar', + week_3: 'Mer', + week_4: 'Jeu', + week_5: 'Ven', + week_6: 'Sam', + week_7: 'Dim', + + extensions_enable: 'Activer', + extensions_disable: 'Désactiver', + extensions_check: 'Vérifier statut', + extensions_install: 'Installer', + extensions_info: 'Information', + extensions_edit: 'Modifier', + extensions_change_name: 'Changer le nom', + extensions_change_link: 'Changer le lien', + extensions_remove: 'Supprimer', + extensions_set_name: 'Nom de l\'extension', + extensions_set_url: 'URL de l\'extension', + extensions_ready: 'Déjà installé', + extensions_no_info: 'Sans information', + extensions_no_name: 'Sans titre', + extensions_worked: 'Fonctionne', + extensions_no_plugin: 'Non vérifiée', + extensions_add: 'Ajouter une extension', + extensions_from_memory: 'Installée en mémoire', + extensions_from_cub: 'Installée depuis CUB', + extensions_from_popular: 'Extensions populaires', + extensions_from_lib: 'Bibliothèque d\'extensions', + extensions_from_connected: 'Extensions connectées', + + settings_webos_launcher: 'Lancement d\'application', + settings_webos_launcher_add_device: 'Installer comme app de démarrage', + settings_webos_launcher_remove_device: 'Retirer des apps de démarrage', + player_normalization: 'Normalisation', + change_source_on_cub: 'Changer la source pour CUB', + settings_param_jackett_interview_all: 'Tous', + settings_param_jackett_interview_healthy: 'Disponibles uniquement', + settings_parser_jackett_interview: 'Sonder les trackers', + title_ongoing: 'En cours de diffusion', + title_pgrating: 'Limite d\'âge', + + settings_interface_card_interfice: 'Interface des fiches', + settings_interface_card_poster: 'Afficher l\'affiche', + title_card: 'Fiche', + settings_param_card_interface_old: 'Ancienne', + settings_param_card_interface_new: 'Nouvelle', + title_seasons: 'Saisons', + title_episodes: 'Épisodes', + title_rewiews: 'Critiques', + settings_interface_glass: 'Effet Verre', + settings_interface_glass_descr: 'Style d\'interface vitré', + settings_interface_black_style: 'Style sombre total', + + plugins_remove: 'Supprimer les extensions', + plugins_add_success: 'Extension connectée', + settings_reset: 'Réinitialiser', + title_channel: 'Chaîne', + + input_detection_touch: 'Passer au contrôle tactile ?', + input_detection_mouse: 'Passer au contrôle à la souris ?', + input_detection_remote: 'Passer au contrôle à la télécommande ?', + + settings_interface_hide_outside_the_screen: 'Masquer les fiches hors écran', + settings_interface_hide_outside_the_screen_descr: 'Accélère l\'affichage et améliore les performances', + + https_text: 'Vous utilisez le protocole HTTPS. Lampa fonctionne mieux en HTTP.', + + extensions_hpu_best: 'Populaires', + extensions_hpu_recomend: 'Recommandées', + extensions_hpu_theme: 'Thèmes', + extensions_hpu_screensaver: 'Économiseurs', + extensions_hpu_video: 'Vidéo', + extensions_hpu_control: 'Contrôle', + extensions_hpu_other: 'Divers', + extensions_hpu_: 'Autre', + + title_author: 'Auteur', + + title_buffer: 'Tampon', + settings_rest_screensaver_time: 'Délai avant l\'écran de veille (min)', + + time_h: 'h.', + time_m: 'm.', + time_s: 's.', + + settings_param_glass_easy: 'Transparent', + settings_param_glass_medium: 'Semi-transparent', + settings_param_glass_blacked: 'Sombre', + + settings_interface_glass_opacity: 'Transparence du verre', + torrent_error_check_no_auth: 'Le serveur a répondu, mais l\'autorisation a échoué', + settings_interface_card_cover: 'Afficher la couverture', + + title_upcoming_episodes: 'Prochaines sorties d\'épisodes', + title_recent_episodes: 'Sorties d\'épisodes récentes', + settings_rest_cache_images: 'Cache d\'images', + settings_rest_cache_images_descr: 'Mettre en cache les affiches et fonds localement', + + settings_player_rewind_title: 'Retour rapide', + settings_player_rewind_descr: 'Intervalle de retour (secondes)', + + settings_interface_card_reactions: 'Afficher les réactions', + title_look: 'Regarde', + title_scheduled: 'Prévu', + title_viewed: 'Vu', + title_thrown: 'Abandonné', + title_reactions: 'Réactions', + reactions_none: 'Aucune réaction', + reactions_fire: 'Génial', + reactions_nice: 'Sympa', + reactions_think: 'Intéressant', + reactions_bore: 'Ennuyeux', + reactions_shit: 'Nul', + reactions_ready: 'Vous avez déjà réagi', + settings_player_launch_trailers: 'Lecteur de bandes-annonces', + title_continued: 'À suivre', + title_language_short: 'Langue', + + speedtest_connect: 'Connexion', + speedtest_test: 'Test en cours', + speedtest_ready: 'Prêt', + speedtest_button: 'Tester la vitesse', + + termsofuse_t_01: 'Conditions d\'utilisation', + termsofuse_t_02: 'Lampa est un outil pour explorer l\'actualité du cinéma. Les données proviennent de themoviedb.org.', + termsofuse_t_03: 'Contenu', + termsofuse_t_04: 'Lampa utilise l\'API de themoviedb.org pour récupérer les infos, affiches et bandes-annonces.', + termsofuse_t_05: 'L\'API permet d\'accéder à une base de données exhaustive de films et séries.', + termsofuse_t_06: 'L\'interaction se fait via des requêtes API standard vers les serveurs de TMDB.', + termsofuse_t_07: 'Lampa respecte les conditions d\'utilisation imposées par TMDB.', + termsofuse_t_08: 'Extensions', + termsofuse_t_09: 'Les extensions permettent d\'ajouter des fonctionnalités à Lampa.', + termsofuse_t_10: 'L\'installation se fait aux risques de l\'utilisateur. Lampa n\'est pas responsable de leur contenu.', + termsofuse_t_11: 'Droits d\'auteur', + termsofuse_t_12: 'En cas de violation, contactez les développeurs. Les données TMDB étant publiques, elles ne constituent pas une infraction en soi.', + termsofuse_t_13: 'Lampa retirera tout contenu sur notification valide de violation de droits d\'auteur.', + settings_rest_protocol_use: 'Connexion sécurisée', + settings_rest_protocol_descr: 'Utiliser HTTPS', + install_app_apk_title: 'Installer Lampa sur Android', + install_app_apk_text: 'Nous recommandons l\'installation via APK pour plus de stabilité. Instructions sur @lampa_group.', + install_app_apk_qr: 'Scannez pour télécharger l\'APK', + copy_link_buffer: 'Copier le lien', + + tv_status_returning_series: 'Série en cours', + tv_status_planned: 'Prévue', + tv_status_in_production: 'En production', + tv_status_ended: 'Terminée', + tv_status_canceled: 'Annulée', + tv_status_pilot: 'Pilote', + + tv_status_released: 'Sorti', + tv_status_rumored: 'Rumeur', + tv_status_post_production: 'Post-production', + + title_last_year: 'L\'année dernière', + + title_reset: 'Redémarrer', + back_to_card: 'Retour à la fiche', + + premiere_author_recomend_1: 'Commandez une pizza et profitez.', + premiere_author_recomend_2: 'La fête commence maintenant.', + premiere_author_recomend_3: 'Préparez-vous pour l\'adrénaline.', + premiere_author_recomend_4: 'Prêt pour une soirée inoubliable ?', + premiere_author_recomend_5: 'Je recommande ce visionnage.', + premiere_title: 'Première', + + settings_clear_cache_only: 'Cache vidé', + settings_rest_cache_only: 'Uniquement le cache', + settings_rest_cache_only_descr: 'Les paramètres de base seront conservés', + settings_rest_cache_all: 'Cache et données', + settings_rest_cache_all_descr: 'Tout sera réinitialisé', + settings_rest_cache_calculate: 'Mémoire restante', + + title_left: 'Restant', + + account_export_fail_500: 'Erreur inconnue', + account_export_fail_610: 'Limite quotidienne dépassée', + account_export_fail_200: 'Erreur de base de données', + account_export_fail_600: 'Échec du téléchargement du fichier', + account_export_fail_620: 'Fichier non transmis', + + title_parental_control: 'Contrôle parental', + settings_parental_control_param_time_always: 'Toujours', + settings_parental_control_param_time_once: 'Une fois', + settings_parental_control_param_time_10: 'Dans 10 minutes', + settings_parental_control_param_time_20: 'Dans 20 minutes', + settings_parental_control_param_time_30: 'Dans 30 minutes', + settings_parental_control_param_time_60: 'Dans 1 heure', + settings_parental_control_param_time_120: 'Dans 2 heures', + settings_parental_control_change_pin: 'Changer le PIN', + settings_parental_control_demand_title: 'Fréquence de demande', + settings_parental_control_demand_descr: 'Délai avant de redemander le PIN', + settings_parental_control_enabled: 'Activé', + settings_parental_control_disabled: 'Désactivé', + parental_control_input_new_code: 'Entrez le nouveau PIN', + parental_control_confirm_new_code: 'Confirmez le PIN', + parental_control_no_match_code: 'Les codes ne correspondent pas', + parental_control_input_code: 'Entrez le PIN', + parental_control_input_error: 'PIN incorrect', + title_worth_rewatch: 'À revoir absolument', + + ad_disable: 'Abonnez-vous à CUB Premium pour supprimer les publicités.', + ad_after: 'Publicité dans', + ad: 'Publicité', + ad_skip: 'Passer', + ad_continue_after: 'Lecture dans', + settings_parser_prowlarr_link_descr: 'Lien vers le serveur Prowlarr', + settings_parser_prowlarr_key_descr: 'Clé API trouvée dans les paramètres Prowlarr', + settings_player_torrent_type: 'Lecteur pour torrents', + settings_player_torrent_type_descr: 'Lecteur utilisé pour les fichiers torrent', + + full_crew: 'Équipe complète', + full_editing: 'Montage', + full_creator: 'Créateur', + player_normalization_step_none: 'Aucun', + + settings_cub_backup_export_descr: 'Sauvegarder sur le cloud', + settings_cub_backup_import_descr: 'Restaurer depuis le cloud', + + settings_interface_sound: 'Sons système', + settings_interface_sound_play: 'Transitions', + settings_interface_sound_level: 'Volume', + settings_interface_advanced_animation: 'Animations avancées', + + confirm_open_player: 'Un autre appareil demande l\'accès au lecteur. Autoriser ?', + + pincode_use_remote: 'Utilisez les flèches pour sélectionner les chiffres.', + pincode_use_toggle: 'Maintenez OK pour changer la disposition.', + + settings_parental_control_where: 'Où demander le PIN', + title_fire: 'Incendiaire !', + title_top_100: 'Top 100', + + player_normalization_type_title: 'Type de normalisation', + player_normalization_type_all: 'Tout', + player_normalization_type_up: 'Augmenter seulement', + player_normalization_type_down: 'Diminuer seulement', + storage_quota_exceeded: 'Quota de stockage dépassé. Videz le cache.', + settings_cub_domain: 'Domaine principal', + + title_ai_assistant: 'Assistant IA', + title_facts: 'Anecdotes', + ai_search_start_typing: 'Posez une question à l\'IA. Ex: "Films sur l\'espace"', + ai_search_limit: 'Limite IA atteinte. Abonnez-vous à CUB Premium pour plus de requêtes.', + ai_subscribe_title: 'Débloquez l\'IA', + ai_subscribe_descr: 'Abonnez-vous pour profiter pleinement de l\'assistant IA.', + + dmca_title: 'Contenu bloqué', + dmca_descr: 'Matériel indisponible suite à une plainte de l\'ayant-droit.', + + loading_progress_step_0: 'Préparation', + loading_progress_step_1: 'Chargement des langues', + loading_progress_step_2: 'Recherche de miroirs', + loading_progress_step_3: 'Préparation des extensions', + loading_progress_step_4: 'Presque fini', + loading_progress_step_5: 'À tout de suite', + + install_extension_rule_1: 'Installation d\'extension tierce', + install_extension_rule_2: 'LAMPA ne vérifie pas le contenu des extensions tierces. En continuant, vous acceptez que :', + install_extension_rule_3: '- Certaines extensions peuvent accéder à vos données.', + install_extension_rule_4: '- Vous êtes responsable de l\'usage légal des extensions.', + install_extension_rule_5: '- N\'installez que des sources fiables.', + install_extension_rule_6: 'LAMPA ne soutient pas le piratage.', + install_extension_rule_7: 'En continuant, vous confirmez comprendre ces risques.', + ad_plugin: 'Publicité de l\'extension', + + terminal_title: 'Terminal', + terminal_no_access: 'Accès refusé', + terminal_confirm: 'Autoriser', + terminal_deny: 'Refuser', + terminal_update: 'Mettre à jour', + terminal_code: 'Code d\'accès', + terminal_text: 'Accès au terminal demandé. Les développeurs pourront diagnostiquer votre appareil. Ne l\'autorisez que si vous avez confiance.', + + title_anons: 'Annonce', + title_developer: 'Développeur', + title_navigation: 'Navigation', + title_page: 'Page', + title_person_about: 'À propos', + account_qr_premium: 'Scannez pour CUB Premium', + account_qr_code: 'Scannez pour lier l\'appareil', + account_qr_create: 'Scannez pour créer un compte', + account_add_device_title: 'Ajouter un appareil', + account_add_device_text: 'Allez sur {site}/add pour obtenir un code.', + account_none_title: 'Pas encore de compte ?', + account_none_include_1: 'Favoris et historique dans le cloud', + account_none_include_2: 'Synchronisation multi-appareils', + account_none_include_3: 'Alertes nouveaux épisodes', + account_none_include_4: 'Profils multiples', + account_premium_include_1: 'Nombre de favoris accru', + account_premium_include_2: 'Historique étendu', + account_premium_include_3: 'Plus de codes temporels', + account_premium_include_4: 'Plus de profils', + empty_subscribes_title: 'Vos abonnements aux doublages', + empty_subscribes_text: 'Abonnez-vous pour être prévenu des sorties.', + empty_history_title: 'Votre historique', + empty_history_text: 'Votre historique apparaîtra ici.', + empty_bookmark_title: 'Vos favoris', + empty_bookmark_text: 'Ajoutez des films pour les retrouver ici.', + empty_mytorrents_title: 'Vos torrents', + empty_mytorrents_text: 'Les torrents téléchargés via TorrServer apparaîtront ici.', + developer_param_enabled: 'Mode Développeur', + developer_param_nopremium: 'Désactiver CUB Premium', + developer_param_nodemo: 'Désactiver Mode Démo', + developer_param_ads: 'Afficher les pubs', + developer_param_fps: 'Afficher FPS', + developer_trigger_help_1: 'Presque ! :)', + developer_trigger_help_2: 'Encore un peu :)', + developer_trigger_help_3: 'Vraiment activer le mode développeur ?', + developer_trigger_help_4: 'Mode Développeur activé', + settings_param_navigation_touch: 'Tactile', + account_discuss_add_qr: 'Scannez le QR code', + account_discuss_add_title: 'Laissez un commentaire', + account_discuss_add_text: 'Scannez avec votre téléphone pour commenter ce film.', + account_discuss_added: 'Merci pour votre commentaire !', + account_discuss_added_ready: 'Vous avez déjà commenté ce contenu.', + remote_helper_long: 'Maintenez (OK) pour le menu', + account_premium: 'Débloquez de nouveaux horizons avec CUB Premium ! Plus de limites, plus de fonctions. Visitez {site}/premium.', + player_segments_title: 'Segments', + player_segments_descr: 'Ignorer l\'intro et autres parties', + player_segments_ad_title: 'Publicités', + player_segments_skip_title: 'Intro et divers', + player_segments_value_none: 'Ne pas ignorer', + player_segments_value_auto: 'Saut automatique', + player_segments_value_user: 'Personnalisé', + player_segments_skiped: 'Segment ignoré', + player_segments_skip_now: 'Ignorer', + player_segments_skip_in: 'Saut dans', + player_segments_skip_intro: 'Passer l\'intro', + player_segments_next: 'Épisode suivant', + player_segments_next_in: 'Épisode suivant dans', + subscribe_info: 'Retrouvez vos abonnements ici. Notifications activées pour les nouvelles sorties.', + no_watch_history: 'Aucun historique de visionnage', + + settings_request_caching_use: 'Mise en cache des requêtes', + settings_request_caching_descr: 'Accélère l\'interface en réduisant l\'usage des données.', + + account_profile_child: 'Enfant', + account_profile_add: 'Ajouter un profil', + account_profile_name: 'Nom du profil', + account_profile_created: 'Profil créé avec succès', + account_profile_limited: 'Limite de profils atteinte : {count}', + account_profile_info: 'Gérez vos profils sur {site}/profiles', + player_youtube_no_support: 'Votre appareil ne supporte pas la lecture YouTube.', + title_channels: 'Chaînes', + title_best_of_2000: 'Années 2000 dorées', + title_best_of_2010: 'Hits des années 2010', + title_best_of_2015: 'Classiques modernes', + title_comedy_of_2000: 'Rires des années 2000', + title_comedy_of_2010: 'Humour des années 2010', + title_comedy_of_2015: 'Comédies modernes', + + filter_keyword_sequel: 'Suite', + filter_keyword_based_comic: 'Adapté de comics', + filter_keyword_space: 'Espace', + filter_keyword_survival: 'Survie', + filter_keyword_zombie: 'Zombie', + filter_keyword_school: 'École', + filter_keyword_revenge: 'Vengeance', + filter_keyword_detective: 'Détective', + filter_keyword_robots: 'Robots', + filter_keyword_vampires: 'Vampires', + filter_keyword_aliens: 'Extraterrestres', + filter_keyword_police: 'Police', + filter_keyword_reincarnation: 'Réincarnation', + filter_keyword_spy: 'Espionnage', + filter_keyword_disaster: 'Catastrophe', + filter_keyword_christmas: 'Noël', + + dmca_title_lgbt: 'Contenu restreint', + dmca_descr_lgbt: 'Visionnage restreint dans votre région (Contenu LGBT).', + + settings_lgbt_content_block: 'Bloquer le contenu LGBT', + + // todo: + adult_content_title: 'Contenu adulte', + adult_content_text_warning: 'Le contenu peut contenir du matériel adulte qui pourrait être inapproprié pour certains spectateurs.', + adult_content_text_modal: "Ce film ou cette série est marqué comme contenant du contenu adulte. Vous devez avoir 18 ans ou plus pour visionner ce matériel. Veuillez confirmer que vous avez atteint l'âge légal pour continuer à regarder.", + + adult_content_confirm: "J'ai 18 ans ou plus", + adult_content_deny: "J'ai moins de 18 ans", + + inner_player_disclaimer_title: 'Avertissement du lecteur', + inner_player_disclaimer_text: 'Je comprends que je lance un lecteur avec une prise en charge incomplète, et je comprends que cela peut provoquer un comportement atypique de l appareil. Il est recommande de passer aux lecteurs de la famille tvOS ou a d autres alternatives.', + + inner_player_disclaimer_change_player: 'Changer le lecteur', + + remote_configuration_settings_title: 'Configuration à distance', + remote_configuration_registration_text: "La configuration à distance fournit un accès temporaire à votre application, une autre application pourra installer des extensions et configurer des paramètres.", + remote_configuration_waite_text: "Vous pouvez maintenant transmettre ce code à une autre application pour lui accorder l'accès aux paramètres.", + remote_configuration_open_button: "Ouvrir l'accès", + remote_configuration_code_life: 'Le code est valide', + remote_configuration_notice_nocode: "Impossible d'ouvrir l'accès", + + settings_server_gts: 'Transcodage', + settings_server_gts_descr: 'Convertir automatiquement la vidéo dans un format compatible si nécessaire.', + settings_server_tracktimecode: 'Activer TrackTimecode', + settings_server_tracktimecode_descr: 'Enregistre la progression de lecture des films et séries sur le serveur TorrServer. Pour fonctionner, cette option doit également être activée dans TorrServer.', + + title_metadata: 'Métadonnées', + title_moods: 'Ambiances', + title_meta_violence: 'Violence', + title_meta_fear: 'Peur', + title_meta_profanity: 'Langage', + title_meta_sadness: 'Tristesse', + title_meta_sex: 'Sexualité', + player_pip: 'Réduire', + player_volume: 'Volume', + player_time_end: 'Se termine à', + player_ai_agent_info: "Vous souhaitez en savoir plus sur la vidéo ? Demandez à l'assistant AI et il vous fournira un graphique d'ambiances, un bref résumé et des moments forts.", + player_ai_agent_ask_plot: 'Résumé', + player_ai_agent_ask_moods: 'Afficher le graphique', + player_ai_agent_ask_highlights: 'Moments forts', + player_ai_agent_ask: 'Demander', + player_ai_agent_processing: 'Analyse en cours...', + player_ai_agent_no_data: 'Aucune donnée à afficher.', + player_ai_agent_no_analysis: "Impossible d'analyser la vidéo.", + player_ai_agent_quota: 'Limite de requêtes dépassée. Veuillez réessayer plus tard.', + player_ai_agent_working: 'Je travaille encore dessus...', + title_meta_humor: 'Humour', + title_meta_tension: 'Tension', + title_meta_romance: 'Romance', + title_meta_pace: 'Rythme', + title_meta_importance: 'Scènes clés', + title_meta_action: 'Action' +} diff --git a/lampa-main/lang/he.js b/lampa-main/lang/he.js new file mode 100644 index 0000000..c0605c6 --- /dev/null +++ b/lampa-main/lang/he.js @@ -0,0 +1,1264 @@ +export default { + lang_choice_title: 'ברוך הבא', + lang_choice_subtitle: 'בחר את השפה שלך', + more: 'עוד', + show_more: 'הצג עוד', + more_results: 'הצג תוצאות נוספות', + loading: 'טוען', + nofind_movie: 'לא ניתן למצוא את הסרט', + noname: 'ללא שם', + nochoice: 'לא נבחר', + cancel: 'ביטול', + confirm: 'אני מאשר', + sure: '? אתה בטוח', + nodata: 'אין נתונים', + back: 'אחורה', + ready: 'מוכן', + close_app_modal: 'אתה בטוח שאתה רוצה לעזוב את האפליקציה', + search: 'חיפוש', + search_input: 'הזן טקסט', + search_empty: 'היסטוריית החיפוש ריקה', + search_delete: 'מחק חיפוש', + search_start_typing: 'התחל להקליד טקסט חיפוש', + search_searching: 'חיפוש בתהליך...', + search_start: 'להתחיל לחפש', + search_nofound: 'שום דבר לא נמצא לפי בקשתך', + global_search: 'חיפוש כללי', + full_genre: 'סגנון', + full_production: 'הפקה', + full_date_of_release: 'תאריך השקה', + full_budget: 'תקציב', + full_countries: 'מדינה', + full_like: 'כמו', + full_torrents: 'טורנטים', + full_trailers: 'טריילרים', + full_detail: 'תקציר', + full_notext: 'אין תיאור.', + full_series_release: 'שחרור סידרה', + full_next_episode: 'הבא', + full_episode_days_left: 'ימים נותרו', + full_trailer_official: 'רשמי', + full_trailer_no_official: 'לא רשמי', + full_season: 'עונה', + full_episode: 'פרק', + full_directing: 'נתוב', + full_writing: 'כתיבה', + settings_cub_sync: 'סנכרון', + settings_cub_sync_descr: 'סנכרון עם שירות CUB: סנכרון של הסימניות שלך, היסטוריית גלישה, תגים וקודי זמן.', + settings_cub_account: 'חשבון', + settings_cub_logged_in_as: 'מחובר בתור', + settings_cub_profile: 'פרופיל', + settings_cub_sync_btn: 'סינכרון', + settings_cub_sync_btn_descr: 'שמור סימניות מקומיות לחשבון CUB', + settings_cub_backup: 'גיבוי', + settings_cub_backup_descr: 'שמור או טען נתוני גיבוי', + settings_cub_logout: 'תחתמי.', + settings_cub_signin: 'הרשאה', + settings_cub_not_specified: 'לא צויין', + settings_cub_password: 'סיסמה', + settings_cub_status: 'מצב', + settings_cub_backup_import: 'ייבוא', + settings_cub_backup_export: 'ייצא', + settings_cub_sync_filters: 'סינכרון מסננים', + settings_cub_sync_calendar: 'סינכרון לוח שנה', + settings_cub_sync_quality: 'סינכרון איכות', + settings_cub_sync_search: 'סנכרון היסטוריית החיפוש', + settings_cub_sync_recomends: 'סנכרון המלצות', + settings_cub_sync_timecodes: 'Timecode Synchronization', + settings_input_links: 'מועדפים', + settings_interface_type: 'גרסת לייט', + settings_interface_size: 'גודל ממשק', + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: 'רקע כללי', + settings_interface_background_use: 'הצג רקע', + settings_interface_background_type: 'סוג רקע', + settings_interface_performance: 'ביצועים', + settings_interface_animation: 'אנימציה', + settings_interface_animation_descr: 'אנימציה של כרטיסים ותכנים', + settings_interface_attenuation: 'הנחתה', + settings_interface_attenuation_descr: 'החלקה של כרטיסים מלמטה ומלמעלה', + settings_interface_scroll: 'סוג החלקה ', + settings_interface_view_card: 'סוג תצוגת כרטיס', + settings_interface_view_card_descr: 'כשתגללו את השידור, הקלפים יעמיסו בהדרגה או יעמיסו את כולם', + settings_interface_lang: 'שפת ממשק', + settings_interface_lang_reload: 'אתה צריך להפעיל מחדש את היישום, ללחוץ "OK" כדי להפעיל מחדש', + settings_main_account: 'חשבון', + settings_main_interface: 'ממשק', + settings_main_player: 'הגדרות נגן', + settings_main_parser: 'parser', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'הרחבות', + settings_main_rest: 'אחר', + settings_rest_start: 'התחל עמוד', + settings_rest_start_descr: 'איזה עמוד להתחיל בהפעלה', + settings_rest_source: 'מקור', + settings_rest_source_use: 'מקור ראשי', + settings_rest_source_descr: 'היכן ניתן להשיג מידע על סרטים', + settings_rest_tmdb_lang: 'איזו שפה להציג נתונים מ- TMDB', + settings_rest_tmdb_prox: 'פרוקסי TMDB', + settings_rest_tmdb_prox_auto: 'אפשר פרוקסי באופן אוטומטי', + settings_rest_tmdb_posters: 'רזולוציה של כרזות TMDB', + settings_rest_screensaver: 'שומר מסך', + settings_rest_screensaver_use: 'הצג מסך התזה כאשר בטל', + settings_rest_screensaver_type: 'סוג שומר המסך', + settings_rest_helper: 'רמזים', + settings_rest_helper_use: 'הצג רמזים', + settings_rest_helper_reset: 'הצג רמזים שוב', + settings_rest_pages: 'כמה דפים לזכור', + settings_rest_pages_descr: 'שומר דפים במצב שהשארת אותם', + settings_rest_time: 'Shift time', + settings_rest_navigation: 'סוג ניווט', + settings_rest_keyboard: 'סוג המקלדת', + settings_rest_device: 'שם התקן', + settings_rest_device_placeholder: 'לדוגמה: המנורה שלי', + settings_rest_cache: 'נקה מטמון', + settings_rest_cache_descr: 'כל ההגדרות והנתונים יטוהרו', + settings_rest_tmdb_example: 'לדוגמה:', + settings_rest_tmdb_api_descr: 'כדי לקבל נתונים', + settings_rest_tmdb_image_descr: 'כדי לקבל תמונות', + settings_rest_card_quality: 'סימני איכות', + settings_rest_card_quality_descr: 'הצג סימני איכות על גבי קלפים', + settings_rest_card_episodes: 'סימני פרק', + settings_rest_card_episodes_descr: 'הצג סמני פרק בכרטיסים', + settings_parser_use: 'Use parser', + settings_parser_use_descr: 'בזאת, אתה מסכים לקבל את כל האחריות לשימוש בקישורים ציבוריים לצפייה בטורנט ובתוכן מקוון', + settings_parser_jackett_link: 'קישור', + settings_parser_jackett_link_descr: 'ספק קישור לתסריט של Jackett', + settings_parser_jackett_key_placeholder: 'לדוגמה: sa0sk83d..', + settings_parser_jackett_key: 'מקש Api', + settings_parser_jackett_key_descr: 'ממוקם בגקט', + settings_parser_torlook_type: 'Name', + settings_parser_scraperapi_placeholder: 'לדוגמה: cradrapi.com', + settings_parser_scraperapi_link: 'קישור אל parser אתר', + settings_parser_scraperapi_descr: 'הרשמה באתר scrappi.com, הזן את הקישור api.scrappi.com.api_key=... {url= {q} {br} W41.torlook.info ימסר אל {q}', + settings_parser_search: 'חיפוש', + settings_parser_search_descr: 'באיזו שפה לחפש?', + settings_parser_in_search: 'Parser in search', + settings_parser_in_search_descr: 'הצג תוצאות חיפוש?', + settings_parser_timeout_title: 'פסק-זמן של פארזר.', + settings_parser_timeout_descr: 'זמן בשניות לחכות לתגובה מהשרת', + settings_player_type: 'סוג שחקן', + settings_player_type_descr: 'VOD בחר סוג נגן', + settings_infuse_launch_mode: 'הפעלה ב-Infuse', + settings_infuse_launch_mode_descr: 'מה לעשות בפתיחת וידאו ב-Infuse. טורנטים תמיד מתחילים מיד', + settings_infuse_launch_ask: 'שאל בהפעלה', + settings_infuse_launch_play: 'השמע', + settings_infuse_launch_save_and_play: 'שמור והשמע', + settings_player_iptv_type: 'IPTV סוג נגן עבור', + settings_player_iptv_type_descr: 'IPTV איזה נגן להפעיל בערוצי', + settings_player_reset: 'אפס נגן ברירת מחדל', + settings_player_reset_descr: 'מאתחל את נגן האנדרואיד הנבחר ביישום', + settings_player_path: 'נתיב אל נגן', + settings_player_path_descr: 'exe. סמן את הנתיב אל הנגן', + settings_player_external_header: 'נגן חיצוני', + settings_player_external_fullscreen: 'הפעלה במצב מסך מלא', + settings_player_normalization: 'נימול צלילי', + settings_player_normalization_descr: 'מנרמל את הצליל לרמה אחת, מוריד את הצלילים הקולניים ומקפיץ את השקטים.', + settings_player_next_episode: 'הפרק הבא', + settings_player_next_episode_descr: 'עבור באופן אוטומטי לסדרה הבאה לאחר סיום הסדרה הנוכחית', + settings_player_timecode: 'לוח זמנים', + settings_player_timecode_descr: 'המשך ממיקום הנצפה האחרונה', + settings_player_scale: 'שיטת קנה מידה', + settings_player_scale_descr: 'כיצד לחשב את גודל הווידאו', + settings_player_subs: 'כתוביות', + settings_player_subs_use: 'הפעל', + settings_player_subs_use_descr: 'תמיד להפעיל כתוביות אחרי התחלת וידאו', + settings_player_subs_lang: 'שפת כתוביות', + settings_player_subs_lang_descr: 'אילו כתוביות להפעיל אוטומטית כשיש כמה שפות', + settings_param_subtitles_lang_auto: 'שפת הממשק', + settings_player_subs_size: 'הגודל', + settings_player_subs_size_descr: 'גודל המסך של כתוביות', + settings_player_subs_stroke_use: 'השתמש בהגדלה', + settings_player_subs_stroke_use_descr: 'כתוביות יוגדרו בשחור לקריאה טובה יותר', + settings_player_subs_backdrop_use: 'השתמש בשכבת משנה', + settings_player_subs_backdrop_use_descr: 'כתוביות יוצגו על גבי גיבוי שקוף כדי לשפר את הקריאה', + settings_player_quality: 'איכות וידאו ברירת מחדל', + settings_player_quality_descr: 'איכות וידאו מועדפת לצפייה', + settings_player_hls_title: 'מעבד את זרם ה-M3U8', + settings_player_hls_descr: 'אל תיגע בפרמטר זה אם אינך יודע מדוע.', + settings_plugins_notice: 'כדי להפעיל את התוסף, עליך להפעיל מחדש את היישום', + settings_plugins_add: 'הוסף תוסף', + settings_plugins_add_descr: 'כדי למחוק תוסף נוסף, החזק או לחץ כפול על מקש (OK) עליו', + settings_plugins_install: 'התקנת תוסף', + settings_plugins_install_descr: 'התקן תוסף מתוך רשימת הנגישות', + settings_server_link: 'השתמש בחיבור', + settings_server_links: 'קישורים', + settings_server_placeholder: 'לדוגמה: 192.168.X', + settings_server_link_one: 'קישור ראשי', + settings_server_link_one_descr: 'סמן את הקישור הראשי לתסריט TorrServer', + settings_server_link_two: 'קישור נוסף', + settings_server_link_two_descr: 'ספק קישור נוסף לתסריט TorrServer', + settings_server_additionally: 'בנוסף', + settings_server_client: 'לקוח משובץ', + settings_server_client_descr: 'השתמש בלקוח המובנה בTorrServe JS, אחרת המערכת אחת מתחילה.', + settings_server_base: 'שמור לבסיס הנתונים', + settings_server_base_descr: 'הזרם יווסף למסד הנתונים של TorrServer', + settings_server_preload: 'השתמש בחיץ Prefetch', + settings_server_preload_descr: 'חכה לTorrServer\'s preload buffer to fill before playing', + settings_server_auth: 'הרשאה', + settings_server_password_use: 'כניסה', + settings_server_login: 'שם משתמש', + settings_server_password: 'סיסמה', + settings_server_not_specified: 'לא צויין', + settings_server_search_type: 'סוג חיפוש', + settings_server_search_type_descr: 'היכן לחפש טורנטים: rutor מובנה, מפתחי Torznab ב-TorrServer, או שני המקורות.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + torent_nohash_reasons: 'הסיבות', + torent_nohash_reason_one: 'TorServer לא הצליח להוריד את קובץ הנחל', + torent_nohash_reason_two: 'תשובה מ- TorServer', + torent_nohash_reason_three: 'קישור', + torent_nohash_do: 'מה לעשות?', + torent_nohash_do_one: 'בדוק אם הגדרת את גקט כהלכה', + torent_nohash_do_two: 'מקורות פרטיים לא יכולים לספק קישור לקובץ', + torent_nohash_do_three: 'ודא גקט יכול להוריד גם את הקובץ', + torent_nohash_do_four: 'כתוב לקבוצת המברקים שלנו:', + torent_nohash_do_five: 'ציין איזה סרט, איזה הפצה ואם אפשר, תמונה של הפצה זו', + torrent_error_text: 'נכשל החיבור בואו נעבור במהירות על רשימת הבעיות האפשריות ונבדוק הכל TorrServe', + torrent_error_step_2: 'IP דינמי', + torrent_error_step_3: 'פרוטוקול ויציאה', + torrent_error_step_4: 'חסימת אנטי וירוס', + torrent_error_step_5: 'בדוק זמינות', + torrent_error_step_6: 'עדיין עושה\'t work', + torrent_error_info_1: 'ודא שיש לך השיק TorrServe על המכשיר שבו הוא מותקן.', + torrent_error_info_2: 'שגיאה נפוצה, כתובת ה-IP של המכשיר עם TorrServe השתנתה. ודא כי כתובת ה- IP אתה נכנס - {iP} - תואם את הכתובת של המכשיר שעליו מותקנת TorrServe.', + torrent_error_info_3: 'על מנת להתחבר אל TorrServe, עליך לציין את הפרוטוקול http:// / בהתחלה וביציאה:8090 בסוף הכתובת. ודא שיש יציאה לאחר כתובת ה- IP, כתובתך הנוכחית היא {ip}', + torrent_error_info_4: 'לעתים קרובות קורה, אנטי וירוס או חומת אש יכול לחסום גישה על ידי כתובת IP, לנסות לנטרל אנטי וירוס וחומת אש.', + torrent_error_info_5: 'על כל התקן אחר באותה רשת, פתח את כתובת ה־ {ip} בדפדפן ובדוק אם ממשק האינטרנט של TorrServe זמין.', + torrent_error_info_6: 'אם, אחרי כל הבדיקות, שגיאה בקשר עדיין מתרחשת, נסה להפעיל מחדש את טורסרב ואת מתאם האינטרנט.', + torrent_error_info_7: 'אם הבעיה נמשכת, כתוב אל קבוצת המברק עם הטקסט (לאמפה לא מתחברת לTorrServe אחרי כל הבדיקות, הכתובת הנוכחית היא {ip)', + torrent_error_start: 'התחל אימות', + torrent_error_nomatrix: 'אין אפשרות לאמת את גרסת המטריקס', + torrent_error_made: 'בוצע', + torrent_error_from: 'מ', + torrent_error_next: 'נוסף', + torrent_error_complite: 'להשלים', + torrent_error_connect: 'בעיית חיבור', + torrent_install_need: 'דורש TorrServe', + torrent_install_text: 'TorrServe היא אפליקציה המאפשרת לך לצפות בתוכן מקבצי טורנט באינטרנט.

    מידע מפורט יותר על התקנה ניתן למצוא בקבוצות הטלגרם למטה.', + torrent_install_contact: 'Telegram groups', + torrent_item_bitrate: 'קצב סיביות', + torrent_item_seeds: 'זרעים', + torrent_item_grabs: 'ליצרס', + torrent_item_mb: 'Mbps', + torrent_serial_episode: 'סדרה', + torrent_serial_season: 'עונה', + torrent_serial_date: 'יציאה', + torrent_get_magnet: 'מבקש קישור מגנטי', + torrent_remove_title: 'מחק', + torrent_remove_descr: 'הנחל יוסר מהרשימה שלך.', + torrent_parser_any_one: 'כל', + torrent_parser_any_two: 'כל', + torrent_parser_no_choice: 'לא נבחר', + torrent_parser_yes: 'כן', + torrent_parser_no: 'לא', + torrent_parser_quality: 'איכות', + torrent_parser_subs: 'כתוביות', + torrent_parser_voice: 'תרגום', + torrent_parser_tracker: 'גשש', + torrent_parser_year: 'שנה', + torrent_parser_season: 'עונה', + torrent_parser_sort_by_seeders: 'על ידי מפיצים', + torrent_parser_sort_by_size: 'גודל', + torrent_parser_sort_by_name: 'לפי שם', + torrent_parser_sort_by_tracker: 'לפי מקור', + torrent_parser_sort_by_date: 'לפי תאריך', + torrent_parser_sort_by_viewed: 'נצפה', + torrent_parser_voice_dubbing: 'דיבוב', + torrent_parser_voice_polyphonic: 'פוליפוני', + torrent_parser_voice_two: 'דו־ קול', + torrent_parser_voice_amateur: 'חובבן', + torrent_parser_reset: 'אפס סנון', + torrent_parser_empty: 'נכשל בהשגת תוצאות', + torrent_parser_no_hash: 'אין אפשרות להשיג את HASH, נסה להפעיל מחדש את TorrServer', + torrent_parser_added_to_mytorrents: 'הוסיף ל" הנחלים שלי', + torrent_parser_add_to_mytorrents: 'הוסף ל" הנחלים שלי', + torrent_parser_label_title: 'דגל', + torrent_parser_label_descr: 'דגל יד עם דגל (נצפתה)', + torrent_parser_label_cancel_title: 'בטל בדיקה', + torrent_parser_label_cancel_descr: 'הסר את הסימן מההפצה (נבדק)', + torrent_parser_timeout: 'Timeout expired', + torrent_parser_nofiles: 'אין אפשרות לחלץ קבצים מתאימים', + torrent_parser_set_link: 'קבע קישור לפיענוח', + torrent_parser_request_error: 'שגיאה בבקשות', + torrent_parser_magnet_error: 'אין אפשרות לקבל קישור מגנטי', + torrent_parser_no_responce: 'הקואורדינטות לא מגיבות לבקשה.', + torrent_parser_torlook_fallback_search_notification: 'parser Jackett אינו זמין או הגדרות החיבור שגויות. חיפוש Torlook...', + about_text: 'האפליקציה חינמית לחלוטין ומשתמשת בקישורים ציבוריים כדי לקבל מידע על סרטונים, מהדורות חדשות, סרטים פופולריים וכו. כל המידע הזמין משמש אך ורק למטרות חינוכיות, האפליקציה אינה משתמשת בשרתים שלה להפצת מידע.', + about_channel: 'הערוץ שלנו', + about_group: 'קבוצה', + about_version: 'גרסה', + about_donate: 'Donat', + title_watched: 'אתה צפית.', + title_settings: 'הגדרות', + title_collections: 'אוספים', + title_company: 'חברה', + title_actors: 'שחקנים', + title_actor: 'שחקן', + title_actress: 'אַקטריסע', + title_person: 'אדם', + title_persons: 'אנשים', + title_comments: 'הערות', + title_torrents: 'Torrents', + title_trailers: 'טריילרים', + title_watch: 'צפה', + title_error: 'שגיאה', + title_links: 'קישורים', + title_choice: 'בחר', + title_main: 'ראשי', + title_book: 'סימניות', + title_like: 'כמו', + title_wath: 'אחר כך.', + title_history: 'היסטוריית גלישה', + title_mytorrents: 'הטורנטים שלי', + title_last: 'אחרון', + title_action: 'פעולה', + title_action_infuse: 'פעולת Infuse', + title_producer: 'מפיק', + title_collection: 'אוסף', + title_recomendations: 'המלצות', + title_similar: 'דומה', + title_about: 'אודות היישום', + title_timetable: 'לוח זמנים', + title_relises: 'שחרורים דיגיטליים', + title_catalog: 'קטלוג', + title_category: 'קטגוריה', + title_parser: 'פארזר.', + title_type: 'סוג של', + title_rating: 'דירוג', + title_country: 'מדינה', + title_year: 'שנה', + title_genre: 'סגנון', + title_filter: 'סנון', + title_notice: 'הודעות', + title_files: 'קבצים', + title_now_watch: 'צופים עכשיו', + title_latest: 'תוספת אחרונה', + title_continue: 'המשך לעיין', + title_recomend_watch: 'אנחנו ממליצים לראות', + title_new_episodes: 'פרקים חדשים', + title_popular: 'פופולרי', + title_popular_movie: 'סרטים פופולריים', + title_popular_tv: 'תוכניות טלוויזיה פופולריות', + title_new_this_year: 'חדש השנה', + title_hight_voite: 'מדורג גבוה', + title_new: 'חדש', + title_trend_day: 'היום בטרנד', + title_trend_week: 'טרנד שבועיי', + title_upcoming: 'סרטים', + title_top_movie: 'סרטים מהשורה הראשונה', + title_top_tv: 'שורה עליונה', + title_tv_today: 'בשידור היום', + title_this_week: 'השבוע', + title_in_top: 'למעלה', + title_out: 'יציאה', + title_out_confirm: 'כן, צא החוצה.', + title_continue_two: 'המשך', + title_choice_language: 'בחר שפה', + title_subscribe: 'הירשם', + title_subscribes: 'מנויים', + title_unsubscribe: 'בטל את המנוי', + title_language: 'שפת מקור', + subscribe_success: 'נרשמת בהצלחה', + subscribe_error: 'אירעה שגיאה בעת ההרשמה, אנא נסה שוב מאוחר יותר', + subscribe_noinfo: 'אחזור המידע נכשל, אנא נסה שוב מאוחר יותר', + company_headquarters: 'Headquarters', + company_homepage: 'Website', + company_country: 'Country', + country_ad: 'Andorra', + country_ae: 'UAE', + country_af: 'Afghanistan', + country_al: 'Albania', + country_am: 'Armenia', + country_ao: 'Angola', + country_ar: 'Argentina', + country_at: 'Austria', + country_au: 'Australia', + country_aw: 'Aruba', + country_az: 'Azerbaijan', + country_bа: 'Bosnia & Herzegovina', + country_bd: 'Bangladesh', + country_be: 'Belgium', + country_bg: 'Bulgaria', + country_bh: 'Bahrain', + country_bi: 'Burundi', + country_bj: 'Benin', + country_bo: 'Bolivia', + country_br: 'Brazil', + country_bs: 'Bahamas', + country_bt: 'Bhutan', + country_bw: 'Botswana', + country_by: 'Belarus', + country_ca: 'Canada', + country_ch: 'Switzerland', + country_cl: 'Chile', + country_cm: 'Cameroon', + country_cn: 'China', + country_co: 'Colombia', + country_cr: 'Costa Rica', + country_cu: 'Cuba', + country_cv: 'Cape Verde', + country_cy: 'Cyprus', + country_cz: 'Czech Republic', + country_de: 'Germany', + country_dj: 'Djibouti', + country_dk: 'Denmark', + country_do: 'Dominican Republic', + country_dz: 'Algeria', + country_ec: 'Ecuador', + country_ee: 'Estonia', + country_eg: 'Egypt', + country_es: 'Spain', + country_et: 'Ethiopia', + country_fi: 'Finland', + country_fo: 'Faroe Islands', + country_fr: 'France', + country_ga: 'Gabon', + country_gb: 'United Kingdom', + country_ge: 'Georgia', + country_gh: 'Ghana', + country_gl: 'Greenland', + country_gp: 'Guadeloupe', + country_gr: 'Greece', + country_gt: 'Guatemala', + country_hk: 'Hong Kong', + country_hr: 'Croatia', + country_ht: 'Haiti', + country_hu: 'Hungary', + country_id: 'Indonesia', + country_ie: 'Ireland', + country_il: 'Israel', + country_in: 'India', + country_iq: 'Iraq', + country_ir: 'Iran', + country_is: 'Iceland', + country_it: 'Italy', + country_jm: 'Jamaica', + country_jo: 'Jordan', + country_jp: 'Japan', + country_ke: 'Kenya', + country_kg: 'Kyrgyzstan', + country_kh: 'Cambodia', + country_kp: 'North Korea', + country_kr: 'South Korea', + country_kz: 'Kazakhstan', + country_kw: 'Kuwait', + country_la: 'Laos', + country_lb: 'Lebanon', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Liberia', + country_lt: 'Lithuania', + country_lu: 'Luxembourg', + country_lv: 'Latvia', + country_ly: 'Libya', + country_ma: 'Morocco', + country_mc: 'Monaco', + country_md: 'Moldova', + country_me: 'Montenegro', + country_mk: 'Macedonia', + country_mm: 'Myanmar', + country_mn: 'Mongolia', + country_mo: 'Macau', + country_mt: 'Malta', + country_mu: 'Mauritius', + country_mv: 'Maldives', + country_mw: 'Malawi', + country_mx: 'Mexico', + country_my: 'Malaysia', + country_mz: 'Mozambique', + country_na: 'Namibia', + country_ne: 'Niger', + country_ng: 'Nigeria', + country_ni: 'Nicaragua', + country_nl: 'Netherlands', + country_no: 'Norway', + country_np: 'Nepal', + country_nz: 'New Zealand', + country_om: 'Oman', + country_pa: 'Panama', + country_pe: 'Peru', + country_pg: 'Papua New Guinea', + country_ph: 'Philippines', + country_pk: 'Pakistan', + country_pl: 'Poland', + country_pr: 'Puerto Rico', + country_ps: 'Palestinian Territory', + country_pt: 'Portugal', + country_py: 'Paraguay', + country_qa: 'Qatar', + country_ro: 'Romania', + country_rs: 'Serbia', + country_ru: 'Russia', + country_rw: 'Rwanda', + country_sa: 'Saudi Arabia', + country_sd: 'Sudan', + country_se: 'Sweden', + country_sg: 'Singapore', + country_si: 'Slovenia', + country_sk: 'Slovakia', + country_sn: 'Senegal', + country_su: 'USSR', + country_sv: 'El Salvador', + country_sy: 'Syria', + country_th: 'Thailand', + country_tj: 'Tajikistan', + country_tm: 'Turkmenistan', + country_tn: 'Tunisia', + country_tr: 'Turkey', + country_tw: 'Taiwan', + country_tz: 'Tanzania', + country_ua: 'Ukraine', + country_ug: 'Uganda', + country_us: 'USA', + country_uy: 'Uruguay', + country_uz: 'Uzbekistan', + country_ve: 'Venezuela', + country_vn: 'Viet Nam', + country_xk: 'Kosovo', + country_ws: 'Samoa', + country_ye: 'Yemen', + country_yu: 'Yugoslavia', + country_za: 'South Africa', + country_zm: 'Zambia', + country_zw: 'Zimbabwe', + filter_clarify: 'Clarify', + filter_clarify_two: 'Refine Search', + filter_set_name: 'Specify title', + filter_sorted: 'Sort', + filter_filtred: 'Filter', + filter_any: 'Any', + filter_combinations: 'Combinations', + filter_alt_names: 'Other names', + filter_rating_from: 'from', + filter_rating_to: 'to', + filter_lang_af: 'Afrikaans', + filter_lang_ar: 'Arabic', + filter_lang_az: 'Azerbaijani', + filter_lang_ba: 'Bashkir', + filter_lang_be: 'Belarusian', + filter_lang_bg: 'Bulgarian', + filter_lang_bn: 'Bengali', + filter_lang_bs: 'Bosnian', + filter_lang_ca: 'Catalan', + filter_lang_ce: 'Chechen', + filter_lang_cs: 'Czech', + filter_lang_da: 'Danish', + filter_lang_de: 'German', + filter_lang_el: 'Greek', + filter_lang_en: 'English', + filter_lang_es: 'Spanish', + filter_lang_et: 'Estonian', + filter_lang_fa: 'Persian', + filter_lang_fi: 'Finnish', + filter_lang_fr: 'French', + filter_lang_ga: 'Irish', + filter_lang_gl: 'Galician', + filter_lang_gn: 'Guarani', + filter_lang_he: 'עברית', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Croatian', + filter_lang_hu: 'Hungarian', + filter_lang_hy: 'Armenian', + filter_lang_id: 'Indonesian', + filter_lang_is: 'Icelandic', + filter_lang_it: 'Italian', + filter_lang_ja: 'Japanese', + filter_lang_ka: 'Georgian', + filter_lang_kk: 'Kazakh', + filter_lang_ko: 'Korean', + filter_lang_ks: 'Kashmiri', + filter_lang_ku: 'Kurdish', + filter_lang_ky: 'Kirghiz', + filter_lang_lt: 'Lithuanian', + filter_lang_lv: 'Latvian', + filter_lang_mi: 'Maori', + filter_lang_mk: 'Macedonian', + filter_lang_mn: 'Mongolian', + filter_lang_mt: 'Maltese', + filter_lang_ne: 'Nepali', + filter_lang_nl: 'Dutch (Nederlands)', + filter_lang_no: 'Norwegian', + filter_lang_pa: 'Punjabi', + filter_lang_pl: 'Polish', + filter_lang_ps: 'Pushto', + filter_lang_pt: 'Portuguese', + filter_lang_ro: 'Romanian', + filter_lang_ru: 'Russian', + filter_lang_si: 'Sinhalese', + filter_lang_sk: 'Slovak', + filter_lang_sl: 'Slovenian', + filter_lang_sm: 'Samoan', + filter_lang_so: 'Somali', + filter_lang_sq: 'Albanian', + filter_lang_sr: 'Serbian', + filter_lang_sv: 'Swedish', + filter_lang_sw: 'Swahili', + filter_lang_ta: 'Tamil', + filter_lang_tg: 'Tajik', + filter_lang_th: 'Thai', + filter_lang_tk: 'Turkmen', + filter_lang_tr: 'Turkish', + filter_lang_tt: 'Tatar', + filter_lang_ur: 'Urdu', + filter_lang_uk: 'Ukrainian', + filter_lang_uz: 'Uzbek', + filter_lang_vi: 'Vietnamese', + filter_lang_yi: 'Yiddish', + filter_lang_zh: 'Chinese', + filter_genre_ac: 'פעולה', + filter_genre_ad: 'הרפתקאות', + filter_genre_mv: 'מצוירים', + filter_genre_cm: 'קומדיה', + filter_genre_cr: 'פשע', + filter_genre_dc: 'דוקומנטרי', + filter_genre_dr: 'דרמה', + filter_genre_fm: 'משפחה', + filter_genre_fe: 'פנטזיה', + filter_genre_hi: 'סיפורים', + filter_genre_ho: 'אימה', + filter_genre_mu: 'מוזיקה', + filter_genre_de: 'בלשים', + filter_genre_md: 'מלודרמה', + filter_genre_fa: 'ספרות בדיונית', + filter_genre_tv: 'סדרות', + filter_genre_tr: 'סרט מתח', + filter_genre_mi: 'כוח מזוין', + filter_genre_ve: 'מערביים', + filter_genre_aa: 'פעולה והרפתקאות', + filter_genre_ch: 'ילדים', + filter_genre_nw: 'חדשות', + filter_genre_rs: 'תוכנית ריאליטי', + filter_genre_hf: 'מדע בדיוני ופנטזיה', + filter_genre_op: 'Soap opera', + filter_genre_tc: 'טוק שואו', + filter_genre_mp: 'מלחמה ופוליטיקה', + empty_title: 'ריק', + empty_text: 'שום דבר לא נמצא למסנן שלך, בבקשה לזקק את המסנן שלך.', + empty_title_two: '', + empty_text_two: 'הרשימה כרגע ריקה.', + menu_main: 'ראשי', + menu_movies: 'סרטים', + menu_tv: 'סדרה', + menu_catalog: 'קטלוג', + menu_filter: 'סנון', + menu_collections: 'קולקציות', + menu_relises: 'השקה', + menu_anime: 'אנימה', + menu_bookmark: 'סימניות', + menu_like: 'ליק', + menu_time: 'אחר כך.', + menu_history: 'היסטוריה', + menu_timeline: 'לוח זמנים', + menu_torrents: 'טורנטים', + menu_settings: 'הגדרות', + menu_about: 'מידע', + menu_console: 'קונסולה', + menu_multmovie: 'סרטים מצוירים', + menu_multtv: 'סדרות משופשפות', + plugins_catalog_work: 'תוספים עבודה', + plugins_catalog_work_descr: 'תוספים שעובדים בדיוק במנורה.', + plugins_catalog_popular: 'תוספים פופולריים בין המשתמשים', + plugins_catalog_popular_descr: 'התקנה ממקורות לא ידועים עלולה לגרום ליישום לעבוד בצורה שגויה.', + plugins_online: 'תצוגה מקוונת', + plugins_check_fail: 'אין אפשרות לבדוק את הפונקציונליות של התוסף. עם זאת, אין זה אומר שהתוסף לא עובד. טען מחדש את היישום כדי לראות אם התוסף נטען.', + plugins_need_reload: 'כדי להפעיל את התוסף, עליך להפעיל מחדש את היישום', + plugins_install: 'התקן', + plugins_install_ready: 'תוסף זה כבר מותקן.', + plugins_installed: 'התקנה', + plugins_load_from: ' CUB טעינה מ', + plugins_ok_for_check: 'לחץ (OK) כדי לבדוק את התוסף', + plugins_no_loaded: 'בעת טעינת היישום, לא ניתן היה לטעון כמה תוספים', + time_viewed: 'צפייה', + time_from: 'מ', + time_reset: 'אפס את קוד הזמן', + settings_clear_cache: 'מטמון ונתונים פונו', + settings_user_links: 'קישור מותאם אישית', + settings_for_local: 'עבור TorrServer המקומי', + settings_add: 'הוסף', + settings_remove: 'מחק', + settings_this_value: 'ערך נוכחי', + settings_added: 'הוסף', + settings_removed: 'הוסר', + settings_param_player_inner: 'IL', + settings_param_player_outside: 'חיצוני', + settings_param_player_inner_tvos: 'פנימי', + settings_param_yes: 'כן', + settings_param_no: 'לא', + settings_param_interface_size_small: 'קטן', + settings_param_interface_size_normal: 'רגיל', + settings_param_interface_size_bigger: 'עוד', + settings_param_poster_quality_low: 'נמוך', + settings_param_poster_quality_average: 'ממוצע', + settings_param_poster_quality_high: 'גבוה', + settings_param_parse_directly: 'ישירות', + settings_param_parse_api: 'באמצעות אתר האינטרנט API', + settings_param_background_complex: 'מורכב', + settings_param_background_simple: 'פשוט', + settings_param_background_image: 'תמונה', + settings_param_link_use_one: 'ראשי', + settings_param_link_use_two: 'נוסף', + settings_param_link_use_both: 'שניהם', + settings_param_subtitles_size_small: 'קטן', + settings_param_subtitles_size_normal: 'רגיל', + settings_param_subtitles_size_bigger: 'גדול', + settings_param_screensaver_nature: 'טבע', + settings_param_torrent_lang_orig: 'מקורי', + settings_param_torrent_lang_ru: 'רוסיתName', + settings_param_player_timecode_again: 'התחל מחדש', + settings_param_player_timecode_continue: 'המשך', + settings_param_player_timecode_ask: 'לשאול', + settings_param_player_scale_method: 'חישוב', + settings_param_player_hls_app: 'מערכתי', + settings_param_player_hls_js: 'תוכנית', + settings_param_card_view_load: 'העלה', + settings_param_card_view_all: 'הצג הכל', + settings_param_navigation_remote: 'בקר מרוחק', + settings_param_navigation_mouse: 'שלט רחוק עם עכבר', + settings_param_keyboard_lampa: 'IL', + settings_param_keyboard_system: 'מערכתי', + helper_keyboard: 'לאחר הזנת הערך, לחץ על כפתור "החזרה" כדי לשמור', + helper_torrents: 'החזק את המפתח (OK) כדי להעלות את תפריט ההקשר', + helper_cleared: 'הצלחה, קצות הכלים יוצגו שוב.', + helper_torrents_view: 'החזק את מקש (OK) כדי לאפס את קוד הזמן ולהציג את התפריט', + fav_sync_title: 'סינכרון סימניות', + fav_sync_text: '', + fav_sync_site: 'אתר אינטרנט', + fav_remove_title: 'הסר מההיסטוריה', + fav_remove_descr: 'מחק את הכרטיס הנבחר', + fav_clear_title: 'נקה את ההיסטוריה', + fav_clear_descr: 'מחק את כל הקלפים מההיסטוריה', + fav_clear_label_title: 'נקה תוויות', + fav_clear_label_descr: 'נקה תגיות תצוגה', + fav_clear_time_title: 'נקה צירי זמן', + fav_clear_time_descr: 'נקה את כל קודי הזמן', + fav_label_cleared: 'מסמנים נמחקו', + fav_time_cleared: 'לוח זמנים פנוי', + timetable_empty: 'סעיף זה יציג את תאריכי השחרור של פרקים חדשים.', + player_quality: 'איכות', + player_flow: 'זְרִימָה', + player_tracks: 'רצועות שמע', + player_disabled: 'לא פעיל', + player_unknown: 'לא ידוע', + player_subs: 'כתוביות', + player_size_default_title: 'ברירת מחדל', + player_size_default_descr: 'גודל וידאו ברירת מחדל', + player_size_cover_title: 'הרחב', + player_size_cover_descr: 'הרחב את הווידאו למסך מלא', + player_size_fill_title: 'מלא', + player_size_fill_descr: 'התאם את הווידאו למסך מלא', + player_size_s115_title: 'זום 115%.', + player_size_s115_descr: 'הגדל את הווידאו ב-115%.', + player_size_s130_title: 'התקרבות 130%', + player_size_s130_descr: 'הגדל את הווידאו ב-130%', + player_size_v115_title: 'אנכי 115%', + player_size_v115_descr: 'הגדל את הווידאו ב-115%.', + player_size_v130_title: 'אנכי 130%', + player_size_v130_descr: 'הגדל את הווידאו ב-130%', + player_video_size: 'גודל וידאו', + player_playlist: 'רשימת השמעה', + player_error_one: 'אין אפשרות לפענח את הווידאו', + player_error_two: 'וידאו לא נמצא או פגום', + player_start_from: 'המשך לעיין מ', + player_not_found: 'נגן לא נמצא', + player_lauch: 'השקת נגן', + player_speed_default_title: 'רגיל', + player_speed_two_descr: 'נגן ללא קול', + player_video_speed: 'Playback מהירות', + player_share_title: 'שתף', + player_share_descr: 'נגן את הווידאו הזה במכשיר אחר', + player_normalization_power_title: 'כוח הנורמליזציה', + player_normalization_smooth_title: 'מהירות הנורמליזציה', + player_normalization_step_low: 'נמוך', + player_normalization_step_medium: 'ממוצע', + player_normalization_step_hight: 'גבוה', + player_youtube_no_played: 'מצטערים, וידאו זה אינו זמין באזור שלך ואולי נחסם או הוסר', + player_youtube_start_play: 'כדי להתחיל לנגן את הוידאו, לחץ על כפתור ה"נגן', + broadcast_open: 'פתח כרטיס על התקן אחר', + broadcast_play: 'בחר את ההתקן שיש לצפות בו', + card_new_episode: 'סדרה חדשה', + card_book_remove: 'הסרת סימניות', + card_book_add: 'סימניות', + card_book_descr: 'חפש בתפריט (סימני קריאה)', + card_like_remove: 'הסר מהמועדפים', + card_like_add: 'כמו', + card_like_descr: 'תסתכל בתפריט (כמו)', + card_wath_remove: 'הסר מהמצופה', + card_wath_add: 'צפה מאוחר יותר', + card_wath_descr: 'ראה תפריט (מאוחר יותר)', + card_history_remove: 'הסר מההיסטוריה', + card_history_add: 'לתוך ההיסטוריה.', + card_history_descr: 'חפש בתפריט (היסטוריה)', + keyboard_listen: '', + keyboard_nomic: 'אין גישה למיקרופון', + notice_new_quality: 'איכות חדשה זמינה', + notice_quality: 'איכות', + notice_new_episode: 'סדרה חדשה', + notice_none: '', + notice_in_quality: 'כ', + notice_none_account: '', + notice_none_system: 'כרגע אין לך הודעות, אנו נודיע לך כשההודעות החדשות יהיו זמינות.', + copy_link: 'העתק קישור וידאו', + copy_secuses: 'קישור הועתק ללוח העריכה', + copy_error: 'שגיאה בהעתקת קישור', + account_sync_to_profile: 'כל הסימניות יועברו לפרופיל', + account_sync_secuses: 'כל הסימניות הועברו בהצלחה', + account_profiles: 'פרופילים', + account_profiles_empty: 'אין אפשרות לקבל רשימה של פרופילים', + account_authorized: 'מאושר', + account_logged_in: 'אתה מחובר', + account_login_failed: 'התחברות נכשלה', + account_login_wait: 'ממתין לכניסה', + account_profile_main: 'כללי', + account_export_secuses: 'ייצוא הושלם בהצלחה', + account_export_fail: 'שגיאה בייצוא', + account_import_secuses: 'ייבוא הושלם בהצלחה', + account_import_fail: 'שגיאה ביבוא', + account_imported: 'מיובא', + account_reload_after: 'אתחל אחרי 5 שניות.', + account_create: '', + account_premium: 'פתחו אופקים חדשים עם חשבון CUB Premium! תיהנו ממגבלות מוגדלות ופונקציונליות שירות משופרת. בקרו באתר ולמדו עוד על היתרונות של חשבון פרימיום.', + account_premium_more: 'למד עוד על CUB Premium', + account_limited: '', + account_code_enter: 'הזן קוד בעל שש ספרות', + account_code_error: 'אולי הכנסת קוד שגוי או מיושן', + account_code_wrong: 'אולי נכנסת לפורמט שגוי.', + account_code_where: '"', + account_code_input: 'הכנס קוד', + settings_cub_signin_button: 'לחצן כניסה', + network_noconnect: 'אין חיבור לרשת', + network_404: '[404] העמוד המבוקש לא נמצא', + network_401: 'ההרשאה נכשלה', + network_500: 'שגיאה בשרת פנימי.', + network_parsererror: 'JSON parsing הבקשה נכשלה ל', + network_timeout: 'הבקשה הסתיימה.', + network_abort: 'הבקשה בוטלה.', + network_error: 'שגיאה לא ידועה', + size_zero: 'בית 0', + size_byte: 'בית', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'שחפת', + size_pp: 'PBName', + speed_bit: 'קצת', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbit', + speed_tb: 'סיביות', + speed_pp: 'Pbit', + month_1: 'ינואר', + month_2: 'פברואר', + month_3: 'מרץ', + month_4: 'אפריל', + month_5: 'מאי', + month_6: 'יוני', + month_7: 'יולי', + month_8: 'אוגוסט', + month_9: 'ספטמבר', + month_10: 'אוקטובר', + month_11: 'נובמבר', + month_12: 'דצמבר', + day_1: 'יום שני', + day_2: 'יום שלישי', + day_3: 'יום רביעי', + day_4: 'יום חמישי', + day_5: 'יום שישי', + day_6: 'שבת', + day_7: 'יום ראשון', + month_1_e: 'ינואר', + month_2_e: 'פברואר', + month_3_e: 'מרץ', + month_4_e: 'אפריל', + month_5_e: 'מאי', + month_6_e: 'יוני', + month_7_e: 'יולי', + month_8_e: 'אוגוסט', + month_9_e: 'ספטמבר', + month_10_e: 'אוקטובר', + month_11_e: 'נובמבר', + month_12_e: 'דצמבר', + week_1: 'שני', + week_2: 'שלישי', + week_3: 'רביעי', + week_4: 'חמישי', + week_5: 'שישי', + week_6: 'שבת', + week_7: 'ראשון', + extensions_enable: 'להדליק', + extensions_disable: 'כבה', + extensions_check: 'לבדוק מצב', + extensions_install: 'להתקין', + extensions_info: 'מידע', + extensions_edit: 'ערוך', + extensions_change_name: 'שנה שם', + extensions_change_link: 'שנה קישור', + extensions_remove: 'למחוק', + extensions_set_name: 'הזן את שם הפלאגין', + extensions_set_url: 'הזן את כתובת האתר של התוסף', + extensions_ready: 'תוסף זה כבר מותקן', + extensions_no_info: 'ללא מידע', + extensions_no_name: 'ללא כותרת', + extensions_worked: 'עובד', + extensions_no_plugin: 'הפלאגין לא מאומת', + extensions_add: 'הוסף פלאגין', + extensions_from_memory: 'מותקן בזיכרון', + extensions_from_cub: 'CUB מותקן מ', + extensions_from_popular: 'תוספים פופולריים', + extensions_from_lib: 'ספריית פלאגין', + extensions_from_connected: 'תוספים מחוברים', + settings_webos_launcher: 'השקת אפליקציה', + settings_webos_launcher_add_device: 'התקן כאפליקציה למתחילים', + settings_webos_launcher_remove_device: 'הסר מיישומי הפעלה', + player_normalization: 'נורמליזציה', + change_source_on_cub: 'CUB שנה מקור ל', + settings_param_jackett_interview_all: 'הכול', + settings_param_jackett_interview_healthy: 'זמין בלבד', + settings_parser_jackett_interview: 'עוקבי סקרים', + title_ongoing: 'מתמשכים', + title_pgrating: 'הגבלת גיל', + settings_interface_card_interfice: 'כרטיס', + settings_interface_card_poster: 'הצג פוסטר', + title_card: 'כרטיס', + settings_param_card_interface_old: 'ישן', + settings_param_card_interface_new: 'חדש', + title_seasons: 'עונות', + title_episodes: 'פרקים', + title_rewiews: 'ביקורות', + settings_interface_glass: 'זכוכית', + settings_interface_glass_descr: 'הצג ממשק בסגנון זכוכית', + settings_interface_black_style: 'סטייל שחור', + plugins_remove: 'הסר תוספים', + plugins_add_success: 'התוסף מחובר בהצלחה', + settings_reset: 'איפוס', + title_channel: 'ערוץ', + input_detection_touch: '? רוצה לעבור לבקרת מגע', + input_detection_mouse: '? רוצה לעבור לשליטה בעכבר', + input_detection_remote: '? רוצים לעבור לשלט רחוק', + settings_interface_hide_outside_the_screen: 'הסתר כרטיסים מחוץ למסך', + settings_interface_hide_outside_the_screen_descr: 'זה יאיץ את רינדור ממשק המשתמש וישפר את הביצועים', + https_text: 'אתה משתמש בפרוטוקול HTTPS, בפרוטוקול זה המנורה אינה פועלת כהלכה. להפעלה נכונה של המנורה, השתמש בכתובת עם פרוטוקול HTTP', + extensions_hpu_best: 'פופולרי', + extensions_hpu_recomend: 'מומלץ', + extensions_hpu_theme: 'ערכות נושא', + extensions_hpu_screensaver: 'שומר מסך', + extensions_hpu_video: 'וידאו', + extensions_hpu_control: 'שליטה', + extensions_hpu_other: 'מגוון', + extensions_hpu_: 'אחר', + title_author: 'מחבר', + title_buffer: 'מאגר', + settings_rest_screensaver_time: 'לאחר כמה דקות להפעיל את שומר המסך', + time_h: 'ש.', + time_m: 'מ.', + time_s: 'ש.', + settings_param_glass_easy: 'שקוף', + settings_param_glass_medium: 'שקוף למחצה', + settings_param_glass_blacked: 'מושחר', + settings_interface_glass_opacity: 'שקיפות זכוכית', + torrent_error_check_no_auth: 'השרת הגיב לבקשה, אך ההרשאה נכשלה', + settings_interface_card_cover: 'הצג את העטיפה', + title_upcoming_episodes: 'שיחרור פרקים קרובים', + title_recent_episodes: 'שחרורי פרקים אחרונים', + settings_rest_cache_images: 'מטמון תמונה', + settings_rest_cache_images_descr: 'שמור פוסטרים ורקעים לאחסון מקומי', + settings_player_rewind_title: 'החזר לאחור', + settings_player_rewind_descr: 'מרווח החזרה לאחור בשניות', + settings_interface_card_reactions: 'הצג תגובות', + title_look: 'מחפשים', + title_scheduled: 'מתוזמנים', + title_viewed: 'נצפה', + title_thrown: 'נזרק', + title_reactions: 'תגובות', + reactions_none: 'אין תגובות', + reactions_fire: 'גדול', + reactions_nice: 'נחמד', + reactions_think: 'מעניין', + reactions_bore: 'משעמם', + reactions_shit: 'רע', + reactions_ready: 'השארת כבר תגובה', + settings_player_launch_trailers: 'נגן טריילר', + title_continued: 'המשך יבוא', + termsofuse_t_01: 'תנאי שימוש', + termsofuse_t_02: 'Lampa הוא כלי נוח לחקור את החדשות האחרונות בתעשיית הקולנוע, כולל סרטים, תוכניות טלוויזיה, קריקטורות ומידע אחר. כדי לקבל מידע על סרטים, נעשה שימוש באתר קוד פתוח, themoviedb.org', + termsofuse_t_03: 'תוכן', + termsofuse_t_04: 'Lampa משתמש ב-API (ממשק תכנות יישומים) מקטלוג themoviedb.org כדי לאחזר מידע על סרטים ותוכניות טלוויזיה, כמו גם כדי לצפות בקובצי מדיה משויכים כגון פוסטרים, טריילרים ועוד.', + termsofuse_t_05: 'ה-API של themoviedb.org מאפשר ליישום Lampa לגשת למסד נתונים של סרטים ותוכניות טלוויזיה, ומספק את היכולת לחפש ולהציג מידע על קבצי מדיה.', + termsofuse_t_06: 'האינטראקציה בין אפליקציית Lampa לבין themoviedb.org מתרחשת באמצעות בקשות API הנשלחות מאפליקציית Lampa לשרתי themoviedb.org כדי להשיג מידע וקובצי מדיה. Themoviedb.org מעבד את הבקשות ושולח את הנתונים המבוקשים בחזרה לאפליקציית Lampa', + termsofuse_t_07: 'כך, הודות לשימוש ב-API themoviedb.org, אפליקציית Lampa מספקת למשתמשים גישה למאגר נרחב של סרטים ותוכניות טלוויזיה, תוך עמידה בתנאי השימוש וההגבלות שנקבעו על ידי בעל הזכויות.', + termsofuse_t_08: 'הרחבות', + termsofuse_t_09: 'הרחבות הן כלי רב עוצמה המסופק לאפליקציית Lampa, המאפשרת למשתמשים לשפר את היכולות שלה, להוסיף פונקציונליות נוספת ולשנות תוכן בהתאם לצרכיהם.', + termsofuse_t_10: 'עם זאת, יש לציין שמשתמשים מתקינים תוספים על אחריותם בלבד. כל ההשלכות הנובעות מהשימוש בהרחבות הן באחריות המשתמש. מומלץ למשתמשים לנקוט משנה זהירות בעת התקנה ושימוש בתוספים, תוך הערכה קפדנית של מהימנותם ואבטחתם.', + termsofuse_t_11: 'הפרות זכויות יוצרים', + termsofuse_t_12: 'אם אתה מגלה הפרת זכויות יוצרים באפליקציית Lampa, עליך ליצור קשר עם מפתחי אפליקציית Lampa. אתה יכול להשתמש באנשי הקשר שסופקו באפליקציית Lampa כדי לעשות זאת. עם זאת, חשוב לציין שאפליקציית Lampa משתמשת ב-API מקטלוג themoviedb.org, המספק גישה פתוחה למידע על סרטים ותוכניות טלוויזיה. המשמעות היא שהמידע המוצג באפליקציית Lampa זמין לציבור ואינו מפר זכויות יוצרים.', + termsofuse_t_13: 'אם אתה סבור שאפליקציית Lampa עדיין מכילה תוכן המפר את זכויות היוצרים שלך, תוכל לפנות לבעל הזכויות של תוכן זה ולבקש את הסרתו מאתר themoviedb.org. בתורו, אפליקציית Lampa יכולה להסיר תוכן עם קבלת הודעה מתאימה על הפרת זכויות יוצרים.', + premiere_author_recomend_1: 'הזמינו פיצה והתכוננו לנסיעה.', + premiere_author_recomend_2: 'המסיבה רק מתחילה.', + premiere_author_recomend_3: 'תתכוננו לאדרנלין.', + premiere_author_recomend_4: 'מוכנים לערב בלתי נשכח?', + premiere_author_recomend_5: 'אני ממליץ לצפות.', + premiere_title: 'הקרנת בכורה', + settings_clear_cache_only: 'זיכרון מטמון נקי', + settings_rest_cache_only: 'רק זיכרון מטמון', + settings_rest_cache_only_descr: 'הגדרות בסיסיות יישמרו', + settings_rest_cache_all: 'זיכרון מטמון ונתונים', + settings_rest_cache_all_descr: 'כל הגדרות והנתונים יימחקו', + title_left:'שמאלה', + settings_rest_cache_calculate: 'כמה זיכרון נשאר', + account_export_fail_500: 'שגיאה לא ידועה', + account_export_fail_610: 'חרגת מהגבלה של היום', + account_export_fail_200: 'שגיאת בסיס נתונים, אנא נסו שוב מאוחר יותר', + account_export_fail_600: 'שגיאה, כשל בהעלאת הקובץ', + account_export_fail_620: 'שגיאה, הקובץ לא הועבר', + + title_parental_control: 'שליטה הורית', + settings_parental_control_param_time_always: 'תמיד', + settings_parental_control_param_time_once: 'פעם אחת', + settings_parental_control_param_time_10: 'בעוד 10 דקות', + settings_parental_control_param_time_20: 'בעוד 20 דקות', + settings_parental_control_param_time_30: 'בעוד 30 דקות', + settings_parental_control_param_time_60: 'בעוד שעה', + settings_parental_control_param_time_120: 'בעוד 2 שעות', + settings_parental_control_change_pin: 'שנה קוד PIN', + settings_parental_control_demand_title: 'מתי לבקש', + settings_parental_control_demand_descr: 'בעוד כמה זמן לבקש את קוד ה-PIN', + settings_parental_control_enabled: 'מופעל', + settings_parental_control_disabled: 'מנוטרל', + parental_control_input_new_code: 'הזן קוד PIN חדש', + parental_control_confirm_new_code: 'אשר קוד PIN', + parental_control_no_match_code: 'קוד PIN אינו תואם לקוד הקודם', + parental_control_input_code: 'הזן קוד PIN', + parental_control_input_error: 'הזנת קוד PIN שגוי', + title_worth_rewatch: 'שווה צפייה חוזרת', + + ad_disable: 'על ידי הרשמה ל-CUB Premium, תשכח מפרסום.', + ad_after: 'פרסום באמצעות', + ad: 'פִּרסוּם', + ad_skip: 'לדלג', + ad_continue_after: 'הצפייה תתחיל בעוד', + settings_parser_prowlarr_link_descr: 'ספק קישור לשרת Prowlarr', + settings_parser_prowlarr_key_descr: 'ממוקם בלשונית הגדרות Prowlarr בקטגוריה הכללית', + settings_player_torrent_type: 'סוג נגן עבור טורנטים', + settings_player_torrent_type_descr: 'באיזה שחקן לשחק טורנטים', + + full_crew: 'עוד', + full_editing: 'עריכה', + full_creator: 'יוצר', + player_normalization_step_none: 'אֶפֶס', + + settings_cub_backup_export_descr: 'שמור הגדרות בענן', + settings_cub_backup_import_descr: 'שחזר הגדרות מהענן', + + settings_interface_sound: 'צלילי מערכת', + settings_interface_sound_play: 'מעברים', + settings_interface_sound_level: 'רמת עוצמת הקול', + settings_interface_advanced_animation: 'אנימציה מתקדמת', + + confirm_open_player: 'מכשיר אחר מבקש גישה לנגן. רוצה להפעיל את הסרטון?', + + pincode_use_remote: 'השתמש בשלט הרחוק כדי להזין את הקוד, לחץ על החצים כדי לבחור את המספר הרצוי.', + pincode_use_toggle: 'לחץ והחזק את הלחצן אישור כדי לשנות את הפריסה.', + + settings_parental_control_where: 'היכן לבקש קוד PIN', + title_fire: 'אֵשׁ!', + title_top_100: '100 המובילים', + + player_normalization_type_title: 'סוג נירמול', + player_normalization_type_all: 'הכל', + player_normalization_type_up: 'רק הגבהה', + player_normalization_type_down: 'רק הנמכה', + storage_quota_exceeded: 'מכסת האחסון חרגה. נקה את המטמון ונסה שוב.', + settings_cub_domain: 'דומיין ראשי', + + title_ai_assistant: 'עוזר AI', + title_facts: 'עובדות מעניינות', + ai_search_start_typing: 'שאלו את עוזר ה-AI אילו סרטים אתם רוצים למצוא. למשל: "סרטים על חלל"', + ai_search_limit: 'חרגת ממגבלת הבקשות. נסה שוב מאוחר יותר. עם מנוי CUB Premium המגבלות יגדלו ולא תצטרך להמתין!', + ai_subscribe_title: 'פתחו אפשרויות נוספות עם AI', + ai_subscribe_descr: 'עשו מנוי ל-CUB Premium והגדילו את מספר הבקשות ל-AI. יחד עם AI נמצא עבורכם את הסרטים הטובים ביותר שאפשר.', + + dmca_title: 'תוכן חסום', + dmca_descr: 'חומר זה אינו זמין לצפייה. הוא נחסם לבקשת בעל זכויות היוצרים בהתאם לחוק זכויות היוצרים.', + + loading_progress_step_0: 'הכנה', + loading_progress_step_1: 'טעינת שפות', + loading_progress_step_2: 'חיפוש מראות', + loading_progress_step_3: 'הכנת הרחבות', + loading_progress_step_4: 'כמעט סיימנו', + loading_progress_step_5: 'ממש בקרוב', + + install_extension_rule_1: 'התקנת תוסף צד שלישי', + install_extension_rule_2: 'תוספים נוצרים על ידי מפתחים עצמאיים, ו-LAMPA אינה בודקת את תוכנם. על ידי התקנתם, אתה מסכים כי:', + install_extension_rule_3: '- חלק מהתוספים עשויים לבקש גישה לנתונים שלך או לעבוד עם מקורות לא מאומתים.', + install_extension_rule_4: '- אם התוסף שהתקנת מפר זכויות יוצרים או חוקים אחרים, האחריות המלאה על השימוש בו חלה עליך.', + install_extension_rule_5: '- התקן תוספים רק ממקורות מהימנים. אם יש לך ספקות לגבי אבטחתו או חוקיותו של תוסף, עדיף להימנע מהתקנתו.', + install_extension_rule_6: 'LAMPA אינה תומכת ואינה מאשרת תוספים הקשורים לתוכן פיראטי.', + install_extension_rule_7: 'בהמשך, אתה מאשר שאתה מבין את הסיכונים הללו.', + ad_plugin: 'פרסומת מהתוסף', + terminal_title: 'טרמינל', + terminal_no_access: 'אין גישה', + terminal_confirm: 'לאפשר', + terminal_deny: 'לסרב', + terminal_update: 'לעדכן', + terminal_code: 'קוד גישה', + terminal_text: 'אתה מבקש גישה לטרמינל. מפתחים עשויים לקבל גישה למכשיר שלך ולשלוט בו. זה יכול להיות שימושי לאבחון ופתרון בעיות, אך גם עלול להוות סיכון אבטחה. ודא שאתה סומך על המפתחים לפני מתן גישה.

    באפשרותך להשבית תכונה זו בכל עת על ידי לחיצה על כפתור "לסרב".', + + title_anons: 'הודעה', + title_developer: 'מפתח', + title_navigation: 'ניווט', + title_page: 'עמוד', + title_person_about: 'על', + account_qr_premium: 'סרקו את קוד ה-QR כדי ללמוד עוד על CUB Premium', + account_qr_code: 'סרקו את קוד ה-QR כדי לקבל קוד לקישור המכשיר', + account_qr_create: 'סרקו את קוד ה-QR כדי ליצור חשבון', + account_add_device_title: 'הוספת מכשיר', + account_add_device_text: 'גשו אל כדי לקבל קוד להוספת המכשיר.', + account_none_title: 'עדיין אין לכם חשבון?', + account_none_include_1: 'סימניות והיסטוריית צפייה נשמרות בענן', + account_none_include_2: 'סנכרון בין מכשירים', + account_none_include_3: 'התראות על פרקים חדשים והוצאות חדשות', + account_none_include_4: 'צרו מספר פרופילים תחת חשבון אחד', + account_premium_include_1: 'מספר מוגדל של סימניות', + account_premium_include_2: 'היסטוריית צפייה מורחבת', + account_premium_include_3: 'יותר סימוני זמן זמינים', + account_premium_include_4: 'מספר פרופילים לחשבון', + empty_subscribes_title: 'המנויים שלכם לתרגומים', + empty_subscribes_text: 'פשוט הירשמו לתרגום המועדף עליכם ונודיע לכם כשיצא פרק חדש.', + empty_history_title: 'היסטוריית הצפייה שלכם', + empty_history_text: 'היסטוריית הצפייה שלכם תופיע כאן.', + empty_bookmark_title: 'המועדפים שלכם', + empty_bookmark_text: 'הוסיפו סרטים וסדרות שאהבתם למועדפים כדי למצוא אותם במהירות בחלק זה.', + empty_mytorrents_title: 'הטורנטים שלכם', + empty_mytorrents_text: 'הטורנטים שהורדו דרך TorServer יופיעו כאן.', + developer_param_enabled: 'מצב מפתח', + developer_param_nopremium: 'השבת CUB Premium', + developer_param_nodemo: 'השבת מצב הדגמה', + developer_param_ads: 'הצג פרסומות', + developer_param_fps: 'הצג FPS', + developer_trigger_help_1: 'כמעט ניחשתם :)', + developer_trigger_help_2: 'עוד קצת :)', + developer_trigger_help_3: 'האם אתם בטוחים שברצונכם להיכנס למצב מפתח?', + developer_trigger_help_4: 'מצב מפתח הופעל', + settings_param_navigation_touch: 'מגע', + account_discuss_add_qr: 'סרקו את קוד ה-QR', + account_discuss_add_title: 'רוצים להשאיר תגובה?', + account_discuss_add_text: 'סרקו את קוד ה-QR כדי לעבור לאפליקציה ולהוסיף תגובה לסרט או לסדרה הזו.

    - קחו את הטלפון או הטאבלט שלכם
    - פתחו את המצלמה
    - כוונו אל קוד ה-QR
    - עקבו אחרי הקישור שמופיע על המסך', + account_discuss_added: 'תודה על תגובתכם!', + account_discuss_added_ready: 'כבר השארתם תגובה לסרט או לסדרה הזו.', + remote_helper_long: 'החזיקו את הכפתור (OK) כדי לפתוח את התפריט', + account_premium: 'פתחו אופקים חדשים עם חשבון CUB Premium! תהנו ממגבלות מוגדלות ומפונקציות משופרות. בקרו ב- למידע נוסף על יתרונות החשבון הפרימיום.', + player_segments_title: 'קטעים', + player_segments_descr: 'דלגו על פתיח וחלקים אחרים של הסרטון', + player_segments_ad_title: 'פרסומות', + player_segments_skip_title: 'פתיח ואחרים', + player_segments_value_none: 'אל תדלג', + player_segments_value_auto: 'דלג אוטומטית', + player_segments_value_user: 'מותאם אישית', + player_segments_skiped: 'קטע דולג', + player_segments_skip_now: 'דלג', + player_segments_skip_in: 'דילוג בעוד', + player_segments_skip_intro: 'דלג על הפתיח', + player_segments_next: 'הפרק הבא', + player_segments_next_in: 'הפרק הבא בעוד', + subscribe_info: 'בקטע "מנויים" תוכלו לראות את כל מנויי התרגום שלכם. תקבלו התראה כאשר יצא פרק חדש עם התרגום שבחרתם.', + no_watch_history: 'אין היסטוריית גלישה', + + settings_request_caching_use: 'שימוש במטמון לבקשות', + settings_request_caching_descr: 'שמור תשובות לבקשות נפוצות במטמון כדי להאיץ את העבודה', + + account_profile_child: 'ילד', + account_profile_add: 'הוספת פרופיל', + account_profile_name: 'שם הפרופיל', + account_profile_created: 'הפרופיל נוצר בהצלחה', + account_profile_limited: 'הגעת למגבלת הפרופיל המקסימלית: {count}', + account_profile_info: 'באפשרותך לנהל פרופילים בהגדרות החשבון שלך. לשם כך, עבור אל ', + player_youtube_no_support: 'המכשיר שלך אינו תומך בניגון וידאו של YouTube, בדוק את חיבור האינטרנט שלך.', + title_channels: 'ערוצים', + title_best_of: 'הכי טוב של', + title_comedy_of: 'קומדיות של', + title_best_of_2000: 'שנות ה-2000 המוזהבות', + title_best_of_2010: 'להיטי שנות ה-2010', + title_best_of_2015: 'קלאסיקות מודרניות', + title_comedy_of_2000: 'צחוק שנות ה-2000', + title_comedy_of_2010: 'הומור שנות ה-2010', + title_comedy_of_2015: 'קומדיות מודרניות', + + filter_keyword_sequel: 'המשך', + filter_keyword_based_comic: 'מבוסס על קומיקס', + filter_keyword_space: 'חלל', + filter_keyword_survival: 'הישרדות', + filter_keyword_zombie: 'זומבי', + filter_keyword_school: 'בית ספר', + filter_keyword_revenge: 'נקמה', + filter_keyword_detective: 'בלש', + filter_keyword_robots: 'רובוטים', + filter_keyword_vampires: 'ערפדים', + filter_keyword_aliens: 'חייזרים', + filter_keyword_police: 'משטרה', + filter_keyword_reincarnation: 'גלגול נשמות', + filter_keyword_spy: 'מרגל', + filter_keyword_disaster: 'קטסטרופה', + filter_keyword_christmas: 'חג המולד', + + install_app_apk_title: 'כיצד להתקין את Lampa באנדרואיד', + install_app_apk_text: 'שמנו לב שאתה משתמש ב-MediaStationX כדי להפעיל את Lampa באנדרואיד. אנו ממליצים להתקין את Lampa כאפליקציית APK. זה יבטיח פעולה יציבה יותר וגישה לכל תכונות האפליקציה.

    עבור לקבוצת הטלגרם כדי להוריד את ה-APK והוראות ההתקנה העדכניות ביותר.', + install_app_apk_qr: 'סרוק את קוד ה-QR כדי להוריד את ה-APK של Lampa', + copy_link_buffer: 'העתק קישור', + + dmca_title_lgbt: 'התוכן מוגבל', + dmca_descr_lgbt: 'הצפייה אינה זמינה באזור שלך מכיוון שהיא עשויה להכיל תוכן להט"בי. חומר כזה עשוי להיות אסור או מוגבל במדינות מסוימות.', + + settings_lgbt_content_block: 'חסימת תוכן להט"בי', + + // todo: + adult_content_title: 'תוכן למבוגרים', + adult_content_text_warning: 'התוכן עשוי להכיל חומר למבוגרים שעלול להיות בלתי הולם לחלק מהצופים.', + adult_content_text_modal: 'סרט או סדרה זו מסומנים כמכילים תוכן למבוגרים. עליך להיות בן 18 ומעלה כדי לצפות בחומר זה. אנא אשר שהגעת לגיל החוקי כדי להמשיך לצפות.', + + adult_content_confirm: 'אני בן 18 ומעלה', + adult_content_deny: 'אני מתחת לגיל 18', + + inner_player_disclaimer_title: 'הצהרת נגן', + inner_player_disclaimer_text: 'אני מבין שאני מפעיל נגן עם תמיכה חלקית, ואני מבין שזה עלול לגרום להתנהגות לא טיפוסית במכשיר. מומלץ לעבור לנגנים ממשפחת tvOS או לחלופות אחרות.', + + inner_player_disclaimer_change_player: 'החלף נגן', + remote_configuration_settings_title: 'הגדרה מרחוק', + remote_configuration_registration_text: 'ההגדרה מרחוק מספקת גישה זמנית לאפליקציה שלך, אפליקציה אחרת תוכל להתקין הרחבות ולהגדיר פרמטרים.', + remote_configuration_waite_text: 'כעת תוכל להעביר קוד זה לאפליקציה אחרת כדי להעניק גישה להגדרות.', + remote_configuration_open_button: 'פתח גישה', + remote_configuration_code_life: 'הקוד בתוקף', + remote_configuration_notice_nocode: 'נכשל בפתיחת הגישה', + + settings_server_gts: 'קידוד מחדש', + settings_server_gts_descr: 'המרה אוטומטית של וידאו לפורמט תואם בעת הצורך.', + settings_server_tracktimecode: 'הפעל את TrackTimecode', + settings_server_tracktimecode_descr: 'שומר את התקדמות הצפייה בסרטים ובסדרות בשרת TorrServer. כדי שהאפשרות תפעל, יש להפעיל אותה גם ב-TorrServer.', + + title_metadata: 'מטא-נתונים', + title_moods: 'מצבי רוח', + title_meta_violence: 'אלימות', + title_meta_fear: 'פחד', + title_meta_profanity: 'שפה', + title_meta_sadness: 'עצב', + title_meta_sex: 'מיניות', + player_pip: 'מזעור', + player_volume: 'עוצמת קול', + player_time_end: 'מסתיים ב', + player_ai_agent_info: 'רוצה לדעת יותר על הסרטון? שאל את עוזר ה-AI והוא יספק לך תרשים מצבי רוח, תקציר עלילה קצר ורגעים מעניינים.', + player_ai_agent_ask_plot: 'תקציר עלילה', + player_ai_agent_ask_moods: 'הצג תרשים', + player_ai_agent_ask_highlights: 'רגעים מעניינים', + player_ai_agent_ask: 'שאל', + player_ai_agent_processing: 'מנתח...', + player_ai_agent_no_data: 'אין נתונים להצגה.', + player_ai_agent_no_analysis: 'לא ניתן לנתח את הסרטון.', + player_ai_agent_quota: 'מגבלת הבקשות חרגה. אנא נסה שוב מאוחר יותר.', + player_ai_agent_working: 'עדיין עובד על זה...', + title_meta_humor: 'הומור', + title_meta_tension: 'מתח', + title_meta_romance: 'רומנטיקה', + title_meta_pace: 'קצב', + title_meta_importance: 'סצנות מפתח', + title_meta_action: 'אקשן' +} diff --git a/lampa-main/lang/meta.js b/lampa-main/lang/meta.js new file mode 100644 index 0000000..791ca77 --- /dev/null +++ b/lampa-main/lang/meta.js @@ -0,0 +1,95 @@ +export default { + languages: { + ru: { + code: 'ru', + name: 'Русский', + + lang_choice_title: 'Добро пожаловать', + lang_choice_subtitle: 'Выберите свой язык', + }, + en: { + code: 'en', + name: 'English', + + lang_choice_title: 'Welcome', + lang_choice_subtitle: 'Choose your language', + }, + uk: { + code: 'uk', + name: 'Українська', + + lang_choice_title: 'Ласкаво просимо', + lang_choice_subtitle: 'Виберіть мову', + }, + be: { + code: 'be', + name: 'Беларуская', + + lang_choice_title: 'Сардэчна запрашаем', + lang_choice_subtitle: 'Выберыце сваю мову', + }, + zh: { + code: 'zh', + name: '简体中文', + + lang_choice_title: '欢迎', + lang_choice_subtitle: '选择你的语言', + }, + pt: { + code: 'pt', + name: 'Português', + + lang_choice_title: 'Bem-vindo', + lang_choice_subtitle: 'Escolhe o teu idioma', + }, + bg: { + code: 'bg', + name: 'Български', + + lang_choice_title: 'Здравейте', + lang_choice_subtitle: 'Изберете вашият език', + }, + he: { + code: 'he', + name: 'עִברִית', + + lang_choice_title: 'ברוך הבא', + lang_choice_subtitle: 'בחר את השפה שלך', + }, + cs: { + code: "cs", + name: "Čeština", + + lang_choice_title: "Vítejte", + lang_choice_subtitle: "Vyberte svůj jazyk", + }, + ro: { + code: "ro", + name: "Română", + + lang_choice_title: "Bun venit", + lang_choice_subtitle: "Alegeți limba", + }, + fr: { + code: 'fr', + name: 'Français', + + lang_choice_title: 'Bienvenue', + lang_choice_subtitle: 'Choisissez votre langue', + }, + pl: { + code: "pl", + name: "Polski", + + lang_choice_title: "Witamy", + lang_choice_subtitle: "Wybierz język", + }, + es: { + code: 'es', + name: 'Español', + + lang_choice_title: 'Bienvenido', + lang_choice_subtitle: 'Elige tu idioma', + } + } +} \ No newline at end of file diff --git a/lampa-main/lang/pl.js b/lampa-main/lang/pl.js new file mode 100644 index 0000000..1a2fec1 --- /dev/null +++ b/lampa-main/lang/pl.js @@ -0,0 +1,1370 @@ +export default { + lang_choice_title: 'Witamy', + lang_choice_subtitle: 'Wybierz swój język', + + more: 'Więcej', + show_more: 'Pokaż więcej', + more_results: 'Pokaż więcej wyników', + loading: 'Ładowanie', + nofind_movie: 'Nie udało się znaleźć filmu.', + noname: 'Bez nazwy', + nochoice: 'Nie wybrano', + cancel: 'Anuluj', + confirm: 'Potwierdzam', + sure: 'Czy na pewno?', + nodata: 'Brak danych', + back: 'Wstecz', + ready: 'Gotowe', + close_app_modal: 'Czy na pewno chcesz opuścić aplikację?', + connected_seeds: 'poł.', + + search: 'Szukaj', + search_input: 'Wprowadź tekst', + search_empty: 'Historia wyszukiwania jest pusta.', + search_delete: 'Przesuń w lewo, aby usunąć', + search_start_typing: 'Zacznij wpisywać tekst, aby wyszukać.', + search_searching: 'Trwa wyszukiwanie...', + search_start: 'Rozpocznij wyszukiwanie', + search_nofound: 'Nic nie znaleziono dla podanego zapytania.', + global_search: 'Wyszukiwanie globalne', + + full_genre: 'Gatunek', + full_production: 'Produkcja', + full_date_of_release: 'Data premiery', + full_budget: 'Budżet', + full_countries: 'Kraje', + full_like: 'Lubię to', + full_torrents: 'Torrenty', + full_trailers: 'Zwiastuny', + full_detail: 'Szczegóły', + full_notext: 'Brak opisu.', + full_series_release: 'Premiera odcinków', + full_next_episode: 'Następny', + full_episode_days_left: 'Pozostało dni', + full_trailer_official: 'Oficjalny', + full_trailer_no_official: 'Nieoficjalny', + full_season: 'Sezon', + full_episode: 'Odcinek', + full_directing: 'Reżyseria', + full_writing: 'Scenariusz', + full_keywords: 'Tagi', + full_crew: 'Więcej', + full_editing: 'Montaż', + full_creator: 'Twórca', + + settings_cub_sync: 'Synchronizacja', + settings_cub_sync_descr: 'Synchronizacja z usługą CUB', + settings_cub_account: 'Konto', + settings_cub_logged_in_as: 'Zalogowano jako', + settings_cub_profile: 'Profil', + settings_cub_sync_btn: 'Synchronizuj', + settings_cub_sync_btn_descr: 'Zapisz lokalne zakładki na koncie CUB', + settings_cub_backup: 'Kopia zapasowa', + settings_cub_backup_descr: 'Zapisz lub wczytaj kopię zapasową danych', + settings_cub_logout: 'Wyloguj się', + settings_cub_signin: 'Logowanie', + settings_cub_not_specified: 'Nie określono', + settings_cub_password: 'Hasło', + settings_cub_status: 'Status', + settings_cub_backup_import: 'Import', + settings_cub_backup_export: 'Eksport', + settings_cub_backup_export_descr: 'Zapisz ustawienia w chmurze', + settings_cub_backup_import_descr: 'Przywróć ustawienia z chmury', + settings_cub_sync_filters: 'Synchronizacja filtrów', + settings_cub_sync_calendar: 'Synchronizacja kalendarza', + settings_cub_sync_quality: 'Synchronizacja oznaczeń (jakość)', + settings_cub_sync_search: 'Synchronizacja historii wyszukiwania', + settings_cub_sync_recomends: 'Synchronizacja rekomendacji', + settings_cub_sync_timecodes: 'Synchronizacja znaczników czasu', + settings_cub_signin_button: 'Zaloguj się', + settings_cub_domain: 'Domena główna', + + settings_input_links: 'Ulubione', + + settings_interface_type: 'Wersja uproszczona', + settings_interface_size: 'Rozmiar interfejsu', + settings_interface_menu_always: 'Zawsze pokazuj menu po lewej stronie', + settings_interface_background: 'Tło', + settings_interface_background_use: 'Pokaż tło', + settings_interface_background_type: 'Typ tła', + settings_interface_performance: 'Wydajność', + settings_interface_animation: 'Animacje', + settings_interface_advanced_animation: 'Zaawansowane animacje', + settings_interface_animation_descr: 'Animacje kart i treści', + settings_interface_attenuation: 'Wygaszanie', + settings_interface_attenuation_descr: 'Płynne wygaszanie kart u góry i na dole', + settings_interface_scroll: 'Typ przewijania', + settings_interface_view_card: 'Typ wyświetlania kart', + settings_interface_view_card_descr: 'Podczas przewijania karty będą ładowane stopniowo lub wszystkie naraz', + settings_interface_lang: 'Język interfejsu', + settings_interface_lang_reload: 'Należy ponownie uruchomić aplikację, naciśnij „OK”, aby zrestartować', + settings_interface_card_interfice: 'Interfejs kart', + settings_interface_card_poster: 'Pokaż plakat', + settings_interface_card_cover: 'Pokaż okładkę', + settings_interface_card_reactions: 'Pokaż reakcje', + settings_interface_glass: 'Szkło', + settings_interface_glass_descr: 'Wyświetlaj interfejs w stylu szklanym', + settings_interface_glass_opacity: 'Przezroczystość szkła', + settings_interface_black_style: 'Czarny motyw', + settings_interface_hide_outside_the_screen: 'Ukrywaj karty poza ekranem', + settings_interface_hide_outside_the_screen_descr: 'Przyspieszy to renderowanie interfejsu i poprawi wydajność', + + settings_interface_sound: 'Dźwięki systemowe', + settings_interface_sound_play: 'Przejścia', + settings_interface_sound_level: 'Poziom głośności', + + settings_main_account: 'Konto', + settings_main_interface: 'Interfejs', + settings_main_player: 'Odtwarzacz', + settings_main_parser: 'Parser', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Rozszerzenia', + settings_main_rest: 'Pozostałe', + + settings_rest_start: 'Strona startowa', + settings_rest_start_descr: 'Od której strony rozpoczynać po uruchomieniu', + settings_rest_source: 'Źródło', + settings_rest_source_use: 'Główne źródło', + settings_rest_source_descr: 'Skąd pobierać informacje o filmach', + settings_rest_tmdb_lang: 'Język danych z TMDB', + settings_rest_tmdb_prox: 'Proxy dla TMDB', + settings_rest_tmdb_prox_auto: 'Automatycznie włącz proxy', + settings_rest_tmdb_posters: 'Rozdzielczość plakatów TMDB', + settings_rest_screensaver: 'Wygaszacz ekranu', + settings_rest_screensaver_use: 'Pokazuj wygaszacz podczas bezczynności', + settings_rest_screensaver_type: 'Typ wygaszacza', + settings_rest_screensaver_time: 'Po ilu minutach uruchomić wygaszacz', + settings_rest_helper: 'Podpowiedzi', + settings_rest_helper_use: 'Pokazuj podpowiedzi', + settings_rest_helper_reset: 'Pokaż podpowiedzi ponownie', + settings_rest_pages: 'Liczba stron przechowywanych w pamięci', + settings_rest_pages_descr: 'Przechowuje strony w stanie, w jakim zostały opuszczone.', + settings_rest_time: 'Przesunięcie czasu', + settings_rest_navigation: 'Typ nawigacji', + settings_rest_keyboard: 'Typ klawiatury', + settings_rest_device: 'Nazwa urządzenia', + settings_rest_device_placeholder: 'Np.', + settings_rest_cache: 'Wyczyść pamięć podręczną', + settings_rest_tmdb_example: 'Na przykład', + settings_rest_tmdb_api_descr: 'Do pobierania danych', + settings_rest_tmdb_image_descr: 'Do pobierania obrazów', + settings_rest_card_quality: 'Oznaczenia jakości', + settings_rest_card_quality_descr: 'Wyświetlaj oznaczenia jakości na kartach', + settings_rest_card_episodes: 'Oznaczenia odcinków', + settings_rest_card_episodes_descr: 'Wyświetlaj oznaczenia odcinków na kartach', + settings_rest_cache_images: 'Pamięć podręczna obrazów', + settings_rest_cache_images_descr: 'Buforuj plakaty i tła w pamięci lokalnej', + settings_rest_protocol_use: 'Bezpieczne połączenie', + settings_rest_protocol_descr: 'Używaj protokołu HTTPS', + settings_rest_cache_only: 'Tylko pamięć podręczna', + settings_rest_cache_only_descr: 'Podstawowe ustawienia zostaną zachowane', + settings_rest_cache_all: 'Pamięć podręczna i dane', + settings_rest_cache_all_descr: 'Wszystkie ustawienia i dane zostaną usunięte', + settings_rest_cache_calculate: 'Ilość wolnej pamięci', + settings_request_caching_use: 'Buforowanie zapytań', + settings_request_caching_descr: 'Zapisuj odpowiedzi serwerów w pamięci podręcznej, aby przyspieszyć działanie aplikacji', + + settings_parser_use: 'Używaj parsera', + settings_parser_use_descr: 'Tym samym zgadzasz się przejąć pełną odpowiedzialność za korzystanie z publicznych linków do treści torrentowych i online.', + settings_parser_type: 'Typ parsera torrentów', + settings_parser_jackett_placeholder: 'Np.192.168.х', + settings_parser_jackett_link: 'Adres', + settings_parser_jackett_link_descr: 'Podaj adres skryptu Jackett', + settings_parser_prowlarr_link_descr: 'Podaj adres serwera Prowlarr', + settings_parser_jackett_key_placeholder: 'Np.: sa0sk83d..', + settings_parser_jackett_key: 'Klucz API', + settings_parser_jackett_key_descr: 'Znajduje się w Jackett', + settings_parser_prowlarr_key_descr: 'Znajduje się w ustawieniach Prowlarr w sekcji głównej', + settings_parser_torlook_type: 'Metoda parsowania strony TorLook', + settings_parser_scraperapi_placeholder: 'Np.', + settings_parser_scraperapi_link: 'Adres parsera stron', + settings_parser_scraperapi_descr: 'Zarejestruj się na scraperapi.com i wpisz adres api.scraperapi.com?api_key=...&url={q}
    W miejsce {q} zostanie podstawiona strona w41.torlook.info', + settings_parser_search: 'Wyszukiwanie', + settings_parser_search_descr: 'W jakim języku wyszukiwać?', + settings_parser_in_search: 'Parser w wyszukiwance', + settings_parser_in_search_descr: 'Pokazywać wyniki w wyszukiwaniu?', + settings_parser_timeout_title: 'Limit czasu parsera', + settings_parser_timeout_descr: 'Czas oczekiwania na odpowiedź serwera (w sekundach)', + + settings_player_type: 'Typ odtwarzacza', + settings_player_type_descr: 'Którego odtwarzacza używać do odtwarzania wideo', + settings_infuse_launch_mode: 'Uruchamianie w Infuse', + settings_infuse_launch_mode_descr: 'Co robić przy otwieraniu wideo w Infuse. Torrenty zawsze odtwarzane od razu', + settings_infuse_launch_ask: 'Pytaj przy uruchomieniu', + settings_infuse_launch_play: 'Odtwórz', + settings_infuse_launch_save_and_play: 'Zapisz i odtwórz', + settings_player_iptv_type: 'Typ odtwarzacza IPTV', + settings_player_iptv_type_descr: 'Którego odtwarzacza używać do kanałów IPTV', + settings_player_torrent_type: 'Typ odtwarzacza torrentów', + settings_player_torrent_type_descr: 'Którego odtwarzacza używać do torrentów', + settings_player_reset: 'Zresetuj domyślny odtwarzacz', + settings_player_reset_descr: 'Resetuje wybrany odtwarzacz Android w aplikacji', + settings_player_path: 'Ścieżka do odtwarzacza', + settings_player_path_descr: 'Podaj ścieżkę do pliku wykonywalnego odtwarzacza', + settings_player_external_header: 'Zewnętrzny odtwarzacz', + settings_player_external_fullscreen: 'Uruchamiaj w trybie pełnoekranowym', + settings_player_normalization: 'Normalizacja dźwięku', + settings_player_normalization_descr: 'Wyrównuje poziom dźwięku, ścisza głośne i wzmacnia ciche fragmenty.', + settings_player_next_episode: 'Następny odcinek', + settings_player_next_episode_descr: 'Automatycznie przełączaj na następny odcinek po zakończeniu bieżącego', + settings_player_timecode: 'Znacznik czasu', + settings_player_timecode_descr: 'Wznów od ostatnio oglądanego miejsca', + settings_player_scale: 'Metoda skalowania', + settings_player_scale_descr: 'Sposób obliczania skalowania wideo', + settings_player_subs: 'Napisy', + settings_player_subs_use: 'Włącz', + settings_player_subs_use_descr: 'Zawsze włączaj napisy po uruchomieniu wideo', + settings_player_subs_lang: 'Język napisów', + settings_player_subs_lang_descr: 'Które napisy włączać automatycznie, gdy dostępnych jest kilka języków', + settings_param_subtitles_lang_auto: 'Język interfejsu', + settings_player_subs_size: 'Rozmiar', + settings_player_subs_size_descr: 'Rozmiar napisów na ekranie', + settings_player_subs_stroke_use: 'Użyj obramowania', + settings_player_subs_stroke_use_descr: 'Napisy będą obrysowane na czarno dla lepszej czytelności', + settings_player_subs_backdrop_use: 'Użyj tła', + settings_player_subs_backdrop_use_descr: 'Napisy będą wyświetlane na półprzezroczystym tle dla lepszej czytelności', + settings_player_quality: 'Domyślna jakość wideo', + settings_player_quality_descr: 'Preferowana jakość wideo do oglądania', + settings_player_hls_title: 'Obsługa strumienia .m3u8', + settings_player_hls_descr: 'Nie zmieniaj tego ustawienia, jeśli nie wiesz, do czego służy.', + settings_player_rewind_title: 'Przewijanie', + settings_player_rewind_descr: 'Interwał przewijania w sekundach', + settings_player_launch_trailers: 'Odtwarzacz zwiastunów', + + settings_plugins_notice: 'Aby zastosować wtyczkę, należy ponownie uruchomić aplikację', + settings_plugins_add: 'Dodaj wtyczkę', + settings_plugins_add_descr: 'Aby usunąć dodaną wtyczkę, przytrzymaj lub naciśnij dwukrotnie przycisk (OK)', + settings_plugins_install: 'Zainstaluj wtyczkę', + settings_plugins_install_descr: 'Zainstaluj wtyczkę z listy dostępnych', + + settings_server_link: 'Użyj adresu', + settings_server_links: 'Adresy', + settings_server_placeholder: 'Np.: 192.168.х', + settings_server_link_one: 'Główny adres', + settings_server_link_one_descr: 'Podaj główny adres TorrServer', + settings_server_link_two: 'Dodatkowy adres', + settings_server_link_two_descr: 'Podaj dodatkowy adres TorrServer', + settings_server_additionally: 'Dodatkowo', + settings_server_client: 'Wbudowany klient', + settings_server_client_descr: 'Używaj wbudowanego klienta JS TorrServer, w przeciwnym razie uruchamiany będzie systemowy.', + settings_server_base: 'Zapisuj do bazy', + settings_server_base_descr: 'Torrent zostanie dodany do bazy TorrServer', + settings_server_preload: 'Używaj bufora wstępnego ładowania', + settings_server_preload_descr: 'Poczekaj na zapełnienie bufora TorrServer przed rozpoczęciem odtwarzania', + settings_server_auth: 'Autoryzacja', + settings_server_password_use: 'Logowanie hasłem', + settings_server_login: 'Login', + settings_server_password: 'Hasło', + settings_server_not_specified: 'Nie określono', + settings_server_search_type: 'Typ wyszukiwania', + settings_server_search_type_descr: 'Gdzie szukać torrentów: wbudowany rutor, indeksery Torznab w TorrServer, lub oba źródła.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + settings_webos_launcher: 'Uruchamianie aplikacji', + settings_webos_launcher_add_device: 'Ustaw jako aplikację startową', + settings_webos_launcher_remove_device: 'Usuń z aplikacji startowych', + + settings_parental_control_param_time_always: 'Zawsze', + settings_parental_control_param_time_once: 'Jeden raz', + settings_parental_control_param_time_10: 'Za 10 minut', + settings_parental_control_param_time_20: 'Za 20 minut', + settings_parental_control_param_time_30: 'Za 30 minut', + settings_parental_control_param_time_60: 'Za 1 godzinę', + settings_parental_control_param_time_120: 'Za 2 godziny', + settings_parental_control_change_pin: 'Zmień kod PIN', + settings_parental_control_demand_title: 'Kiedy wymagać', + settings_parental_control_demand_descr: 'Po jakim czasie wymagać podania kodu PIN', + settings_parental_control_enabled: 'Włączone', + settings_parental_control_disabled: 'Wyłączone', + settings_parental_control_where: 'Gdzie wymagać kodu PIN', + + settings_lgbt_content_block: 'Blokuj treści LGBT', + + parental_control_input_new_code: 'Wprowadź nowy kod PIN', + parental_control_confirm_new_code: 'Powtórz kod PIN', + parental_control_no_match_code: 'Kod PIN nie jest zgodny z poprzednim', + parental_control_input_code: 'Wprowadź kod PIN', + parental_control_input_error: 'Wprowadzono nieprawidłowy kod PIN', + + + torent_nohash_reasons: 'Przyczyny', + torent_nohash_reason_one: 'TorrServer nie mógł pobrać pliku torrent', + torent_nohash_reason_two: 'Odpowiedź od TorrServer', + torent_nohash_reason_three: 'Adres', + torent_nohash_do: 'Co zrobić?', + torent_nohash_do_one: 'Sprawdź, czy Jackett jest poprawnie skonfigurowany', + torent_nohash_do_two: 'Prywatne źródła mogą nuie udostępniać linku do pliku', + torent_nohash_do_three: 'Upewnij się, że Jackett również może pobrać plik', + torent_nohash_do_four: 'Napisz do naszej grupy Telegram', + torent_nohash_do_five: 'Podaj nazwę filmu, wydanie oraz, jeśli to możliwe, zdjęcie tego wydania', + + torrent_error_text: 'Nie udało się połączyć z TorrServer. Sprawdźmy szybko możliwe przyczyny problemu.', + torrent_error_step_1: 'Czy TorrServer jest uruchomiony', + torrent_error_step_2: 'Dynamiczny adres IP', + torrent_error_step_3: 'Protokół i port', + torrent_error_step_4: 'Blokada przez antywirusa', + torrent_error_step_5: 'Sprawdź dostępność', + torrent_error_step_6: 'Nadal nie działa', + torrent_error_info_1: 'Upewnij się, że TorrServer jest uruchomiony na urządzeniu, na którym został zainstalowany.', + torrent_error_info_2: 'Częsty problem', + torrent_error_info_3: 'Do połączenia z TorrServer należy podać protokół http', + torrent_error_info_4: 'Antywirus lub zapora sieciowa mogą blokować połączenie. Spróbuj je tymczasowo wyłączyć.', + torrent_error_info_5: 'Na innym urządzeniu w tej samej sieci otwórz w przeglądarce adres {ip} i sprawdź, czy interfejs TorrServer jest dostępny.', + torrent_error_info_6: 'Jeśli problem nadal występuje, spróbuj ponownie uruchomić TorrServer oraz kartę sieciową.', + torrent_error_info_7: 'Jeśli problem nie ustąpił, napisz do grupy Telegram @lampa_group z wiadomością', + torrent_error_start: 'Rozpocznij sprawdzanie', + torrent_error_nomatrix: 'Nie udało się potwierdzić wersji Matrix', + torrent_error_made: 'Wykonano', + torrent_error_from: 'z', + torrent_error_next: 'Dalej', + torrent_error_complite: 'Zakończ', + torrent_error_connect: 'Błąd połączenia', + torrent_error_check_no_auth: 'Serwer odpowiedział, ale nie udało się przejść autoryzacji', + + torrent_install_need: 'Wymagany TorrServer', + torrent_install_text: 'TorrServer to aplikacja umożliwiająca oglądanie treści z plików torrent w trybie online.

    Szczegółowe informacje o instalacji znajdziesz w grupach Telegram podanych poniżej.', + torrent_install_contact: 'Grupy Telegram', + + torrent_item_bitrate: 'Bitrate', + torrent_item_seeds: 'Seedy', + torrent_item_grabs: 'Peery', + torrent_item_mb: 'Mb/s', + + torrent_serial_episode: 'Odcinek', + torrent_serial_season: 'Sezon', + torrent_serial_date: 'Data premiery', + + torrent_get_magnet: 'Pobieranie linku magnet', + torrent_remove_title: 'Usuń', + torrent_remove_descr: 'Torrent zostanie usunięty z Twojej listy', + + torrent_parser_any_one: 'Dowolne', + torrent_parser_any_two: 'Dowolny', + torrent_parser_no_choice: 'Nie wybrano', + torrent_parser_yes: 'Tak', + torrent_parser_no: 'Nie', + torrent_parser_quality: 'Jakość', + torrent_parser_subs: 'Napisy', + torrent_parser_voice: 'Tłumaczenie', + torrent_parser_tracker: 'Tracker', + torrent_parser_year: 'Rok', + torrent_parser_season: 'Sezon', + torrent_parser_sort_by_seeders: 'Według seedów', + torrent_parser_sort_by_size: 'Według rozmiaru', + torrent_parser_sort_by_name: 'Według nazwy', + torrent_parser_sort_by_tracker: 'Według źródła', + torrent_parser_sort_by_date: 'Według daty', + torrent_parser_sort_by_viewed: 'Według obejrzanych', + torrent_parser_voice_dubbing: 'Dubbing', + torrent_parser_voice_polyphonic: 'Wielogłosowy', + torrent_parser_voice_two: 'Dwugłosowy', + torrent_parser_voice_amateur: 'Amatorski', + torrent_parser_reset: 'Resetuj filtr', + torrent_parser_empty: 'Nie udało się uzyskać wyników', + torrent_parser_no_hash: 'Nie udało się uzyskać HASH, spróbuj ponownie uruchomić TorrServer', + torrent_parser_added_to_mytorrents: 'dodano do „Moje torrenty”', + torrent_parser_add_to_mytorrents: 'Dodaj do „Moje torrenty”', + torrent_parser_label_title: 'Oznacz', + torrent_parser_label_descr: 'Oznacz torrent jako obejrzany', + torrent_parser_label_cancel_title: 'Usuń oznaczenie', + torrent_parser_label_cancel_descr: 'Usuń oznaczenie z torrenta (obejrzane)', + torrent_parser_timeout: 'Przekroczono czas oczekiwania', + torrent_parser_nofiles: 'Nie udało się wyodrębnić odpowiednich plików', + torrent_parser_set_link: 'Podaj link do parsowania', + torrent_parser_request_error: 'Błąd żądania', + torrent_parser_magnet_error: 'Nie udało się uzyskać linku magnet', + torrent_parser_no_responce: 'Parser nie odpowiada na żądanie', + torrent_parser_torlook_fallback_search_notification: 'Parser Jackett jest niedostępny lub błędnie skonfigurowany. Wyszukiwanie w Torlook...', + + about_text: 'Aplikacja jest całkowicie darmowa i korzysta z publicznych źródeł do pobierania informacji o wideo, nowościach, popularnych filmach itp. Wszystkie dostępne informacje są wykorzystywane wyłącznie w celach informacyjnych, aplikacja nie używa własnych serwerów do dystrybucji treści.', + about_channel: 'Nasz kanał', + about_group: 'Grupa', + about_version: 'Wersja', + about_donate: 'Darowizna', + + title_watched: 'Oglądane', + title_settings: 'Ustawienia', + title_collections: 'Kolekcje', + title_company: 'Firma', + title_actors: 'Aktorzy', + title_actor: 'Aktor', + title_actress: 'Aktorka', + title_person: 'Osoba', + title_persons: 'Osoby', + title_person_about: 'O osobie', + title_comments: 'Komentarze', + title_torrents: 'Torrenty', + title_trailers: 'Zwiastuny', + title_watch: 'Oglądaj', + title_error: 'Błąd', + title_links: 'Linki', + title_choice: 'Wybór', + title_main: 'Strona główna', + title_book: 'Zakładki', + title_like: 'Lubię to', + title_wath: 'Później', + title_look: 'Oglądam', + title_scheduled: 'Zaplanowane', + title_viewed: 'Obejrzane', + title_thrown: 'Porzucone', + title_continued: 'Ciąg dalszy nastąpi', + title_history: 'Historia oglądania', + title_mytorrents: 'Moje torrenty', + title_last: 'Ostatnie', + title_action: 'Akcja', + title_action_infuse: 'Akcja Infuse', + title_producer: 'Reżyser', + title_collection: 'Kolekcja', + title_recomendations: 'Rekomendacje', + title_similar: 'Podobne', + title_about: 'O aplikacji', + title_timetable: 'Harmonogram', + title_relises: 'Wydania cyfrowe', + title_catalog: 'Katalog', + title_category: 'Kategoria', + title_parser: 'Parser', + title_type: 'Typ', + title_rating: 'Ocena', + title_country: 'Kraj', + title_year: 'Rok', + title_genre: 'Gatunek', + title_filter: 'Filtr', + title_notice: 'Powiadomienia', + title_files: 'Pliki', + title_now_watch: 'Obecnie oglądają', + title_latest: 'Najnowsze dodania', + title_continue: 'Kontynuuj oglądanie', + title_recomend_watch: 'Polecamy obejrzeć', + title_new_episodes: 'Nowe odcinki', + title_popular: 'Popularne', + title_popular_movie: 'Popularne filmy', + title_popular_tv: 'Popularne seriale', + title_new_this_year: 'Nowości tego roku', + title_hight_voite: 'Wysoko oceniane', + title_new: 'Nowości', + title_trend_day: 'Trending dziś', + title_trend_week: 'Trending w tygodniu', + title_upcoming: 'W kinach', + title_top_movie: 'Top filmy', + title_top_tv: 'Top seriale', + title_tv_today: 'Dziś w emisji', + title_this_week: 'W tym tygodniu', + title_in_top: 'W topie', + title_out: 'Wyjście', + title_out_confirm: 'Tak, wyjdź', + title_continue_two: 'Kontynuuj', + title_choice_language: 'Wybierz język', + title_subscribe: 'Subskrybuj', + title_subscribes: 'Subskrypcje', + title_unsubscribe: 'Wypisz się', + title_language: 'Język oryginalny', + title_language_short: 'Język', + title_ongoing: 'Trwające', + title_pgrating: 'Ograniczenie wiekowe', + title_card: 'Karta', + title_seasons: 'Sezony', + title_episodes: 'Odcinki', + title_rewiews: 'Recenzje', + title_channel: 'Kanał', + title_in_high_quality: 'W wysokiej jakości', + title_author: 'Autor', + title_buffer: 'Bufor', + title_upcoming_episodes: 'Nadchodzące odcinki', + title_recent_episodes: 'Ostatnie odcinki', + title_reactions: 'Reakcje', + title_last_year: 'Poprzedni rok', + title_reset: 'Resetuj', + title_left: 'Pozostało', + title_parental_control: 'Kontrola rodzicielska', + title_worth_rewatch: 'Warto obejrzeć ponownie', + title_fire: 'Ogień!', + title_top_100: 'Top 100', + title_ai_assistant: 'Asystent AI', + title_facts: 'Ciekawostki', + title_anons: 'Zapowiedź', + title_developer: 'Deweloper', + title_navigation: 'Nawigacja', + title_page: 'Strona', + title_channels: 'Kanały', + title_best_of_2000: 'Złote lata 2000', + title_best_of_2010: 'Hity lat 2010', + title_best_of_2015: 'Współczesna klasyka', + title_comedy_of_2000: 'Komedia lat 2000', + title_comedy_of_2010: 'Humor lat 2010', + title_comedy_of_2015: 'Współczesne komedie', + + reactions_none: 'Brak reakcji', + reactions_fire: 'Super', + reactions_nice: 'Niezłe', + reactions_think: 'Da się oglądać', + reactions_bore: 'Nuda', + reactions_shit: 'Słabe', + reactions_ready: 'Już dodałeś reakcję', + + subscribe_success: 'Subskrypcja zakończona sukcesem', + subscribe_error: 'Wystąpił błąd podczas subskrypcji, spróbuj później', + subscribe_noinfo: 'Nie udało się pobrać informacji, spróbuj później', + subscribe_info: 'W sekcji (Subskrypcje) będą wyświetlane wszystkie Twoje subskrypcje lektorów. Gdy pojawi się nowy odcinek z wybranym lektorem, otrzymasz powiadomienie.', + + company_headquarters: 'Siedziba', + company_homepage: 'Strona internetowa', + company_country: 'Kraj', + + country_ad: 'Andora', + country_ae: 'Zjednoczone Emiraty Arabskie', + country_af: 'Afganistan', + country_al: 'Albania', + country_am: 'Armenia', + country_ao: 'Angola', + country_ar: 'Argentyna', + country_at: 'Austria', + country_au: 'Australia', + country_aw: 'Aruba', + country_az: 'Azerbejdżan', + country_bа: 'Bośnia i Hercegowina', + country_bd: 'Bangladesz', + country_be: 'Belgia', + country_bg: 'Bułgaria', + country_bh: 'Bahrajn', + country_bi: 'Burundi', + country_bj: 'Benin', + country_bo: 'Boliwia', + country_br: 'Brazylia', + country_bs: 'Bahamy', + country_bt: 'Bhutan', + country_bw: 'Botswana', + country_by: 'Białoruś', + country_ca: 'Kanada', + country_ch: 'Szwajcaria', + country_cl: 'Chile', + country_cm: 'Kamerun', + country_cn: 'Chiny', + country_co: 'Kolumbia', + country_cr: 'Kostaryka', + country_cu: 'Kuba', + country_cv: 'Republika Zielonego Przylądka', + country_cy: 'Cypr', + country_cz: 'Czechy', + country_de: 'Niemcy', + country_dj: 'Dżibuti', + country_dk: 'Dania', + country_do: 'Dominikana', + country_dz: 'Algieria', + country_ec: 'Ekwador', + country_ee: 'Estonia', + country_eg: 'Egipt', + country_es: 'Hiszpania', + country_et: 'Etiopia', + country_fi: 'Finlandia', + country_fo: 'Wyspy Owcze', + country_fr: 'Francja', + country_ga: 'Gabon', + country_gb: 'Wielka Brytania', + country_ge: 'Gruzja', + country_gh: 'Ghana', + country_gl: 'Grenlandia', + country_gp: 'Gwadelupa', + country_gr: 'Grecja', + country_gt: 'Gwatemala', + country_hk: 'Hongkong', + country_hr: 'Chorwacja', + country_ht: 'Haiti', + country_hu: 'Węgry', + country_id: 'Indonezyjski', + country_ie: 'Irlandia', + country_il: 'Izrael', + country_in: 'Indie', + country_iq: 'Irak', + country_ir: 'Iran', + country_is: 'Islandia', + country_it: 'Włochy', + country_jm: 'Jamajka', + country_jo: 'Jordania', + country_jp: 'Japonia', + country_ke: 'Kenia', + country_kg: 'Kirgistan', + country_kh: 'Kambodża', + country_kp: 'Korea Północna', + country_kr: 'Korea Południowa', + country_kz: 'Kazachstan', + country_kw: 'Kuwejt', + country_la: 'Laos', + country_lb: 'Liban', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Liberia', + country_lt: 'Litwa', + country_lu: 'Luksemburg', + country_lv: 'Łotwa', + country_ly: 'Libia', + country_ma: 'Maroko', + country_mc: 'Monako', + country_md: 'Mołdawia', + country_me: 'Czarnogóra', + country_mk: 'Macedonia Północna', + country_mm: 'Mjanma', + country_mn: 'Mongolia', + country_mo: 'Makau', + country_mt: 'Malta', + country_mu: 'Mauritius', + country_mv: 'Malediwy', + country_mw: 'Malawi', + country_mx: 'Meksyk', + country_my: 'Malezja', + country_mz: 'Mozambik', + country_na: 'Namibia', + country_ne: 'Niger', + country_ng: 'Nigeria', + country_ni: 'Nikaragua', + country_nl: 'Holandia', + country_no: 'Norwegia', + country_np: 'Nepal', + country_nz: 'Nowa Zelandia', + country_om: 'Oman', + country_pa: 'Panama', + country_pe: 'Peru', + country_pg: 'Papua-Nowa Gwinea', + country_ph: 'Filipiny', + country_pk: 'Pakistan', + country_pl: 'Polska', + country_pr: 'Portoryko', + country_ps: 'Palestyna', + country_pt: 'Portugalia', + country_py: 'Paragwaj', + country_qa: 'Katar', + country_ro: 'Rumunia', + country_rs: 'Serbia', + country_ru: 'Rosja', + country_rw: 'Rwanda', + country_sa: 'Arabia Saudyjska', + country_sd: 'Sudan', + country_se: 'Szwecja', + country_sg: 'Singapur', + country_si: 'Słowenia', + country_sk: 'Słowacja', + country_sn: 'Senegal', + country_su: 'ZSRR', + country_sv: 'Salwador', + country_sy: 'Syria', + country_th: 'Tajlandia', + country_tj: 'Tadżykistan', + country_tm: 'Turkmenistan', + country_tn: 'Tunezja', + country_tr: 'Turcja', + country_tw: 'Tajwan', + country_tz: 'Tanzania', + country_ua: 'Ukraina', + country_ug: 'Uganda', + country_us: 'USA', + country_uy: 'Urugwaj', + country_uz: 'Uzbekistan', + country_ve: 'Wenezuela', + country_vn: 'Wietnam', + country_ws: 'Samoa', + country_xk: 'Kosowo', + country_ye: 'Jemen', + country_yu: 'Jugosławia', + country_za: 'Republika Południowej Afryki', + country_zm: 'Zambia', + country_zw: 'Zimbabwe', + + filter_clarify: 'Doprecyzuj', + filter_clarify_two: 'Doprecyzuj wyszukiwanie', + filter_set_name: 'Podaj nazwę', + filter_sorted: 'Sortuj', + filter_filtred: 'Filtr', + filter_any: 'Dowolny', + filter_combinations: 'Kombinacje', + filter_alt_names: 'Inne nazwy', + filter_rating_from: 'od', + filter_rating_to: 'do', + + filter_lang_af: 'Afrikaans', + filter_lang_ar: 'Arabski', + filter_lang_az: 'Azerbejdżański', + filter_lang_ba: 'Baszkirski', + filter_lang_be: 'Białoruski', + filter_lang_bg: 'Bułgarski', + filter_lang_bn: 'Bengalski', + filter_lang_bs: 'Bośniacki', + filter_lang_ca: 'Kataloński', + filter_lang_ce: 'Czeczeński', + filter_lang_cs: 'Czeski', + filter_lang_da: 'Duński', + filter_lang_de: 'Niemiecki', + filter_lang_el: 'Grecki', + filter_lang_en: 'Angielski', + filter_lang_es: 'Hiszpański', + filter_lang_et: 'Estoński', + filter_lang_fa: 'Perski', + filter_lang_fi: 'Fiński', + filter_lang_fr: 'Francuski', + filter_lang_ga: 'Irlandzki', + filter_lang_gl: 'Galicyjski', + filter_lang_gn: 'Guarani', + filter_lang_he: 'Hebrajski', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Chorwacki', + filter_lang_hu: 'Węgierski', + filter_lang_hy: 'Ormiański', + filter_lang_id: 'Indonezyjski', + filter_lang_is: 'Islandzki', + filter_lang_it: 'Włoski', + filter_lang_ja: 'Japoński', + filter_lang_ka: 'Gruziński', + filter_lang_kk: 'Kazachski', + filter_lang_ko: 'Koreański', + filter_lang_ks: 'Kaszmirski', + filter_lang_ku: 'Kurdyjski', + filter_lang_ky: 'Kirgijski', + filter_lang_lt: 'Litewski', + filter_lang_lv: 'Łotewski', + filter_lang_mi: 'Maoryski', + filter_lang_mk: 'Macedoński', + filter_lang_mn: 'Mongolski', + filter_lang_mt: 'Maltański', + filter_lang_ne: 'Nepalski', + filter_lang_nl: 'Holenderski', + filter_lang_no: 'Norweski', + filter_lang_pa: 'Pendżabski', + filter_lang_pl: 'Polski', + filter_lang_ps: 'Paszto', + filter_lang_pt: 'Portugalski', + filter_lang_ro: 'Rumuński', + filter_lang_ru: 'Rosyjski', + filter_lang_si: 'Syngaleski', + filter_lang_sk: 'Słowacki', + filter_lang_sl: 'Słoweński', + filter_lang_sm: 'Samoański', + filter_lang_so: 'Somalijski', + filter_lang_sq: 'Albański', + filter_lang_sr: 'Serbski', + filter_lang_sv: 'Szwedzki', + filter_lang_sw: 'Suahili', + filter_lang_ta: 'Tamilski', + filter_lang_tg: 'Tadżycki', + filter_lang_th: 'Tajski', + filter_lang_tk: 'Turkmeński', + filter_lang_tr: 'Turecki', + filter_lang_tt: 'Tatarski', + filter_lang_ur: 'Urdu', + filter_lang_uk: 'Ukraiński', + filter_lang_uz: 'Uzbecki', + filter_lang_vi: 'Wietnamski', + filter_lang_yi: 'Jidysz', + filter_lang_zh: 'Chiński', + + filter_genre_ac: 'Akcja', + filter_genre_ad: 'Przygodowy', + filter_genre_mv: 'Animacja', + filter_genre_cm: 'Komedia', + filter_genre_cr: 'Kryminał', + filter_genre_dc: 'Dokumentalny', + filter_genre_dr: 'Dramat', + filter_genre_fm: 'Familijny', + filter_genre_fe: 'Fantasy', + filter_genre_hi: 'Historyczny', + filter_genre_ho: 'Horror', + filter_genre_mu: 'Muzyka', + filter_genre_de: 'Detektywistyczny', + filter_genre_md: 'Melodramat', + filter_genre_fa: 'Sci-Fi', + filter_genre_tv: 'Film telewizyjny', + filter_genre_tr: 'Thriller', + filter_genre_mi: 'Wojenny', + filter_genre_ve: 'Western', + filter_genre_aa: 'Akcja i przygoda', + filter_genre_ch: 'Dla dzieci', + filter_genre_nw: 'Wiadomości', + filter_genre_rs: 'Reality show', + filter_genre_hf: 'Sci-Fi i Fantasy', + filter_genre_op: 'Opera mydlana', + filter_genre_tc: 'Talk-show', + filter_genre_mp: 'Wojna i polityka', + + filter_keyword_sequel: 'Sequel', + filter_keyword_based_comic: 'Na podstawie komiksu', + filter_keyword_space: 'Kosmos', + filter_keyword_survival: 'Przetrwanie', + filter_keyword_zombie: 'Zombie', + filter_keyword_school: 'Szkoła', + filter_keyword_revenge: 'Zemsta', + filter_keyword_detective: 'Detektyw', + filter_keyword_robots: 'Roboty', + filter_keyword_vampires: 'Wampiry', + filter_keyword_aliens: 'Obcy', + filter_keyword_police: 'Policja', + filter_keyword_reincarnation: 'Reinkarnacja', + filter_keyword_spy: 'Szpieg', + filter_keyword_disaster: 'Katastrofa', + filter_keyword_christmas: 'Boże Narodzenie', + + empty_title: 'Pusto', + empty_text: 'Nic nie znaleziono według Twojego filtra, doprecyzuj filtr.', + empty_title_two: 'Tutaj pusto', + empty_text_two: 'Obecnie lista jest pusta', + + empty_subscribes_title: 'Twoje subskrypcje dubbingów i lektrów', + empty_subscribes_text: 'Po prostu zasubskrybuj ulubiony dubbing lub lektora, a będziemy powiadamiać Cię o nowych odcinkach.', + empty_history_title: 'Twoja historia oglądania', + empty_history_text: 'Tutaj będzie wyświetlana Twoja historia oglądania.', + empty_bookmark_title: 'Twoje ulubione', + empty_bookmark_text: 'Dodawaj ulubione filmy i seriale, aby szybko je znaleźć w tej sekcji.', + empty_mytorrents_title: 'Twoje torrenty', + empty_mytorrents_text: 'Tutaj będą wyświetlane torrenty pobrane przez TorrServer.', + + back_to_card: 'Powrót do karty', + + menu_main: 'Strona główna', + menu_movies: 'Filmy', + menu_tv: 'Seriale', + menu_catalog: 'Katalog', + menu_filter: 'Filtr', + menu_collections: 'Kolekcje', + menu_relises: 'Wydania', + menu_anime: 'Anime', + menu_bookmark: 'Zakładki', + menu_like: 'Lubię to', + menu_time: 'Później', + menu_history: 'Historia', + menu_timeline: 'Harmonogram', + menu_torrents: 'Torrenty', + menu_settings: 'Ustawienia', + menu_about: 'Informacje', + menu_console: 'Konsola', + menu_multmovie: 'Filmy animowane', + menu_multtv: 'Seriale animowane', + menu_feed: 'Kanał', + + lampa_movie_title: 'Lampa Kino', + lampa_movie_descr: 'Śledź nowości na swoim smartfonie.
    Telegram', + + plugins_catalog_work: 'Działające wtyczki', + plugins_catalog_work_descr: 'Wtyczki, które na pewno działają w aplikacji.', + plugins_catalog_popular: 'Popularne wtyczki użytkowników', + plugins_catalog_popular_descr: 'Instalacja z nieznanych źródeł może powodować nieprawidłowe działanie aplikacji.', + plugins_online: 'Oglądanie online', + plugins_check_fail: 'Nie udało się sprawdzić działania wtyczki. To nie oznacza, że nie działa. Uruchom ponownie aplikację.', + plugins_need_reload: 'Aby zastosować wtyczkę, należy ponownie uruchomić aplikację', + plugins_install: 'Zainstaluj', + plugins_install_ready: 'Ta wtyczka jest już zainstalowana.', + plugins_installed: 'Instalacje', + plugins_load_from: 'Załadowano z CUB', + plugins_ok_for_check: 'Naciśnij (OK), aby sprawdzić wtyczkę', + plugins_no_loaded: 'Nie udało się załadować części wtyczek przy uruchomieniu aplikacji', + plugins_remove: 'Usuń wtyczki', + plugins_add_success: 'Wtyczka została pomyślnie podłączona', + + time_viewed: 'Oglądane', + time_from: 'z', + time_reset: 'Resetuj kod czasu', + + settings_clear_cache: 'Pamięć podręczna i dane zostały wyczyszczone', + settings_clear_cache_only: 'Pamięć podręczna wyczyszczona', + settings_user_links: 'Link użytkownika', + settings_for_local: 'Dla lokalnego TorrServer', + settings_add: 'Dodaj', + settings_remove: 'Usuń', + settings_this_value: 'aktualna wartość', + settings_added: 'Dodano', + settings_removed: 'Usunięto', + settings_reset: 'Reset ustawień', + + settings_param_player_inner: 'Wbudowany', + settings_param_player_outside: 'Zewnętrzny', + settings_param_player_inner_tvos: 'Wbudowany', + settings_param_yes: 'Tak', + settings_param_no: 'Nie', + settings_param_interface_size_small: 'Mniejszy', + settings_param_interface_size_normal: 'Normalny', + settings_param_interface_size_bigger: 'Większy', + settings_param_poster_quality_low: 'Niska', + settings_param_poster_quality_average: 'Średnia', + settings_param_poster_quality_high: 'Wysoka', + settings_param_parse_directly: 'Bezpośrednio', + settings_param_parse_api: 'Przez API strony', + settings_param_background_complex: 'Złożone', + settings_param_background_simple: 'Proste', + settings_param_background_image: 'Obraz', + settings_param_link_use_one: 'Główny', + settings_param_link_use_two: 'Dodatkowy', + settings_param_link_use_both: 'Oba', + settings_param_subtitles_size_small: 'Małe', + settings_param_subtitles_size_normal: 'Normalne', + settings_param_subtitles_size_bigger: 'Duże', + settings_param_screensaver_nature: 'Natura', + settings_param_torrent_lang_orig: 'Oryginał', + settings_param_player_timecode_again: 'Od początku', + settings_param_player_timecode_continue: 'Kontynuuj', + settings_param_player_timecode_ask: 'Pytaj', + settings_param_player_scale_method: 'Oblicz', + settings_param_player_hls_app: 'Systemowy', + settings_param_player_hls_js: 'Programowy', + settings_param_card_view_load: 'Wczytuj', + settings_param_card_view_all: 'Pokaż wszystko', + settings_param_navigation_remote: 'Pilot', + settings_param_navigation_mouse: 'Pilot z myszą', + settings_param_navigation_touch: 'Dotyk', + settings_param_keyboard_lampa: 'Wbudowana', + settings_param_keyboard_system: 'Systemowa', + settings_param_card_interface_old: 'Stary', + settings_param_card_interface_new: 'Nowy', + + settings_param_glass_easy: 'Przezroczysty', + settings_param_glass_medium: 'Półprzezroczysty', + settings_param_glass_blacked: 'Przyciemniony', + + settings_param_jackett_interview_all: 'Wszystkie', + settings_param_jackett_interview_healthy: 'Tylko dostępne', + settings_parser_jackett_interview: 'Przesłuchuj trackery', + + helper_keyboard: 'Po wpisaniu wartości naciśnij „Wstecz”, aby zapisać', + helper_torrents: 'Przytrzymaj (OK), aby otworzyć menu kontekstowe', + helper_cleared: 'Sukces, podpowiedzi zostaną pokazane ponownie', + helper_torrents_view: 'Aby zresetować kod czasu i otworzyć menu, przytrzymaj (OK)', + + fav_sync_title: 'Synchronizacja zakładek', + fav_sync_text: 'Twoje ulubione zakładki zawsze z Tobą. Włącz synchronizację i korzystaj na każdym urządzeniu.

    Zarejestruj się na stronie {site}, utwórz profil i zaloguj się w aplikacji.', + fav_sync_site: 'Strona', + fav_remove_title: 'Usuń z historii', + fav_remove_descr: 'Usuń wybraną kartę', + fav_clear_title: 'Wyczyść historię', + fav_clear_descr: 'Usuń wszystkie karty z historii', + fav_clear_label_title: 'Wyczyść oznaczenia', + fav_clear_label_descr: 'Usuń oznaczenia obejrzenia', + fav_clear_time_title: 'Wyczyść kody czasu', + fav_clear_time_descr: 'Usuń wszystkie kody czasu', + fav_label_cleared: 'Oznaczenia wyczyszczone', + fav_time_cleared: 'Kody czasu wyczyszczone', + + timetable_empty: 'W tej sekcji będą wyświetlane daty premier nowych odcinków', + + player_quality: 'Jakość', + player_flow: 'Strumień', + player_tracks: 'Ścieżki audio', + player_disabled: 'Wyłączone', + player_unknown: 'Nieznane', + player_subs: 'Napisy', + player_size_default_title: 'Domyślny', + player_size_default_descr: 'Domyślny rozmiar wideo', + player_size_cover_title: 'Rozszerz', + player_size_cover_descr: 'Rozciąga wideo na pełny ekran', + player_size_fill_title: 'Wypełnij', + player_size_fill_descr: 'Dopasuj wideo do ekranu', + player_size_s115_title: 'Powiększ 115%', + player_size_s115_descr: 'Powiększenie wideo o 115%', + player_size_s130_title: 'Powiększ 130%', + player_size_s130_descr: 'Powiększenie wideo o 130%', + player_size_v115_title: 'W pionie 115%', + player_size_v115_descr: 'Powiększenie wideo o 115%', + player_size_v130_title: 'W pionie 130%', + player_size_v130_descr: 'Powiększenie wideo o 130%', + player_video_size: 'Rozmiar wideo', + player_playlist: 'Playlista', + player_error_one: 'Nie udało się zdekodować wideo', + player_error_two: 'Wideo nie znalezione lub uszkodzone', + player_start_from: 'Kontynuuj od', + player_not_found: 'Nie znaleziona odtwarzacza', + player_lauch: 'Uruchom odtwarzacz', + player_speed_default_title: 'Normalna', + player_speed_two_descr: 'Odtwarzanie bez dźwięku', + player_video_speed: 'Prędkość odtwarzania', + player_share_title: 'Udostępnij', + player_share_descr: 'Uruchom to wideo na innym urządzeniu', + player_normalization_power_title: 'Siła normalizacji', + player_normalization_smooth_title: 'Płynność normalizacji', + player_normalization_step_none: 'Brak', + player_normalization_step_low: 'Niska', + player_normalization_step_medium: 'Średnia', + player_normalization_step_hight: 'Wysoka', + player_normalization: 'Normalizacja', + player_normalization_type_title: 'Typ normalizacji', + player_normalization_type_all: 'Wszystkie', + player_normalization_type_up: 'Tylko podnoszenie', + player_normalization_type_down: 'Tylko obniżanie', + player_youtube_no_played: 'Ten film nie jest dostępny w Twoim regionie.', + player_youtube_start_play: 'Naciśnij „Play”, aby rozpocząć', + player_youtube_no_support: 'Twoje urządzenie nie obsługuje YouTube.', + player_segments_title: 'Segmenty', + player_segments_descr: 'Pomijanie intro i innych części', + player_segments_ad_title: 'Reklamy', + player_segments_skip_title: 'Intro i inne', + player_segments_value_none: 'Nie pomijaj', + player_segments_value_auto: 'Auto pomijanie', + player_segments_value_user: 'Użytkownik', + player_segments_skiped: 'Segment pominięty', + player_segments_skip_now: 'Pomiń', + player_segments_skip_in: 'Pominięcie za', + player_segments_skip_intro: 'Pomiń intro', + player_segments_next: 'Następny odcinek', + player_segments_next_in: 'Następny odcinek za', + + broadcast_open: 'Otwórz kartę na innym urządzeniu', + broadcast_play: 'Wybierz urządzenie do odtwarzania', + + card_new_episode: 'Nowy odcinek', + card_book_remove: 'Usuń z zakładek', + card_book_add: 'Dodaj do zakładek', + card_book_descr: 'Zobacz w menu (Zakładki)', + card_like_remove: 'Usuń z polubionych', + card_like_add: 'Lubię to', + card_like_descr: 'Zobacz w menu (Lubię to)', + card_wath_remove: 'Usuń z „później”', + card_wath_add: 'Oglądaj później', + card_wath_descr: 'Zobacz w menu (Później)', + card_history_remove: 'Usuń z historii', + card_history_add: 'Dodaj do historii', + card_history_descr: 'Zobacz w menu (Historia)', + + keyboard_listen: 'Mów, słucham...', + keyboard_nomic: 'Brak dostępu do mikrofonu', + + notice_new_quality: 'Dostępna nowa jakość', + notice_quality: 'Jakość', + notice_new_episode: 'Nowy odcinek', + notice_none: 'Brak powiadomień. Zarejestruj się na {site}, aby śledzić nowości.', + notice_in_quality: 'W jakości', + notice_none_account: 'Brak powiadomień. Dodaj seriale do zakładek, aby otrzymywać aktualizacje.', + notice_none_system: 'Obecnie brak powiadomień.', + + copy_link: 'Kopiuj link do wideo', + copy_secuses: 'Link skopiowany do schowka', + copy_error: 'Błąd kopiowania linku', + copy_link_buffer: 'Skopiuj link', + + account_sync_to_profile: 'Zakładki zostaną przeniesione do profilu', + account_sync_secuses: 'Zakładki przeniesione', + account_profiles: 'Profile', + account_profiles_empty: 'Nie udało się pobrać listy profili', + account_authorized: 'Zalogowany', + account_logged_in: 'Zalogowano na konto', + account_login_failed: 'Logowanie nieudane', + account_login_wait: 'Oczekiwanie na logowanie', + account_profile_main: 'Główny', + account_profile_child: 'Dziecięcy', + account_profile_add: 'Dodaj profil', + account_profile_name: 'Nazwa profilu', + account_profile_created: 'Profil utworzony', + account_profile_limited: 'Osiągnięto limit profili', + account_profile_info: 'Zarządzaj profilami na stronie ', + account_export_secuses: 'Eksport zakończony sukcesem', + account_export_fail: 'Błąd eksportu', + account_export_fail_500: 'Nieznany błąd', + account_export_fail_610: 'Dzienny limit wyczerpany', + account_export_fail_200: 'Błąd bazy danych', + account_export_fail_600: 'Błąd pobierania pliku', + account_export_fail_620: 'Plik nie został przesłany', + account_import_secuses: 'Import zakończony sukcesem', + account_import_fail: 'Błąd importu', + account_imported: 'zaimportowano', + account_reload_after: 'restart za 5 sek.', + account_create: 'Załóż konto CUB, aby korzystać z synchronizacji zakładek i historii. Zarejestruj się na .', + account_premium: 'CUB Premium daje więcej możliwości. Odwiedź .', + account_premium_more: 'Więcej o Premium', + account_limited: 'Osiągnięto limit. Zwiększ go w CUB Premium.', + account_premium_include_1: 'Więcej zakładek', + account_premium_include_2: 'Większa historia', + account_premium_include_3: 'Więcej kodów czasu', + account_premium_include_4: 'Więcej profili', + account_premium_include_5: 'Powiadomienia', + account_premium_include_6: 'Synchronizacja danych', + account_premium_include_text_1: 'Więcej zakładek = więcej możliwości.', + account_premium_include_text_2: 'Rozszerzona historia oglądania.', + account_premium_include_text_3: 'Więcej punktów czasowych w filmach.', + account_premium_include_text_4: 'Więcej profili dla rodziny.', + account_premium_include_text_5: 'Powiadomienia o nowych odcinkach.', + account_premium_include_text_6: 'Synchronizacja między urządzeniami.', + account_code_enter: 'Wpisz 6-cyfrowy kod', + account_code_error: 'Kod nieprawidłowy lub wygasł', + account_code_wrong: 'Nieprawidłowy format kodu', + account_code_where: 'Wejdź na i wpisz kod.', + account_code_input: 'Wpisz kod', + account_qr_premium: 'Zeskanuj QR, aby dowiedzieć się o Premium', + account_qr_code: 'Zeskanuj QR, aby dodać urządzenie', + account_qr_create: 'Zeskanuj QR, aby utworzyć konto', + account_add_device_title: 'Dodaj urządzenie', + account_add_device_text: 'Wejdź na , aby uzyskać kod.', + account_none_title: 'Nie masz konta?', + account_none_include_1: 'Zakładki w chmurze', + account_none_include_2: 'Synchronizacja urządzeń', + account_none_include_3: 'Powiadomienia', + account_none_include_4: 'Profile użytkowników', + account_discuss_add_qr: 'Zeskanuj QR', + account_discuss_add_title: 'Chcesz dodać komentarz?', + account_discuss_add_text: 'Zeskanuj QR, aby dodać komentarz do filmu.', + account_discuss_added: 'Dziękujemy za komentarz!', + account_discuss_added_ready: 'Już dodałeś komentarz.', + + + network_noconnect: 'Brak połączenia z siecią', + network_404: 'Strona nie znaleziona [404]', + network_401: 'Błąd autoryzacji', + network_500: 'Błąd serwera [500]', + network_parsererror: 'Błąd parsowania JSON', + network_timeout: 'Przekroczono czas żądania', + network_abort: 'Żądanie przerwane', + network_error: 'Nieznany błąd', + + size_zero: '0 bajtów', + size_byte: 'bajt', + size_kb: 'Kbit', + size_mb: 'Mbit', + size_gb: 'Gbit', + size_tb: 'Tbit', + size_pp: 'Pbit', + + speed_bit: 'bit/s', + speed_kb: 'Kbit/s', + speed_mb: 'Mbit/s', + speed_gb: 'Gbit/s', + speed_tb: 'Tbit/s', + speed_pp: 'Pbit/s', + + month_1: 'Styczeń', + month_2: 'Luty', + month_3: 'Marzec', + month_4: 'Kwiecień', + month_5: 'Maj', + month_6: 'Czerwiec', + month_7: 'Lipiec', + month_8: 'Sierpień', + month_9: 'Wrzesień', + month_10: 'Październik', + month_11: 'Listopad', + month_12: 'Grudzień', + + day_1: 'Poniedziałek', + day_2: 'Wtorek', + day_3: 'Środa', + day_4: 'Czwartek', + day_5: 'Piątek', + day_6: 'Sobota', + day_7: 'Niedziela', + + month_1_e: 'Stycznia', + month_2_e: 'Lutego', + month_3_e: 'Marca', + month_4_e: 'Kwietnia', + month_5_e: 'Maja', + month_6_e: 'Czerwca', + month_7_e: 'Lipca', + month_8_e: 'Sierpnia', + month_9_e: 'Września', + month_10_e: 'Października', + month_11_e: 'Listopada', + month_12_e: 'Grudnia', + + week_1: 'Pn', + week_2: 'Wt', + week_3: 'Śr', + week_4: 'Cz', + week_5: 'Pt', + week_6: 'Sb', + week_7: 'Nd', + + time_h: 'h', + time_m: 'm', + time_s: 's', + + extensions_enable: 'Włącz', + extensions_disable: 'Wyłącz', + extensions_check: 'Sprawdź status', + extensions_install: 'Zainstaluj', + extensions_info: 'Informacje', + extensions_edit: 'Edytuj', + extensions_change_name: 'Zmień nazwę', + extensions_change_link: 'Zmień link', + extensions_remove: 'Usuń', + extensions_set_name: 'Wpisz nazwę wtyczki', + extensions_set_url: 'Wpisz adres wtyczki', + extensions_ready: 'Ta wtyczka jest już zainstalowana', + extensions_no_info: 'Brak informacji', + extensions_no_name: 'Bez nazwy', + extensions_worked: 'Działająca', + extensions_no_plugin: 'Wtyczka niepotwierdzona', + extensions_add: 'Dodaj wtyczkę', + extensions_from_memory: 'Zainstalowane w pamięci', + extensions_from_cub: 'Zainstalowane z CUB', + extensions_from_popular: 'Popularne wtyczki', + extensions_from_lib: 'Biblioteka wtyczek', + extensions_from_connected: 'Podłączone wtyczki', + extensions_hpu_best: 'Popularne', + extensions_hpu_recomend: 'Polecane', + extensions_hpu_theme: 'Motywy', + extensions_hpu_screensaver: 'Wygaszacz ekranu', + extensions_hpu_video: 'Wideo', + extensions_hpu_control: 'Sterowanie', + extensions_hpu_other: 'Różne', + extensions_hpu_: 'Pozostałe', + + speedtest_connect: 'łączenie', + speedtest_test: 'testowanie', + speedtest_ready: 'gotowe', + speedtest_button: 'Testuj prędkość', + + change_source_on_cub: 'Zmień źródło na CUB', + + tv_status_returning_series: 'Ongoing', + tv_status_planned: 'Zaplanowane', + tv_status_in_production: 'W produkcji', + tv_status_ended: 'Zakończone', + tv_status_canceled: 'Anulowane', + tv_status_pilot: 'Pilot', + tv_status_released: 'Wydane', + tv_status_rumored: 'Plotki', + tv_status_post_production: 'Wkrótce', + + input_detection_touch: 'Czy przełączyć na sterowanie dotykowe?', + input_detection_mouse: 'Czy przełączyć na sterowanie myszą?', + input_detection_remote: 'Czy przełączyć na sterowanie pilotem?', + + https_text: 'Używasz protokołu HTTPS, z którym Lampa działa nieprawidłowo. Dla poprawnego działania użyj adresu HTTP', + + premiere_author_recomend_1: 'Zamów pizzę i przygotuj się na akcję.', + premiere_author_recomend_2: 'Impreza dopiero się zaczyna.', + premiere_author_recomend_3: 'Przygotuj się na adrenalinę.', + premiere_author_recomend_4: 'Gotowy na niezapomniany wieczór?', + premiere_author_recomend_5: 'Polecam do obejrzenia.', + premiere_title: 'Premiera', + + termsofuse_t_01: 'Warunki użytkowania', + termsofuse_t_02: 'Lampa to narzędzie do przeglądania nowości filmowych...', + termsofuse_t_03: 'Treści', + termsofuse_t_04: 'Lampa korzysta z API themoviedb.org...', + termsofuse_t_05: 'API themoviedb.org umożliwia dostęp do bazy danych filmów...', + termsofuse_t_06: 'Komunikacja odbywa się przez zapytania API...', + termsofuse_t_07: 'Dzięki temu aplikacja zapewnia dostęp do bazy filmów...', + termsofuse_t_08: 'Rozszerzenia', + termsofuse_t_09: 'Rozszerzenia pozwalają rozszerzyć funkcje aplikacji...', + termsofuse_t_10: 'Użytkownik instaluje rozszerzenia na własne ryzyko...', + termsofuse_t_11: 'Naruszenia praw autorskich', + termsofuse_t_12: 'W razie naruszeń skontaktuj się z twórcami...', + termsofuse_t_13: 'Zgłoś problem właścicielowi treści...', + + install_app_apk_title: 'Jak zainstalować Lampa na Androidzie', + install_app_apk_text: 'Zalecamy instalację APK dla stabilności...', + install_app_apk_qr: 'Zeskanuj QR, aby pobrać APK', + + ad: 'Reklama', + ad_disable: 'Subskrypcja CUB Premium usuwa reklamy.', + ad_plugin: 'Reklama z wtyczki', + ad_after: 'Reklama za', + ad_skip: 'Pomiń', + ad_continue_after: 'Odtwarzanie rozpocznie się za', + + discuss_rules_title: 'Przestrzegaj zasad i szanuj innych', + discuss_rules_rule_1: 'Nie używaj samych cyfr.', + discuss_rules_rule_2: 'Pisz w jednym języku.', + discuss_rules_rule_3: 'Używaj interpunkcji.', + discuss_rules_rule_4: 'Unikaj symboli !?#%', + discuss_rules_rule_5: 'Pisz pełne zdania.', + discuss_rules_rule_6: 'Nie używaj bardzo długich słów.', + discuss_rules_rule_7: 'Maks. 300 znaków.', + discuss_voited: 'Dziękujemy za ocenę!', + + confirm_open_player: 'Inne urządzenie chce uzyskać dostęp do odtwarzacza. Odtworzyć wideo?', + + pincode_use_remote: 'Użyj pilota do wpisania kodu.', + pincode_use_toggle: 'Przytrzymaj OK, aby zmienić układ.', + + storage_quota_exceeded: 'Przekroczono limit pamięci. Wyczyść cache.', + + ai_search_start_typing: 'Zapytaj AI o filmy, np. „filmy o kosmosie”', + ai_search_limit: 'Przekroczono limit zapytań AI.', + ai_subscribe_title: 'Więcej możliwości z AI', + ai_subscribe_descr: 'Subskrybuj CUB Premium i zwiększ limity AI.', + + dmca_title: 'Treść zablokowana', + dmca_descr: 'Ten materiał został zablokowany na wniosek właściciela praw.', + dmca_title_lgbt: 'Treść ograniczona', + dmca_descr_lgbt: 'Niedostępne w Twoim regionie.', + + loading_progress_step_0: 'Przygotowanie', + loading_progress_step_1: 'Ładowanie języków', + loading_progress_step_2: 'Wyszukiwanie mirrorów', + loading_progress_step_3: 'Ładowanie rozszerzeń', + loading_progress_step_4: 'Jeszcze chwilę', + loading_progress_step_5: 'Już prawie', + + install_extension_rule_1: 'Instalacja wtyczki zewnętrznej', + install_extension_rule_2: 'Wtyczki są tworzone przez niezależnych twórców...', + install_extension_rule_3: '- Mogą wymagać dostępu do danych', + install_extension_rule_4: '- Odpowiedzialność spoczywa na użytkowniku', + install_extension_rule_5: '- Instaluj tylko z zaufanych źródeł', + install_extension_rule_6: 'LAMPA nie wspiera pirackich wtyczek.', + install_extension_rule_7: 'Kontynuując akceptujesz ryzyko.', + + terminal_title: 'Terminal', + terminal_no_access: 'Brak dostępu', + terminal_confirm: 'Zezwól', + terminal_deny: 'Odmów', + terminal_update: 'Aktualizuj', + terminal_code: 'Kod dostępu', + terminal_text: 'Żądanie dostępu do terminala...', + + developer_param_enabled: 'Tryb deweloperski', + developer_param_nopremium: 'Wyłącz CUB Premium', + developer_param_nodemo: 'Wyłącz tryb demo', + developer_param_ads: 'Pokaż reklamy', + developer_param_fps: 'Pokaż FPS', + + developer_trigger_help_1: 'Prawie', + developer_trigger_help_2: 'Jeszcze trochę', + developer_trigger_help_3: 'Na pewno chcesz?', + developer_trigger_help_4: 'Tryb deweloperski aktywny', + + remote_helper_long: 'Przytrzymaj OK, aby otworzyć menu', + no_watch_history: 'Brak historii', + + adult_content_title: 'Treści dla dorosłych', + adult_content_text_warning: 'Materiał może zawierać treści 18+.', + adult_content_text_modal: 'Potwierdź pełnoletność.', + + adult_content_confirm: 'Mam 18 lat lub więcej', + adult_content_deny: 'Mam mniej niż 18 lat', + + inner_player_disclaimer_title: 'Ostrzeżenie odtwarzacza', + inner_player_disclaimer_text: 'Odtwarzacz może działać niestabilnie.', + + inner_player_disclaimer_change_player: 'Zmień odtwarzacz', + remote_configuration_settings_title: 'Konfiguracja zdalna', + remote_configuration_registration_text: 'Zdalny dostęp do ustawień...', + remote_configuration_waite_text: 'Przekaż kod do innej aplikacji.', + remote_configuration_open_button: 'Otwórz dostęp', + remote_configuration_code_life: 'Kod ważny', + remote_configuration_notice_nocode: 'Nie udało się otworzyć dostępu', + + settings_server_gts: 'Transkodowanie', + settings_server_gts_descr: 'Automatycznie konwertuj filmy do zgodnego formatu, gdy jest to potrzebne.', + settings_server_tracktimecode: 'Ativar TrackTimecode', + settings_server_tracktimecode_descr: 'Zapisuje postęp odtwarzania filmów i seriali na serwerze TorrServer. Aby funkcja działała, opcja musi być również włączona w TorrServer.', + + title_metadata: 'Metadane', + title_moods: 'Nastroje', + title_meta_violence: 'Przemoc', + title_meta_fear: 'Strach', + title_meta_profanity: 'Słownictwo', + title_meta_sadness: 'Smutek', + title_meta_sex: 'Seksualność', + player_pip: 'Zmniejsz', + player_volume: 'Głośność', + player_time_end: 'Koniec o', + player_ai_agent_info: 'Chcesz dowiedzieć się więcej o filmie? Zapytaj asystenta AI, a on dostarczy Ci wykres nastrojów, krótkie streszczenie fabuły i ciekawe momenty.', + player_ai_agent_ask_plot: 'Krótko o fabule', + player_ai_agent_ask_moods: 'Pokaż wykres', + player_ai_agent_ask_highlights: 'Ciekawe momenty', + player_ai_agent_ask: 'Zapytaj', + player_ai_agent_processing: 'Analizuję...', + player_ai_agent_no_data: 'Brak danych do wyświetlenia.', + player_ai_agent_no_analysis: 'Nie udało się przeanalizować wideo.', + player_ai_agent_quota: 'Limit zapytań przekroczony. Spróbuj ponownie później.', + player_ai_agent_working: 'Nadal nad tym pracuję...', + title_meta_humor: 'Humor', + title_meta_tension: 'Napięcie', + title_meta_romance: 'Romans', + title_meta_pace: 'Tempo', + title_meta_importance: 'Kluczowe sceny', + title_meta_action: 'Akcja' +} \ No newline at end of file diff --git a/lampa-main/lang/pt.js b/lampa-main/lang/pt.js new file mode 100644 index 0000000..41ea917 --- /dev/null +++ b/lampa-main/lang/pt.js @@ -0,0 +1,1348 @@ +export default { + lang_choice_title: 'Bem-vindo', + lang_choice_subtitle: 'Escolhe o teu idioma', + + more: 'Mais', + show_more: 'Mostrar mais', + more_results: 'Mostrar mais resultados', + loading: 'Carregando', + nofind_movie: 'Não foi possível encontrar o filme.', + noname: 'Sem título', + nochoice: 'Não escolhido', + cancel: 'Cancelar', + confirm: 'Confirmar', + sure: 'Tem a certeza?', + nodata: 'Sem resultados', + back: 'Voltar', + ready: 'Preparar', + close_app_modal: 'Tem certeza de que deseja sair do aplicativo?', + connected_seeds: 'conect.', + + search: 'Procurar', + search_input: 'Inserir texto', + search_empty: 'Histórico de procura está vazio.', + search_delete: 'Esquerda - apagar', + search_start_typing: 'Comece a inserir o texto de pesquisa.', + search_searching: 'Procura em progresso...', + search_start: 'Começar a pesquisar', + search_nofound: 'Não encontrámos nada relacionado com a sua pesquisa.', + global_search: 'Pesquisa global', + + full_genre: 'Gênero', + full_production: 'Produção', + full_date_of_release: 'Data de lançamento', + full_budget: 'Orçamento', + full_countries: 'Países', + full_like: 'Gostos', + full_torrents: 'Torrents', + full_trailers: 'Trailers', + full_detail: 'Detalhes', + full_notext: 'Sem descrição.', + full_series_release: 'Lançamento da série', + full_next_episode: 'Seguinte', + full_episode_days_left: 'Dias restantes', + full_trailer_official: 'Oficial', + full_trailer_no_official: 'Não oficial', + full_season: 'Temporada', + full_episode: 'Episódio', + full_directing: 'Dirigir', + + settings_cub_sync: 'Sincronização', + settings_cub_sync_descr: 'Sincronização com serviço CUB: favoritos, histórico de navegação, tags e retomar reprodução.', + settings_cub_account: 'Conta', + settings_cub_logged_in_as: 'Logado como', + settings_cub_profile: 'Perfil', + settings_cub_sync_btn: 'Sincronizar', + settings_cub_sync_btn_descr: 'Guardar favoritos na conta CUB', + settings_cub_backup: 'Backup', + settings_cub_backup_descr: 'Guardar ou importar backup', + settings_cub_logout: 'Sair', + settings_cub_signin: 'Autorização', + settings_cub_not_specified: 'Não específicado', + settings_cub_password: 'Password', + settings_cub_status: 'Estado', + settings_cub_backup_import: 'Importar', + settings_cub_backup_export: 'Exportar', + settings_cub_sync_filters: 'Sincronizar filtros', + settings_cub_sync_calendar: 'Sincronizar calendário', + settings_cub_sync_quality: 'Sincronizar qualidade', + settings_cub_sync_search: 'Sincronizar histórico de pesquisa', + settings_cub_sync_recomends: 'Sincronizar recomendações', + settings_cub_sync_timecodes: 'Sincronização de código de tempo', + + settings_input_links: 'Favoritos', + + settings_interface_type: 'Versão Lite', + settings_interface_size: 'Tamanho interface', + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: 'Fundo', + settings_interface_background_use: 'Mostar fundo', + settings_interface_background_type: 'Tipo de fundo', + settings_interface_performance: 'Performance', + settings_interface_animation: 'Animação', + settings_interface_animation_descr: 'Animação de cartões e conteúdo', + settings_interface_attenuation: 'Atenuação', + settings_interface_attenuation_descr: 'Desvanecimento suave dos cartões de baixo e de cima', + settings_interface_scroll: 'Tipo de rolagem (scroll)', + settings_interface_view_card: 'Tipo de visualização do cartão', + settings_interface_view_card_descr: 'Conforme rola o feed, os cartões serão carregados gradualmente ou carregarão todos', + settings_interface_lang: 'Idioma da interface', + settings_interface_lang_reload: 'É necessário reiniciar a aplicação, clique "OK" para reiniciar.', + + settings_main_account: 'Conta', + settings_main_interface: 'Interface', + settings_main_player: 'Videoplayer', + settings_main_parser: 'Analisador', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Extensões', + settings_main_rest: 'Outros', + + settings_rest_start: 'Página inicial', + settings_rest_start_descr: 'Qual página iniciar na inicialização', + settings_rest_source: 'Fonte', + settings_rest_source_use: 'Fonte principal', + settings_rest_source_descr: 'Onde obter a informação sobre os filmes', + settings_rest_tmdb_lang: 'Qual o idioma para mostrar os dados do TMDB', + settings_rest_tmdb_prox: 'Proxy TMDB', + settings_rest_tmdb_prox_auto: 'Ativar proxy automaticamente', + settings_rest_tmdb_posters: 'Resolução dos posters do TMDB', + settings_rest_screensaver: 'Protetor de ecrã', + settings_rest_screensaver_use: 'Mostrar quando ocupado', + settings_rest_screensaver_type: 'Tipo protetor de ecrã', + settings_rest_helper: 'Dicas', + settings_rest_helper_use: 'Mostrar dicas', + settings_rest_helper_reset: 'Mostrar dicas novamente', + settings_rest_pages: 'Quantas páginas manter na memória', + settings_rest_pages_descr: 'Manter as páginas no estado em as deixei', + settings_rest_time: 'Shift time', + settings_rest_navigation: 'Tipo de navegação', + settings_rest_keyboard: 'Teclado', + settings_rest_device: 'Nome do dispositivo', + settings_rest_device_placeholder: 'Examplo: Meu Lamp', + settings_rest_cache: 'Limpar cache', + settings_rest_cache_descr: 'Todas as configurações e dados serão apagados', + settings_rest_tmdb_example: 'Por examplo:', + settings_rest_tmdb_api_descr: 'Para obter dados', + settings_rest_tmdb_image_descr: 'Para obter imagens', + settings_rest_card_quality: 'Marcas da qualidade', + settings_rest_card_quality_descr: 'Mostrar marcas da qualidade nos cartões', + settings_rest_card_episodes: 'Marcas do episódio', + settings_rest_card_episodes_descr: 'Mostrar marcas do episódio nos cartões', + + settings_parser_use: 'Usar analisador', + settings_parser_use_descr: 'Por meio deste, você concorda em aceitar toda a responsabilidade pelo uso de links públicos para visualizar torrents e conteúdo online.', + settings_parser_type: 'Tipo de analisador para torrents', + settings_parser_jackett_placeholder: 'Por exemplo: 192.168.x', + settings_parser_jackett_link: 'Endereço', + settings_parser_jackett_link_descr: 'Fornecer um endereço para a aplicação Jackett', + settings_parser_jackett_key_placeholder: 'Por exemplo: sa0sk83d..', + settings_parser_jackett_key: 'Chave da API', + settings_parser_jackett_key_descr: 'Localizado em Jackett', + settings_parser_torlook_type: 'Método de análise do site TorLook', + settings_parser_scraperapi_placeholder: 'Por exemplo: scraperapi.com', + settings_parser_scraperapi_link: 'Endereço para o analisador do site', + settings_parser_scraperapi_descr: 'Registar-se no site scraperapi.com, digite o endereço api.scraperapi.com?api_key=...&url={q}
    W41.torlook.info será entregue em {q}', + settings_parser_search: 'Pesquisar', + settings_parser_search_descr: 'Pesquisar em que idioma?', + settings_parser_in_search: 'Analisador na pesquisa', + settings_parser_in_search_descr: 'Mostrar resultados de pesquisa?', + settings_parser_timeout_title: 'Tempo limite do analisador', + settings_parser_timeout_descr: 'Tempo em segundos para aguardar uma resposta do servidor', + + settings_player_type: 'Tipo player', + settings_player_type_descr: 'Qual o player a utilizar', + settings_infuse_launch_mode: 'Iniciar no Infuse', + settings_infuse_launch_mode_descr: 'O que fazer ao abrir vídeo no Infuse. Torrents sempre reproduzem imediatamente', + settings_infuse_launch_ask: 'Perguntar ao iniciar', + settings_infuse_launch_play: 'Reproduzir', + settings_infuse_launch_save_and_play: 'Guardar e reproduzir', + settings_player_iptv_type: 'Tipo de player para IPTV', + settings_player_iptv_type_descr: 'Qual player reproduzir canais de IPTV', + settings_player_reset: 'Redefinir player padrão', + settings_player_reset_descr: 'Reinicia o player Android selecionado no aplicativo', + settings_player_path: 'Caminho para o player', + settings_player_path_descr: 'Especifique o caminho para o player .exe', + settings_player_external_header: 'Reprodutor externo', + settings_player_external_fullscreen: 'Iniciar em modo de tela cheia', + settings_player_normalization: 'Normalização de som', + settings_player_normalization_descr: 'Normaliza o som para um nível, diminui os sons altos e aumenta os silenciosos.', + settings_player_next_episode: 'Próximo episódio', + settings_player_next_episode_descr: 'Passar automaticamente para o próximo episódio após o final do atual', + settings_player_timecode: 'Tempo visualizado', + settings_player_timecode_descr: 'Retomar reprodução na última localização visualizada', + settings_player_scale: 'Método de dimensionamento', + settings_player_scale_descr: 'Como calcular o dimensionamento de vídeo', + settings_player_subs: 'Legendas', + settings_player_subs_use: 'Ativar', + settings_player_subs_use_descr: 'Ativar sempre as legendas depois de iniciar um vídeo', + settings_player_subs_lang: 'Idioma das legendas', + settings_player_subs_lang_descr: 'Quais legendas ativar automaticamente quando houver vários idiomas', + settings_param_subtitles_lang_auto: 'Idioma da interface', + settings_player_subs_size: 'Tamanho', + settings_player_subs_size_descr: 'Tamanho das legendas', + settings_player_subs_stroke_use: 'Usar borda', + settings_player_subs_stroke_use_descr: 'As legendas serão contornadas em preto para melhor legibilidade', + settings_player_subs_backdrop_use: 'Usar fundo', + settings_player_subs_backdrop_use_descr: 'As legendas serão mostradas em um fundo translúcido para melhorar a legibilidade', + settings_player_quality: 'Qualidade de vídeo padrão', + settings_player_quality_descr: 'Qualidade de vídeo preferida para visualização', + settings_player_hls_title: 'Processando o stream .m3u8', + settings_player_hls_descr: 'Não toque neste parâmetro se você não sabe o motivo.', + + settings_plugins_notice: 'Para aplicar o plugin, você precisa reiniciar a aplicação', + settings_plugins_add: 'Adicionar plugin', + settings_plugins_add_descr: 'Para remover um plugin, segure ou clique duas vezes na tecla (OK) nele', + settings_plugins_install: 'Instalar Plugin', + settings_plugins_install_descr: 'Instalar um plugin da lista de disponíveis', + + settings_server_link: 'Usar endereço', + settings_server_links: 'Endereços', + settings_server_placeholder: 'Por exemplo: 192.168.X', + settings_server_link_one: 'Endereço principal', + settings_server_link_one_descr: 'Especifique o link principal para a aplicação TorrServer', + settings_server_link_two: 'Endereço secundário', + settings_server_link_two_descr: 'Fornecer um link adicional para a aplicação TorrServer', + settings_server_additionally: 'Adicionalmente', + settings_server_client: 'Cliente incorporado', + settings_server_client_descr: 'Use o cliente TorrServer JS embutido, caso contrário o sistema será iniciado.', + settings_server_base: 'Guardar na base de dados', + settings_server_base_descr: 'O torrent será adicionado na base de dados do TorrServer', + settings_server_preload: 'Usar buffer de pré-busca', + settings_server_preload_descr: 'Aguardar que o buffer de pré-carregamento do TorrServer seja preenchido antes de iniciar', + settings_server_auth: 'Autorização', + settings_server_password_use: 'Login com password', + settings_server_login: 'Login', + settings_server_password: 'Password', + settings_server_not_specified: 'Não especificado', + settings_server_search_type: 'Tipo de pesquisa', + settings_server_search_type_descr: 'Onde procurar torrents: rutor integrado, indexadores Torznab em TorrServer, ou ambos.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + torent_nohash_reasons: 'Motivos', + torent_nohash_reason_one: 'TorrServer não conseguiu fazer o download do ficheiro torrent', + torent_nohash_reason_two: 'Resposta do TorrServer', + torent_nohash_reason_three: 'Endereço', + torent_nohash_do: 'O que fazer?', + torent_nohash_do_one: 'Verifique se configurou o Jackett corretamente', + torent_nohash_do_two: 'Fontes privadas podem não fornecer um endereço para o ficheiro', + torent_nohash_do_three: 'Certifique-se de que o Jackett também pode fazer o download do ficheiro', + torent_nohash_do_four: 'Escreva para nosso grupo do Telegram: @lampa_group', + torent_nohash_do_five: 'Especifique qual o filme, qual distribuição e, se possível, uma foto desta distribuição', + + torrent_error_text: 'Falha ao conectar ao TorrServer. Vamos passar rapidamente pela lista de possíveis problemas e verificar tudo.', + torrent_error_step_1: 'O TorrServer está a correr', + torrent_error_step_2: 'IP dinâmico', + torrent_error_step_3: 'Protocolo e Porta', + torrent_error_step_4: 'Bloqueio de antivírus', + torrent_error_step_5: 'Verificar disponibilidade', + torrent_error_step_6: 'Ainda não funciona', + torrent_error_info_1: 'Certifique-se de ter iniciado o TorrServer no dispositivo onde está instalado.', + torrent_error_info_2: 'Um erro comum, o endereço IP do dispositivo com TorrServer mudou. Certifique-se de que o endereço IP que você digitou - {ip} - corresponde ao endereço do dispositivo no qual o TorrServer está instalado.', + torrent_error_info_3: 'Para se conectar ao TorrServer, você deve especificar o protocolo http:// no início e a porta :8090 no final do endereço. Verifique se há uma porta após o endereço IP, seu endereço atual é {ip}', + torrent_error_info_4: 'Ocorrência frequente, antivírus ou firewall pode bloquear o acesso por endereço IP, tente desabilitar antivírus e firewall.', + torrent_error_info_5: 'Em qualquer outro dispositivo na mesma rede, abra o endereço {ip} em um navegador e verifique se a interface web do TorrServer está disponível.', + torrent_error_info_6: 'Se, após todas as verificações, ainda ocorrer um erro de conexão, tente reiniciar o TorrServer e o adaptador de Internet.', + torrent_error_info_7: 'Se o problema persistir, escreva para o grupo do Telegram @lampa_group.', + torrent_error_start: 'Iniciar verificação', + torrent_error_nomatrix: 'Falha ao verificar a versão Matrix', + torrent_error_made: 'Executado', + torrent_error_from: 'de', + torrent_error_next: 'Seguinte', + torrent_error_complite: 'Para completar', + torrent_error_connect: 'Erro de conexão', + + torrent_install_need: 'Requer TorrServer', + torrent_install_text: 'TorrServer é uma aplicação que permite visualizar conteúdo de ficheiros torrent online.

    Informações mais detalhadas sobre instalação podem ser encontradas nos grupos do Telegram abaixo.', + torrent_install_contact: 'Grupos do Telegram', + + torrent_item_bitrate: 'Bitrate', + torrent_item_seeds: 'Seeds', + torrent_item_grabs: 'Leechers', + torrent_item_mb: 'Mbps', + + torrent_serial_episode: 'Episódio', + torrent_serial_season: 'Temporada', + torrent_serial_date: 'Data', + + torrent_get_magnet: 'Solicitando um link magnético', + torrent_remove_title: 'Remover', + torrent_remove_descr: 'O torrent será removido da sua lista', + + torrent_parser_any_one: 'Qualquer', + torrent_parser_any_two: 'Qualquer', + torrent_parser_no_choice: 'Não escolhido', + torrent_parser_yes: 'Sim', + torrent_parser_no: 'Não', + torrent_parser_quality: 'Qualidade', + torrent_parser_subs: 'Legendas', + torrent_parser_voice: 'Tradução', + torrent_parser_tracker: 'Tracker', + torrent_parser_year: 'Ano', + torrent_parser_season: 'Temporada', + torrent_parser_sort_by_seeders: 'Por seeders', + torrent_parser_sort_by_size: 'Por tamanho', + torrent_parser_sort_by_name: 'Por nome', + torrent_parser_sort_by_tracker: 'Por tracker', + torrent_parser_sort_by_date: 'Por data', + torrent_parser_sort_by_viewed: 'Por vistos', + torrent_parser_voice_dubbing: 'Dobrados', + torrent_parser_voice_polyphonic: 'Polifônico', + torrent_parser_voice_two: 'Duas vozes', + torrent_parser_voice_amateur: 'Amador', + torrent_parser_reset: 'Redefinir filtro', + torrent_parser_empty: 'Falha ao obter resultados', + torrent_parser_no_hash: 'Falha ao obter HASH, tente recarregar o TorrServer', + torrent_parser_added_to_mytorrents: 'Adicionado a "Meus torrents"', + torrent_parser_add_to_mytorrents: 'Adicionar a "Meus torrents"', + torrent_parser_label_title: 'Sinalizador', + torrent_parser_label_descr: 'Sinalize uma mão com uma bandeira (visualizada)', + torrent_parser_label_cancel_title: 'Desmarcar', + torrent_parser_label_cancel_descr: 'Remover a marca da distribuição (visualizada)', + torrent_parser_timeout: 'Tempo limite expirado', + torrent_parser_nofiles: 'Falha ao extrair ficheiros', + torrent_parser_set_link: 'Especifique um endereço para análise', + torrent_parser_request_error: 'Erro na solicitação', + torrent_parser_magnet_error: 'Falha ao obter o endereço magnético', + torrent_parser_no_responce: 'O analisador não está respondendo à solicitação', + torrent_parser_torlook_fallback_search_notification: 'O analisador Jackett não está disponível ou as configurações de conexão estão incorretas. Procurando Torlook...', + + about_text: 'A aplicação é totalmente gratuita e usa endereços públicos para obter informações sobre vídeos, novos lançamentos, filmes populares, etc. Todas as informações disponíveis são usadas exclusivamente para fins educacionais, a aplicação não usa servidores próprios para distribuir informações.', + about_channel: 'Nosso canal', + about_group: 'Grupo', + about_version: 'Versão', + about_donate: 'Donativos', + + title_watched: 'Você assistiu', + title_settings: 'Configurações', + title_collections: 'Coleções', + title_company: 'Empresa', + title_actors: 'Atores', + title_actor: 'Ator', + title_actress: 'Atriz', + title_person: 'Pessoa', + title_persons: 'Pessoas', + title_comments: 'Comentários', + title_torrents: 'Torrents', + title_trailers: 'Trailers', + title_watch: 'Assistir', + title_error: 'Erro', + title_links: 'Endereços', + title_choice: 'Escolher', + title_main: 'Início', + title_book: 'Favoritos', + title_like: 'Gosto', + title_wath: 'Ver mais tarde', + title_history: 'Histórico de navegação', + title_mytorrents: 'Meus torrents', + title_last: 'Último', + title_action: 'Ação', + title_action_infuse: 'Ação Infuse', + title_producer: 'Produtor', + title_collection: 'Coleção', + title_recomendations: 'Recomendações', + title_similar: 'Semelhantes', + title_about: 'Sobre a aplicação', + title_timetable: 'Programação', + title_relises: 'Lançamentos digitais', + title_catalog: 'Catálogo', + title_category: 'Categoria', + title_parser: 'Analisador', + title_type: 'Tipo de', + title_rating: 'Classificação', + title_country: 'País', + title_year: 'Ano', + title_genre: 'Gênero', + title_filter: 'Filtro', + title_notice: 'Notificações', + title_files: 'Ficheiros', + title_now_watch: 'Assistindo agora', + title_latest: 'Última adição', + title_continue: 'Continuar navegando', + title_recomend_watch: 'Recomendamos ver', + title_new_episodes: 'Novos episódios', + title_popular: 'Popular', + title_popular_movie: 'Filmes populares', + title_popular_tv: 'Séries populares', + title_new_this_year: 'Novo este ano', + title_hight_voite: 'Altamente avaliado', + title_new: 'Novo', + title_trend_day: 'Tendências de hoje', + title_trend_week: 'Tendências da semana', + title_upcoming: 'Assista nos cinemas', + title_top_movie: 'Principais filmes', + title_top_tv: 'Melhor série', + title_tv_today: 'No ar hoje', + title_this_week: 'Esta semana', + title_in_top: 'Top', + title_out: 'Sair', + title_out_confirm: 'Sim, quero sair', + title_continue_two: 'Continuar', + title_choice_language: 'Escolha um idioma', + title_subscribe: 'Inscrever-se', + title_subscribes: 'Subscrições', + title_unsubscribe: 'Cancelar inscrição', + title_language: 'Idioma original', + + subscribe_success: 'Inscreveu-se com sucesso', + subscribe_error: 'Ocorreu um erro ao inscrever, por favor tente novamente mais tarde', + subscribe_noinfo: 'Falha ao recuperar informações, tente novamente mais tarde', + + company_headquarters: 'Sede', + company_homepage: 'Website', + company_country: 'País', + + country_ad: 'Andorra', + country_ae: 'Emirados Árabes Unidos', + country_af: 'Afeganistão', + country_al: 'Albânia', + country_am: 'Armênia', + country_ao: 'Angola', + country_ar: 'Argentina', + country_at: 'Áustria', + country_au: 'Austrália', + country_aw: 'Aruba', + country_az: 'Azerbaijão', + country_bа: 'Bósnia e Herzegovina', + country_bd: 'Bangladesh', + country_be: 'Bélgica', + country_bg: 'Bulgária', + country_bh: 'Bahrein', + country_bi: 'Burundi', + country_bj: 'Benin', + country_bo: 'Bolívia', + country_br: 'Brasil', + country_bs: 'Bahamas', + country_bt: 'Butão', + country_bw: 'Botsuana', + country_by: 'Bielorrússia', + country_ca: 'Canadá', + country_ch: 'Suíça', + country_cl: 'Chile', + country_cm: 'Camarões', + country_cn: 'China', + country_co: 'Colômbia', + country_cr: 'Costa Rica', + country_cu: 'Cuba', + country_cv: 'Cabo Verde', + country_cy: 'Chipre', + country_cz: 'República Tcheca', + country_de: 'Alemanha', + country_dj: 'Djibuti', + country_dk: 'Dinamarca', + country_do: 'República Dominicana', + country_dz: 'Argélia', + country_ec: 'Equador', + country_ee: 'Estônia', + country_eg: 'Egito', + country_es: 'Espanha', + country_et: 'Etiópia', + country_fi: 'Finlândia', + country_fo: 'Ilhas Faroé', + country_fr: 'França', + country_ga: 'Gabão', + country_gb: 'Reino Unido', + country_ge: 'Geórgia', + country_gh: 'Gana', + country_gl: 'Gronelândia', + country_gp: 'Guadalupe', + country_gr: 'Grécia', + country_gt: 'Guatemala', + country_hk: 'Hong Kong', + country_hr: 'Croácia', + country_ht: 'Haiti', + country_hu: 'Hungria', + country_id: 'Indonésia', + country_ie: 'Irlanda', + country_il: 'Israel', + country_in: 'Índia', + country_iq: 'Iraque', + country_ir: 'Irã', + country_is: 'Islândia', + country_it: 'Itália', + country_jm: 'Jamaica', + country_jo: 'Jordânia', + country_jp: 'Japão', + country_ke: 'Quênia', + country_kg: 'Quirguistão', + country_kh: 'Camboja', + country_kp: 'Coreia do Norte', + country_kr: 'Coreia do Sul', + country_kz: 'Cazaquistão', + country_kw: 'Kuwait', + country_la: 'Laos', + country_lb: 'Líbano', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Libéria', + country_lt: 'Lituânia', + country_lu: 'Luxemburgo', + country_lv: 'Letônia', + country_ly: 'Líbia', + country_ma: 'Marrocos', + country_mc: 'Mônaco', + country_md: 'Moldávia', + country_me: 'Montenegro', + country_mk: 'Macedônia', + country_mm: 'Mianmar', + country_mn: 'Mongólia', + country_mo: 'Macau', + country_mt: 'Malta', + country_mu: 'Maurício', + country_mv: 'Maldivas', + country_mw: 'Malawi', + country_mx: 'México', + country_my: 'Malásia', + country_mz: 'Moçambique', + country_na: 'Namíbia', + country_ne: 'Níger', + country_ng: 'Nigéria', + country_ni: 'Nicarágua', + country_nl: 'Holanda', + country_no: 'Noruega', + country_np: 'Nepal', + country_nz: 'Nova Zelândia', + country_om: 'Omã', + country_pa: 'Panamá', + country_pe: 'Peru', + country_pg: 'Papua Nova Guiné', + country_ph: 'Filipinas', + country_pk: 'Paquistão', + country_pl: 'Polônia', + country_pr: 'Porto Rico', + country_ps: 'Território Palestino', + country_pt: 'Portugal', + country_py: 'Paraguai', + country_qa: 'Catar', + country_ro: 'Romênia', + country_rs: 'Sérvia', + country_ru: 'Rússia', + country_rw: 'Ruanda', + country_sa: 'Arábia Saudita', + country_sd: 'Sudão', + country_se: 'Suécia', + country_sg: 'Singapura', + country_si: 'Eslovênia', + country_sk: 'Eslováquia', + country_sn: 'Senegal', + country_su: 'URSS', + country_sv: 'El Salvador', + country_sy: 'Síria', + country_th: 'Tailândia', + country_tj: 'Tajiquistão', + country_tm: 'Turquemenistão', + country_tn: 'Tunísia', + country_tr: 'Turquia', + country_tw: 'Taiwan', + country_tz: 'Tanzânia', + country_ua: 'Ucrânia', + country_ug: 'Uganda', + country_us: 'EUA', + country_uy: 'Uruguai', + country_uz: 'Uzbequistão', + country_ve: 'Venezuela', + country_vn: 'Viet Nam', + country_xk: 'Kosovo', + country_ws: 'Samoa', + country_ye: 'Iêmen', + country_yu: 'Iugoslávia', + country_za: 'África do Sul', + country_zm: 'Zâmbia', + country_zw: 'Zimbábue', + + filter_clarify: 'Clarificar', + filter_clarify_two: 'Refinar pesquisa', + filter_set_name: 'Especificar título', + filter_sorted: 'Ordenar', + filter_filtred: 'Filtrar', + filter_any: 'Qualquer', + filter_combinations: 'Combinações', + filter_alt_names: 'Outros nomes', + filter_rating_from: 'desde', + filter_rating_to: 'até', + + filter_lang_af: 'Africâner', + filter_lang_ar: 'Árabe', + filter_lang_az: 'Azerbaijano', + filter_lang_ba: 'Bashkir', + filter_lang_be: 'Bielorrusso', + filter_lang_bg: 'Búlgaro', + filter_lang_bn: 'Bengali', + filter_lang_bs: 'Bósnio', + filter_lang_ca: 'Catalão', + filter_lang_ce: 'Checheno', + filter_lang_cs: 'Tcheco', + filter_lang_da: 'Dinamarquês', + filter_lang_de: 'Alemão', + filter_lang_el: 'Grego', + filter_lang_en: 'Inglês', + filter_lang_es: 'Espanhol', + filter_lang_et: 'Estoniano', + filter_lang_fa: 'Persa', + filter_lang_fi: 'Finlandês', + filter_lang_fr: 'Francês', + filter_lang_ga: 'Irlandês', + filter_lang_gl: 'Galego', + filter_lang_gn: 'Guarani', + filter_lang_he: 'Hebraico', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Croata', + filter_lang_hu: 'Húngaro', + filter_lang_hy: 'Armênio', + filter_lang_id: 'Indonésio', + filter_lang_is: 'Islandês', + filter_lang_it: 'Italiano', + filter_lang_ja: 'Japonês', + filter_lang_ka: 'Georgiano', + filter_lang_kk: 'Cazaque', + filter_lang_ko: 'Coreano', + filter_lang_ks: 'Caxemira', + filter_lang_ku: 'Curdo', + filter_lang_ky: 'Kirghiz', + filter_lang_lt: 'Lituano', + filter_lang_lv: 'Letão', + filter_lang_mi: 'Maori', + filter_lang_mk: 'Macedônio', + filter_lang_mn: 'Mongol', + filter_lang_mt: 'Maltês', + filter_lang_ne: 'Nepalês', + filter_lang_nl: 'Holandês', + filter_lang_no: 'Norueguês', + filter_lang_pa: 'Punjabi', + filter_lang_pl: 'Poláco', + filter_lang_ps: 'Pushto', + filter_lang_pt: 'Português', + filter_lang_ro: 'Romeno', + filter_lang_ru: 'Russo', + filter_lang_si: 'Cingalês', + filter_lang_sk: 'Eslovaco', + filter_lang_sl: 'Esloveno', + filter_lang_sm: 'Samoano', + filter_lang_so: 'Somali', + filter_lang_sq: 'Albanês', + filter_lang_sr: 'Sérvio', + filter_lang_sv: 'Sueco', + filter_lang_sw: 'Suaíli', + filter_lang_ta: 'Tâmil', + filter_lang_tg: 'Tajique', + filter_lang_th: 'Tailandês', + filter_lang_tk: 'Turkmen', + filter_lang_tr: 'Turco', + filter_lang_tt: 'Tártaro', + filter_lang_ur: 'Urdu', + filter_lang_uk: 'Ucraniano', + filter_lang_uz: 'Uzbeque', + filter_lang_vi: 'Vietnamita', + filter_lang_yi: 'Iídiche', + filter_lang_zh: 'Chinês', + + filter_genre_ac: 'Ação', + filter_genre_ad: 'Aventura', + filter_genre_mv: 'Desenhos animados', + filter_genre_cm: 'Comédia', + filter_genre_cr: 'Crime', + filter_genre_dc: 'Documentário', + filter_genre_dr: 'Drama', + filter_genre_fm: 'Família', + filter_genre_fe: 'Fantasia', + filter_genre_hi: 'História', + filter_genre_ho: 'Terror', + filter_genre_mu: 'Música', + filter_genre_de: 'Detetive', + filter_genre_md: 'Melodrama', + filter_genre_fa: 'Ficção', + filter_genre_tv: 'Telefilme', + filter_genre_tr: 'Thriller', + filter_genre_mi: 'Militar', + filter_genre_ve: 'Ocidental', + filter_genre_aa: 'Ação e Aventura', + filter_genre_ch: 'Crianças', + filter_genre_nw: 'Notícias', + filter_genre_rs: 'Reality show', + filter_genre_hf: 'Ficção Científica e Fantasia', + filter_genre_op: 'Telenovela', + filter_genre_tc: 'Talk show', + filter_genre_mp: 'Guerra e Política', + + + empty_title: 'Vazio', + empty_text: 'Nada encontrado para seu filtro, por favor refine seu filtro.', + empty_title_two: 'Está vazio aqui', + empty_text_two: 'A lista está vazia no momento.', + + menu_main: 'Início', + menu_movies: 'Filmes', + menu_tv: 'Séries', + menu_catalog: 'Catálogo', + menu_filter: 'Filtro', + menu_collections: 'Coleções', + menu_relises: 'Lançamentos', + menu_anime: 'Anime', + menu_bookmark: 'Favoritos', + menu_like: 'Gostos', + menu_time: 'Ver mais tarde', + menu_history: 'Histórico', + menu_timeline: 'Calendário', + menu_torrents: 'Torrents', + menu_settings: 'Configurações', + menu_about: 'Informações', + menu_console: 'Logs', + menu_multmovie: 'Desenhos animados', + menu_multtv: 'Séries animada', + + plugins_catalog_work: 'Plugins funcionando', + plugins_catalog_work_descr: 'Plugins que funcionam corretamente na aplicação.', + plugins_catalog_popular: 'Plugins populares entre utilizadores', + plugins_catalog_popular_descr: 'Instalação de fontes desconhecidas pode fazer com que a aplicação não funcione corretamente.', + plugins_online: 'Ver online', + plugins_check_fail: 'Falha ao testar a funcionalidade do plugin. No entanto, isso não significa que o plugin não funcione. Reinicie a aplicação para ver se o plugin está funcionando.', + plugins_need_reload: 'Para aplicar o plugin, você precisa reiniciar a aplicação', + plugins_install: 'Instalar', + plugins_install_ready: 'Este plugin já está instalado.', + plugins_installed: 'Instalações', + plugins_load_from: 'Carregado do CUB', + plugins_ok_for_check: 'Clique em (OK) para testar o plugin', + plugins_no_loaded: 'Ao iniciar a aplicação alguns plugins não puderam ser carregados', + + time_viewed: 'Visualizado', + time_from: 'Desde', + time_reset: 'Reset tempo visualizado', + + settings_clear_cache: 'Cache e dados limpos', + settings_user_links: 'Endereço personalizado', + settings_for_local: 'Para TorrServer local', + settings_add: 'Adicionar', + settings_remove: 'Eliminar', + settings_this_value: 'Valor atual', + settings_added: 'Adicionado', + settings_removed: 'Eliminado', + + settings_param_player_inner: 'Lampa', + settings_param_player_outside: 'Externo', + settings_param_player_inner_tvos: 'Interno', + settings_param_yes: 'Sim', + settings_param_no: 'Não', + settings_param_interface_size_small: 'Menor', + settings_param_interface_size_normal: 'Normal', + settings_param_interface_size_bigger: 'Mais', + settings_param_poster_quality_low: 'Baixo', + settings_param_poster_quality_average: 'Médio', + settings_param_poster_quality_high: 'Alto', + settings_param_parse_directly: 'Diretamente', + settings_param_parse_api: 'Através da API do site', + settings_param_background_complex: 'Complexo', + settings_param_background_simple: 'Simples', + settings_param_background_image: 'Imagem', + settings_param_link_use_one: 'Principal', + settings_param_link_use_two: 'Secundário', + settings_param_link_use_both: 'Ambas', + settings_param_subtitles_size_small: 'Pequeno', + settings_param_subtitles_size_normal: 'Normal', + settings_param_subtitles_size_bigger: 'Grande', + settings_param_screensaver_nature: 'Natureza', + settings_param_torrent_lang_orig: 'Original', + settings_param_torrent_lang_ru: 'Russo', + settings_param_player_timecode_again: 'Começar de novo', + settings_param_player_timecode_continue: 'Continuar', + settings_param_player_timecode_ask: 'Perguntar', + settings_param_player_scale_method: 'Calcular', + settings_param_player_hls_app: 'Sistema', + settings_param_player_hls_js: 'Programa', + settings_param_card_view_load: 'Carregar', + settings_param_card_view_all: 'Mostrar tudo', + settings_param_navigation_remote: 'Comando', + settings_param_navigation_mouse: 'Comando com rato', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: 'Sistema', + + helper_keyboard: 'Depois de inserir o valor, pressione o botão "Voltar" para guardar', + helper_torrents: 'Mantenha pressionada a tecla (OK) para abrir o menu de contexto', + helper_cleared: 'Sucesso, dicas serão mostradas novamente.', + helper_torrents_view: 'Mantenha pressionada a tecla (OK) para redefinir o tempo de visualizado e exibir o menu', + + fav_sync_title: 'Sincronização dos favoritos', + fav_sync_text: 'Conecte a sincronização e visualize em qualquer dispositivo os seus favoritos.

    Para isso, registe-se no site {site}, crie um perfil e faça login na aplicação.', + fav_sync_site: 'Site', + fav_remove_title: 'Remover do histórico', + fav_remove_descr: 'Eliminar cartão selecionado', + fav_clear_title: 'Limpar o histórico', + fav_clear_descr: 'Eliminar todos os cartões do histórico', + fav_clear_label_title: 'Limpar rótulos', + fav_clear_label_descr: 'Limpar rótulos visualizados', + fav_clear_time_title: 'Limpar tempo visualizado', + fav_clear_time_descr: 'Limpar todos os tempos visualizados', + fav_label_cleared: 'Marcas apagadas', + fav_time_cleared: 'Tempos visualizados apagados', + + timetable_empty: 'Esta secção exibirá as datas de lançamento dos novos episódios.', + + player_quality: 'Qualidade', + player_flow: 'Fluxo', + player_tracks: 'Faixas de áudio', + player_disabled: 'Desativado', + player_unknown: 'Desconhecido', + player_subs: 'Legendas', + player_size_default_title: 'Padrão', + player_size_default_descr: 'Tamanho de vídeo padrão', + player_size_cover_title: 'Expandir', + player_size_cover_descr: 'Expande o vídeo para tela cheia', + player_size_fill_title: 'Preencher', + player_size_fill_descr: 'Ajustar vídeo para tela cheia', + player_size_s115_title: 'Zoom 115%', + player_size_s115_descr: 'Ampliar vídeo em 115%', + player_size_s130_title: 'Zoom 130%', + player_size_s130_descr: 'Aumente o vídeo em 130%', + player_size_v115_title: 'Vertical 115%', + player_size_v115_descr: 'Aumente o vídeo em 115%', + player_size_v130_title: 'Vertical 130%', + player_size_v130_descr: 'Aumente o vídeo em 130%', + player_video_size: 'Tamanho do vídeo', + player_playlist: 'Lista de reprodução', + player_error_one: 'Falha ao descodificar vídeo', + player_error_two: 'Vídeo não encontrado ou corrompido', + player_start_from: 'Continuar navegando de', + player_not_found: 'Videoplayer não encontrado', + player_lauch: 'Iniciar videoplayer', + player_speed_default_title: 'Simples', + player_speed_two_descr: 'Tocar sem som', + player_video_speed: 'Velocidade de reprodução', + player_share_title: 'Partilhar', + player_share_descr: 'Reproduzir este vídeo em outro dispositivo', + player_normalization_power_title: 'Normalização', + player_normalization_smooth_title: 'Velocidade de normalização', + player_normalization_step_low: 'Baixo', + player_normalization_step_medium: 'Médio', + player_normalization_step_hight: 'Alto', + player_youtube_no_played: 'Desculpe, este vídeo não está disponível em sua região e pode ter sido bloqueado ou removido.', + player_youtube_start_play: 'Para começar a reproduzir o vídeo, clique no botão "Reproduzir"', + + broadcast_open: 'Abrir o cartão em outro dispositivo', + broadcast_play: 'Escolha o dispositivo para assistir', + + card_new_episode: 'Novo episódio', + card_book_remove: 'Remover dos favoritos', + card_book_add: 'Adicionar aos favoritos', + card_book_descr: 'Procure no menu (Favoritos)', + card_like_remove: 'Remover dos favoritos', + card_like_add: 'Gosto', + card_like_descr: 'Veja o menu (Gostos)', + card_wath_remove: 'Remover do ver mais tarde', + card_wath_add: 'Adicionar ao ver mais tarde', + card_wath_descr: 'Veja o menu (ver mais tarde)', + card_history_remove: 'Remover do histórico', + card_history_add: 'Na história', + card_history_descr: 'Procure no menu (Histórico)', + + keyboard_listen: 'Fale, estou ouvindo...', + keyboard_nomic: 'Sem acesso ao microfone', + + notice_new_quality: 'Nova qualidade disponível', + notice_quality: 'Qualidade', + notice_new_episode: 'Novo episódio', + notice_none: 'Ainda não tem notificações, registe-se em {site} para acompanhar novos episódios e lançamentos.', + notice_in_quality: 'Como', + notice_none_account: 'Você ainda não tem notificações, marque a série e aguarde as notificações de novos episódios.', + notice_none_system: 'Você não tem nenhuma notificação. Nós iremos notificá-lo quando novas notificações estiverem disponíveis.', + + copy_link: 'Copiar endereço do vídeo', + copy_secuses: 'Endereço copiado para a área de transferência', + copy_error: 'Erro ao copiar o endereço', + + account_sync_to_profile: 'Todos os favoritos serão movidos para o perfil', + account_sync_secuses: 'Todos os favoritos foram transferidos com sucesso', + account_profiles: 'Perfis', + account_profiles_empty: 'Falha ao obter lista de perfis', + account_authorized: 'Autorizado', + account_logged_in: 'Você está logado', + account_login_failed: 'Falha no login', + account_login_wait: 'Aguardando login', + account_profile_main: 'Geral', + account_export_secuses: 'Exportação concluída com sucesso', + account_export_fail: 'Erro de exportação', + account_import_secuses: 'Importação concluída com sucesso', + account_import_fail: 'Erro de importação', + account_imported: 'Importado', + account_reload_after: 'Reinicializar após 5 segundos.', + account_create: 'Descubra mais oportunidades com uma conta CUB. Registe-se em e tenha acesso para sincronizar seus favoritos, tempos visualizados e outros recursos da conta CUB.', + account_premium: 'Desbrave novos horizontes com uma conta CUB Premium! Tire partido de limites maiores e funcionalidades de serviço melhoradas. Visite e saiba mais sobre os benefícios de uma conta premium.', + account_premium_more: 'Saiba mais sobre CUB Premium', + account_limited: 'Você atingiu o limite máximo. Aumente o limite com uma conta CUB Premium. Saiba mais em ', + + account_code_enter: 'Digite um código de seis dígitos', + account_code_error: 'Você inseriu um código incorreto ou desatualizado', + account_code_wrong: 'Você especificou um formato incorreto', + account_code_where: 'Acesse o site e insira o código fornecido lá.', + account_code_input: 'Inserir código', + settings_cub_signin_button: 'Fazer login', + + network_noconnect: 'Sem conexão de rede', + network_404: 'A página solicitada não foi encontrada. [404]', + network_401: 'Falha na autorização', + network_500: 'Erro do servidor interno. [500]', + network_parsererror: 'Falha na análise JSON solicitada.', + network_timeout: 'A solicitação expirou.', + network_abort: 'A solicitação foi abortada.', + network_error: 'Erro desconhecido', + + size_zero: '0 Byte', + size_byte: 'Byte', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'TB', + size_pp: 'PB', + + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + + month_1: 'Janeiro', + month_2: 'Fevereiro', + month_3: 'Março', + month_4: 'Abril', + month_5: 'Maio', + month_6: 'Junho', + month_7: 'Julho', + month_8: 'Agosto', + month_9: 'Setembro', + month_10: 'Outubro', + month_11: 'Novembro', + month_12: 'Dezembro', + + day_1: 'Segunda', + day_2: 'Terça', + day_3: 'Quarta', + day_4: 'Quinta', + day_5: 'Sexta', + day_6: 'Sábado', + day_7: 'Domingo', + + month_1_e: 'Jan', + month_2_e: 'Fevereiro', + month_3_e: 'Março', + month_4_e: 'Abril', + month_5_e: 'Maio', + month_6_e: 'Junho', + month_7_e: 'Julho', + month_8_e: 'Agosto', + month_9_e: 'Setembro', + month_10_e: 'Outubro', + month_11_e: 'Novembro', + month_12_e: 'Dezembro', + + week_1: 'Seg', + week_2: 'Ter', + week_3: 'Qua', + week_4: 'Qui', + week_5: 'Sex', + week_6: 'Sáb', + week_7: 'Dom', + + extensions_enable: 'Ativar', + extensions_disable: 'Desativar', + extensions_check: 'Verificar estado', + extensions_install: 'Instalar', + extensions_info: 'Informações', + extensions_edit: 'Editar', + extensions_change_name: 'Alterar nome', + extensions_change_link: 'Alterar endereço', + extensions_remove: 'Eliminar', + extensions_set_name: 'Digite o nome do plugin', + extensions_set_url: 'Digite o URL do plugin', + extensions_ready: 'Este plugin já está instalado', + extensions_no_info: 'Sem informação', + extensions_no_name: 'Sem título', + extensions_worked: 'Verificado', + extensions_no_plugin: 'Plugin não verificado', + extensions_add: 'Adicionar Plugin', + extensions_from_memory: 'Instalado na memória', + extensions_from_cub: 'Instalado do CUB', + extensions_from_popular: 'Plugins populares', + extensions_from_lib: 'Biblioteca de plugins', + extensions_from_connected: 'Plugins conectados', + + settings_webos_launcher: 'Lançamento do aplicativo', + settings_webos_launcher_add_device: 'Definir como início', + settings_webos_launcher_remove_device: 'Remover dos aplicativos iniciais', + player_normalization: 'Normalização', + change_source_on_cub: 'Alterar fonte para CUB', + settings_param_jackett_interview_all: 'Tudo', + settings_param_jackett_interview_healthy: 'Disponível apenas', + settings_parser_jackett_interview: 'Rastreadores de enquetes', + title_ongoing: 'Em andamento', + title_pgrating: 'Limite de idade', + + settings_interface_card_interfice: 'Interface do cartão', + settings_interface_card_poster: 'Mostrar cartaz', + title_card: 'Cartão', + settings_param_card_interface_old: 'Velho', + settings_param_card_interface_new: 'Novo', + title_seasons: 'Temporadas', + title_episodes: 'Series', + title_rewiews: 'Avaliações', + settings_interface_glass: 'Vidro', + settings_interface_glass_descr: 'Mostrar interface em estilo vítreo', + settings_interface_black_style: 'Estilo preto', + + plugins_remove: 'Remover plug-ins', + plugins_add_success: 'Plug-in conectado com sucesso', + settings_reset: 'Redefinir', + title_channel: 'Canal', + + input_detection_touch: 'Quer mudar para o controle de toque?', + input_detection_mouse: 'Deseja alternar para o controle do mouse?', + input_detection_remote: 'Quer mudar para controle remoto?', + + settings_interface_hide_outside_the_screen: 'Ocultar cartões fora da tela', + settings_interface_hide_outside_the_screen_descr: 'Isso acelerará a interface renderizar e melhorar o desempenho', + + https_text: 'Você está usando o protocolo HTTPS, neste protocolo a lâmpada não funciona corretamente. Para o correto funcionamento da lâmpada, utilize o endereço com o protocolo HTTP', + + extensions_hpu_best: 'Popular', + extensions_hpu_recomend: 'Recomendado', + extensions_hpu_theme: 'Temas', + extensions_hpu_screensaver: 'Protetor de tela', + extensions_hpu_video: 'Vídeo', + extensions_hpu_control: 'Ao controle', + extensions_hpu_other: 'Diversos', + extensions_hpu_: 'Descansar', + + title_author: 'Autor', + + title_buffer: 'Amortecedor', + settings_rest_screensaver_time: 'Depois de quantos minutos para iniciar o protetor de tela', + + time_h: 'h.', + time_m: 'm.', + time_s: 's.', + + settings_param_glass_easy: 'Transparente', + settings_param_glass_medium: 'Translúcido', + settings_param_glass_blacked: 'Apagado', + + settings_interface_glass_opacity: 'Transparência de vidro', + torrent_error_check_no_auth: 'O servidor respondeu à solicitação, mas a autorização falhou', + settings_interface_card_cover: 'Mostrar capa', + + title_upcoming_episodes: 'Próximos lançamentos de episódios', + title_recent_episodes: 'Lançamentos recentes de episódios', + settings_rest_cache_images: 'Cache de imagens', + settings_rest_cache_images_descr: 'Armazene pôsteres e planos de fundo no armazenamento local', + + settings_player_rewind_title: 'Rebobinar', + settings_player_rewind_descr: 'Intervalo de retrocesso em segundos', + + settings_interface_card_reactions: 'Mostrar reações', + title_look: 'A assistir', + title_scheduled: 'Agendado', + title_viewed: 'Visualizado', + title_thrown: 'Descartado', + title_reactions: 'Reações', + reactions_none: 'Sem reações', + reactions_fire: 'Ótimo', + reactions_nice: 'Bom', + reactions_think: 'Interessante', + reactions_bore: 'Entediante', + reactions_shit: 'Ruim', + reactions_ready: 'Você já deixou uma reação', + settings_player_launch_trailers: 'Reprodutor do trailer', + title_continued: 'Continua', + title_language_short: 'Linguagem', + + speedtest_connect: 'conexão', + speedtest_test: 'teste', + speedtest_ready: 'pronto', + speedtest_button: 'Testar velocidade', + settings_rest_protocol_use: 'Conexão segura', + settings_rest_protocol_descr: 'Usar protocolo HTTPS', + install_app_apk_title: 'Como instalar o Lampa no Android', + install_app_apk_text: 'Notamos que você usa o MediaStationX para executar o Lampa no Android. Recomendamos instalar o Lampa como um aplicativo APK. Isso garantirá uma operação mais estável e acesso a todos os recursos do aplicativo.

    Acesse o grupo do Telegram para baixar o APK mais recente e as instruções de instalação.', + install_app_apk_qr: 'Escaneie o código QR para baixar o APK do Lampa', + copy_link_buffer: 'Copiar link', + + tv_status_returning_series: 'Em andamento', + tv_status_planned: 'Planejado', + tv_status_in_production: 'Em produção', + tv_status_ended: 'Finalizado', + tv_status_canceled: 'Cancelado', + tv_status_pilot: 'Piloto', + + tv_status_released: 'Lançado', + tv_status_rumored: 'Rumores', + tv_status_post_production: 'Em breve', + full_keywords: 'Tag', + title_last_year: 'Ano passado', + + title_reset: 'Reinício', + back_to_card: 'Voltar ao cartão', + + premiere_author_recomend_1: 'Peça pizza e prepare-se para a emoção.', + premiere_author_recomend_2: 'A festa está apenas começando.', + premiere_author_recomend_3: 'Prepare-se para a adrenalina.', + premiere_author_recomend_4: 'Pronto para uma noite inesquecível?', + premiere_author_recomend_5: 'Eu recomendo assistir.', + premiere_title: 'Estréia', + + settings_clear_cache_only: 'Cache Cleared', + settings_rest_cache_only: 'Apenas Cache', + settings_rest_cache_only_descr: 'As configurações básicas serão preservadas', + settings_rest_cache_all: 'Cache e Dados', + settings_rest_cache_all_descr: 'Todas as configurações e dados serão apagados', + settings_rest_cache_calculate: 'Quanta memória resta', + + title_left:'Esquerda', + + account_export_fail_500: 'Erro desconhecido', + account_export_fail_610: 'Você ultrapassou o limite para hoje', + account_export_fail_200: 'Erro no banco de dados, por favor, tente novamente mais tarde', + account_export_fail_600: 'Erro, falha ao carregar o arquivo', + account_export_fail_620: 'Erro, arquivo não transmitido', + + title_parental_control: 'Controle Parental', + settings_parental_control_param_time_always: 'Sempre', + settings_parental_control_param_time_once: 'Uma vez', + settings_parental_control_param_time_10: 'Em 10 minutos', + settings_parental_control_param_time_20: 'Em 20 minutos', + settings_parental_control_param_time_30: 'Em 30 minutos', + settings_parental_control_param_time_60: 'Em 1 hora', + settings_parental_control_param_time_120: 'Em 2 horas', + settings_parental_control_change_pin: 'Alterar PIN', + settings_parental_control_demand_title: 'Quando solicitar', + settings_parental_control_demand_descr: 'Após quanto tempo solicitar o PIN', + settings_parental_control_enabled: 'Ativado', + settings_parental_control_disabled: 'Desativado', + parental_control_input_new_code: 'Digite o novo código PIN', + parental_control_confirm_new_code: 'Confirme o código PIN', + parental_control_no_match_code: 'O código PIN não coincide com o código anterior', + parental_control_input_code: 'Digite o código PIN', + parental_control_input_error: 'Você digitou um código PIN incorreto', + title_worth_rewatch: 'Vale a pena assistir novamente', + + ad_disable: 'Ao assinar o CUB Premium, você esquecerá a publicidade.', + ad_after: 'Publicidade via', + ad: 'Anúncio', + ad_skip: 'Pular', + ad_continue_after: 'A visualização começará em', + settings_parser_prowlarr_link_descr: 'Forneça um link para o servidor Prowlarr', + settings_parser_prowlarr_key_descr: 'Localizado na guia de configurações do Prowlarr na categoria geral', + settings_player_torrent_type: 'Tipo de player para torrents', + settings_player_torrent_type_descr: 'Qual player jogar torrents', + + full_crew: 'Mais', + full_editing: 'Edição', + full_creator: 'Criador', + player_normalization_step_none: 'Zero', + + settings_cub_backup_export_descr: 'Salvar configurações na nuvem', + settings_cub_backup_import_descr: 'Restaurar configurações da nuvem', + + settings_interface_sound: 'Sons do sistema', + settings_interface_sound_play: 'Transições', + settings_interface_sound_level: 'Nível de volume', + settings_interface_advanced_animation: 'Animação Avançada', + + confirm_open_player: 'Outro dispositivo está solicitando acesso ao player. Quer reproduzir o vídeo?', + + pincode_use_remote: 'Utilize o comando para introduzir o código, premindo as setas para selecionar o número pretendido.', + pincode_use_toggle: 'Prima e mantenha premido o botão OK para alterar o layout.', + + settings_parental_control_where: 'Onde solicitar um código PIN', + title_fire: 'Fogo!', + title_top_100: '100 melhores', + + player_normalization_type_title: 'Tipo de Normalização', + player_normalization_type_all: 'Todos', + player_normalization_type_up: 'Apenas Aumento', + player_normalization_type_down: 'Apenas Diminuição', + storage_quota_exceeded: 'Limite de armazenamento excedido. Limpe o cache e tente novamente.', + settings_cub_domain: 'Domínio primário', + + title_ai_assistant: 'Assistente de IA', + title_facts: 'Fatos Interessantes', + ai_search_start_typing: 'Pergunte ao Assistente de IA quais filmes você deseja encontrar. Por exemplo: "Filmes sobre o espaço"', + ai_search_limit: 'Limite de solicitações excedido. Tente novamente mais tarde. Com a assinatura CUB Premium, os limites serão aumentados e você não precisará esperar!', + ai_subscribe_title: 'Desbloqueie mais possibilidades com a IA', + ai_subscribe_descr: 'Assine o CUB Premium e aumente o número de solicitações para a IA. Junto com a IA, encontraremos os melhores filmes para você.', + + dmca_title: 'Conteúdo bloqueado', + dmca_descr: 'Este material não está disponível para visualização. Foi bloqueado a pedido do detentor dos direitos autorais, de acordo com a lei de direitos autorais.', + + loading_progress_step_0: 'Preparação', + loading_progress_step_1: 'Carregando idiomas', + loading_progress_step_2: 'Procurando espelhos', + loading_progress_step_3: 'Preparando extensões', + loading_progress_step_4: 'Quase pronto', + loading_progress_step_5: 'Chegando em breve', + + install_extension_rule_1: 'Instalação de um plug-in de terceiros', + install_extension_rule_2: 'Os plug-ins são criados por desenvolvedores independentes, e o LAMPA não verifica seu conteúdo. Ao instalá-los, você concorda que:', + install_extension_rule_3: '- Alguns plug-ins podem solicitar acesso aos seus dados ou trabalhar com fontes não verificadas.', + install_extension_rule_4: '- Se o plug-in que você instalar violar direitos autorais ou outras leis, toda a responsabilidade pelo seu uso será sua.', + install_extension_rule_5: '- Instale apenas plug-ins de fontes confiáveis. Se você tiver dúvidas sobre a segurança ou legalidade de um plug-in, é melhor não instalá-lo.', + install_extension_rule_6: 'O LAMPA não apoia nem aprova plug-ins relacionados a conteúdo pirata.', + install_extension_rule_7: 'Ao continuar, você confirma que compreende esses riscos.', + ad_plugin: 'Anúncio do plugin', + + terminal_title: 'Terminal', + terminal_no_access: 'Sem acesso', + terminal_confirm: 'Permitir', + terminal_deny: 'Negar', + terminal_update: 'Atualizar', + terminal_code: 'Código de acesso', + terminal_text: 'Você está solicitando acesso ao terminal. Os desenvolvedores podem acessar e controlar seu dispositivo. Isso pode ser útil para diagnóstico e solução de problemas, mas também pode representar um risco de segurança. Certifique-se de confiar nos desenvolvedores antes de conceder acesso.

    Você pode desativar este recurso a qualquer momento clicando no botão "Negar".', + + title_anons: 'Anúncio', + title_developer: 'Desenvolvedor', + title_navigation: 'Navegação', + title_page: 'Página', + title_person_about: 'Sobre', + account_qr_premium: 'Escaneie o código QR para saber mais sobre o CUB Premium', + account_qr_code: 'Escaneie o código QR para obter o código de vinculação do dispositivo', + account_qr_create: 'Escaneie o código QR para criar uma conta', + account_add_device_title: 'Adicionar dispositivo', + account_add_device_text: 'Acesse para obter um código e adicionar o dispositivo.', + account_none_title: 'Ainda não tem uma conta?', + account_none_include_1: 'Favoritos e histórico de exibição são salvos na nuvem', + account_none_include_2: 'Sincronização entre dispositivos', + account_none_include_3: 'Notificações sobre novos episódios e lançamentos', + account_none_include_4: 'Crie vários perfis em uma única conta', + account_premium_include_1: 'Número aumentado de favoritos', + account_premium_include_2: 'Histórico de exibição expandido', + account_premium_include_3: 'Mais marcadores de tempo disponíveis', + account_premium_include_4: 'Número de perfis por conta', + empty_subscribes_title: 'Suas assinaturas de tradução', + empty_subscribes_text: 'Basta se inscrever na sua tradução favorita e nós avisaremos quando um novo episódio for lançado.', + empty_history_title: 'Seu histórico de exibição', + empty_history_text: 'Seu histórico de exibição aparecerá aqui.', + empty_bookmark_title: 'Seus favoritos', + empty_bookmark_text: 'Adicione filmes e séries que você gosta aos favoritos para encontrá-los facilmente nesta seção.', + empty_mytorrents_title: 'Seus torrents', + empty_mytorrents_text: 'Os torrents baixados via TorServer aparecerão aqui.', + developer_param_enabled: 'Modo desenvolvedor', + developer_param_nopremium: 'Desativar CUB Premium', + developer_param_nodemo: 'Desativar modo de demonstração', + developer_param_ads: 'Mostrar anúncios', + developer_param_fps: 'Mostrar FPS', + developer_trigger_help_1: 'Quase acertou :)', + developer_trigger_help_2: 'Mais um pouco :)', + developer_trigger_help_3: 'Tem certeza de que deseja entrar no modo desenvolvedor?', + developer_trigger_help_4: 'Modo desenvolvedor ativado', + settings_param_navigation_touch: 'Sensor', + account_discuss_add_qr: 'Escaneie o código QR', + account_discuss_add_title: 'Quer deixar um comentário?', + account_discuss_add_text: 'Escaneie o código QR para abrir o aplicativo e deixar um comentário sobre este filme ou série.

    - Pegue seu celular ou tablet
    - Abra a câmera
    - Aponte para o código QR
    - Siga o link que aparecer na tela', + account_discuss_added: 'Obrigado pelo seu comentário!', + account_discuss_added_ready: 'Você já deixou um comentário sobre este filme ou série.', + remote_helper_long: 'Segure o botão (OK) para abrir o menu', + account_premium: 'Desbloqueie novos horizontes com uma conta CUB Premium! Aproveite limites maiores e funcionalidades aprimoradas. Visite e saiba mais sobre os benefícios da conta premium.', + player_segments_title: 'Segmentos', + player_segments_descr: 'Pule a introdução e outras partes do vídeo', + player_segments_ad_title: 'Anúncios', + player_segments_skip_title: 'Introdução e outros', + player_segments_value_none: 'Não pular', + player_segments_value_auto: 'Pular automaticamente', + player_segments_value_user: 'Personalizado', + player_segments_skiped: 'Segmento pulado', + player_segments_skip_now: 'Pular', + player_segments_skip_in: 'Pular em', + player_segments_skip_intro: 'Pular abertura', + player_segments_next: 'Próximo episódio', + player_segments_next_in: 'Próximo episódio em', + subscribe_info: 'Na seção "Assinaturas", você verá todas as suas assinaturas de tradução. Você receberá uma notificação quando um novo episódio com sua tradução selecionada for lançado.', + no_watch_history: 'Sem histórico de navegação', + + settings_request_caching_use: 'Ativar cache de solicitações', + settings_request_caching_descr: 'Melhora o desempenho ao armazenar em cache as respostas das solicitações de rede.', + + account_profile_child: 'Perfil filho', + account_profile_add: 'Adicionar perfil', + account_profile_name: 'Nome do perfil', + account_profile_created: 'Perfil criado com sucesso', + account_profile_limited: 'O limite máximo de perfis foi atingido: {count}', + account_profile_info: 'Você pode gerenciar os perfis nas configurações da sua conta. Para isso, acesse ', + player_youtube_no_support: 'O seu dispositivo não suporta a reprodução de vídeos do YouTube, verifique a sua ligação à Internet.', + title_channels: 'Canais', + title_best_of_2000: 'Os anos dourados da década de 2000', + title_best_of_2010: 'Os sucessos da década de 2010', + title_best_of_2015: 'Clássicos modernos', + title_comedy_of_2000: 'Risos da década de 2000', + title_comedy_of_2010: 'Humor da década de 2010', + title_comedy_of_2015: 'Comédias modernas', + + filter_keyword_sequel: 'Sequência', + filter_keyword_based_comic: 'Baseado em Quadrinhos', + filter_keyword_space: 'Espaço', + filter_keyword_survival: 'Sobrevivência', + filter_keyword_zombie: 'Zumbi', + filter_keyword_school: 'Escola', + filter_keyword_revenge: 'Vingança', + filter_keyword_detective: 'Detetive', + filter_keyword_robots: 'Robôs', + filter_keyword_vampires: 'Vampiros', + filter_keyword_aliens: 'Aliens', + filter_keyword_police: 'Polícia', + filter_keyword_reincarnation: 'Reencarnação', + filter_keyword_spy: 'Espião', + filter_keyword_disaster: 'Catástrofe', + filter_keyword_christmas: 'Natal', + + dmca_title_lgbt: 'Conteúdo restrito', + dmca_descr_lgbt: 'A visualização não está disponível na sua região, pois pode conter conteúdo LGBT. Esse tipo de material pode ser proibido ou restrito em alguns países.', + + settings_lgbt_content_block: 'Bloquear conteúdo LGBT', + + // todo: + adult_content_title: 'Conteúdo adulto', + adult_content_text_warning: 'O conteúdo pode conter material adulto que pode ser inapropriado para alguns espectadores.', + adult_content_text_modal: 'Este filme ou série está marcado como contendo conteúdo adulto. Você deve ter 18 anos ou mais para assistir a este material. Por favor, confirme que você atingiu a maioridade para continuar assistindo.', + + adult_content_confirm: 'Tenho 18 anos ou mais', + adult_content_deny: 'Tenho menos de 18 anos', + + inner_player_disclaimer_title: 'Aviso do player', + inner_player_disclaimer_text: 'Entendo que estou iniciando um player com suporte incompleto e entendo que isso pode causar comportamento atípico no dispositivo. O ideal é mudar para players da família tvOS ou outras alternativas.', + + inner_player_disclaimer_change_player: 'Mudar player', + remote_configuration_settings_title: 'Configuração Remota', + remote_configuration_registration_text: 'A configuração remota fornece acesso temporário ao seu aplicativo, outro aplicativo poderá instalar extensões e configurar parâmetros.', + remote_configuration_waite_text: 'Agora você pode passar este código para outro aplicativo para conceder acesso às configurações.', + remote_configuration_open_button: 'Abrir Acesso', + remote_configuration_code_life: 'O código é válido', + remote_configuration_notice_nocode: 'Falha ao abrir o acesso', + + settings_server_gts: 'Transcodificação', + settings_server_gts_descr: 'Converter automaticamente o vídeo para um formato compatível quando necessário.', + settings_server_tracktimecode: 'Ativar TrackTimecode', + settings_server_tracktimecode_descr: 'Guarda o progresso de reprodução de filmes e séries no servidor TorrServer. Para funcionar, esta opção também deve estar ativada no TorrServer.', + + title_metadata: 'Metadados', + title_moods: 'Humores', + title_meta_violence: 'Violência', + title_meta_fear: 'Medo', + title_meta_profanity: 'Linguagem', + title_meta_sadness: 'Tristeza', + title_meta_sex: 'Sexualidade', + player_pip: 'Minimizar', + player_volume: 'Volume', + player_time_end: 'Termina às', + player_ai_agent_info: 'Quer saber mais sobre o vídeo? Pergunte ao assistente de IA e ele fornecerá um gráfico de humores, um breve resumo do enredo e destaques.', + player_ai_agent_ask_plot: 'Resumo do enredo', + player_ai_agent_ask_moods: 'Mostrar gráfico', + player_ai_agent_ask_highlights: 'Destaques', + player_ai_agent_ask: 'Perguntar', + player_ai_agent_processing: 'Analisando...', + player_ai_agent_no_data: 'Sem dados para exibir.', + player_ai_agent_no_analysis: 'Não foi possível analisar o vídeo.', + player_ai_agent_quota: 'Limite de solicitações excedido. Tente novamente mais tarde.', + player_ai_agent_working: 'Ainda estou trabalhando nisso...', + title_meta_humor: 'Humor', + title_meta_tension: 'Tensão', + title_meta_romance: 'Romance', + title_meta_pace: 'Ritmo', + title_meta_importance: 'Cenas importantes', + title_meta_action: 'Ação' +} diff --git a/lampa-main/lang/ro.js b/lampa-main/lang/ro.js new file mode 100644 index 0000000..0a29ebf --- /dev/null +++ b/lampa-main/lang/ro.js @@ -0,0 +1,1362 @@ +export default { + lang_choice_title: 'Bun venit', + lang_choice_subtitle: 'Alegeți limba', + + more: 'Mai mult', + show_more: 'Afișează mai mult', + more_results: 'Afișează mai multe rezultate', + loading: 'Se încarcă...', + nofind_movie: 'Filmul nu a putut fi găsit.', + noname: 'Fără titlu', + nochoice: 'Neselectat', + cancel: 'Anulează', + confirm: 'Confirmă', + sure: 'Ești sigur?', + nodata: 'Nu există date', + back: 'Înapoi', + ready: 'Gata', + close_app_modal: 'Sigur vrei să părăsești aplicația?', + connected_seeds: 'conectat', + + search: 'Căutare', + search_input: 'Introdu textul', + search_empty: 'Istoricul căutărilor este gol.', + search_delete: 'Stânga - șterge', + search_start_typing: 'Începe să tastezi pentru căutare.', + search_searching: 'Căutare în curs...', + search_start: 'Pentru a începe căutarea', + search_nofound: 'Nu s-a găsit nimic conform solicitării tale.', + global_search: 'Căutare globală', + + full_genre: 'Gen', + full_production: 'Producție', + full_date_of_release: 'Data lansării', + full_budget: 'Buget', + full_countries: 'Țări', + full_like: 'Îmi place', + full_torrents: 'Torrente', + full_trailers: 'Trailere', + full_detail: 'Prezentare', + full_notext: 'Fără descriere.', + full_series_release: 'Lansare serial', + full_next_episode: 'Următorul', + full_episode_days_left: 'Zile rămase', + full_trailer_official: 'Oficial', + full_trailer_no_official: 'Neoficial', + full_season: 'Sezon', + full_episode: 'Episod', + full_directing: 'Regie', + full_writing: 'Scenariu', + full_keywords: 'Etichete', + + settings_cub_sync: 'Sincronizare', + settings_cub_sync_descr: 'Sincronizare cu serviciul CUB: marcaje, istoric de vizionare, etichete și progresul vizionării.', + settings_cub_account: 'Cont', + settings_cub_logged_in_as: 'Autentificat ca', + settings_cub_profile: 'Profil', + settings_cub_sync_btn: 'Sincronizează', + settings_cub_sync_btn_descr: 'Salvează marcajele locale în contul CUB', + settings_cub_backup: 'Backup', + settings_cub_backup_descr: 'Salvează sau încarcă datele din backup', + settings_cub_logout: 'Deconectare', + settings_cub_signin: 'Autorizare', + settings_cub_not_specified: 'Nespecificat', + settings_cub_password: 'Parolă', + settings_cub_status: 'Stare', + settings_cub_backup_import: 'Import', + settings_cub_backup_export: 'Export', + settings_cub_sync_filters: 'Sincronizare filtre', + settings_cub_sync_calendar: 'Sincronizare calendar', + settings_cub_sync_quality: 'Sincronizare calitate', + settings_cub_sync_search: 'Sincronizare istoric căutări', + settings_cub_sync_recomends: 'Sincronizare recomandări', + settings_cub_sync_timecodes: 'Sincronizare progres', + + settings_input_links: 'Favorite', + + settings_interface_type: 'Versiune Lite', + settings_interface_size: 'Dimensiune interfață', + settings_interface_menu_always: 'Afișează mereu meniul din stânga', + settings_interface_background: 'Fundal', + settings_interface_background_use: 'Afișează fundalul', + settings_interface_background_type: 'Tip fundal', + settings_interface_performance: 'Performanță', + settings_interface_animation: 'Animație', + settings_interface_animation_descr: 'Animația posterelor și a conținutului', + settings_interface_attenuation: 'Atenuare', + settings_interface_attenuation_descr: 'Efect de estompare a posterelor sus și jos', + settings_interface_scroll: 'Tip derulare', + settings_interface_view_card: 'Tip vizualizare poster', + settings_interface_view_card_descr: 'Pe măsură ce derulezi, posterele se vor încărca treptat sau toate odată', + settings_interface_lang: 'Limba interfeței', + settings_interface_lang_reload: 'Este necesară repornirea aplicației. Apasă "OK" pentru repornire.', + + settings_main_account: 'Cont', + settings_main_interface: 'Interfață', + settings_main_player: 'Player', + settings_main_parser: 'Parser', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Extensii', + settings_main_rest: 'Altele', + + settings_rest_start: 'Pagina de pornire', + settings_rest_start_descr: 'Pagina care se deschide la pornire', + settings_rest_source: 'Sursă', + settings_rest_source_use: 'Sursă principală', + settings_rest_source_descr: 'De unde se preiau informațiile despre filme', + settings_rest_tmdb_lang: 'Limba pentru datele de pe TMDB', + settings_rest_tmdb_prox: 'Proxy TMDB', + settings_rest_tmdb_prox_auto: 'Activează proxy automat', + settings_rest_tmdb_posters: 'Rezoluție postere TMDB', + settings_rest_screensaver: 'Screensaver', + settings_rest_screensaver_use: 'Afișează screensaver la inactivitate', + settings_rest_screensaver_type: 'Tip screensaver', + settings_rest_helper: 'Sugestii', + settings_rest_helper_use: 'Afișează sugestii', + settings_rest_helper_reset: 'Afișează sugestiile din nou', + settings_rest_pages: 'Pagini păstrate în memorie', + settings_rest_pages_descr: 'Păstrează paginile în starea în care le-ai lăsat', + settings_rest_time: 'Decalaj orar', + settings_rest_navigation: 'Tip navigare', + settings_rest_keyboard: 'Tip tastatură', + settings_rest_device: 'Nume dispozitiv', + settings_rest_device_placeholder: 'De exemplu: Lampa', + settings_rest_cache: 'Șterge cache', + settings_rest_cache_descr: 'Toate setările și datele vor fi șterse', + settings_rest_tmdb_example: 'De exemplu:', + settings_rest_tmdb_api_descr: 'Pentru date', + settings_rest_tmdb_image_descr: 'Pentru imagini', + settings_rest_card_quality: 'Marcaje calitate', + settings_rest_card_quality_descr: 'Afișează calitatea pe postere', + settings_rest_card_episodes: 'Marcaje episoade', + settings_rest_card_episodes_descr: 'Afișează numărul episoadelor pe postere', + + settings_parser_use: 'Folosește parser', + settings_parser_use_descr: 'Prin prezenta, ești de acord cu întreaga responsabilitate pentru utilizarea link-urilor publice pentru vizionarea torrentelor și a conținutului online.', + settings_parser_type: 'Tip parser pentru torrente', + settings_parser_jackett_placeholder: 'Exemplu: 192.168.x', + settings_parser_jackett_link: 'Link', + settings_parser_jackett_link_descr: 'Introdu link-ul către script-ul Jackett', + settings_parser_jackett_key_placeholder: 'Exemplu: sa0sk83d..', + settings_parser_jackett_key: 'Cheie API', + settings_parser_jackett_key_descr: 'Se găsește în Jackett', + settings_parser_torlook_type: 'Metodă parsing site TorLook', + settings_parser_scraperapi_placeholder: 'Exemplu: scraperapi.com', + settings_parser_scraperapi_link: 'Link către parser-ul site-ului', + settings_parser_scraperapi_descr: 'Înregistrează-te pe scraperapi.com, introdu link-ul api.scraperapi.com?api_key=...&url={q}
    W41.torlook.info va fi trimis în {q}', + settings_parser_search: 'Căutare', + settings_parser_search_descr: 'În ce limbă să se caute?', + settings_parser_in_search: 'Parser în căutare', + settings_parser_in_search_descr: 'Afișează rezultatele căutării?', + settings_parser_timeout_title: 'Timeout parser', + settings_parser_timeout_descr: 'Timpul în secunde de așteptare pentru răspuns de la server', + + settings_player_type: 'Tip player', + settings_player_type_descr: 'Ce player să fie folosit', + settings_infuse_launch_mode: 'Lansare în Infuse', + settings_infuse_launch_mode_descr: 'Ce să facă la deschiderea videoclipului în Infuse. Torrentele redau imediat', + settings_infuse_launch_ask: 'Întreabă la lansare', + settings_infuse_launch_play: 'Redă', + settings_infuse_launch_save_and_play: 'Salvează și redă', + settings_player_iptv_type: 'Tip player pentru IPTV', + settings_player_iptv_type_descr: 'Ce player să fie folosit pentru canale IPTV', + settings_player_reset: 'Resetează player implicit', + settings_player_reset_descr: 'Resetează player-ul Android selectat în aplicație', + settings_player_path: 'Cale către player', + settings_player_path_descr: 'Specifică calea către executabilul player-ului (.exe)', + settings_player_external_header: 'Player extern', + settings_player_external_fullscreen: 'Lansare în modul pe tot ecranul', + settings_player_normalization: 'Normalizare sunet', + settings_player_normalization_descr: 'Normalizează sunetul la un singur nivel, scade sunetele puternice și le amplifică pe cele încet.', + settings_player_next_episode: 'Următorul episod', + settings_player_next_episode_descr: 'Trece automat la următorul episod după finalizarea celui curent', + settings_player_timecode: 'Progres', + settings_player_timecode_descr: 'Continuă de la ultima poziție vizionată', + settings_player_scale: 'Metodă scalare', + settings_player_scale_descr: 'Cum se calculează scalarea video', + settings_player_subs: 'Subtitrări', + settings_player_subs_use: 'Activează', + settings_player_subs_use_descr: 'Activează mereu subtitrările la pornirea video-ului', + settings_player_subs_lang: 'Limba subtitrărilor', + settings_player_subs_lang_descr: 'Ce subtitrări să se activeze automat când sunt disponibile mai multe limbi', + settings_param_subtitles_lang_auto: 'Limba interfeței', + settings_player_subs_size: 'Dimensiune', + settings_player_subs_size_descr: 'Dimensiunea subtitrărilor pe ecran', + settings_player_subs_stroke_use: 'Folosește contur', + settings_player_subs_stroke_use_descr: 'Subtitrările vor avea un contur negru pentru o lizibilitate mai bună', + settings_player_subs_backdrop_use: 'Folosește fundal', + settings_player_subs_backdrop_use_descr: 'Subtitrările vor fi afișate pe un fundal translucid', + settings_player_quality: 'Calitate video implicită', + settings_player_quality_descr: 'Calitatea video preferată pentru vizionare', + settings_player_hls_title: 'Procesare flux .m3u8', + settings_player_hls_descr: 'Nu modifica acest parametru dacă nu știi ce face.', + + settings_plugins_notice: 'Pentru a aplica plugin-ul, trebuie să repornești aplicația', + settings_plugins_add: 'Adaugă Plugin', + settings_plugins_add_descr: 'Pentru a șterge un plugin adăugat, ține apăsat sau dă dublu-click pe tasta (OK) de pe el', + settings_plugins_install: 'Instalează Plugin', + settings_plugins_install_descr: 'Instalează un plugin din lista celor disponibile', + + settings_server_link: 'Folosește link', + settings_server_links: 'Link-uri', + settings_server_placeholder: 'Exemplu: 192.168.X', + settings_server_link_one: 'Link principal', + settings_server_link_one_descr: 'Specifică link-ul principal către script-ul TorrServer', + settings_server_link_two: 'Link adițional', + settings_server_link_two_descr: 'Introdu un link secundar către script-ul TorrServer', + settings_server_additionally: 'Adițional', + settings_server_client: 'Client integrat', + settings_server_client_descr: 'Folosește clientul JS TorrServer încorporat, altfel va porni cel de sistem.', + settings_server_base: 'Salvează în baza de date', + settings_server_base_descr: 'Torrent-ul va fi adăugat în baza de date TorrServer', + settings_server_preload: 'Folosește buffer prefetch', + settings_server_preload_descr: 'Așteaptă procesarea buffer-ului de preîncărcare TorrServer înainte de redare', + settings_server_auth: 'Autorizare', + settings_server_password_use: 'Autentificare cu parolă', + settings_server_login: 'Login', + settings_server_password: 'Parolă', + settings_server_not_specified: 'Nespecificat', + settings_server_search_type: 'Tip căutare', + settings_server_search_type_descr: 'Surse pentru căutarea torrentelor: Rutor integrat, indexatoare Torznab din TorrServer sau ambele.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + torent_nohash_reasons: 'Motive posibile', + torent_nohash_reason_one: 'TorServer nu a putut descărca fișierul torrent', + torent_nohash_reason_two: 'Răspuns de la TorServer', + torent_nohash_reason_three: 'Link', + torent_nohash_do: 'Ce este de făcut?', + torent_nohash_do_one: 'Verifică dacă ai configurat corect Jackett', + torent_nohash_do_two: 'Sursele private s-ar putea să nu ofere un link direct către fișier', + torent_nohash_do_three: 'Asigură-te că Jackett poate descărca fișierul', + torent_nohash_do_four: 'Scrie pe grupul nostru de telegram: @lampa_group', + torent_nohash_do_five: 'Specifică filmul, distribuția și, dacă e posibil, o poză cu aceasta', + + torrent_error_text: 'Eșec la conectarea cu TorrServer. Hai să verificăm rapid lista de probleme posibile.', + torrent_error_step_1: 'TorrServer rulează?', + torrent_error_step_2: 'IP dinamic', + torrent_error_step_3: 'Protocol și Port', + torrent_error_step_4: 'Blocare Antivirus', + torrent_error_step_5: 'Verifică disponibilitatea', + torrent_error_step_6: 'Tot nu funcționează', + torrent_error_info_1: 'Asigură-te că ai pornit TorrServer pe dispozitivul unde este instalat.', + torrent_error_info_2: 'O eroare comună: IP-ul dispozitivului cu TorrServer s-a schimbat. Verifică dacă IP-ul introdus - {ip} - coincide cu cel actual.', + torrent_error_info_3: 'Pentru conectare, trebuie să specifici protocolul http:// la început și portul :8090 la sfârșit. Adresa curentă este {ip}', + torrent_error_info_4: 'Antivirusul sau firewall-ul pot bloca accesul prin IP. Încearcă să le dezactivezi temporar.', + torrent_error_info_5: 'Pe orice alt dispozitiv din rețea, deschide {ip} în browser și vezi dacă interfața web TorrServer este accesibilă.', + torrent_error_info_6: 'Dacă după toate verificările eroarea persistă, restartează TorrServer și routerul.', + torrent_error_info_7: 'Dacă problema continuă, scrie pe grupul Telegram @lampa_group cu textul (Lampa nu se conectează la TorrServer, adresa curentă este {ip})', + torrent_error_start: 'Începe verificarea', + torrent_error_nomatrix: 'Eșec la verificarea versiunii Matrix', + torrent_error_made: 'Efectuat', + torrent_error_from: 'din', + torrent_error_next: 'Mai departe', + torrent_error_complite: 'Finalizare', + torrent_error_connect: 'Eroare de conexiune', + + torrent_install_need: 'Necesită TorrServer', + torrent_install_text: 'TorrServer este o aplicație care îți permite să vizionezi conținut din fișiere torrent online.

    Detalii despre instalare găsești pe grupurile de Telegram de mai jos.', + torrent_install_contact: 'Grupuri Telegram', + + torrent_item_bitrate: 'Bitrate', + torrent_item_seeds: 'Seeds', + torrent_item_grabs: 'Leechers', + torrent_item_mb: 'Mbps', + + torrent_serial_episode: 'Episod', + torrent_serial_season: 'Sezon', + torrent_serial_date: 'Lansare', + + torrent_get_magnet: 'Se solicită link-ul magnet', + torrent_remove_title: 'Șterge', + torrent_remove_descr: 'Torrent-ul va fi eliminat din lista ta', + + torrent_parser_any_one: 'Oricare', + torrent_parser_any_two: 'Oricare', + torrent_parser_no_choice: 'Neselectat', + torrent_parser_yes: 'Da', + torrent_parser_no: 'Nu', + torrent_parser_quality: 'Calitate', + torrent_parser_subs: 'Subtitrări', + torrent_parser_voice: 'Traducere', + torrent_parser_tracker: 'Tracker', + torrent_parser_year: 'An', + torrent_parser_season: 'Sezon', + torrent_parser_sort_by_seeders: 'După seederi', + torrent_parser_sort_by_size: 'După mărime', + torrent_parser_sort_by_name: 'După nume', + torrent_parser_sort_by_tracker: 'După sursă', + torrent_parser_sort_by_date: 'După dată', + torrent_parser_sort_by_viewed: 'Vizionat', + torrent_parser_voice_dubbing: 'Dublaj', + torrent_parser_voice_polyphonic: 'Polifonic', + torrent_parser_voice_two: 'Două voci', + torrent_parser_voice_amateur: 'Amator', + torrent_parser_reset: 'Resetează filtrul', + torrent_parser_empty: 'Nu s-au găsit rezultate', + torrent_parser_no_hash: 'Eșec la obținerea HASH-ului, încearcă să repornești TorrServer-ul', + torrent_parser_added_to_mytorrents: 'adăugat la "Torrentele mele"', + torrent_parser_add_to_mytorrents: 'Adaugă la "Torrentele mele"', + torrent_parser_label_title: 'Marcaj', + torrent_parser_label_descr: 'Marchează distribuția ca vizionată', + torrent_parser_label_cancel_title: 'Deselectează', + torrent_parser_label_cancel_descr: 'Elimină marcajul de vizionare', + torrent_parser_timeout: 'Timp expirat', + torrent_parser_nofiles: 'Eșec la extragerea fișierelor potrivite', + torrent_parser_set_link: 'Specifică un link pentru parsing', + torrent_parser_request_error: 'Eroare de solicitare', + torrent_parser_magnet_error: 'Eșec la obținerea link-ului magnet', + torrent_parser_no_responce: 'Parser-ul nu răspunde', + torrent_parser_torlook_fallback_search_notification: 'Parser-ul Jackett nu este disponibil sau setările sunt incorecte. Se caută pe Torlook...', + + about_text: 'Aplicația este complet gratuită și folosește link-uri publice pentru a obține informații despre videoclipuri, noutăți, filme populare etc. Toate informațiile sunt folosite exclusiv în scop educațional, aplicația nu folosește servere proprii pentru a distribui conținutul.', + about_channel: 'Canalul nostru', + about_group: 'Grup', + about_version: 'Versiune', + about_donate: 'Donații', + + title_watched: 'Ai vizionat', + title_settings: 'Setări', + title_collections: 'Colecții', + title_company: 'Companie', + title_actors: 'Actori', + title_actor: 'Actor', + title_actress: 'Actriță', + title_person: 'Persoană', + title_persons: 'Persoane', + title_comments: 'Comentarii', + title_torrents: 'Torrente', + title_trailers: 'Trailere', + title_watch: 'Vizionează', + title_error: 'Eroare', + title_links: 'Link-uri', + title_choice: 'Alege', + title_main: 'Acasă', + title_book: 'Marcaje', + title_like: 'Îmi place', + title_wath: 'Mai târziu', + title_history: 'Istoric vizualizări', + title_mytorrents: 'Torrentele mele', + title_last: 'Ultimele', + title_action: 'Acțiune', + title_action_infuse: 'Acțiune Infuse', + title_producer: 'Producător', + title_collection: 'Colecție', + title_recomendations: 'Recomandări', + title_similar: 'Similare', + title_about: 'Despre aplicație', + title_timetable: 'Program', + title_relises: 'Lansări digitale', + title_catalog: 'Catalog', + title_category: 'Categorie', + title_parser: 'Parser', + title_type: 'Tip', + title_rating: 'Rating', + title_country: 'Țară', + title_year: 'An', + title_genre: 'Gen', + title_filter: 'Filtru', + title_notice: 'Notificări', + title_files: 'Fișiere', + title_now_watch: 'Se vizionează acum', + title_latest: 'Ultima adăugare', + title_continue: 'Continuă vizionarea', + title_recomend_watch: 'Recomandări pentru tine', + title_new_episodes: 'Episoade noi', + title_popular: 'Populare', + title_popular_movie: 'Filme populare', + title_popular_tv: 'Seriale populare', + title_new_this_year: 'Apărute anul acesta', + title_hight_voite: 'Top evaluate', + title_new: 'Noi', + title_trend_day: 'În tendințe astăzi', + title_trend_week: 'În tendințe săptămâna aceasta', + title_upcoming: 'Vizionați în cinematografe', + title_top_movie: 'Top filme', + title_top_tv: 'Top seriale', + title_tv_today: 'La TV azi', + title_this_week: 'Săptămâna aceasta', + title_in_top: 'În top', + title_out: 'Ieșire', + title_out_confirm: 'Da, ieși', + title_continue_two: 'Procedează', + title_choice_language: 'Alege limba', + title_subscribe: 'Abonare', + title_subscribes: 'Abonamente', + title_unsubscribe: 'Dezabonare', + title_language: 'Limba originală', + + subscribe_success: 'Te-ai abonat cu succes', + subscribe_error: 'A apărut o eroare la abonare, te rugăm să încerci mai târziu', + subscribe_noinfo: 'Eșec la preluarea informațiilor, reîncearcă mai târziu', + + company_headquarters: 'Sediu central', + company_homepage: 'Site web', + company_country: 'Țară', + + country_ad: 'Andorra', + country_ae: 'EAU', + country_af: 'Afganistan', + country_al: 'Albania', + country_am: 'Armenia', + country_ao: 'Angola', + country_ar: 'Argentina', + country_at: 'Austria', + country_au: 'Australia', + country_aw: 'Aruba', + country_az: 'Azerbaidjan', + country_ba: 'Bosnia și Herțegovina', + country_bd: 'Bangladesh', + country_be: 'Belgia', + country_bg: 'Bulgaria', + country_bh: 'Bahrain', + country_bi: 'Burundi', + country_bj: 'Benin', + country_bo: 'Bolivia', + country_br: 'Brazilia', + country_bs: 'Bahamas', + country_bt: 'Bhutan', + country_bw: 'Botswana', + country_by: 'Belarus', + country_ca: 'Canada', + country_ch: 'Elveția', + country_cl: 'Chile', + country_cm: 'Camerun', + country_cn: 'China', + country_co: 'Columbia', + country_cr: 'Costa Rica', + country_cu: 'Cuba', + country_cv: 'Capul Verde', + country_cy: 'Cipru', + country_cz: 'Cehia', + country_de: 'Germania', + country_dj: 'Djibouti', + country_dk: 'Danemarca', + country_do: 'Republica Dominicană', + country_dz: 'Algeria', + country_ec: 'Ecuador', + country_ee: 'Estonia', + country_eg: 'Egipt', + country_es: 'Spania', + country_et: 'Etiopia', + country_fi: 'Finlanda', + country_fo: 'Insulele Feroe', + country_fr: 'Franța', + country_ga: 'Gabon', + country_gb: 'Regatul Unit', + country_ge: 'Georgia', + country_gh: 'Ghana', + country_gl: 'Groenlanda', + country_gp: 'Guadelupa', + country_gr: 'Grecia', + country_gt: 'Guatemala', + country_hk: 'Hong Kong', + country_hr: 'Croația', + country_ht: 'Haiti', + country_hu: 'Ungaria', + country_id: 'Indonezia', + country_ie: 'Irlanda', + country_il: 'Israel', + country_in: 'India', + country_iq: 'Irak', + country_ir: 'Iran', + country_is: 'Islanda', + country_it: 'Italia', + country_jm: 'Jamaica', + country_jo: 'Iordania', + country_jp: 'Japonia', + country_ke: 'Kenya', + country_kg: 'Kârgâzstan', + country_kh: 'Cambodgia', + country_kp: 'Coreea de Nord', + country_kr: 'Coreea de Sud', + country_kz: 'Kazahstan', + country_kw: 'Kuweit', + country_la: 'Laos', + country_lb: 'Liban', + country_li: 'Liechtenstein', + country_lk: 'Sri Lanka', + country_lr: 'Liberia', + country_lt: 'Lituania', + country_lu: 'Luxemburg', + country_lv: 'Letonia', + country_ly: 'Libia', + country_ma: 'Maroc', + country_mc: 'Monaco', + country_md: 'Moldova', + country_me: 'Muntenegru', + country_mk: 'Macedonia', + country_mm: 'Myanmar', + country_mn: 'Mongolia', + country_mo: 'Macao', + country_mt: 'Malta', + country_mu: 'Mauritius', + country_mv: 'Maldive', + country_mw: 'Malawi', + country_mx: 'Mexic', + country_my: 'Malaezia', + country_mz: 'Mozambic', + country_na: 'Namibia', + country_ne: 'Niger', + country_ng: 'Nigeria', + country_ni: 'Nicaragua', + country_nl: 'Olanda', + country_no: 'Norvegia', + country_np: 'Nepal', + country_nz: 'Noua Zeelandă', + country_om: 'Oman', + country_pa: 'Panama', + country_pe: 'Peru', + country_pg: 'Papua Noua Guinee', + country_ph: 'Filipine', + country_pk: 'Pakistan', + country_pl: 'Polonia', + country_pr: 'Puerto Rico', + country_ps: 'Teritoriul Palestinian', + country_pt: 'Portugalia', + country_py: 'Paraguay', + country_qa: 'Qatar', + country_ro: 'România', + country_rs: 'Serbia', + country_ru: 'Rusia', + country_rw: 'Rwanda', + country_sa: 'Arabia Saudită', + country_sd: 'Sudan', + country_se: 'Suedia', + country_sg: 'Singapore', + country_si: 'Slovenia', + country_sk: 'Slovacia', + country_sn: 'Senegal', + country_su: 'URSS', + country_sv: 'El Salvador', + country_sy: 'Siria', + country_th: 'Thailanda', + country_tj: 'Tadjikistan', + country_tm: 'Turkmenistan', + country_tn: 'Tunisia', + country_tr: 'Turcia', + country_tw: 'Taiwan', + country_tz: 'Tanzania', + country_ua: 'Ucraina', + country_ug: 'Uganda', + country_us: 'SUA', + country_uy: 'Uruguay', + country_uz: 'Uzbekistan', + country_ve: 'Venezuela', + country_vn: 'Vietnam', + country_xk: 'Kosovo', + country_ws: 'Samoa', + country_ye: 'Yemen', + country_yu: 'Iugoslavia', + country_za: 'Africa de Sud', + country_zm: 'Zambia', + country_zw: 'Zimbabwe', + + filter_clarify: 'Clarifică', + filter_clarify_two: 'Filtrează căutarea', + filter_set_name: 'Specifică titlul', + filter_sorted: 'Sortează', + filter_filtred: 'Filtrează', + filter_any: 'Oricare', + filter_combinations: 'Combinații', + filter_alt_names: 'Alte nume', + filter_rating_from: 'de la', + filter_rating_to: 'până la', + + filter_lang_af: 'Afrikaans', + filter_lang_ar: 'Arabă', + filter_lang_az: 'Azeră', + filter_lang_ba: 'Bașchiră', + filter_lang_be: 'Belarusă', + filter_lang_bg: 'Bulgară', + filter_lang_bn: 'Bengaleză', + filter_lang_bs: 'Bosniacă', + filter_lang_ca: 'Catalană', + filter_lang_ce: 'Cecenă', + filter_lang_cs: 'Cehă', + filter_lang_da: 'Daneză', + filter_lang_de: 'Germană', + filter_lang_el: 'Greacă', + filter_lang_en: 'Engleză', + filter_lang_es: 'Spaniolă', + filter_lang_et: 'Estonă', + filter_lang_fa: 'Persană', + filter_lang_fi: 'Finlandeză', + filter_lang_fr: 'Franceză', + filter_lang_ga: 'Irlandeză', + filter_lang_gl: 'Galiciană', + filter_lang_gn: 'Guarani', + filter_lang_he: 'Ebraică', + filter_lang_hi: 'Hindi', + filter_lang_hr: 'Croată', + filter_lang_hu: 'Maghiară', + filter_lang_hy: 'Armeană', + filter_lang_id: 'Indoneziană', + filter_lang_is: 'Islandeză', + filter_lang_it: 'Italiană', + filter_lang_ja: 'Japoneză', + filter_lang_ka: 'Georgiană', + filter_lang_kk: 'Kazahă', + filter_lang_ko: 'Coreeană', + filter_lang_ks: 'Kașmiră', + filter_lang_ku: 'Kurdă', + filter_lang_ky: 'Kârgâză', + filter_lang_lt: 'Lituaniană', + filter_lang_lv: 'Letonă', + filter_lang_mi: 'Maori', + filter_lang_mk: 'Macedoneană', + filter_lang_mn: 'Mongolă', + filter_lang_mt: 'Malteză', + filter_lang_ne: 'Nepaleză', + filter_lang_nl: 'Olandeză', + filter_lang_no: 'Norvegiană', + filter_lang_pa: 'Punjabi', + filter_lang_pl: 'Poloneză', + filter_lang_ps: 'Paștună', + filter_lang_pt: 'Portugheză', + filter_lang_ro: 'Română', + filter_lang_ru: 'Rusă', + filter_lang_si: 'Sinhaleză', + filter_lang_sk: 'Slovacă', + filter_lang_sl: 'Slovenă', + filter_lang_sm: 'Samoană', + filter_lang_so: 'Somaleză', + filter_lang_sq: 'Albaneză', + filter_lang_sr: 'Sârbă', + filter_lang_sv: 'Suedeză', + filter_lang_sw: 'Swahili', + filter_lang_ta: 'Tamilă', + filter_lang_tg: 'Tadjikă', + filter_lang_th: 'Thailandeză', + filter_lang_tk: 'Turkmenă', + filter_lang_tr: 'Turcă', + filter_lang_tt: 'Tătară', + filter_lang_ur: 'Urdu', + filter_lang_uk: 'Ucraineană', + filter_lang_uz: 'Uzbekă', + filter_lang_vi: 'Vietnameză', + filter_lang_yi: 'Idiș', + filter_lang_zh: 'Chineză', + + filter_genre_ac: 'Acțiune', + filter_genre_ad: 'Aventură', + filter_genre_mv: 'Animație', + filter_genre_cm: 'Comedie', + filter_genre_cr: 'Crimă', + filter_genre_dc: 'Documentar', + filter_genre_dr: 'Dramă', + filter_genre_fm: 'Familie', + filter_genre_fe: 'Fantezie', + filter_genre_hi: 'Istorie', + filter_genre_ho: 'Horror', + filter_genre_mu: 'Muzică', + filter_genre_de: 'Detectiv', + filter_genre_md: 'Melodramă', + filter_genre_fa: 'SF', + filter_genre_tv: 'Film TV', + filter_genre_tr: 'Thriller', + filter_genre_mi: 'Război', + filter_genre_ve: 'Western', + filter_genre_aa: 'Acțiune și Aventură', + filter_genre_ch: 'Copii', + filter_genre_nw: 'Știri', + filter_genre_rs: 'Reality show', + filter_genre_hf: 'Sci-Fi & Fantasy', + filter_genre_op: 'Telenovelă', + filter_genre_tc: 'Talk show', + filter_genre_mp: 'Război și Politică', + + empty_title: 'Fără conținut', + empty_text: 'Nu s-a găsit nimic pentru filtrele tale, te rugăm să ajustezi filtrele.', + empty_title_two: 'Fără conținut', + empty_text_two: 'Lista este în prezent goală.', + + menu_main: 'Acasă', + menu_movies: 'Filme', + menu_tv: 'Seriale', + menu_catalog: 'Catalog', + menu_filter: 'Filtru', + menu_collections: 'Colecții', + menu_relises: 'Lansări', + menu_anime: 'Anime', + menu_bookmark: 'Marcaje', + menu_like: 'Îmi place', + menu_time: 'Mai târziu', + menu_history: 'Istoric', + menu_timeline: 'Program', + menu_torrents: 'Torrente', + menu_settings: 'Setări', + menu_about: 'Informații', + menu_console: 'Consolă', + menu_multmovie: 'Desene animate', + menu_multtv: 'Seriale animate', + + plugins_catalog_work: 'Plugin-uri funcționale', + plugins_catalog_work_descr: 'Plugin-uri care funcționează sigur în aplicație.', + plugins_catalog_popular: 'Plugin-uri populare printre utilizatori', + plugins_catalog_popular_descr: 'Instalarea din surse necunoscute poate duce la funcționarea incorectă a aplicației.', + plugins_online: 'Vizionare online', + plugins_check_fail: 'Eșec la testarea funcționalității plugin-ului. Totuși, asta nu înseamnă că nu funcționează. Repornește aplicația.', + plugins_need_reload: 'Pentru a aplica plugin-ul, trebuie să repornești aplicația', + plugins_install: 'Instalează', + plugins_install_ready: 'Acest plugin este deja instalat.', + plugins_installed: 'Instalări', + plugins_load_from: 'Încărcat din CUB', + plugins_ok_for_check: 'Apasă (OK) pentru a testa plugin-ul', + plugins_no_loaded: 'La încărcarea aplicației, unele plugin-uri nu au putut fi încărcate', + + time_viewed: 'Vizionat', + time_from: 'din', + time_reset: 'Resetează progresul', + + settings_clear_cache: 'Cache și date șterse', + settings_user_links: 'Link personalizat', + settings_for_local: 'Pentru TorrServer local', + settings_add: 'Adaugă', + settings_remove: 'Șterge', + settings_this_value: 'valoare actuală', + settings_added: 'Adăugat', + settings_removed: 'Eliminat', + + settings_param_player_inner: 'Lampa', + settings_param_player_outside: 'Extern', + settings_param_player_inner_tvos: 'Intern', + settings_param_yes: 'Da', + settings_param_no: 'Nu', + settings_param_interface_size_small: 'Mică', + settings_param_interface_size_normal: 'Normală', + settings_param_interface_size_bigger: 'Mare', + settings_param_poster_quality_low: 'Scăzută', + settings_param_poster_quality_average: 'Medie', + settings_param_poster_quality_high: 'Ridicată', + settings_param_parse_directly: 'Direct', + settings_param_parse_api: 'Prin API-ul site-ului', + settings_param_background_complex: 'Complex', + settings_param_background_simple: 'Simplu', + settings_param_background_image: 'Imagine', + settings_param_link_use_one: 'General', + settings_param_link_use_two: 'Adițional', + settings_param_link_use_both: 'Ambele', + settings_param_subtitles_size_small: 'Mici', + settings_param_subtitles_size_normal: 'Obișnuite', + settings_param_subtitles_size_bigger: 'Mari', + settings_param_screensaver_nature: 'Natură', + settings_param_torrent_lang_orig: 'Originală', + settings_param_torrent_lang_ru: 'Rusă', + settings_param_player_timecode_again: 'De la început', + settings_param_player_timecode_continue: 'Continuă', + settings_param_player_timecode_ask: 'Întreabă', + settings_param_player_scale_method: 'Calculat', + settings_param_player_hls_app: 'Sistem', + settings_param_player_hls_js: 'Program', + settings_param_card_view_load: 'Încarcă', + settings_param_card_view_all: 'Afișează tot', + settings_param_navigation_remote: 'Telecomandă', + settings_param_navigation_mouse: 'Telecomandă cu mouse', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: 'Sistem', + + helper_keyboard: 'După introducerea valorii, apasă butonul "Înapoi" pentru a salva', + helper_torrents: 'Ține apăsată tasta (OK) pentru a deschide meniul contextual', + helper_cleared: 'Succes, sugestiile vor fi afișate din nou.', + helper_torrents_view: 'Ține apăsată tasta (OK) pentru a reseta progresul și a afișa meniul', + + fav_sync_title: 'Sincronizare marcaje', + fav_sync_text: 'Marcajele tale preferate. Conectează sincronizarea și vizualizează pe orice dispozitiv.

    Pentru asta, înregistrează-te pe site-ul {site}, creează un profil și autentifică-te în aplicație.', + fav_sync_site: 'Site web', + fav_remove_title: 'Elimină din istoric', + fav_remove_descr: 'Șterge elementul selectat', + fav_clear_title: 'Șterge istoricul', + fav_clear_descr: 'Șterge tot istoricul de vizionare', + fav_clear_label_title: 'Șterge etichetele', + fav_clear_label_descr: 'Șterge etichetele de vizionare', + fav_clear_time_title: 'Șterge progresul de vizionare', + fav_clear_time_descr: 'Șterge tot progresul de vizionare', + fav_label_cleared: 'Etichete șterse', + fav_time_cleared: 'Progresul de vizionare a fost șters', + + timetable_empty: 'Această secțiune va afișa datele de lansare ale noilor episoade.', + + player_quality: 'Calitate', + player_flow: 'Flux', + player_tracks: 'Piste audio', + player_disabled: 'Dezactivat', + player_unknown: 'Necunoscut', + player_subs: 'Subtitrări', + player_size_default_title: 'Implicit', + player_size_default_descr: 'Dimensiune video implicită', + player_size_cover_title: 'Extinde', + player_size_cover_descr: 'Extinde video pe tot ecranul', + player_size_fill_title: 'Umple ecranul', + player_size_fill_descr: 'Potrivește video pe ecran', + player_size_s115_title: 'Zoom 115%', + player_size_s115_descr: 'Mărește video cu 115%', + player_size_s130_title: 'Zoom 130%', + player_size_s130_descr: 'Mărește video cu 130%', + player_size_v115_title: 'Verticală 115%', + player_size_v115_descr: 'Mărește video cu 115% pe verticală', + player_size_v130_title: 'Verticală 130%', + player_size_v130_descr: 'Mărește video cu 130% pe verticală', + player_video_size: 'Dimensiune video', + player_playlist: 'Listă de redare', + player_error_one: 'Eșec la decodarea video', + player_error_two: 'Video negăsit sau corupt', + player_start_from: 'Continuă vizionarea de la', + player_not_found: 'Player-ul nu a fost găsit', + player_lauch: 'Lansează player-ul', + player_speed_default_title: 'Normală', + player_speed_two_descr: 'Redare fără sunet', + player_video_speed: 'Viteză de redare', + player_share_title: 'Partajează', + player_share_descr: 'Redă acest video pe un alt dispozitiv', + player_normalization_power_title: 'Putere normalizare', + player_normalization_smooth_title: 'Viteză normalizare', + player_normalization_step_low: 'Scăzută', + player_normalization_step_medium: 'Medie', + player_normalization_step_hight: 'Ridicată', + player_youtube_no_played: 'Ne pare rău, acest video nu este disponibil în regiunea ta. Este posibil să fi fost blocat sau șters.', + player_youtube_start_play: 'Pentru a începe redarea, apasă butonul "Play".', + + broadcast_open: 'Deschide pe alt dispozitiv', + broadcast_play: 'Alege dispozitivul pentru vizionare', + + card_new_episode: 'Episod nou', + card_book_remove: 'Elimină din marcaje', + card_book_add: 'La marcaje', + card_book_descr: 'Vezi în meniu (Marcaje)', + card_like_remove: 'Elimină din favorite', + card_like_add: 'Îmi place', + card_like_descr: 'Vezi în meniu (Îmi place)', + card_wath_remove: 'Elimină din lista de așteptare', + card_wath_add: 'Vizionează mai târziu', + card_wath_descr: 'Vezi în meniu (Mai târziu)', + card_history_remove: 'Elimină din istoric', + card_history_add: 'În istoric', + card_history_descr: 'Vezi în meniu (Istoric)', + + keyboard_listen: 'Vorbește, ascult...', + keyboard_nomic: 'Fără acces la microfon', + + notice_new_quality: 'Calitate nouă disponibilă', + notice_quality: 'Calitate', + notice_new_episode: 'Episod nou', + notice_none: 'Nu ai încă notificări, înregistrează-te pe {site} pentru a urmări noi episoade.', + notice_in_quality: 'În format', + notice_none_account: 'Nu ai notificări încă, adaugă serialul la favorite și așteaptă noutăți.', + notice_none_system: 'Momentan nu ai notificări. Te vom anunța când apar noutăți.', + + copy_link: 'Copiază link-ul video', + copy_secuses: 'Link copiat în clipboard', + copy_error: 'Eroare la copierea link-ului', + + account_sync_to_profile: 'Toate marcajele vor fi mutate în profil', + account_sync_secuses: 'Toate marcajele au fost transferate cu succes', + account_profiles: 'Profiluri', + account_profiles_empty: 'Eșec la preluarea listei de profiluri', + account_authorized: 'Autorizat', + account_logged_in: 'Ești autentificat', + account_login_failed: 'Autentificare eșuată', + account_login_wait: 'Se așteaptă autentificarea', + account_profile_main: 'General', + account_export_secuses: 'Export finalizat cu succes', + account_export_fail: 'Eroare la export', + account_import_secuses: 'Import finalizat cu succes', + account_import_fail: 'Eroare la import', + account_imported: 'importat', + account_reload_after: 'repornește în 5 sec.', + account_create: 'Descoperă mai multe cu un cont CUB. Înregistrează-te la pentru sincronizare.', + account_premium_more: 'Află mai multe despre CUB Premium', + account_limited: 'Ai atins limita maximă. Crește limita cu un cont CUB Premium la ', + + account_code_enter: 'Introdu codul de șase cifre', + account_code_error: 'Cod incorect sau expirat', + account_code_wrong: 'Format incorect', + account_code_where: 'Mergi pe și introdu codul afișat aici.', + account_code_input: 'Introdu codul', + settings_cub_signin_button: 'Autentificare', + + network_noconnect: 'Lipsă conexiune rețea', + network_404: 'Pagina solicitată nu a fost găsită. [404]', + network_401: 'Autorizare eșuată', + network_500: 'Eroare internă server. [500]', + network_parsererror: 'Eroare la procesarea JSON-ului.', + network_timeout: 'Timp de așteptare expirat.', + network_abort: 'Solicitarea a fost anulată.', + network_error: 'Eroare necunoscută', + + size_zero: '0 Byte', + size_byte: 'Byte', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'TB', + size_pp: 'PB', + + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + + month_1: 'Ianuarie', + month_2: 'Februarie', + month_3: 'Martie', + month_4: 'Aprilie', + month_5: 'Mai', + month_6: 'Iunie', + month_7: 'Iulie', + month_8: 'August', + month_9: 'Septembrie', + month_10: 'Octombrie', + month_11: 'Noiembrie', + month_12: 'Decembrie', + + day_1: 'Luni', + day_2: 'Marți', + day_3: 'Miercuri', + day_4: 'Joi', + day_5: 'Vineri', + day_6: 'Sâmbătă', + day_7: 'Duminică', + + month_1_e: 'Ianuarie', + month_2_e: 'Februarie', + month_3_e: 'Martie', + month_4_e: 'Aprilie', + month_5_e: 'Mai', + month_6_e: 'Iunie', + month_7_e: 'Iulie', + month_8_e: 'August', + month_9_e: 'Septembrie', + month_10_e: 'Octombrie', + month_11_e: 'Noiembrie', + month_12_e: 'Decembrie', + + week_1: 'Lun', + week_2: 'Mar', + week_3: 'Mie', + week_4: 'Joi', + week_5: 'Vin', + week_6: 'Sâm', + week_7: 'Dum', + + extensions_enable: 'Activează', + extensions_disable: 'Dezactivează', + extensions_check: 'Verifică stare', + extensions_install: 'Instalează', + extensions_info: 'Informații', + extensions_edit: 'Editează', + extensions_change_name: 'Schimbă numele', + extensions_change_link: 'Schimbă link-ul', + extensions_remove: 'Șterge', + extensions_set_name: 'Introdu numele plugin-ului', + extensions_set_url: 'Introdu URL-ul plugin-ului', + extensions_ready: 'Acest plugin este deja instalat', + extensions_no_info: 'Fără informații', + extensions_no_name: 'Fără nume', + extensions_worked: 'Funcțional', + extensions_no_plugin: 'Plugin neverificat', + extensions_add: 'Adaugă Plugin', + extensions_from_memory: 'Instalat în memorie', + extensions_from_cub: 'Instalat din CUB', + extensions_from_popular: 'Plugin-uri populare', + extensions_from_lib: 'Biblioteca de plugin-uri', + extensions_from_connected: 'Plugin-uri conectate', + + settings_webos_launcher: 'Lansare aplicație', + settings_webos_launcher_add_device: 'Instalează ca aplicație de pornire', + settings_webos_launcher_remove_device: 'Elimină din aplicațiile de pornire', + player_normalization: 'Normalizare', + change_source_on_cub: 'Schimbă sursa în CUB', + settings_param_jackett_interview_all: 'Toate', + settings_param_jackett_interview_healthy: 'Doar cele disponibile', + settings_parser_jackett_interview: 'Interogare trackere', + title_ongoing: 'În curs de difuzare', + title_pgrating: 'Limită de vârstă', + + settings_interface_card_interfice: 'Interfață poster', + settings_interface_card_poster: 'Afișează poster', + title_card: 'Poster', + settings_param_card_interface_old: 'Veche', + settings_param_card_interface_new: 'Nouă', + title_seasons: 'Sezoane', + title_episodes: 'Episoade', + title_rewiews: 'Recenzii', + settings_interface_glass: 'Efect sticlă (Glass)', + settings_interface_glass_descr: 'Afișează interfața în stilul glass', + settings_interface_black_style: 'Stil negru', + + plugins_remove: 'Elimină plugin-uri', + plugins_add_success: 'Plugin conectat cu succes', + settings_reset: 'Resetare', + title_channel: 'Canal', + + input_detection_touch: 'Vrei să treci la control prin atingere?', + input_detection_mouse: 'Vrei să treci la control prin mouse?', + input_detection_remote: 'Vrei să treci la control prin telecomandă?', + + settings_interface_hide_outside_the_screen: 'Ascunde posterele din afara ecranului', + settings_interface_hide_outside_the_screen_descr: 'Accelerează randarea UI și îmbunătățește performanța', + + https_text: 'Folosești protocolul HTTPS; în acest protocol, aplicația s-ar putea să nu funcționeze corect. Se recomandă HTTP.', + + extensions_hpu_best: 'Populare', + extensions_hpu_recomend: 'Recomandate', + extensions_hpu_theme: 'Teme', + extensions_hpu_screensaver: 'Screensaver', + extensions_hpu_video: 'Video', + extensions_hpu_control: 'Control', + extensions_hpu_other: 'Diverse', + extensions_hpu_: 'Altele', + + title_author: 'Autor', + + title_buffer: 'Buffer', + settings_rest_screensaver_time: 'După câte minute să pornească screensaver-ul', + + time_h: 'h.', + time_m: 'm.', + time_s: 's.', + + settings_param_glass_easy: 'Transparent', + settings_param_glass_medium: 'Semitransparent', + settings_param_glass_blacked: 'Întunecat', + + settings_interface_glass_opacity: 'Transparență stil glass', + torrent_error_check_no_auth: 'Serverul a răspuns, dar autorizarea a eșuat', + settings_interface_card_cover: 'Afișează coperta', + + title_upcoming_episodes: 'Următoarele lansări de episoade', + title_recent_episodes: 'Episoade lansate recent', + settings_rest_cache_images: 'Cache imagini', + settings_rest_cache_images_descr: 'Salvează posterele și fundalurile în stocarea locală', + + settings_player_rewind_title: 'Derulare', + settings_player_rewind_descr: 'Interval de derulare în secunde', + + settings_interface_card_reactions: 'Afișează reacțiile', + title_look: 'Urmăresc', + title_scheduled: 'Programat', + title_viewed: 'Vizionat', + title_thrown: 'Abandonat', + title_reactions: 'Reacții', + reactions_none: 'Fără reacții', + reactions_fire: 'Excelent', + reactions_nice: 'Drăguț', + reactions_think: 'Interesant', + reactions_bore: 'Plictisitor', + reactions_shit: 'Slab', + reactions_ready: 'Ai lăsat deja o reacție', + settings_player_launch_trailers: 'Player trailere', + title_continued: 'Continuă vizionarea', + title_language_short: 'Limbă', + + speedtest_connect: 'conexiune', + speedtest_test: 'testare', + speedtest_ready: 'gata', + speedtest_button: 'Testează viteza', + + termsofuse_t_01: 'Termeni de utilizare', + termsofuse_t_02: 'Lampa este un instrument pentru explorarea noutăților din industria cinematografică. Pentru informații, se folosește site-ul open-source themoviedb.org.', + termsofuse_t_03: 'Conținut', + termsofuse_t_04: 'Lampa utilizează API-ul themoviedb.org pentru a prelua informații despre filme și seriale, precum și imagini sau trailere.', + termsofuse_t_05: 'API-ul themoviedb.org permite accesul la o bază de date vastă, oferind posibilitatea de căutare și vizualizare a metadatelor.', + termsofuse_t_06: 'Interacțiunea are loc prin cereri API trimise de aplicație către serverele themoviedb.org.', + termsofuse_t_07: 'Aplicația respectă termenii de utilizare și restricțiile impuse de deținătorul drepturilor.', + termsofuse_t_08: 'Extensii', + termsofuse_t_09: 'Extensiile permit îmbunătățirea capacităților aplicației și modificarea conținutului conform nevoilor.', + termsofuse_t_10: 'Utilizatorul instalează extensiile pe propriul risc. Lampa nu este responsabilă pentru consecințele utilizării acestora.', + termsofuse_t_11: 'Încălcarea drepturilor de autor', + termsofuse_t_12: 'Dacă descoperiți încălcări ale drepturilor de autor, contactați dezvoltatorii. Totuși, aplicația afișează date publice de pe TMDB.', + termsofuse_t_13: 'Dacă un conținut vă încalcă drepturile, puteți solicita eliminarea acestuia direct de pe themoviedb.org.', + settings_rest_protocol_use: 'Conexiune securizată', + settings_rest_protocol_descr: 'Folosește protocolul HTTPS', + install_app_apk_title: 'Cum instalezi Lampa pe Android', + install_app_apk_text: 'Am observat că folosești MediaStationX. Recomandăm instalarea versiunii APK pentru o experiență mai stabilă.', + install_app_apk_qr: 'Scanează codul QR pentru a descărca APK-ul', + copy_link_buffer: 'Copiază link-ul', + + tv_status_returning_series: 'Serial în curs', + tv_status_planned: 'Planificat', + tv_status_in_production: 'În producție', + tv_status_ended: 'Finalizat', + tv_status_canceled: 'Anulat', + tv_status_pilot: 'Pilot', + + tv_status_released:'Lansat', + tv_status_rumored:'Neconfirmat', + tv_status_post_production:'Post-producție', + + title_last_year: 'Anul trecut', + + title_reset: 'Repornire', + back_to_card: 'Înapoi la poster', + + premiere_author_recomend_1: 'Comandă o pizza și pregătește-te pentru acțiune.', + premiere_author_recomend_2: 'Petrecerea abia începe.', + premiere_author_recomend_3: 'Pregătește-te pentru adrenalină.', + premiere_author_recomend_4: 'Gata pentru o seară de neuitat?', + premiere_author_recomend_5: 'Recomand vizionarea.', + premiere_title: 'Premieră', + + settings_clear_cache_only: 'Cache șters', + settings_rest_cache_only: 'Doar Cache', + settings_rest_cache_only_descr: 'Setările de bază vor fi păstrate', + settings_rest_cache_all: 'Cache și Date', + settings_rest_cache_all_descr: 'Toate setările și datele vor fi șterse', + settings_rest_cache_calculate: 'Câtă memorie a rămas', + + title_left:'Rămas', + + account_export_fail_500: 'Eroare necunoscută', + account_export_fail_610: 'Ai depășit limita pentru astăzi', + account_export_fail_200: 'Eroare bază de date, reîncearcă mai târziu', + account_export_fail_600: 'Eroare la încărcarea fișierului', + account_export_fail_620: 'Fișierul nu a fost transmis', + + title_parental_control: 'Control parental', + settings_parental_control_param_time_always: 'Mereu', + settings_parental_control_param_time_once: 'O dată', + settings_parental_control_param_time_10: 'În 10 minute', + settings_parental_control_param_time_20: 'În 20 minute', + settings_parental_control_param_time_30: 'În 30 minute', + settings_parental_control_param_time_60: 'În o oră', + settings_parental_control_param_time_120: 'În 2 ore', + settings_parental_control_change_pin: 'Schimbă PIN-ul', + settings_parental_control_demand_title: 'Când se solicită', + settings_parental_control_demand_descr: 'După cât timp să ceară PIN-ul', + settings_parental_control_enabled: 'Activat', + settings_parental_control_disabled: 'Dezactivat', + parental_control_input_new_code: 'Introdu noul cod PIN', + parental_control_confirm_new_code: 'Confirmă noul cod PIN', + parental_control_no_match_code: 'Codul PIN nu corespunde', + parental_control_input_code: 'Introdu codul PIN', + parental_control_input_error: 'Cod PIN incorect', + title_worth_rewatch: 'Merită revăzut', + + ad_disable: 'Abonându-te la CUB Premium, vei uita de reclame.', + ad_after: 'Publicitate în', + ad: 'Publicitate', + ad_skip: 'Sari peste', + ad_continue_after: 'Vizionarea va începe în', + settings_parser_prowlarr_link_descr: 'Introdu link-ul către serverul Prowlarr', + settings_parser_prowlarr_key_descr: 'Se află în setările Prowlarr la categoria General', + settings_player_torrent_type: 'Tip player pentru torrente', + settings_player_torrent_type_descr: 'Ce player să ruleze torrentele', + + full_crew: 'Echipă', + full_editing: 'Montaj', + full_creator: 'Creator', + player_normalization_step_none: 'Zero', + + settings_cub_backup_export_descr: 'Salvează setările în cloud', + settings_cub_backup_import_descr: 'Restaurează setările din cloud', + + settings_interface_sound: 'Sunete sistem', + settings_interface_sound_play: 'Tranziții', + settings_interface_sound_level: 'Nivel volum', + settings_interface_advanced_animation: 'Animații avansate', + + confirm_open_player: 'Un alt dispozitiv solicită acces la player. Vrei să rulezi video-ul?', + + pincode_use_remote: 'Folosește tastele direcționale ale telecomenzii pentru a selecta cifrele.', + pincode_use_toggle: 'Ține apăsat butonul OK pentru a schimba formatul.', + + settings_parental_control_where: 'Unde se solicită codul PIN', + title_fire: 'Tare!', + title_top_100: 'Top 100', + + player_normalization_type_title: 'Tip normalizare', + player_normalization_type_all: 'Toate', + player_normalization_type_up: 'Doar creștere', + player_normalization_type_down: 'Doar scădere', + storage_quota_exceeded: 'Spațiu de stocare insuficient. Golește memoria cache și încearcă din nou.', + settings_cub_domain: 'Domeniu principal', + + title_ai_assistant: 'Asistent AI', + title_facts: 'Curiozități', + ai_search_start_typing: 'Întreabă asistentul AI ce filme vrei să găsești. Ex: "Filme despre spațiu"', + ai_search_limit: 'Limita de cereri a fost atinsă. Cu CUB Premium, limitele sunt mai mari!', + ai_subscribe_title: 'Mai multe posibilități cu AI', + ai_subscribe_descr: 'Abonează-te la CUB Premium pentru a crește numărul de cereri AI.', + + dmca_title: 'Conținut blocat', + dmca_descr: 'Acest material nu este disponibil pentru vizionare la cererea deținătorului drepturilor de autor.', + + loading_progress_step_0: 'Inițializare', + loading_progress_step_1: 'Încărcare limbi', + loading_progress_step_2: 'Căutare surse', + loading_progress_step_3: 'Pregătire extensii', + loading_progress_step_4: 'Aproape gata', + loading_progress_step_5: 'Imediat...', + + install_extension_rule_1: 'Instalarea unui plugin terț', + install_extension_rule_2: 'Plugin-urile sunt create de dezvoltatori independenți. Instalându-le, ești de acord că:', + install_extension_rule_3: '- Unele pot cere acces la datele tale.', + install_extension_rule_4: '- Ești responsabil pentru utilizarea lor conform legii.', + install_extension_rule_5: '- Instalează doar din surse sigure.', + install_extension_rule_6: 'LAMPA nu susține conținutul piratat.', + install_extension_rule_7: 'Continuând, confirmi că înțelegi riscurile.', + ad_plugin: 'Publicitate din plugin', + + terminal_title: 'Terminal', + terminal_no_access: 'Fără acces', + terminal_confirm: 'Permite', + terminal_deny: 'Refuză', + terminal_update: 'Actualizează', + terminal_code: 'Cod de acces', + terminal_text: 'Solicitați acces la terminal. Dezvoltatorii ar putea controla dispozitivul pentru diagnoză. Asigurați-vă că aveți încredere în ei.', + + title_anons: 'Anunț', + title_developer: 'Dezvoltator', + title_navigation: 'Navigare', + title_page: 'Pagina', + title_person_about: 'Despre', + account_qr_premium: 'Scanează pentru detalii CUB Premium', + account_qr_code: 'Scanează pentru a primi codul de conectare', + account_qr_create: 'Scanează pentru a crea un cont', + account_add_device_title: 'Adaugă dispozitiv', + account_add_device_text: 'Mergi la pentru cod.', + account_none_title: 'Nu ai cont încă?', + account_none_include_1: 'Marcajele și istoricul vizualizărilor sunt salvate în cloud', + account_none_include_2: 'Sincronizare între dispozitive', + account_none_include_3: 'Notificări despre episoade noi', + account_none_include_4: 'Profiluri multiple sub același cont', + account_premium_include_1: 'Număr extins de marcaje', + account_premium_include_2: 'Istoric de vizionare extins', + account_premium_include_3: 'Mai multe timecode-uri disponibile', + account_premium_include_4: 'Mai multe profiluri pe cont', + empty_subscribes_title: 'Abonamentele tale la traduceri', + empty_subscribes_text: 'Abonează-te la traducerea preferată și te vom anunța la apariția unui nou episod.', + empty_history_title: 'Istoricul tău', + empty_history_text: 'Istoricul tău de vizionare va apărea aici.', + empty_bookmark_title: 'Lista ta de favorite', + empty_bookmark_text: 'Adaugă filmele și serialele care îți plac aici.', + empty_mytorrents_title: 'Torrentele tale', + empty_mytorrents_text: 'Torrentele descărcate prin TorServer vor apărea aici.', + developer_param_enabled: 'Mod Dezvoltator', + developer_param_nopremium: 'Dezactivează CUB Premium', + developer_param_nodemo: 'Dezactivează Mod Demo', + developer_param_ads: 'Afișează reclame', + developer_param_fps: 'Afișează FPS', + developer_trigger_help_1: 'Aproape ai ghicit :)', + developer_trigger_help_2: 'Încă puțin :)', + developer_trigger_help_3: 'Sigur vrei în modul Dezvoltator?', + developer_trigger_help_4: 'Mod Dezvoltator activat', + settings_param_navigation_touch: 'Senzor', + account_discuss_add_qr: 'Scanează codul QR', + account_discuss_add_title: 'Vrei să lași un comentariu?', + account_discuss_add_text: 'Scanează codul pentru a adăuga un comentariu despre acest film sau serial.', + account_discuss_added: 'Mulțumim pentru comentariu!', + account_discuss_added_ready: 'Ai lăsat deja un comentariu pentru acest film sau serial.', + remote_helper_long: 'Ține apăsat OK pentru a deschide meniul', + account_premium: 'Deblochează noi orizonturi cu CUB Premium! Profită de limite mai mari. Vizitează .', + player_segments_title: 'Segmente', + player_segments_descr: 'Sari peste intro și alte părți ale video-ului', + player_segments_ad_title: 'Reclame', + player_segments_skip_title: 'Intro și altele', + player_segments_value_none: 'Nu sări', + player_segments_value_auto: 'Sari automat', + player_segments_value_user: 'Personalizat', + player_segments_skiped: 'Segment sărit', + player_segments_skip_now: 'Sari', + player_segments_skip_in: 'Sări peste în', + player_segments_skip_intro: 'Sari peste intro', + player_segments_next: 'Episodul următor', + player_segments_next_in: 'Episodul următor în', + subscribe_info: 'În secțiunea Abonamente vei vedea toate traducerile urmărite.', + no_watch_history: 'Niciun istoric de vizionare', + + settings_request_caching_use: 'Cache solicitări', + settings_request_caching_descr: 'Salvează cererile API pentru a optimiza viteza interfeței.', + + account_profile_child: 'Copil', + account_profile_add: 'Adaugă profil', + account_profile_name: 'Nume profil', + account_profile_created: 'Profil creat cu succes', + account_profile_limited: 'Limita de profiluri a fost atinsă: {count}', + account_profile_info: 'Gestionați profilurile în setările contului la ', + player_youtube_no_support: 'Dispozitivul nu suportă redarea YouTube. Verifică conexiunea.', + title_channels: 'Canale', + title_best_of_2000: 'Anii 2000 de aur', + title_best_of_2010: 'Hiturile anilor 2010', + title_best_of_2015: 'Clasice moderne', + title_comedy_of_2000: 'Comediile anilor 2000', + title_comedy_of_2010: 'Umorul anilor 2010', + title_comedy_of_2015: 'Comedii moderne', + + filter_keyword_sequel: 'Continuare (Sequel)', + filter_keyword_based_comic: 'Bazat pe benzi desenate', + filter_keyword_space: 'Spațiu', + filter_keyword_survival: 'Supraviețuire', + filter_keyword_zombie: 'Zombie', + filter_keyword_school: 'Școală', + filter_keyword_revenge: 'Răzbunare', + filter_keyword_detective: 'Detectiv', + filter_keyword_robots: 'Roboți', + filter_keyword_vampires: 'Vampiri', + filter_keyword_aliens: 'Extratereștri', + filter_keyword_police: 'Poliție', + filter_keyword_reincarnation: 'Reîncarnare', + filter_keyword_spy: 'Spionaj', + filter_keyword_disaster: 'Catastrofă', + filter_keyword_christmas: 'Crăciun', + + dmca_title_lgbt: 'Conținut restricționat', + dmca_descr_lgbt: 'Vizualizarea nu este disponibilă în regiunea dvs., deoarece poate include conținut LGBT. Un astfel de material poate fi interzis sau restricționat în unele țări.', + + settings_lgbt_content_block: 'Blocați conținutul LGBT', + + // todo: + adult_content_title: 'Conținut pentru adulți', + adult_content_text_warning: 'Conținutul poate include material pentru adulți care poate fi inadecvat pentru unii spectatori.', + adult_content_text_modal: 'Acest film sau serial conține conținut pentru adulți. Pentru a continua, trebuie să ai cel puțin 18 ani. Te rugăm să confirmi că ești major.', + + adult_content_confirm: 'Am 18 ani sau mai mult', + adult_content_deny: 'Am sub 18 ani', + + inner_player_disclaimer_title: 'Avertisment player', + inner_player_disclaimer_text: 'Înțeleg că pornesc un player cu suport incomplet și înțeleg că acest lucru poate duce la comportament atipic pe dispozitiv. Este recomandat să treceți la playere din familia tvOS sau la alte alternative.', + + inner_player_disclaimer_change_player: 'Schimbă playerul', + remote_configuration_settings_title: 'Configurare de la distanță', + remote_configuration_registration_text: 'Configurarea de la distanță oferă acces temporar la aplicația dvs., o altă aplicație va putea instala extensii și configura setările.', + remote_configuration_waite_text: 'Acum puteți transmite acest cod unei alte aplicații pentru a acorda acces la setări.', + remote_configuration_open_button: 'Permite accesul', + remote_configuration_code_life: 'Codul este valabil', + remote_configuration_notice_nocode: 'Nu s-a putut acorda accesul', + + settings_server_gts: 'Transcodare', + settings_server_gts_descr: 'Convertiți automat videoclipul într-un format compatibil atunci când este necesar.', + settings_server_tracktimecode: 'Activează TrackTimecode', + settings_server_tracktimecode_descr: 'Salvează progresul de redare pentru filme și seriale pe serverul TorrServer. Pentru funcționare, această opțiune trebuie activată în TorrServer.', + + title_metadata: 'Metadate', + title_moods: 'Stări', + title_meta_violence: 'Violență', + title_meta_fear: 'Frică', + title_meta_profanity: 'Limbaj vulgar', + title_meta_sadness: 'Tristețe', + title_meta_sex: 'Sexualitate', + player_pip: 'Minimizare', + player_volume: 'Volum', + player_time_end: 'Se termină la', + player_ai_agent_info: 'Vrei să afli mai multe despre videoclip? Întreabă asistentul AI, iar acesta îți va oferi un grafic al stării de spirit, un scurt rezumat și momentele interesante.', + player_ai_agent_ask_plot: 'Rezumat', + player_ai_agent_ask_moods: 'Afișează graficul', + player_ai_agent_ask_highlights: 'Momente interesante', + player_ai_agent_ask: 'Întreabă', + player_ai_agent_processing: 'Analizez...', + player_ai_agent_no_data: 'Nu există date de afișat.', + player_ai_agent_no_analysis: 'Nu s-a putut analiza videoclipul.', + player_ai_agent_quota: 'Limita de cereri a fost depășită. Vă rugăm să încercați din nou mai târziu.', + player_ai_agent_working: 'Lucrez încă la asta...', + title_meta_humor: 'Umor', + title_meta_tension: 'Tensiune', + title_meta_romance: 'Romantism', + title_meta_pace: 'Ritm', + title_meta_importance: 'Scene importante', + title_meta_action: 'Acțiune' +} diff --git a/lampa-main/lang/ru.js b/lampa-main/lang/ru.js new file mode 100644 index 0000000..f414a10 --- /dev/null +++ b/lampa-main/lang/ru.js @@ -0,0 +1,1371 @@ +export default { + lang_choice_title: 'Добро пожаловать', + lang_choice_subtitle: 'Выберите свой язык', + + more: 'Еще', + show_more: 'Показать ещё', + more_results: 'Показать больше результатов', + loading: 'Загрузка', + nofind_movie: 'Не удалось найти фильм.', + noname: 'Без названия', + nochoice: 'Не выбрано', + cancel: 'Отменить', + confirm: 'Подтверждаю', + sure: 'Вы уверены?', + nodata: 'Нет данных', + back: 'Назад', + ready: 'Готово', + close_app_modal: 'Вы уверены, что хотите покинуть приложение?', + connected_seeds: 'подкл.', + + search: 'Поиск', + search_input: 'Введите текст', + search_empty: 'История поиска пуста.', + search_delete: 'Влево - удалить', + search_start_typing: 'Начните вводить текст для поиска.', + search_searching: 'Идет поиск...', + search_start: 'Начать поиск', + search_nofound: 'По вашему запросу ничего не найдено.', + global_search: 'Глобальный поиск', + + full_genre: 'Жанр', + full_production: 'Производство', + full_date_of_release: 'Дата релиза', + full_budget: 'Бюджет', + full_countries: 'Страны', + full_like: 'Нравится', + full_torrents: 'Торренты', + full_trailers: 'Трейлеры', + full_detail: 'Подробно', + full_notext: 'Без описания.', + full_series_release: 'Выход серий', + full_next_episode: 'Следующая', + full_episode_days_left: 'Осталось дней', + full_trailer_official: 'Официальный', + full_trailer_no_official: 'Неофициальный', + full_season: 'Сезон', + full_episode: 'Эпизод', + full_directing: 'Режиссура', + full_writing: 'Сценарий', + full_keywords: 'Теги', + full_crew: 'Еще', + full_editing: 'Монтаж', + full_creator: 'Создатель', + + settings_cub_sync: 'Синхронизация', + settings_cub_sync_descr: 'Синхронизация с сервисом CUB: синхронизация ваших закладок, истории просмотров, меток и тайм-кодов.', + settings_cub_account: 'Аккаунт', + settings_cub_logged_in_as: 'Вошли как', + settings_cub_profile: 'Профиль', + settings_cub_sync_btn: 'Синхронизировать', + settings_cub_sync_btn_descr: 'Сохранить локальные закладки в аккаунт CUB', + settings_cub_backup: 'Бэкап', + settings_cub_backup_descr: 'Сохранить или загрузить бэкап данных', + settings_cub_logout: 'Выйти из аккаунта', + settings_cub_signin: 'Авторизация', + settings_cub_not_specified: 'Не указан', + settings_cub_password: 'Пароль', + settings_cub_status: 'Статус', + settings_cub_backup_import: 'Импорт', + settings_cub_backup_export: 'Экспорт', + settings_cub_backup_export_descr: 'Сохранить настройки в облако', + settings_cub_backup_import_descr: 'Восстановить настройки из облака', + settings_cub_sync_filters: 'Синхронизация фильтров', + settings_cub_sync_calendar: 'Синхронизация календаря', + settings_cub_sync_quality: 'Синхронизация отметок (качество)', + settings_cub_sync_search: 'Синхронизация истории поиска', + settings_cub_sync_recomends: 'Синхронизация рекомендаций', + settings_cub_sync_timecodes: 'Синхронизация тайм-кодов', + settings_cub_signin_button: 'Выполнить вход', + settings_cub_domain: 'Основной домен', + + settings_input_links: 'Избранное', + + settings_interface_type: 'Облегчённая версия', + settings_interface_size: 'Размер интерфейса', + settings_interface_menu_always: 'Всегда показывать левое меню', + settings_interface_background: 'Фон', + settings_interface_background_use: 'Показывать фон', + settings_interface_background_type: 'Тип фона', + settings_interface_performance: 'Быстродействие', + settings_interface_animation: 'Анимация', + settings_interface_advanced_animation: 'Продвинутая анимация', + settings_interface_animation_descr: 'Анимация карточек и контента', + settings_interface_attenuation: 'Затухание', + settings_interface_attenuation_descr: 'Плавное затухание карточек снизу и сверху', + settings_interface_scroll: 'Тип скроллинга', + settings_interface_view_card: 'Тип просмотра карточек', + settings_interface_view_card_descr: 'По мере скроллинга ленты карточки будут подгружаться постепенно или загружаться все', + settings_interface_lang: 'Язык интерфейса', + settings_interface_lang_reload: 'Необходимо перезапустить приложение, нажмите «OK» для перезагрузки', + settings_interface_card_interfice: 'Интерфейс карточек', + settings_interface_card_poster: 'Показать постер', + settings_interface_card_cover: 'Показать обложку', + settings_interface_card_reactions: 'Показать реакции', + settings_interface_glass: 'Стекло', + settings_interface_glass_descr: 'Показывать интерфейс в стекловидном стиле', + settings_interface_glass_opacity: 'Прозрачность стекла', + settings_interface_black_style: 'Чёрный стиль', + settings_interface_hide_outside_the_screen: 'Скрывать карточки за пределами экрана', + settings_interface_hide_outside_the_screen_descr: 'Это ускорит рендер интерфейса и улучшит производительность', + + settings_interface_sound: 'Системные звуки', + settings_interface_sound_play: 'Переходы', + settings_interface_sound_level: 'Уровень громкости', + + settings_main_account: 'Аккаунт', + settings_main_interface: 'Интерфейс', + settings_main_player: 'Плеер', + settings_main_parser: 'Парсер', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Расширения', + settings_main_rest: 'Остальное', + + settings_rest_start: 'Стартовая страница', + settings_rest_start_descr: 'С какой страницы начинать при запуске', + settings_rest_source: 'Источник', + settings_rest_source_use: 'Основной источник', + settings_rest_source_descr: 'Откуда брать информацию о фильмах', + settings_rest_tmdb_lang: 'На каком языке отображать данные с TMDB', + settings_rest_tmdb_prox: 'Проксировать TMDB', + settings_rest_tmdb_prox_auto: 'Включить прокси автоматически', + settings_rest_tmdb_posters: 'Разрешение постеров TMDB', + settings_rest_screensaver: 'Скринсейвер', + settings_rest_screensaver_use: 'Показывать заставку при бездействии', + settings_rest_screensaver_type: 'Тип заставки', + settings_rest_screensaver_time: 'Через сколько минут запустить скринсейвер', + settings_rest_helper: 'Подсказки', + settings_rest_helper_use: 'Показывать подсказки', + settings_rest_helper_reset: 'Показать подсказки снова', + settings_rest_pages: 'Сколько страниц хранить в памяти', + settings_rest_pages_descr: 'Хранит страницы в том состоянии, в котором вы их покинули.', + settings_rest_time: 'Сместить время', + settings_rest_navigation: 'Тип навигации', + settings_rest_keyboard: 'Тип клавиатуры', + settings_rest_device: 'Название устройства', + settings_rest_device_placeholder: 'Например: Моя Лампа', + settings_rest_cache: 'Очистить кэш', + settings_rest_tmdb_example: 'Например:', + settings_rest_tmdb_api_descr: 'Для получения данных', + settings_rest_tmdb_image_descr: 'Для получения изображений', + settings_rest_card_quality: 'Отметки качества', + settings_rest_card_quality_descr: 'Отображать отметки качества на карточках', + settings_rest_card_episodes: 'Отметки эпизодов', + settings_rest_card_episodes_descr: 'Отображать отметки эпизодов на карточках', + settings_rest_cache_images: 'Кэш изображений', + settings_rest_cache_images_descr: 'Кэшировать постеры и фоны в локальное хранилище', + settings_rest_protocol_use: 'Безопасное соединение', + settings_rest_protocol_descr: 'Использовать протокол HTTPS', + settings_rest_cache_only: 'Только кеш', + settings_rest_cache_only_descr: 'Основные настройки сохранятся', + settings_rest_cache_all: 'Кеш и данные', + settings_rest_cache_all_descr: 'Будут очищены все настройки и данные', + settings_rest_cache_calculate: 'Сколько осталось памяти', + settings_request_caching_use: 'Кэширование запросов', + settings_request_caching_descr: 'Сохранять ответы от серверов в кэш для ускорения работы приложения', + + settings_parser_use: 'Использовать парсер', + settings_parser_use_descr: 'Тем самым, вы соглашаетесь принять на себя всю ответственность за использование публичных ссылок для просмотра торрент и онлайн контента.', + settings_parser_type: 'Тип парсера для торрентов', + settings_parser_jackett_placeholder: 'Например: 192.168.х', + settings_parser_jackett_link: 'Ссылка', + settings_parser_jackett_link_descr: 'Укажите ссылку на скрипт Jackett', + settings_parser_prowlarr_link_descr: 'Укажите ссылку на сервер Prowlarr', + settings_parser_jackett_key_placeholder: 'Например: sa0sk83d..', + settings_parser_jackett_key: 'Api-ключ', + settings_parser_jackett_key_descr: 'Находится в Jackett', + settings_parser_prowlarr_key_descr: 'Находится во вкладке настроек Prowlarr в категории основное', + settings_parser_torlook_type: 'Метод парсинга сайта TorLook', + settings_parser_scraperapi_placeholder: 'Например: scraperapi.com', + settings_parser_scraperapi_link: 'Ссылка на парсер сайтов', + settings_parser_scraperapi_descr: 'Зарегистрируйтесь на сайте scraperapi.com, введите ссылку api.scraperapi.com?api_key=...&url={q}
    В {q} будет поставляться сайт w41.torlook.info', + settings_parser_search: 'Поиск', + settings_parser_search_descr: 'На каком языке производить поиск?', + settings_parser_in_search: 'Парсер в поиске', + settings_parser_in_search_descr: 'Показывать результаты в поиске?', + settings_parser_timeout_title: 'Таймаут парсера', + settings_parser_timeout_descr: 'Время (в секундах) ожидания ответа от сервера', + + settings_player_type: 'Тип плеера', + settings_player_type_descr: 'Каким плеером воспроизводить видео', + settings_infuse_launch_mode: 'Запуск в Infuse', + settings_infuse_launch_mode_descr: 'Что делать при открытии видео в Infuse. Для торрентов всегда сразу воспроизведение', + settings_infuse_launch_ask: 'Спрашивать при запуске', + settings_infuse_launch_play: 'Играть', + settings_infuse_launch_save_and_play: 'Сохранить и играть', + settings_player_iptv_type: 'Тип плеера для IPTV', + settings_player_iptv_type_descr: 'Каким плеером воспроизводить IPTV-каналы', + settings_player_torrent_type: 'Тип плеера для торрентов', + settings_player_torrent_type_descr: 'Каким плеером воспроизводить торренты', + settings_player_reset: 'Сбросить плеер по умолчанию', + settings_player_reset_descr: 'Сбрасывает выбранный Android-плеер в приложении', + settings_player_path: 'Путь к плееру', + settings_player_path_descr: 'Укажите путь к исполняемому файлу плеера', + settings_player_external_header: 'Внешний плеер', + settings_player_external_fullscreen: 'Запускать в полноэкранном режиме', + settings_player_normalization: 'Нормализация звука', + settings_player_normalization_descr: 'Нормализирует звук в один уровень, понижает громкие звуки и повышает тихие.', + settings_player_next_episode: 'Следующая серия', + settings_player_next_episode_descr: 'Автоматически переключать на следующую серию по окончании текущей', + settings_player_timecode: 'Тайм-код', + settings_player_timecode_descr: 'Продолжить с последнего места просмотра', + settings_player_scale: 'Метод масштабирования', + settings_player_scale_descr: 'Каким образом производить вычисления для масштабирования видео', + settings_player_subs: 'Субтитры', + settings_player_subs_use: 'Включить', + settings_player_subs_use_descr: 'Всегда включать субтитры после запуска видео', + settings_player_subs_lang: 'Язык субтитров', + settings_player_subs_lang_descr: 'Какие субтитры включать автоматически, если доступно несколько языков', + settings_param_subtitles_lang_auto: 'Язык интерфейса', + settings_player_subs_size: 'Размер', + settings_player_subs_size_descr: 'Размер субтитров на экране', + settings_player_subs_stroke_use: 'Использовать окантовку', + settings_player_subs_stroke_use_descr: 'Субтитры будут обведены черным цветом для улучшения читаемости', + settings_player_subs_backdrop_use: 'Использовать подложку', + settings_player_subs_backdrop_use_descr: 'Субтитры будут отображаться на полупрозрачной подложке для улучшения читаемости', + settings_player_quality: 'Качество видео по умолчанию', + settings_player_quality_descr: 'Предпочтительное качество видео для просмотра', + settings_player_hls_title: 'Обработка потока .m3u8', + settings_player_hls_descr: 'Не трогайте этот параметр, если не знаете, зачем он.', + settings_player_rewind_title: 'Перемотка', + settings_player_rewind_descr: 'Интервал перемотки в секундах', + settings_player_launch_trailers: 'Плеер для трейлеров', + + settings_plugins_notice: 'Для применения плагина необходимо перезагрузить приложение', + settings_plugins_add: 'Добавить плагин', + settings_plugins_add_descr: 'Для удаления добавленного плагина удерживайте или нажмите дважды клавишу (OK) на нем', + settings_plugins_install: 'Установить плагин', + settings_plugins_install_descr: 'Установить плагин из списка доступных', + + settings_server_link: 'Использовать ссылку', + settings_server_links: 'Ссылки', + settings_server_placeholder: 'Например: 192.168.х', + settings_server_link_one: 'Основная ссылка', + settings_server_link_one_descr: 'Укажите основную ссылку на TorrServer', + settings_server_link_two: 'Дополнительная ссылка', + settings_server_link_two_descr: 'Укажите дополнительную ссылку на TorrServer', + settings_server_additionally: 'Дополнительно', + settings_server_client: 'Встроенный клиент', + settings_server_client_descr: 'Использовать встроенный JS-клиент TorrServer, иначе запускается системный.', + settings_server_base: 'Сохранять в базу', + settings_server_base_descr: 'Торрент будет добавлен в базу TorrServer', + settings_server_preload: 'Использовать буфер пред.загрузки', + settings_server_preload_descr: 'Дожидаться заполнения буфера предварительной загрузки TorrServer перед проигрыванием', + settings_server_auth: 'Авторизация', + settings_server_password_use: 'Вход по паролю', + settings_server_login: 'Логин', + settings_server_password: 'Пароль', + settings_server_not_specified: 'Не указан', + settings_server_search_type: 'Тип поиска', + settings_server_search_type_descr: 'Где искать торренты: встроенный rutor, Torznab-индексеры в TorrServer, или оба источника.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + + settings_server_gts: 'Транскодирование', + settings_server_gts_descr: 'Автоматически преобразовывать видео в совместимый формат при необходимости.', + settings_server_tracktimecode: 'Включить TrackTimecode', + settings_server_tracktimecode_descr: 'Сохраняет прогресс просмотра фильмов и сериалов на сервере TorrServer. Для работы эту опцию также необходимо включить в TorrServer.', + + settings_webos_launcher: 'Запуск приложения', + settings_webos_launcher_add_device: 'Установить как стартовое', + settings_webos_launcher_remove_device: 'Убрать из стартовых приложений', + + settings_parental_control_param_time_always: 'Всегда', + settings_parental_control_param_time_once: 'Один раз', + settings_parental_control_param_time_10: 'Через 10 минут', + settings_parental_control_param_time_20: 'Через 20 минут', + settings_parental_control_param_time_30: 'Через 30 минут', + settings_parental_control_param_time_60: 'Через 1 час', + settings_parental_control_param_time_120: 'Через 2 часа', + settings_parental_control_change_pin: 'Изменить PIN-код', + settings_parental_control_demand_title: 'Когда запрашивать', + settings_parental_control_demand_descr: 'Через какое время запрашивать PIN-код', + settings_parental_control_enabled: 'Включено', + settings_parental_control_disabled: 'Отключено', + settings_parental_control_where: 'Где запрашивать PIN-код', + + settings_lgbt_content_block: 'Блокировать ЛГБТ контент', + + parental_control_input_new_code: 'Введите новый PIN-код', + parental_control_confirm_new_code: 'Повторите PIN-код', + parental_control_no_match_code: 'PIN-код не совпадает с прошлым кодом', + parental_control_input_code: 'Введите PIN-код', + parental_control_input_error: 'Вы ввели неправильный PIN-код', + + + torent_nohash_reasons: 'Причины', + torent_nohash_reason_one: 'TorServer не смог скачать торрент файл', + torent_nohash_reason_two: 'Ответ от TorServer', + torent_nohash_reason_three: 'Ссылка', + torent_nohash_do: 'Что делать?', + torent_nohash_do_one: 'Проверьте правильно ли вы настроили Jackett', + torent_nohash_do_two: 'Приватные источники могут не выдавать ссылку на файл', + torent_nohash_do_three: 'Убедитесь что Jackett тоже может скачать файл', + torent_nohash_do_four: 'Написать в нашу Telegram-группу: @lampa_group', + torent_nohash_do_five: 'Укажите какой фильм, какая раздача и по возможности фото этой раздачи', + + torrent_error_text: 'Не удалось подключиться к TorrServer. Давайте быстро пройдёмся по списку возможных проблем и всё проверим.', + torrent_error_step_1: 'Запущен ли TorrServer', + torrent_error_step_2: 'Динамический IP-адрес', + torrent_error_step_3: 'Протокол и порт', + torrent_error_step_4: 'Блокировка антивирусами', + torrent_error_step_5: 'Проверьте на доступность', + torrent_error_step_6: 'Все равно не работает', + torrent_error_info_1: 'Убедитесь, что вы запустили TorrServer на устройстве, где он установлен.', + torrent_error_info_2: 'Частая ошибка, изменился IP-адрес устройства с TorrServer. Убедитесь, что IP-адрес, который вы ввели - {ip}, совпадает с адресом устройства, на котором установлен TorrServer.', + torrent_error_info_3: 'Для подключения к TorrServer, необходимо указать протокол http:// в начале и порт :8090 в конце адреса. Убедитесь, что после IP-адреса указан порт, ваш текущий адрес - {ip}', + torrent_error_info_4: 'Частое явление, антивирус или брандмауэр может блокировать доступ по IP-адресу, попробуйте отключить антивирус и брандмауэр.', + torrent_error_info_5: 'На любом другом устройстве в этой же сети, откройте в браузере адрес {ip} и проверьте, доступен ли веб-интерфейс TorrServer.', + torrent_error_info_6: 'Если после всех проверок всё равно возникает ошибка подключения, попробуйте перезагрузить TorrServer и интернет-адаптер.', + torrent_error_info_7: 'Если проблема не устранена, пишите в Telegram-группу @lampa_group с текстом (Lampa не подключается к TorrServer после всех проверок, текущий адрес {ip})', + torrent_error_start: 'Начать проверку', + torrent_error_nomatrix: 'Не удалось подтвердить версию Matrix', + torrent_error_made: 'Выполнено', + torrent_error_from: 'из', + torrent_error_next: 'Далее', + torrent_error_complite: 'Завершить', + torrent_error_connect: 'Ошибка подключения', + torrent_error_check_no_auth: 'Сервер ответил на запрос, но не удалось пройти авторизацию', + + torrent_install_need: 'Необходим TorrServer', + torrent_install_text: 'TorrServer – приложение, которое позволяет просматривать контент из торрент-файлов в онлайн режиме.

    Более детальную информацию по установке вы найдете в Telegram-группах, указанных ниже.', + torrent_install_contact: 'Telegram-группы', + + torrent_item_bitrate: 'Битрейт', + torrent_item_seeds: 'Раздают', + torrent_item_grabs: 'Качают', + torrent_item_mb: 'Мбит/с', + + torrent_serial_episode: 'Серия', + torrent_serial_season: 'Сезон', + torrent_serial_date: 'Выход', + + torrent_get_magnet: 'Запрашиваю magnet ссылку', + torrent_remove_title: 'Удалить', + torrent_remove_descr: 'Торрент будет удален из вашего списка', + + torrent_parser_any_one: 'Любое', + torrent_parser_any_two: 'Любой', + torrent_parser_no_choice: 'Не выбрано', + torrent_parser_yes: 'Да', + torrent_parser_no: 'Нет', + torrent_parser_quality: 'Качество', + torrent_parser_subs: 'Субтитры', + torrent_parser_voice: 'Перевод', + torrent_parser_tracker: 'Трекер', + torrent_parser_year: 'Год', + torrent_parser_season: 'Сезон', + torrent_parser_sort_by_seeders: 'По раздающим', + torrent_parser_sort_by_size: 'По размеру', + torrent_parser_sort_by_name: 'По названию', + torrent_parser_sort_by_tracker: 'По источнику', + torrent_parser_sort_by_date: 'По дате', + torrent_parser_sort_by_viewed: 'По просмотренным', + torrent_parser_voice_dubbing: 'Дубляж', + torrent_parser_voice_polyphonic: 'Многоголосый', + torrent_parser_voice_two: 'Двухголосый', + torrent_parser_voice_amateur: 'Любительский', + torrent_parser_reset: 'Сбросить фильтр', + torrent_parser_empty: 'Не удалось получить результатов', + torrent_parser_no_hash: 'Не удалось получить HASH, попробуйте перезагрузить TorrServer', + torrent_parser_added_to_mytorrents: 'добавлено в «Мои торренты»', + torrent_parser_add_to_mytorrents: 'Добавить в «Мои торренты»', + torrent_parser_label_title: 'Пометить', + torrent_parser_label_descr: 'Пометить раздачу с флагом (просмотрено)', + torrent_parser_label_cancel_title: 'Снять отметку', + torrent_parser_label_cancel_descr: 'Снять отметку с раздачи (просмотрено)', + torrent_parser_timeout: 'Время ожидания истекло', + torrent_parser_nofiles: 'Не удалось извлечь подходящие файлы', + torrent_parser_set_link: 'Укажите ссылку для парсинга', + torrent_parser_request_error: 'Ошибка в запросе', + torrent_parser_magnet_error: 'Не удалось получить magnet ссылку', + torrent_parser_no_responce: 'Парсер не отвечает на запрос', + torrent_parser_torlook_fallback_search_notification: 'Парсер Jackett не доступен или настройки подключения не верны. Осуществляется поиск в Torlook...', + + about_text: 'Приложение полностью бесплатное и использует публичные ссылки для получения информации о видео, новинках, популярных фильмах и т.д. Вся доступная информация используется исключительно в познавательных целях, приложение не использует свои собственные серверы для распространения информации.', + about_channel: 'Наш канал', + about_group: 'Группа', + about_version: 'Версия', + about_donate: 'Донат', + + title_watched: 'Вы смотрели', + title_settings: 'Настройки', + title_collections: 'Подборки', + title_company: 'Компания', + title_actors: 'Актеры', + title_actor: 'Актер', + title_actress: 'Актриса', + title_person: 'Персона', + title_persons: 'Персоны', + title_person_about: 'О персоне', + title_comments: 'Комментарии', + title_torrents: 'Торренты', + title_trailers: 'Трейлеры', + title_watch: 'Смотреть', + title_error: 'Ошибка', + title_links: 'Ссылки', + title_choice: 'Выбрать', + title_main: 'Главная', + title_book: 'Закладки', + title_like: 'Нравится', + title_wath: 'Позже', + title_look: 'Смотрю', + title_scheduled: 'Запланировано', + title_viewed: 'Просмотрено', + title_thrown: 'Брошено', + title_continued: 'Продолжение следует', + title_history: 'История просмотров', + title_mytorrents: 'Мои торренты', + title_last: 'Последняя', + title_action: 'Действие', + title_action_infuse: 'Действие Infuse', + title_producer: 'Режиссер', + title_collection: 'Коллекция', + title_recomendations: 'Рекомендации', + title_similar: 'Похожие', + title_about: 'О приложении', + title_timetable: 'Расписание', + title_relises: 'Цифровые релизы', + title_catalog: 'Каталог', + title_category: 'Категория', + title_parser: 'Парсер', + title_type: 'Тип', + title_rating: 'Рейтинг', + title_country: 'Страна', + title_year: 'Год', + title_genre: 'Жанр', + title_filter: 'Фильтр', + title_notice: 'Уведомления', + title_files: 'Файлы', + title_now_watch: 'Сейчас смотрят', + title_latest: 'Последнее добавление', + title_continue: 'Продолжить просмотр', + title_recomend_watch: 'Рекомендуем посмотреть', + title_new_episodes: 'Новые серии', + title_popular: 'Популярное', + title_popular_movie: 'Популярные фильмы', + title_popular_tv: 'Популярные сериалы', + title_new_this_year: 'Новинки этого года', + title_hight_voite: 'С высоким рейтингом', + title_new: 'Новинки', + title_trend_day: 'Сегодня в тренде', + title_trend_week: 'В тренде за неделю', + title_upcoming: 'Смотрите в кинозалах', + title_top_movie: 'Топ фильмы', + title_top_tv: 'Топ сериалы', + title_tv_today: 'Сегодня в эфире', + title_this_week: 'На этой неделе', + title_in_top: 'В топе', + title_out: 'Выход', + title_out_confirm: 'Да, выйти', + title_continue_two: 'Продолжить', + title_choice_language: 'Выбрать язык', + title_subscribe: 'Подписаться', + title_subscribes: 'Подписки', + title_unsubscribe: 'Отписаться', + title_language: 'Язык оригинала', + title_language_short: 'Язык', + title_ongoing: 'Онгоинги', + title_pgrating: 'Возрастное ограничение', + title_card: 'Карточка', + title_seasons: 'Сезоны', + title_episodes: 'Серии', + title_rewiews: 'Отзывы', + title_channel: 'Канал', + title_in_high_quality: 'В высоком качестве', + title_author: 'Автор', + title_buffer: 'Буфер', + title_upcoming_episodes: 'Ближайшие выходы эпизодов', + title_recent_episodes: 'Недавние выходы эпизодов', + title_reactions: 'Реакции', + title_last_year: 'Прошлый год', + title_reset: 'Перезагрузить', + title_left:'Осталось', + title_parental_control: 'Родительский контроль', + title_worth_rewatch: 'Стоит пересмотреть', + title_fire: 'Огонь!', + title_top_100: 'Топ 100', + title_ai_assistant: 'AI-ассистент', + title_facts: 'Интересные факты', + title_anons: 'Анонс', + title_developer: 'Разработчик', + title_navigation: 'Навигация', + title_page: 'Страница', + title_channels: 'Каналы', + title_best_of_2000: 'Золотые 2000-е', + title_best_of_2010: 'Хиты 2010-х', + title_best_of_2015: 'Современная классика', + title_comedy_of_2000: 'Смех 2000-х', + title_comedy_of_2010: 'Юмор 2010-х', + title_comedy_of_2015: 'Современные комедии', + + title_metadata: 'Метаданные', + title_moods: 'Настроения', + title_meta_violence: 'Насилие', + title_meta_fear: 'Страх', + title_meta_profanity: 'Лексика', + title_meta_sadness: 'Грусть', + title_meta_sex: 'Сексуальность', + title_meta_humor: 'Юмор', + title_meta_tension: 'Напряжение', + title_meta_romance: 'Романтика', + title_meta_pace: 'Темп', + title_meta_importance: 'Важные сцены', + title_meta_action: 'Экшн', + + reactions_none: 'Нет реакций', + reactions_fire: 'Супер', + reactions_nice: 'Неплохо', + reactions_think: 'Смотрибельно', + reactions_bore: 'Скука', + reactions_shit: 'Плохо', + reactions_ready: 'Вы уже оставили реакцию', + + subscribe_success: 'Вы успешно подписались', + subscribe_error: 'Возникла ошибка при подписке, попробуйте позже', + subscribe_noinfo: 'Не удалось получить информацию, попробуйте позже', + subscribe_info: 'В разделе (Подписки) у вас будут отображаться все ваши подписки на переводы. Когда выйдет новая серия с выбранным переводом, вы получите уведомление.', + + company_headquarters: 'Штаб', + company_homepage: 'Сайт', + company_country: 'Страна', + + country_ad: 'Андорра', + country_ae: 'ОАЭ', + country_af: 'Афганистан', + country_al: 'Албания', + country_am: 'Армения', + country_ao: 'Ангола', + country_ar: 'Аргентина', + country_at: 'Австрия', + country_au: 'Австралия', + country_aw: 'Аруба', + country_az: 'Азербайджан', + country_bа: 'Босния и Герцеговина', + country_bd: 'Бангладеш', + country_be: 'Бельгия', + country_bg: 'Болгария', + country_bh: 'Бахрейн', + country_bi: 'Бурунди', + country_bj: 'Бенин', + country_bo: 'Боливия', + country_br: 'Бразилия', + country_bs: 'Багамские о-ва', + country_bt: 'Бутан', + country_bw: 'Ботсвана', + country_by: 'Беларусь', + country_ca: 'Канада', + country_ch: 'Швейцария', + country_cl: 'Чили', + country_cm: 'Камерун', + country_cn: 'Китай', + country_co: 'Колумбия', + country_cr: 'Коста-Рика', + country_cu: 'Куба', + country_cv: 'Кабо-Верде', + country_cy: 'Кипр', + country_cz: 'Чехия', + country_de: 'Германия', + country_dj: 'Джибути', + country_dk: 'Дания', + country_do: 'Доминикана', + country_dz: 'Алжир', + country_ec: 'Эквадор', + country_ee: 'Эстония', + country_eg: 'Египет', + country_es: 'Испания', + country_et: 'Эфиопия', + country_fi: 'Финляндия', + country_fo: 'Фарерские о-ва', + country_fr: 'Франция', + country_ga: 'Габон', + country_gb: 'Великобритания', + country_ge: 'Грузия', + country_gh: 'Гана', + country_gl: 'Гренландия', + country_gp: 'Гваделупа', + country_gr: 'Греция', + country_gt: 'Гватемала', + country_hk: 'Гонконг', + country_hr: 'Хорватия', + country_ht: 'Гаити', + country_hu: 'Венгрия', + country_id: 'Индонезия', + country_ie: 'Ирландия', + country_il: 'Израиль', + country_in: 'Индия', + country_iq: 'Ирак', + country_ir: 'Иран', + country_is: 'Исландия', + country_it: 'Италия', + country_jm: 'Ямайка', + country_jo: 'Иордания', + country_jp: 'Япония', + country_ke: 'Кения', + country_kg: 'Киргизия', + country_kh: 'Камбоджа', + country_kp: 'Северная Корея', + country_kr: 'Южная Корея', + country_kz: 'Казахстан', + country_kw: 'Кувейт', + country_la: 'Лаос', + country_lb: 'Ливан', + country_li: 'Лихтенштейн', + country_lk: 'Шри-Ланка', + country_lr: 'Либерия', + country_lt: 'Литва', + country_lu: 'Люксембург', + country_lv: 'Латвия', + country_ly: 'Ливия', + country_ma: 'Марокко', + country_mc: 'Монако', + country_md: 'Молдова', + country_me: 'Черногория', + country_mk: 'Македония', + country_mm: 'Мьянма', + country_mn: 'Монголия', + country_mo: 'Макао', + country_mt: 'Мальта', + country_mu: 'Маврикий', + country_mv: 'Мальдивы', + country_mw: 'Малави', + country_mx: 'Мексика', + country_my: 'Малайзия', + country_mz: 'Мозамбик', + country_na: 'Намибия', + country_ne: 'Нигер', + country_ng: 'Нигерия', + country_ni: 'Никарагуа', + country_nl: 'Нидерланды', + country_no: 'Норвегия', + country_np: 'Непал', + country_nz: 'Новая Зеландия', + country_om: 'Оман', + country_pa: 'Панама', + country_pe: 'Перу', + country_pg: 'Папуа - Новая Гвинея', + country_ph: 'Филиппины', + country_pk: 'Пакистан', + country_pl: 'Польша', + country_pr: 'Пуэрто-Рико', + country_ps: 'Палестина', + country_pt: 'Португалия', + country_py: 'Парагвай', + country_qa: 'Катар', + country_ro: 'Румыния', + country_rs: 'Сербия', + country_ru: 'Россия', + country_rw: 'Руанда', + country_sa: 'Саудовская Аравия', + country_sd: 'Судан', + country_se: 'Швеция', + country_sg: 'Сингапур', + country_si: 'Словения', + country_sk: 'Словакия', + country_sn: 'Сенегал', + country_su: 'СССР', + country_sv: 'Сальвадор', + country_sy: 'Сирия', + country_th: 'Таиланд', + country_tj: 'Таджикистан', + country_tm: 'Туркменистан', + country_tn: 'Тунис', + country_tr: 'Турция', + country_tw: 'Тайвань', + country_tz: 'Танзания', + country_ua: 'Украина', + country_ug: 'Уганда', + country_us: 'США', + country_uy: 'Уругвай', + country_uz: 'Узбекистан', + country_ve: 'Венесуэла', + country_vn: 'Вьетнам', + country_ws: 'Самоа', + country_xk: 'Косово', + country_ye: 'Йемен', + country_yu: 'Югославия', + country_za: 'ЮАР', + country_zm: 'Замбия', + country_zw: 'Зимбабве', + + filter_clarify: 'Уточнить', + filter_clarify_two: 'Уточнить поиск', + filter_set_name: 'Указать название', + filter_sorted: 'Сортировать', + filter_filtred: 'Фильтр', + filter_any: 'Любой', + filter_combinations: 'Комбинации', + filter_alt_names: 'Другие названия', + filter_rating_from: 'от', + filter_rating_to: 'до', + + filter_lang_af: 'Африкаанс', + filter_lang_ar: 'Арабский', + filter_lang_az: 'Азербайджанский', + filter_lang_ba: 'Башкирский', + filter_lang_be: 'Белорусский', + filter_lang_bg: 'Болгарский', + filter_lang_bn: 'Бенгальский', + filter_lang_bs: 'Боснийский', + filter_lang_ca: 'Каталанский', + filter_lang_ce: 'Чеченский', + filter_lang_cs: 'Чешский', + filter_lang_da: 'Датский', + filter_lang_de: 'Немецкий', + filter_lang_el: 'Греческий', + filter_lang_en: 'Английский', + filter_lang_es: 'Испанский', + filter_lang_et: 'Эстонский', + filter_lang_fa: 'Персидский', + filter_lang_fi: 'Финский', + filter_lang_fr: 'Французский', + filter_lang_ga: 'Ирландский', + filter_lang_gl: 'Галисийский', + filter_lang_gn: 'Гуарани', + filter_lang_he: 'Иврит', + filter_lang_hi: 'Хинди', + filter_lang_hr: 'Хорватский', + filter_lang_hu: 'Венгерский', + filter_lang_hy: 'Армянский', + filter_lang_id: 'Индонезийский', + filter_lang_is: 'Исландский', + filter_lang_it: 'Итальянский', + filter_lang_ja: 'Японский', + filter_lang_ka: 'Грузинский', + filter_lang_kk: 'Казахский', + filter_lang_ko: 'Корейский', + filter_lang_ks: 'Кашмири', + filter_lang_ku: 'Курдский', + filter_lang_ky: 'Киргизский', + filter_lang_lt: 'Литовский', + filter_lang_lv: 'Латышский', + filter_lang_mi: 'Маори', + filter_lang_mk: 'Македонский', + filter_lang_mn: 'Монгольский', + filter_lang_mt: 'Мальтийский', + filter_lang_ne: 'Непальский', + filter_lang_nl: 'Нидерландский', + filter_lang_no: 'Норвежский', + filter_lang_pa: 'Панджаби', + filter_lang_pl: 'Польский', + filter_lang_ps: 'Пушту', + filter_lang_pt: 'Португальский', + filter_lang_ro: 'Румынский', + filter_lang_ru: 'Русский', + filter_lang_si: 'Сингальский', + filter_lang_sk: 'Словацкий', + filter_lang_sl: 'Словенский', + filter_lang_sm: 'Самоанский', + filter_lang_so: 'Сомалийский', + filter_lang_sq: 'Албанский', + filter_lang_sr: 'Сербский', + filter_lang_sv: 'Шведский', + filter_lang_sw: 'Суахили', + filter_lang_ta: 'Тамильский', + filter_lang_tg: 'Таджикский', + filter_lang_th: 'Тайский', + filter_lang_tk: 'Туркменский', + filter_lang_tr: 'Турецкий', + filter_lang_tt: 'Татарский', + filter_lang_ur: 'Урду', + filter_lang_uk: 'Украинский', + filter_lang_uz: 'Узбекский', + filter_lang_vi: 'Вьетнамский', + filter_lang_yi: 'Идиш', + filter_lang_zh: 'Китайский', + + filter_genre_ac: 'Боевик', + filter_genre_ad: 'Приключения', + filter_genre_mv: 'Мультфильм', + filter_genre_cm: 'Комедия', + filter_genre_cr: 'Криминал', + filter_genre_dc: 'Документальный', + filter_genre_dr: 'Драма', + filter_genre_fm: 'Семейный', + filter_genre_fe: 'Фэнтези', + filter_genre_hi: 'История', + filter_genre_ho: 'Ужасы', + filter_genre_mu: 'Музыка', + filter_genre_de: 'Детектив', + filter_genre_md: 'Мелодрама', + filter_genre_fa: 'Фантастика', + filter_genre_tv: 'Телевизионный фильм', + filter_genre_tr: 'Триллер', + filter_genre_mi: 'Военный', + filter_genre_ve: 'Вестерн', + filter_genre_aa: 'Боевик и Приключения', + filter_genre_ch: 'Детский', + filter_genre_nw: 'Новости', + filter_genre_rs: 'Реалити-шоу', + filter_genre_hf: 'НФ и Фэнтези', + filter_genre_op: 'Мыльная опера', + filter_genre_tc: 'Ток-шоу', + filter_genre_mp: 'Война и Политика', + + filter_keyword_sequel: 'Сиквел', + filter_keyword_based_comic: 'По комиксам', + filter_keyword_space: 'Космос', + filter_keyword_survival: 'Выживание', + filter_keyword_zombie: 'Зомби', + filter_keyword_school: 'Школа', + filter_keyword_revenge: 'Месть', + filter_keyword_detective: 'Детектив', + filter_keyword_robots: 'Роботы', + filter_keyword_vampires: 'Вампиры', + filter_keyword_aliens: 'Инопланетяне', + filter_keyword_police: 'Полиция', + filter_keyword_reincarnation: 'Перерождение', + filter_keyword_spy: 'Шпион', + filter_keyword_disaster: 'Катастрофа', + filter_keyword_christmas: 'Рождество', + + empty_title: 'Пусто', + empty_text: 'По вашему фильтру ничего не нашлось, уточните фильтр.', + empty_title_two: 'Здесь пусто', + empty_text_two: 'На данный момент список пустой', + + empty_subscribes_title: 'Ваши подписки на переводы', + empty_subscribes_text: 'Просто подпишитесь на любимый перевод и мы будем уведомлять вас о выходе новой серии.', + empty_history_title: 'Ваша история просмотров', + empty_history_text: 'Здесь будет отображаться ваша история просмотров.', + empty_bookmark_title: 'Ваше избранное', + empty_bookmark_text: 'Добавляйте в избранное понравившиеся фильмы и сериалы, чтобы быстро находить их в этом разделе.', + empty_mytorrents_title: 'Ваши торренты', + empty_mytorrents_text: 'Здесь будут отображаться загруженные вами торренты через TorServer.', + + back_to_card: 'Вернуться в карточку', + + menu_main: 'Главная', + menu_movies: 'Фильмы', + menu_tv: 'Сериалы', + menu_catalog: 'Каталог', + menu_filter: 'Фильтр', + menu_collections: 'Подборки', + menu_relises: 'Релизы', + menu_anime: 'Аниме', + menu_bookmark: 'Закладки', + menu_like: 'Нравится', + menu_time: 'Позже', + menu_history: 'История', + menu_timeline: 'Расписание', + menu_torrents: 'Торренты', + menu_settings: 'Настройки', + menu_about: 'Информация', + menu_console: 'Консоль', + menu_multmovie: 'Мультфильмы', + menu_multtv: 'Мультсериалы', + menu_feed: 'Лента', + + lampa_movie_title: 'Ламповое кино', + lampa_movie_descr: 'Следите за новинками на своем смартфоне.
    Телеграм: @lampa_movie', + + plugins_catalog_work: 'Рабочие плагины', + plugins_catalog_work_descr: 'Плагины, которые точно работают в лампе.', + plugins_catalog_popular: 'Популярные плагины среди пользователей', + plugins_catalog_popular_descr: 'Установка из неизвестных источников может привести к некорректной работе приложения.', + plugins_online: 'Просмотр онлайн', + plugins_check_fail: 'Не удалось проверить работоспособность плагина. Однако это не означает, что плагин не работает. Перезагрузите приложение для выяснения, загружается ли плагин.', + plugins_need_reload: 'Для применения плагина необходимо перезагрузить приложение', + plugins_install: 'Установить', + plugins_install_ready: 'Этот плагин уже установлен.', + plugins_installed: 'Установок', + plugins_load_from: 'Загружено из CUB', + plugins_ok_for_check: 'Нажмите (OK) для проверки плагина', + plugins_no_loaded: 'При загрузке приложения, часть плагинов не удалось загрузить', + plugins_remove: 'Удалить плагины', + plugins_add_success: 'Плагин успешно подключен', + + time_viewed: 'Просмотрено', + time_from: 'из', + time_reset: 'Сбросить тайм-код', + + settings_clear_cache: 'Кеш и данные очищены', + settings_clear_cache_only: 'Кеш очищен', + settings_user_links: 'Пользовательская ссылка', + settings_for_local: 'Для локального TorrServer', + settings_add: 'Добавить', + settings_remove: 'Удалить', + settings_this_value: 'текущее значение', + settings_added: 'Добавлено', + settings_removed: 'Удалено', + settings_reset: 'Сброс настроек', + + settings_param_player_inner: 'Встроенный', + settings_param_player_outside: 'Внешний', + settings_param_player_inner_tvos: 'Встроенный', + settings_param_yes: 'Да', + settings_param_no: 'Нет', + settings_param_interface_size_small: 'Меньше', + settings_param_interface_size_normal: 'Нормальный', + settings_param_interface_size_bigger: 'Больше', + settings_param_poster_quality_low: 'Низкое', + settings_param_poster_quality_average: 'Среднее', + settings_param_poster_quality_high: 'Высокое', + settings_param_parse_directly: 'Напрямую', + settings_param_parse_api: 'Через API сайта', + settings_param_background_complex: 'Сложный', + settings_param_background_simple: 'Простой', + settings_param_background_image: 'Картинка', + settings_param_link_use_one: 'Основную', + settings_param_link_use_two: 'Дополнительную', + settings_param_link_use_both: 'Обе', + settings_param_subtitles_size_small: 'Маленькие', + settings_param_subtitles_size_normal: 'Обычные', + settings_param_subtitles_size_bigger: 'Большие', + settings_param_screensaver_nature: 'Природа', + settings_param_torrent_lang_orig: 'Оригинал', + settings_param_player_timecode_again: 'Начать с начала', + settings_param_player_timecode_continue: 'Продолжить', + settings_param_player_timecode_ask: 'Спрашивать', + settings_param_player_scale_method: 'Рассчитать', + settings_param_player_hls_app: 'Системный', + settings_param_player_hls_js: 'Программный', + settings_param_card_view_load: 'Подгружать', + settings_param_card_view_all: 'Показать все', + settings_param_navigation_remote: 'Пульт', + settings_param_navigation_mouse: 'Пульт с мышкой', + settings_param_navigation_touch: 'Сенсор', + settings_param_keyboard_lampa: 'Встроенная', + settings_param_keyboard_system: 'Системная', + settings_param_card_interface_old: 'Старый', + settings_param_card_interface_new: 'Новый', + + settings_param_glass_easy: 'Прозрачная', + settings_param_glass_medium: 'Полупрозрачная', + settings_param_glass_blacked: 'Затемнённая', + + settings_param_jackett_interview_all: 'Все', + settings_param_jackett_interview_healthy: 'Только доступные', + settings_parser_jackett_interview: 'Опрашивать трекеры', + + helper_keyboard: 'После ввода значения нажмите кнопку «Назад» для сохранения', + helper_torrents: 'Удерживайте клавишу (ОК) для вызова контекстного меню', + helper_cleared: 'Успешно, подсказки будут показаны заново.', + helper_torrents_view: 'Для сброса тайм-кода и вызова меню удерживайте клавишу (ОК)', + + fav_sync_title: 'Синхронизация закладок', + fav_sync_text: 'Ваши любимые закладки вместе с Вами. Подключите синхронизацию и просматривайте на любом устройстве.

    Для этого зарегистрируйтесь на сайте {site}, создайте профиль и авторизуйтесь в приложение.', + fav_sync_site: 'Сайт', + fav_remove_title: 'Удалить из истории', + fav_remove_descr: 'Удалить выделенную карточку', + fav_clear_title: 'Очистить историю', + fav_clear_descr: 'Удалить все карточки из истории', + fav_clear_label_title: 'Очистить метки', + fav_clear_label_descr: 'Очистить метки о просмотрах', + fav_clear_time_title: 'Очистить тайм-коды', + fav_clear_time_descr: 'Очистить все тайм-коды', + fav_label_cleared: 'Отметки очищены', + fav_time_cleared: 'Тайм-коды очищены', + + timetable_empty: 'В этом разделе будут отображаться даты выхода новых серий', + + player_quality: 'Качество', + player_flow: 'Поток', + player_tracks: 'Аудиодорожки', + player_disabled: 'Отключено', + player_unknown: 'Неизвестно', + player_subs: 'Субтитры', + player_size_default_title: 'По умолчанию', + player_size_default_descr: 'Размер видео по умолчанию', + player_size_cover_title: 'Расширить', + player_size_cover_descr: 'Расширяет видео на весь экран', + player_size_fill_title: 'Заполнить', + player_size_fill_descr: 'Вместить видео на весь экран', + player_size_s115_title: 'Увеличить 115%', + player_size_s115_descr: 'Увеличить видео на 115%', + player_size_s130_title: 'Увеличить 130%', + player_size_s130_descr: 'Увеличить видео на 130%', + player_size_v115_title: 'По вертикали 115%', + player_size_v115_descr: 'Увеличить видео на 115%', + player_size_v130_title: 'По вертикали 130%', + player_size_v130_descr: 'Увеличить видео на 130%', + player_video_size: 'Размер видео', + player_playlist: 'Плейлист', + player_error_one: 'Не удалось декодировать видео', + player_error_two: 'Видео не найдено или повреждено', + player_start_from: 'Продолжить просмотр с', + player_not_found: 'Плеер не найден', + player_lauch: 'Запустить плеер', + player_speed_default_title: 'Обычная', + player_speed_two_descr: 'Воспроизводиться без звука', + player_video_speed: 'Скорость воспроизведения', + player_share_title: 'Поделиться', + player_share_descr: 'Запустить это видео на другом устройстве', + player_normalization_power_title: 'Сила нормализации', + player_normalization_smooth_title: 'Скорость нормализации', + player_normalization_step_none: 'Нулевая', + player_normalization_step_low: 'Низкое', + player_normalization_step_medium: 'Среднее', + player_normalization_step_hight: 'Высокое', + player_normalization: 'Нормализация', + player_normalization_type_title: 'Тип нормализации', + player_normalization_type_all: 'Все', + player_normalization_type_up: 'Только повышение', + player_normalization_type_down: 'Только понижение', + player_youtube_no_played: 'К сожалению, это видео не доступно в вашем регионе, возможно, оно было заблокировано или удалено.', + player_youtube_start_play: 'Для начала проигрывания видео, нажмите кнопку "Плей"', + player_youtube_no_support: 'Ваше устройство не поддерживает воспроизведение YouTube видео, проверьте интернет соединение.', + player_segments_title: 'Сегменты', + player_segments_descr: 'Пропуск интро и другие части видео', + player_segments_ad_title: 'Рекламные вставки', + player_segments_skip_title: 'Интро и другое', + player_segments_value_none: 'Не пропускать', + player_segments_value_auto: 'Автопропуск', + player_segments_value_user: 'Пользовательский', + player_segments_skiped: 'Сегмент пропущен', + player_segments_skip_now: 'Пропустить', + player_segments_skip_in: 'Пропуск через', + player_segments_skip_intro: 'Пропустить заставку', + player_segments_next: 'Следующая серия', + player_segments_next_in: 'Следующая серия через', + player_pip: 'Уменьшить', + player_volume: 'Громкость', + player_time_end: 'Конец в', + + broadcast_open: 'Открыть карточку на другом устройстве', + broadcast_play: 'Выберите устройство для просмотра', + + card_new_episode: 'Новая серия', + card_book_remove: 'Убрать из закладок', + card_book_add: 'В закладки', + card_book_descr: 'Смотрите в меню (Закладки)', + card_like_remove: 'Убрать из понравившихся', + card_like_add: 'Нравится', + card_like_descr: 'Смотрите в меню (Нравится)', + card_wath_remove: 'Убрать из ожидаемых', + card_wath_add: 'Смотреть позже', + card_wath_descr: 'Смотрите в меню (Позже)', + card_history_remove: 'Убрать из истории', + card_history_add: 'В историю', + card_history_descr: 'Смотрите в меню (История)', + + keyboard_listen: 'Говорите, я слушаю...', + keyboard_nomic: 'Нет доступа к микрофону', + + notice_new_quality: 'Доступно новое качество', + notice_quality: 'Качество', + notice_new_episode: 'Новая серия', + notice_none: 'У вас еще нет никаких уведомлений, зарегистрируйтесь на сайте {site}, чтобы следить за новыми сериями и релизами.', + notice_in_quality: 'В качестве', + notice_none_account: 'У вас еще нет никаких уведомлений, добавьте сериалы в закладки и ожидайте уведомления о новых сериях.', + notice_none_system: 'На данный момент у вас отсутствуют уведомления. Мы обязательно оповестим вас, когда появятся новые уведомления.', + + copy_link: 'Копировать ссылку на видео', + copy_secuses: 'Ссылка скопирована в буфер обмена', + copy_error: 'Ошибка при копирование ссылки', + copy_link_buffer: 'Скопировать ссылку', + + account_sync_to_profile: 'Все закладки будут перенесены в профиль', + account_sync_secuses: 'Все закладки успешно перенесены', + account_profiles: 'Профили', + account_profiles_empty: 'Не удалось получить список профилей', + account_authorized: 'Авторизованы', + account_logged_in: 'Вы вошли под аккаунтом', + account_login_failed: 'Вход не выполнен', + account_login_wait: 'Ожидаем входа в аккаунт', + account_profile_main: 'Общий', + account_profile_child: 'Детский', + account_profile_add: 'Добавить профиль', + account_profile_name: 'Имя профиля', + account_profile_created: 'Профиль успешно создан', + account_profile_limited: 'Достигнут максимальный лимит профилей: {count}', + account_profile_info: 'Вы можете управлять профилями в настройках аккаунта, для этого перейдите на сайт ', + account_export_secuses: 'Экспорт успешно завершён', + account_export_fail: 'Ошибка при экспорте', + account_export_fail_500: 'Неизвестная ошибка', + account_export_fail_610: 'Вы исчерпали лимит на сегодня', + account_export_fail_200: 'Ошибка базы данных, попробуйте позже', + account_export_fail_600: 'Ошибка, не удалось загрузить файл', + account_export_fail_620: 'Ошибка, файл не передан', + account_import_secuses: 'Импорт успешно завершён', + account_import_fail: 'Ошибка при импорте', + account_imported: 'импортировано', + account_reload_after: 'перезагрузка через 5 сек.', + account_create: 'Откройте больше возможностей с аккаунтом CUB. Зарегистрируйтесь на сайте и получите доступ к синхронизации ваших закладок, тайм-кодов и других возможностей аккаунта CUB.', + account_premium: 'Раскройте новые горизонты с аккаунтом CUB Premium! Наслаждайтесь увеличенными лимитами и обогащенным функционалом сервиса. Перейдите на сайт и узнайте больше о преимуществах премиум аккаунта.', + account_premium_more: 'Подробнее о CUB Premium', + account_limited: 'Вы достигли максимального лимита. Увеличьте лимит с аккаунтом CUB Premium. Подробнее на сайте ', + account_premium_include_1: 'Увеличение количества закладок', + account_premium_include_2: 'Увеличение истории просмотров', + account_premium_include_3: 'Увеличение количества тайм-кодов', + account_premium_include_4: 'Количество профилей на аккаунт', + account_premium_include_5: 'Уведомления', + account_premium_include_6: 'Синхронизация данных', + account_premium_include_text_1: 'Больше закладок - больше возможностей! Сохраняйте свои любимые фильмы и сериалы, создавайте списки просмотра и наслаждайтесь просмотром в любое удобное время.', + account_premium_include_text_2: 'Увеличьте историю просмотров в приложении и следите за тем, что уже посмотрели. Легко находите и пересматривайте свои любимые фильмы и сериалы.', + account_premium_include_text_3: 'Не бойтесь пропустить ни одной важной сцены! Увеличьте количество тайм-кодов в приложении и легко отслеживайте, где остановились в просмотре любимых фильмов и сериалов.', + account_premium_include_text_4: 'Получите больше свободы с нашим премиум доступом! Увеличьте количество профилей на аккаунте и позвольте своим друзьям и близким наслаждаться фильмами и сериалами вместе с вами. Никаких ограничений - наслаждайтесь просмотром с любимыми людьми.', + account_premium_include_text_5: 'Не пропустите ни одной новой серии или перевода! Получайте уведомления вовремя и будьте в курсе всех обновлений. Увеличьте свой кинопоток вместе с нами и получайте уведомления о выходе новых серий и переводов прямо на свой смартфон.', + account_premium_include_text_6: 'Синхронизуйте свои данные между устройствами с премиум доступом! Больше не нужно тратить время на поиск последнего эпизода, на котором вы остановились. С нашим премиум доступом вы можете синхронизировать свои данные между устройствами, чтобы продолжать просмотр с места, где вы остановились, на любом устройстве, где установлено приложение.', + account_code_enter: 'Введите шестизначный код', + account_code_error: 'Возможно, вы ввели неверный или устаревший код', + account_code_wrong: 'Возможно, вы указали неверный формат', + account_code_where: 'Перейдите на сайт и введите указанный там код.', + account_code_input: 'Ввести код', + account_qr_premium: 'Отсканируйте QR-код, чтобы узнать больше о CUB Premium', + account_qr_code: 'Отсканируйте QR-код для получения кода добавления устройства', + account_qr_create: 'Отсканируйте QR-код, чтобы создать аккаунт', + account_add_device_title: 'Добавить устройство', + account_add_device_text: 'Перейдите на сайт по ссылки чтобы получить код для добавления устройства.', + account_none_title: 'Еще нет аккаунта?', + account_none_include_1: 'Закладки и история просмотров сохраняются в облаке', + account_none_include_2: 'Синхронизация между устройствами', + account_none_include_3: 'Уведомления о новых сериях и релизах', + account_none_include_4: 'Создание нескольких профилей на одном аккаунте', + account_discuss_add_qr: 'Отсканируйте QR-код', + account_discuss_add_title: 'Хотите оставить комментарий?', + account_discuss_add_text: 'Отсканируйте QR-код, чтобы перейти в приложение и добавить комментарий к этому фильму или сериалу.

    - Возьмите телефон или планшет
    - Откройте камеру
    - Наведите на QR-код
    - Перейдите по ссылки, которая появится на экране', + account_discuss_added: 'Спасибо за ваш комментарий!', + account_discuss_added_ready: 'Вы уже оставили комментарий к этому фильму или сериалу.', + + + network_noconnect: 'Нет подключения к сети', + network_404: 'Запрошенная страница не найдена. [404]', + network_401: 'Авторизация не удалась', + network_500: 'Внутренняя ошибка сервера. [500]', + network_parsererror: 'Запрошенный синтаксический анализ JSON завершился неудачно.', + network_timeout: 'Время запроса истекло.', + network_abort: 'Запрос был прерван.', + network_error: 'Неизвестная ошибка', + + size_zero: '0 Байт', + size_byte: 'Байт', + size_kb: 'КБ', + size_mb: 'МБ', + size_gb: 'ГБ', + size_tb: 'ТБ', + size_pp: 'ПБ', + + speed_bit: 'бит/c', + speed_kb: 'Кбит/c', + speed_mb: 'Мбит/c', + speed_gb: 'Гбит/c', + speed_tb: 'Тбит/c', + speed_pp: 'Пбит/c', + + month_1: 'Январь', + month_2: 'Февраль', + month_3: 'Март', + month_4: 'Апрель', + month_5: 'Ма', + month_6: 'Июнь', + month_7: 'Июль', + month_8: 'Август', + month_9: 'Сентябрь', + month_10: 'Октябрь', + month_11: 'Ноябрь', + month_12: 'Декабрь', + + day_1: 'Понедельник', + day_2: 'Вторник', + day_3: 'Среда', + day_4: 'Четверг', + day_5: 'Пятница', + day_6: 'Суббота', + day_7: 'Воскресенье', + + month_1_e: 'Января', + month_2_e: 'Февраля', + month_3_e: 'Марта', + month_4_e: 'Апреля', + month_5_e: 'Мая', + month_6_e: 'Июня', + month_7_e: 'Июля', + month_8_e: 'Августа', + month_9_e: 'Сентября', + month_10_e: 'Октября', + month_11_e: 'Ноября', + month_12_e: 'Декабря', + + week_1: 'Пн', + week_2: 'Вт', + week_3: 'Ср', + week_4: 'Чт', + week_5: 'Пт', + week_6: 'Сб', + week_7: 'Вс', + + time_h: 'ч.', + time_m: 'м.', + time_s: 'с.', + + extensions_enable: 'Включить', + extensions_disable: 'Отключить', + extensions_check: 'Проверить статус', + extensions_install: 'Установить', + extensions_info: 'Информация', + extensions_edit: 'Редактировать', + extensions_change_name: 'Изменить название', + extensions_change_link: 'Изменить ссылку', + extensions_remove: 'Удалить', + extensions_set_name: 'Введите название плагина', + extensions_set_url: 'Введите адрес плагина', + extensions_ready: 'Этот плагин уже установлен', + extensions_no_info: 'Без информации', + extensions_no_name: 'Без названия', + extensions_worked: 'Рабочий', + extensions_no_plugin: 'Плагин не подтверждён ', + extensions_add: 'Добавить плагин', + extensions_from_memory: 'Установленные в память ', + extensions_from_cub: 'Установленные из CUB', + extensions_from_popular: 'Популярные плагины', + extensions_from_lib: 'Библиотека плагинов', + extensions_from_connected: 'Подключенные плагины', + extensions_hpu_best: 'Популярные', + extensions_hpu_recomend: 'Рекомендуем', + extensions_hpu_theme: 'Темы', + extensions_hpu_screensaver: 'Скринсейвер', + extensions_hpu_video: 'Видео', + extensions_hpu_control: 'Управление', + extensions_hpu_other: 'Разное', + extensions_hpu_: 'Остальное', + + speedtest_connect: 'подключение', + speedtest_test: 'тестирование', + speedtest_ready: 'готово', + speedtest_button: 'Тестировать скорость', + + change_source_on_cub: 'Сменить источник на CUB', + + tv_status_returning_series: 'Онгоинг', + tv_status_planned: 'Запланировано', + tv_status_in_production: 'В производстве', + tv_status_ended: 'Завершено', + tv_status_canceled: 'Отменено', + tv_status_pilot: 'Пилотный', + tv_status_released:'Выпущенный', + tv_status_rumored:'По слухам', + tv_status_post_production:'Скоро', + + input_detection_touch: 'Хотите переключить на сенсорное управление?', + input_detection_mouse: 'Хотите переключить на управление мышью?', + input_detection_remote: 'Хотите переключить на управление пультом?', + + https_text: 'Вы используете протокол HTTPS, с которым Lampa работает некорректно. Для корректной работы приложения используйте адрес с протоколом HTTP', + + premiere_author_recomend_1: 'Закажите пиццу и готовьтесь к драйву.', + premiere_author_recomend_2: 'Вечеринка только начинается.', + premiere_author_recomend_3: 'Подготовьтесь к адреналину.', + premiere_author_recomend_4: 'Готовы к незабываемому вечеру?', + premiere_author_recomend_5: 'Рекомендую к просмотру.', + premiere_title: 'Премьера', + + termsofuse_t_01: 'Правила использования', + termsofuse_t_02: 'Lampa - это удобный инструмент для ознакомления с новинками киноиндустрии, включая фильмы, сериалы, мультфильмы и другую информацию. Для получения информации о фильмах используется открытый источник - сайт themoviedb.org', + termsofuse_t_03: 'Контент', + termsofuse_t_04: 'Lampa использует API (Application Programming Interface) от каталога themoviedb.org для получения информации о фильмах и телесериалах, а также для просмотра связанных с ними медиафайлов, таких как постеры, трейлеры и другое.', + termsofuse_t_05: 'API от themoviedb.org позволяет приложению Lampa получать доступ к базе данных фильмов и телесериалов, предоставляя возможность поиска медиафайлов и просмотра информации о них.', + termsofuse_t_06: 'Взаимодействие между приложением Lampa и themoviedb.org происходит через запросы к API, которые отправляются из приложения Lampa на серверы themoviedb.org для получения информации и медиафайлов. Themoviedb.org обрабатывает запросы и отправляет обратно в приложение Lampa запрошенные данные.', + termsofuse_t_07: 'Таким образом, благодаря использованию API от themoviedb.org, приложение Lampa предоставляет пользователям доступ к обширной базе данных фильмов и телесериалов, соблюдая при этом условия использования и ограничения, установленные правообладателем.', + termsofuse_t_08: 'Расширения', + termsofuse_t_09: 'Расширения - это мощный инструмент, предоставляемый для приложения Lampa, который позволяет пользователям расширить его возможности, добавить дополнительный функционал и изменить контент в соответствии с их потребностями.', + termsofuse_t_10: 'Однако, следует отметить, что пользователи устанавливают расширения на свой страх и риск. Все последствия, возникающие в результате использования расширений, ложатся на пользователя. Пользователям рекомендуется быть осторожными при установке и использовании расширений, тщательно оценивая их надежность и безопасность.', + termsofuse_t_11: 'Нарушения авторских прав', + termsofuse_t_12: 'Если вы обнаружили нарушение авторских прав в приложении Lampa - свяжитесь с разработчиками, используя раздел Контакты приложения. Однако, важно учесть, что приложение Lampa использует API от каталога themoviedb.org, который предоставляет открытый доступ к информации о фильмах и сериалах. Это означает, что информация, которая отображается в приложении Lampa, является общедоступной и не нарушает авторских прав.', + termsofuse_t_13: 'Если вы считаете, что в приложении Lampa все же есть контент, нарушающий авторские права - обратитесь к правообладателю этого контента с просьбой удалить его со страниц сайта themoviedb.org. В свою очередь, приложение Lampa может удалить контент при получении соответствующего уведомления о нарушении авторских прав.', + + install_app_apk_title: 'Как установить Lampa на Android', + install_app_apk_text: 'Мы заметили, что для запуска Lampa на Android вы используете MediaStationX. Мы рекомендуем вам установить Lampa в виде APK-приложения. Это обеспечит более стабильную работу и доступ ко всем функциям приложения.

    Перейдите в группу в Телеграме, чтобы скачать последнюю версию APK и инструкции по установке.', + install_app_apk_qr: 'Отсканируйте QR-код, чтобы скачать Lampa APK', + + ad: 'Реклама', + ad_disable: 'Подписавшись на CUB Premium, вы забудете о рекламе.', + ad_plugin: 'Реклама от плагина', + ad_after: 'Реклама через', + ad_skip: 'Пропустить', + ad_continue_after: 'Просмотр начнется через', + + discuss_rules_title: 'Следуйте правилам и уважайте других — создаём комфорт вместе!', + discuss_rules_rule_1: 'Не используйте слова, состоящие только из цифр.', + discuss_rules_rule_2: 'Пишите на одном языке, используйте слова из 5 и более букв.', + discuss_rules_rule_3: 'Используйте знаки препинания и завершайте предложения точками.', + discuss_rules_rule_4: 'Избегайте непонятных символов !?#%', + discuss_rules_rule_5: 'Пишите полные предложения, используйте предложение из 5 и более слов.', + discuss_rules_rule_6: 'Не используйте слишком длинные слова.', + discuss_rules_rule_7: 'Постарайтесь уместиться в 300 символов.', + discuss_voited: 'Спасибо за вашу оценку! Ваш голос помогает улучшать контент.', + + confirm_open_player: 'Другое устройство запрашивает доступ к плееру. Хотите воспроизвести видео?', + + pincode_use_remote: 'Используйте пульт для ввода кода, нажимая стрелки для выбора нужной цифры.', + pincode_use_toggle: 'Нажмите и удерживайте кнопку OK, чтобы сменить раскладку.', + + storage_quota_exceeded: 'Превышен лимит хранилища. Удалите кеш и повторите попытку.', + + ai_search_start_typing: 'Спросите у AI-ассистента, какие фильмы вы хотите найти. Например: "Фильмы про космос"', + ai_search_limit: 'Лимит запросов превышен. Попробуйте повторить запрос позже. С подпиской CUB Premium лимиты будут увеличены, и вам не придется ждать!', + ai_subscribe_title: 'Откройте больше возможностей с AI', + ai_subscribe_descr: 'Оформите подписку CUB Premium и увеличьте количество запросов к AI. Вместе с AI мы подберем вам лучшие фильмы которые только сможем.', + + dmca_title: 'Контент заблокирован', + dmca_descr: 'Данный материал недоступен для просмотра. Он был заблокирован по просьбе правообладателя в соответствии с законодательством об авторских правах.', + dmca_title_lgbt: 'Контент ограничен', + dmca_descr_lgbt: 'Просмотр недоступен в вашем регионе, так как возможно содержит ЛГБТ-контент. В некоторых странах такие материалы могут быть запрещены или ограничены.', + + loading_progress_step_0: 'Подготовка', + loading_progress_step_1: 'Загрузка языков', + loading_progress_step_2: 'Поиск зеркал', + loading_progress_step_3: 'Подготовка расширений', + loading_progress_step_4: 'Осталось немного', + loading_progress_step_5: 'Уже скоро', + + install_extension_rule_1: 'Установка стороннего плагина', + install_extension_rule_2: 'Плагины создаются независимыми разработчиками, и LAMPA не проверяет их содержимое. Устанавливая их, вы соглашаетесь с тем, что:', + install_extension_rule_3: '- Некоторые плагины могут запрашивать доступ к вашим данным или работать с непроверенными источниками.', + install_extension_rule_4: '- Если устанавливаемый вами плагин нарушает авторские права или другие законы, вся ответственность за его использование лежит на вас.', + install_extension_rule_5: '- Устанавливайте только плагины из доверенных источников. Если вы сомневаетесь в безопасности или законности плагина, лучше откажитесь от его установки.', + install_extension_rule_6: 'LAMPA не поддерживает и не одобряет плагины, связанные с пиратским контентом.', + install_extension_rule_7: 'Продолжая, вы подтверждаете, что понимаете эти риски.', + + terminal_title: 'Терминал', + terminal_no_access: 'Без доступа', + terminal_confirm: 'Разрешить', + terminal_deny: 'Запретить', + terminal_update: 'Обновить', + terminal_code: 'Код доступа', + terminal_text: 'Вы запрашиваете доступ к терминалу. Разработчики могут получить доступ к вашему устройству и управлять им. Это может быть полезно для диагностики и устранения проблем, но также может представлять риск безопасности. Пожалуйста, убедитесь, что вы доверяете разработчикам, прежде чем предоставлять доступ.

    Вы можете в любой момент отключить эту функцию нажав на кнопку "Запретить".', + + developer_param_enabled: 'Режим разработчика', + developer_param_nopremium: 'Отключить CUB Premium', + developer_param_nodemo: 'Отключить демонстрационный режим', + developer_param_ads: 'Показывать рекламу', + developer_param_fps: 'Показывать FPS', + + developer_trigger_help_1: 'Почти догадались :)', + developer_trigger_help_2: 'Еще немного :)', + developer_trigger_help_3: 'Точно хочешь войти в режим разработчика?', + developer_trigger_help_4: 'Режим разработчика активирован', + + remote_helper_long: 'Удерживайте кнопку (ОК) для вызова меню', + no_watch_history: 'Нет истории просмотра', + + adult_content_title: 'Взрослый контент', + adult_content_text_warning: 'Контент может содержать материалы для взрослых, которые могут быть неуместны для некоторых зрителей.', + adult_content_text_modal: 'Этот фильм или сериал помечен как содержащий взрослый контент. Для просмотра этого материала вам должно быть 18 лет или больше. Пожалуйста, подтвердите, что вы достигли совершеннолетия, чтобы продолжить просмотр.', + + adult_content_confirm: 'Мне 18 лет или больше', + adult_content_deny: 'Мне меньше 18 лет', + + inner_player_disclaimer_title: 'Дисклеймер плеера', + inner_player_disclaimer_text: 'Я понимаю, что запускаю плеер с неполной поддержкой, и понимаю, что это может приводить к нетипичному поведению устройства. Оптимально перейти на плееры семейства tvOS или другие альтернативы.', + + inner_player_disclaimer_change_player: 'Сменить плеер', + remote_configuration_settings_title: 'Удалённая конфигурация', + remote_configuration_registration_text: 'Удалённая конфигурация предоставляет временный доступ к вашему приложению, другое приложение сможет установить расширения и настроить параметры.', + remote_configuration_waite_text: 'Теперь вы можете передать этот код в другое приложение, чтобы предоставить доступ к настройкам.', + remote_configuration_open_button: 'Открыть доступ', + remote_configuration_code_life: 'Код действителен', + remote_configuration_notice_nocode: 'Не удалось открыть доступ', + + player_ai_agent_info: 'Хотите узнать больше о видео? Спросите у AI-ассистента, и он предоставит вам график настроений, краткий сюжет и интересные моменты.', + player_ai_agent_ask_plot: 'Кратко о сюжете', + player_ai_agent_ask_moods: 'Показать график', + player_ai_agent_ask_highlights: 'Интересные моменты', + player_ai_agent_ask: 'Спросить', + player_ai_agent_processing: 'Анализирую...', + player_ai_agent_no_data: 'Нет данных для показа.', + player_ai_agent_no_analysis: 'Не удалось провести анализ видео.', + player_ai_agent_quota: 'Лимит запросов превышен. Попробуйте повторить запрос позже.', + player_ai_agent_working: 'Я еще работаю над этим...', +} diff --git a/lampa-main/lang/uk.js b/lampa-main/lang/uk.js new file mode 100644 index 0000000..91cb497 --- /dev/null +++ b/lampa-main/lang/uk.js @@ -0,0 +1,1340 @@ +export default { + lang_choice_title: 'Ласкаво просимо', + lang_choice_subtitle: 'Виберіть мову', + more: 'Ще', + back: 'Назад', + ready: 'Готово', + close_app_modal: 'Ви впевнені, що хочете залишити програму?', + connected_seeds: 'підкл.', + show_more: 'Показати ще', + more_results: 'Показати більше результатів', + loading: 'Завантаження', + nofind_movie: 'Не вдалось знайти фільм.', + noname: 'Без назви', + nochoice: 'Не вибрано', + cancel: 'Скасувати', + confirm: 'Підтверджую', + sure: 'Ви впевнені?', + nodata: 'Немає даних', + search: 'Пошук', + search_input: 'Введіть текст', + search_empty: 'Історія пошуку порожня.', + search_delete: 'Ліворуч - видалити', + search_start_typing: 'Почніть вводити текст для пошуку.', + search_searching: 'Йде пошук...', + search_start: 'Розпочати пошук', + search_nofound: 'На ваш запит нічого не знайдено.', + global_search: 'Глобальний пошук', + full_genre: 'Жанр', + full_production: 'Виробництво', + full_date_of_release: 'Дата релізу', + full_budget: 'Бюджет', + full_countries: 'Країни', + full_like: 'Подобається', + full_torrents: 'Торренти', + full_trailers: 'Трейлери', + full_detail: 'Детально', + full_notext: 'Без опису.', + full_series_release: 'Вихід серій', + full_next_episode: 'Наступна', + full_episode_days_left: 'Залишилось днів', + full_trailer_official: 'Офіційний', + full_trailer_no_official: 'Неофіційний', + full_season: 'Сезон', + full_episode: 'Епізод', + full_directing: 'Режисура', + full_writing: 'Сценарій', + + settings_cub_sync: 'Синхронізація', + settings_cub_sync_descr: 'Синхронізація із сервісом CUB: синхронізація ваших закладок, історії переглядів, міток та тайм-кодів.', + settings_cub_account: 'Акаунт', + settings_cub_logged_in_as: 'Увійшли як', + settings_cub_profile: 'Профіль', + settings_cub_sync_btn: 'Синхронізувати', + settings_cub_sync_btn_descr: 'Зберегти локальні закладки в обліковий запис CUB', + settings_cub_backup: 'Бекап', + settings_cub_backup_descr: 'Зберегти або завантажити бекап даних', + settings_cub_logout: 'Вийти з облікового запису', + settings_cub_signin: 'Авторизація', + settings_cub_not_specified: 'Не вказано', + settings_cub_password: 'Пароль', + settings_cub_status: 'Статус', + settings_cub_backup_import: 'Імпорт', + settings_cub_backup_export: 'Експорт', + settings_cub_sync_filters: 'Синхронізація фільтрів', + settings_cub_sync_calendar: 'Синхронізація календаря', + settings_cub_sync_quality: 'Синхронізація позначок (якість)', + settings_cub_sync_search: 'Синхронізація історії пошуку', + settings_cub_sync_recomends: 'Синхронізація рекомендацій', + settings_cub_sync_timecodes: 'Синхронізація тайм-кодів', + settings_input_links: 'Вибране', + settings_interface_type: 'Полегшена версія', + settings_interface_size: 'Розмір інтерфейсу', + settings_interface_menu_always: 'Завжди показувати ліве меню', + settings_interface_background: 'Фон', + settings_interface_background_use: 'Показувати фон', + settings_interface_background_type: 'Тип фону', + settings_interface_performance: 'Швидкодія', + settings_interface_animation: 'Анімація', + settings_interface_animation_descr: 'Анімація карток та контенту', + settings_interface_attenuation: 'Згасання', + settings_interface_attenuation_descr: 'Плавне згасання карток знизу та зверху', + settings_interface_scroll: 'Тип скролінгу', + settings_interface_view_card: 'Тип перегляду карток', + settings_interface_view_card_descr: 'У міру скролінгу стрічки картки підвантажуватимуться поступово або завантажуватимуться всі', + settings_interface_lang: 'Мова інтерфейсу', + settings_interface_lang_reload: 'Необхідно перезавантажити програму, натисніть "OK" для перезавантаження.', + settings_main_account: 'Акаунт', + settings_main_interface: 'Інтерфейс', + settings_main_player: 'Плеєр', + settings_main_parser: 'Парсер', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: 'Розширення', + settings_main_rest: 'Iнше', + settings_rest_start: 'Початкова сторінка', + settings_rest_start_descr: 'З якої сторінки починати під час запуску', + settings_rest_source: 'Джерело', + settings_rest_source_use: 'Основне джерело', + settings_rest_source_descr: 'Звідки брати інформацію про фільми', + settings_rest_tmdb_lang: 'Якою мовою відображати дані з TMDB', + settings_rest_tmdb_prox: 'Проксирувати TMDB', + settings_rest_tmdb_prox_auto: 'Увімкнути проксі автоматично', + settings_rest_tmdb_posters: 'Раздільна здатність TMDB', + settings_rest_screensaver: 'Скрінсейвер', + settings_rest_screensaver_use: 'Показувати заставку за бездіяльності', + settings_rest_screensaver_type: 'Тип заставки', + settings_rest_helper: 'Підказки', + settings_rest_helper_use: 'Показувати підказки', + settings_rest_helper_reset: 'Показати підказки знову', + settings_rest_pages: 'Скільки сторінок зберігати у пам\'яті', + settings_rest_pages_descr: 'Зберігає сторінки в тому стані, в якому ви їх покинули', + settings_rest_time: 'Змістити час', + settings_rest_navigation: 'Тип навігації', + settings_rest_keyboard: 'Тип клавіатури', + settings_rest_device: 'Назва пристрою', + settings_rest_device_placeholder: 'Наприклад: Моя Лампа', + settings_rest_cache: 'Очистити кеш', + settings_rest_cache_descr: 'Будуть очищені всі налаштування та дані', + settings_rest_tmdb_example: 'Наприклад:', + settings_rest_tmdb_api_descr: 'Для отримання даних', + settings_rest_tmdb_image_descr: 'Для отримання зображень', + settings_rest_card_quality: 'Відмітки якості', + settings_rest_card_quality_descr: 'Відображати позначки якості на картках', + settings_rest_card_episodes: 'Відмітки епізодів', + settings_rest_card_episodes_descr: 'Показувати позначки епізодів на картках', + settings_parser_use: 'Використовувати парсер', + settings_parser_use_descr: 'Тим самим ви погоджуєтесь взяти на себе всю відповідальність за використання публічних посилань для перегляду торрент та онлайн контенту.', + settings_parser_type: 'Тип парсера для торентів', + settings_parser_jackett_placeholder: 'Наприклад: 192.168.х', + settings_parser_jackett_link: 'Посилання', + settings_parser_jackett_link_descr: 'Вкажіть посилання на скрипт Jackett', + settings_parser_jackett_key_placeholder: 'Наприклад: sa0sk83d.', + settings_parser_jackett_key: 'Api ключ', + settings_parser_jackett_key_descr: 'Знаходиться у Jackett', + settings_parser_torlook_type: 'Метод парсингу сайту TorLook', + settings_parser_scraperapi_placeholder: 'Наприклад: scraperapi.com', + settings_parser_scraperapi_link: 'Посилання на парсер сайтів', + settings_parser_scraperapi_descr: 'Зареєструйтесь на сайті scraperapi.com, введіть посилання api.scraperapi.com?api_key=...&url={q}
    У {q} буде поставлятися сайт w41.torlook.info', + settings_parser_search: 'Пошук', + settings_parser_search_descr: 'Якою мовою здійснювати пошук?', + settings_parser_in_search: 'Парсер у пошуку', + settings_parser_in_search_descr: 'Показувати результати у пошуку?', + settings_parser_timeout_title: 'Таймаут парсера', + settings_parser_timeout_descr: 'Час у секундах, який очікуватиметься відповіді від сервера', + settings_player_type: 'Тип плеєра', + settings_player_type_descr: 'Яким плеєром відтворювати', + settings_infuse_launch_mode: 'Запуск в Infuse', + settings_infuse_launch_mode_descr: 'Що робити при відкритті відео в Infuse. Для торрентів завжди одразу відтворення', + settings_infuse_launch_ask: 'Питати при запуску', + settings_infuse_launch_play: 'Грати', + settings_infuse_launch_save_and_play: 'Зберегти і грати', + settings_player_iptv_type: 'Тип плеєра для IPTV', + settings_player_iptv_type_descr: 'Яким плеєром відтворювати IPTV канали', + settings_player_reset: 'Скинути програвач за замовчуванням', + settings_player_reset_descr: 'Скидає вибраний Android плеєр у програмі', + settings_player_path: 'Шлях до плеєра', + settings_player_path_descr: 'Вкажіть шлях до програвача .exe.', + settings_player_external_header: 'Зовнішній плеєр', + settings_player_external_fullscreen: 'Запустити в повноекранному режимі', + settings_player_normalization: 'Нормалізація звуку', + settings_player_normalization_descr: 'Нормалізує звук в один рівень, знижує гучні звуки та підвищує тихі.', + settings_player_next_episode: 'Наступна серія', + settings_player_next_episode_descr: 'Автоматично перемикати на наступну серію після закінчення поточної', + settings_player_timecode: 'Тайм-код', + settings_player_timecode_descr: 'Продовжити з останнього місця перегляду', + settings_player_scale: 'Метод масштабування', + settings_player_scale_descr: 'Як проводити обчислення для масштабування відео', + settings_player_subs: 'Субтитри', + settings_player_subs_use: 'Увімкнути', + settings_player_subs_use_descr: 'Завжди включати субтитри після запуску відео', + settings_player_subs_lang: 'Мова субтитрів', + settings_player_subs_lang_descr: 'Які субтитри вмикати автоматично, якщо доступно кілька мов', + settings_param_subtitles_lang_auto: 'Мова інтерфейсу', + settings_player_subs_size: 'Розмір', + settings_player_subs_size_descr: 'Розмір субтитрів на екрані', + settings_player_subs_stroke_use: 'Використовувати окантовку', + settings_player_subs_stroke_use_descr: 'Субтитри будуть обведені чорним кольором для покращення читаності', + settings_player_subs_backdrop_use: 'Використовувати підкладку', + settings_player_subs_backdrop_use_descr: 'Субтитри відображатимуться на напівпрозорій підкладці для покращення читаності', + settings_player_quality: 'Якість відео за замовчуванням', + settings_player_quality_descr: 'Переважна якість відео для перегляду', + settings_player_hls_title: 'Обробка потоку .m3u8', + settings_player_hls_descr: 'Не чіпайте цей параметр, якщо не знаєте навіщо він.', + settings_plugins_notice: 'Для застосування плагіна необхідно перезавантажити програму', + settings_plugins_add: 'Додати плагін', + settings_plugins_add_descr: 'Щоб видалити доданий плагін, утримуйте або натисніть двічі клавішу (OK) на ньому.', + settings_plugins_install: 'Встановити плагін', + settings_plugins_install_descr: 'Встановити плагін зі списку доступних', + settings_server_link: 'Використовувати посилання', + settings_server_links: 'Посилання', + settings_server_placeholder: 'Наприклад: 192.168.х', + settings_server_link_one: 'Основне посилання', + settings_server_link_one_descr: 'Вкажіть основне посилання на скрипт TorrServer', + settings_server_link_two: 'Додаткове посилання', + settings_server_link_two_descr: 'Вкажіть додаткове посилання на скрипт TorrServer', + settings_server_additionally: 'Додатково', + settings_server_client: 'Вбудований клієнт', + settings_server_client_descr: 'Використовувати вбудований JS-клієнт TorrServer, інакше запускається системний.', + settings_server_base: 'Зберегти у базу', + settings_server_base_descr: 'Торрент буде додано до бази TorrServer', + settings_server_preload: 'Використовувати буфер попереднього завантаження', + settings_server_preload_descr: 'Чекати на заповнення буфера попереднього завантаження TorrServer перед програванням', + settings_server_auth: 'Авторизація', + settings_server_password_use: 'Вхід паролем', + settings_server_login: 'Логін', + settings_server_password: 'Пароль', + settings_server_not_specified: 'Не вказано', + settings_server_search_type: 'Тип пошуку', + settings_server_search_type_descr: 'Де шукати торренти: вбудований rutor, Torznab-індексери в TorrServer, або обидва джерела.', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + settings_server_not_specified: 'Не вказано', + torent_nohash_reasons: 'Причини', + torent_nohash_reason_one: 'TorServer не зміг завантажити файл торрент', + torent_nohash_reason_two: 'Відповідь від TorServer', + torent_nohash_reason_three: 'Посилання', + torent_nohash_do: 'Що робити?', + torent_nohash_do_one: 'Перевірте, чи правильно ви налаштували Jackett', + torent_nohash_do_two: 'Приватні джерела можуть не видавати посилання на файл', + torent_nohash_do_three: 'Переконайтеся, що Jackett теж може завантажити файл', + torent_nohash_do_four: 'Написати в нашу телеграму групу: @lampa_group', + torent_nohash_do_five: 'Вкажіть який фільм, яка роздача та по можливості фото цієї роздачі', + torrent_error_text: 'Не вдалося підключитися до TorrServer. Давайте швидко пройдемося по списку можливих проблем і перевіримо все.', + torrent_error_step_1: 'Чи запущений TorrServer', + torrent_error_step_2: 'Динамічна IP-адреса', + torrent_error_step_3: 'Протокол та порт', + torrent_error_step_4: 'Блокування антивірусами', + torrent_error_step_5: 'Перевірте доступність', + torrent_error_step_6: 'Все одно не працює', + torrent_error_info_1: 'Переконайтеся, що TorrServer запущено на пристрої, де він встановлений.', + torrent_error_info_2: 'Часта помилка змінилася IP-адреса пристрою з TorrServer. Переконайтеся, що IP-адреса, яку ви ввели - {ip}, збігається з адресою пристрою, на якому встановлено TorrServer.', + torrent_error_info_3: 'Для підключення до TorrServer необхідно вказати протокол http:// на початку та порт :8090 в кінці адреси. Переконайтеся, що після IP-адреси вказано порт, ваша поточна адреса - {ip}', + torrent_error_info_4: 'Часте явище, антивірус або брандмауер може блокувати доступ за IP-адресою, спробуйте вимкнути антивірус та брандмауер.', + torrent_error_info_5: 'На будь-якому іншому пристрої в цій мережі, відкрийте в браузері адресу {ip} і перевірте, чи доступний веб-інтерфейс TorrServer.', + torrent_error_info_6: 'Якщо після всіх перевірок все одно виникає помилка підключення, спробуйте перезавантажити TorrServer та інтернет-адаптер.', + torrent_error_info_7: 'Якщо проблему не вирішено, пишіть у Telegram-групу @lampa_group з текстом (Lampa не підключається до TorrServer після всіх перевірок, поточна адреса {ip})', + torrent_error_start: 'Розпочати перевірку', + torrent_error_nomatrix: 'Неможливо підтвердити версію Matrix', + torrent_error_made: 'Виконано', + torrent_error_from: 'з', + torrent_error_next: 'Далі', + torrent_error_complite: 'Завершити', + torrent_error_connect: 'Помилка підключення', + torrent_install_need: 'Необхідний TorrServer', + torrent_install_text: 'TorrServer – додаток, який дозволяє переглядати контент з торрент-файлів в онлайн режимі.', + torrent_install_contact: 'Telegram-групи', + torrent_item_bitrate: 'Бітрейт', + torrent_item_seeds: 'Роздають', + torrent_item_grabs: 'Качають', + torrent_item_mb: 'Мбіт/с', + torrent_serial_episode: 'Серія', + torrent_serial_season: 'Сезон', + torrent_serial_date: 'Вихід', + torrent_get_magnet: 'Запитую magnet посилання', + torrent_remove_title: 'вилучити', + torrent_remove_descr: 'Торрент буде видалено зі списку', + torrent_parser_any_one: 'Будь-яке', + torrent_parser_any_two: 'Будь-який', + torrent_parser_no_choice: 'Не вибрано', + torrent_parser_yes: 'Так', + torrent_parser_no: 'Ні', + torrent_parser_quality: 'Якість', + torrent_parser_subs: 'Субтитри', + torrent_parser_voice: 'Переклад', + torrent_parser_tracker: 'Трекер', + torrent_parser_year: 'Рік', + torrent_parser_season: 'Сезон', + torrent_parser_sort_by_seeders: 'По роздаючих', + torrent_parser_sort_by_size: 'По розміру', + torrent_parser_sort_by_name: 'За назвою', + torrent_parser_sort_by_tracker: 'За джерелом', + torrent_parser_sort_by_date: 'По даті', + torrent_parser_sort_by_viewed: 'За переглянутими', + torrent_parser_voice_dubbing: 'Дубляж', + torrent_parser_voice_polyphonic: 'Багатоголосий', + torrent_parser_voice_two: 'Двоголосий', + torrent_parser_voice_amateur: 'Аматорський', + torrent_parser_reset: 'Скинути фільтр', + torrent_parser_empty: 'Не вдалося отримати результатів', + torrent_parser_no_hash: 'Неможливо отримати HASH, спробуйте перезавантажити TorrServer', + torrent_parser_added_to_mytorrents: 'додано до «Моїх торрентів»', + torrent_parser_add_to_mytorrents: 'Додати до «Моїх торентів»', + torrent_parser_label_title: 'Позначити', + torrent_parser_label_descr: 'Позначити роздачу з прапором (переглянуто)', + torrent_parser_label_cancel_title: 'Зняти позначку', + torrent_parser_label_cancel_descr: 'Зняти відмітку з роздачі (переглянуто)', + torrent_parser_timeout: 'Час очікування минув', + torrent_parser_nofiles: 'Не вдалося вилучити відповідні файли', + torrent_parser_set_link: 'Вкажіть посилання для парсингу', + torrent_parser_request_error: 'Помилка у запиті', + torrent_parser_magnet_error: 'Не вдалося отримати magnet посилання', + torrent_parser_torlook_fallback_search_notification: 'Парсер Jackett недоступний або налаштування підключення не вірні. Здійснюється пошук у Torlook...', + about_text: 'Додаток повністю безкоштовний і використовує публічні посилання для отримання інформації про відео, новинки, популярні фільми і т.д. Вся доступна інформація використовується виключно з пізнавальною метою, додаток не використовує свої власні сервери для поширення інформації.', + about_channel: 'Наш канал', + about_group: 'Група', + about_version: 'Версія', + about_donate: 'Донат', + title_watched: 'Ви дивилися', + title_settings: 'Налаштування', + title_collections: 'Добірки', + title_company: 'Компанія', + title_actors: 'Актори', + title_actor: 'Актор', + title_actress: 'Актриса', + title_person: 'Персона', + title_persons: 'Особи', + title_comments: 'Коментарі', + title_torrents: 'Торренти', + title_trailers: 'Трейлери', + title_watch: 'Дивитись', + title_error: 'Помилка', + title_links: 'Посилання', + title_choice: 'Вибрати', + title_main: 'Головна', + title_book: 'Закладки', + title_like: 'Подобається', + title_wath: 'Пізніше', + title_history: 'Історія переглядів', + title_mytorrents: 'Мої торенти', + title_last: 'Остання', + title_action: 'Дія', + title_action_infuse: 'Дія Infuse', + title_producer: 'Режисер', + title_collection: 'Колекція', + title_recomendations: 'Рекомендації', + title_similar: 'Подібні', + title_about: 'Про додаток', + title_timetable: 'Розклад', + title_relises: 'Цифрові релізи', + title_catalog: 'Каталог', + title_category: 'Категорія', + title_parser: 'Парсер', + title_type: 'Тип', + title_rating: 'Рейтинг', + title_country: 'Країна', + title_year: 'Рік', + title_genre: 'Жанр', + title_filter: 'Фільтр', + title_notice: 'Повідомлення', + title_files: 'Файли', + title_now_watch: 'Зараз дивляться', + title_latest: 'Останнє додавання', + title_continue: 'Продовжити перегляд', + title_recomend_watch: 'Рекомендуємо подивитись', + title_new_episodes: 'Нові серії', + title_popular: 'Популярне', + title_popular_movie: 'Популярні фільми', + title_popular_tv: 'Популярні серіали', + title_new_this_year: 'Новинки цього року', + title_hight_voite: 'З високим рейтингом', + title_new: 'Новинки', + title_trend_day: 'Сьогодні у тренді', + title_trend_week: 'У тренді за тиждень', + title_upcoming: 'Дивіться у кінозалах', + title_top_movie: 'Топ фільми', + title_top_tv: 'Топ серіали', + title_tv_today: 'Сьогодні в ефірі', + title_this_week: 'На цьому тижні', + title_in_top: 'У топі', + title_out: 'Вихід', + title_out_confirm: 'Так, вийти', + title_continue_two: 'Продовжити', + title_choice_language: 'Вибрати мову', + title_subscribe: 'Підписатися', + title_subscribes: 'Підписки', + title_unsubscribe: 'Відписатися', + title_language: 'Мова оригіналу', + subscribe_success: 'Ви успішно підписалися', + subscribe_error: 'Виникла помилка під час передплати, спробуйте пізніше', + subscribe_noinfo: 'Не вдалося отримати інформацію, спробуйте пізніше', + company_headquarters: 'Штаб', + company_homepage: 'Сайт', + company_country: 'Країна', + country_ad: 'Андорра', + country_ae: 'ОАЕ', + country_af: 'Афганістан', + country_al: 'Албанія', + country_am: 'Вірменія', + country_ao: 'Ангола', + country_ar: 'Аргентина', + country_at: 'Австрія', + country_au: 'Австралія', + country_aw: 'Аруба', + country_az: 'Азербайджан', + country_bа: 'Боснія і Герцеговина', + country_bd: 'Бангладеш', + country_be: 'Бельгія', + country_bg: 'Болгарія', + country_bh: 'Бахрейн', + country_bi: 'Бурунді', + country_bj: 'Бенін', + country_bo: 'Болівія', + country_br: 'Бразилія', + country_bs: 'Багамські острови', + country_bt: 'Бутан', + country_bw: 'Ботсвана', + country_by: 'Білорусь', + country_ca: 'Канада', + country_ch: 'Швейцарія', + country_cl: 'Чилі', + country_cm: 'Камерун', + country_cn: 'Китай', + country_co: 'Колумбія', + country_cr: 'Коста-Рика', + country_cu: 'Куба', + country_cv: 'Кабо-Верде', + country_cy: 'Кіпр', + country_cz: 'Чехія', + country_de: 'Німеччина', + country_dj: 'Джибуті', + country_dk: 'Данія', + country_do: 'Домініканська Республіка', + country_dz: 'Алжир', + country_ec: 'Еквадор', + country_ee: 'Естонія', + country_eg: 'Єгипет', + country_es: 'Іспанія', + country_et: 'Ефіопія', + country_fi: 'Фінляндія', + country_fo: 'Фарерські острови', + country_fr: 'Франція', + country_ga: 'Габон', + country_gb: 'Великобританія', + country_ge: 'Грузія', + country_gh: 'Гана', + country_gl: 'Гренландія', + country_gp: 'Гваделупа', + country_gr: 'Греція', + country_gt: 'Гватемала', + country_hk: 'Гонконг', + country_hr: 'Хорватія', + country_ht: 'Гаїті', + country_hu: 'Угорщина', + country_id: 'Індонезія', + country_ie: 'Ірландія', + country_il: 'Ізраїль', + country_in: 'Індія', + country_iq: 'Ірак', + country_ir: 'Іран', + country_is: 'Ісландія', + country_it: 'Італія', + country_jm: 'Ямайка', + country_jo: 'Йорданія', + country_jp: 'Японія', + country_ke: 'Кенія', + country_kg: 'Киргизстан', + country_kh: 'Камбоджа', + country_kp: 'Північна Корея', + country_kr: 'Південна Корея', + country_kz: 'Казахстан', + country_kw: 'Кувейт', + country_la: 'Лаос', + country_lb: 'Ліван', + country_li: 'Ліхтенштейн', + country_lk: 'Шрі-Ланка', + country_lr: 'Ліберія', + country_lt: 'Литва', + country_lu: 'Люксембург', + country_lv: 'Латвія', + country_ly: 'Лівія', + country_ma: 'Марокко', + country_mc: 'Монако', + country_md: 'Молдова', + country_me: 'Чорногорія', + country_mk: 'Македонія', + country_mm: 'М\'янма', + country_mn: 'Монголія', + country_mo: 'Макао', + country_mt: 'Мальта', + country_mu: 'Маврикій', + country_mv: 'Мальдіви', + country_mw: 'Малаві', + country_mx: 'Мексика', + country_my: 'Малайзія', + country_mz: 'Мозамбік', + country_na: 'Намібія', + country_ne: 'Нігер', + country_ng: 'Нігерія', + country_ni: 'Нікарагуа', + country_nl: 'Нідерланди', + country_no: 'Норвегія', + country_np: 'Непал', + country_nz: 'Нова Зеландія', + country_om: 'Оман', + country_pa: 'Панама', + country_pe: 'Перу', + country_pg: 'Папуа - Нова Гвінея', + country_ph: 'Філіппіни', + country_pk: 'Пакистан', + country_pl: 'Польща', + country_pr: 'Пуерто-Рико', + country_ps: 'Палестина', + country_pt: 'Португалія', + country_py: 'Парагвай', + country_qa: 'Катар', + country_ro: 'Румунія', + country_rs: 'Сербія', + country_ru: 'Росія', + country_rw: 'Руанда', + country_sa: 'Саудівська Аравія', + country_sd: 'Судан', + country_se: 'Швеція', + country_sg: 'Сінгапур', + country_si: 'Словенія', + country_sk: 'Словаччина', + country_sn: 'Сенегал', + country_su: 'СРСР', + country_sv: 'Сальвадор', + country_sy: 'Сирія', + country_th: 'Таїланд', + country_tj: 'Таджикистан', + country_tm: 'Туркменістан', + country_tn: 'Туніс', + country_tr: 'Туреччина', + country_tw: 'Тайвань', + country_tz: 'Танзанія', + country_ua: 'Україна', + country_ug: 'Уганда', + country_us: 'США', + country_uy: 'Уругвай', + country_uz: 'Узбекистан', + country_ve: 'Венесуела', + country_vn: 'В\'єтнам', + country_ws: 'Самоа', + country_xk: 'Косово', + country_ye: 'Ємен', + country_yu: 'Югославія', + country_za: 'ПАР', + country_zm: 'Замбія', + country_zw: 'Зімбабве', + filter_clarify: 'Уточнити', + filter_clarify_two: 'Уточнити пошук', + filter_set_name: 'Вказати назву', + filter_sorted: 'Сортувати', + filter_filtred: 'Фільтр', + filter_any: 'Будь-який', + filter_combinations: 'Комбінації', + filter_alt_names: 'Інші назви', + filter_rating_from: 'від', + filter_rating_to: 'до', + filter_lang_af: 'Африкаанс', + filter_lang_ar: 'Арабська', + filter_lang_az: 'Азербайджанська', + filter_lang_ba: 'Башкирська', + filter_lang_be: 'Білоруська', + filter_lang_bg: 'Болгарська', + filter_lang_bn: 'Бенгальська', + filter_lang_bs: 'Боснійська', + filter_lang_ca: 'Каталанська', + filter_lang_ce: 'Чеченська', + filter_lang_cs: 'Чеська', + filter_lang_da: 'Дацька', + filter_lang_de: 'Німецька', + filter_lang_el: 'Грецька', + filter_lang_en: 'Англійська', + filter_lang_es: 'Іспанська', + filter_lang_et: 'Естонська', + filter_lang_fa: 'Персидська', + filter_lang_fi: 'Фінська', + filter_lang_fr: 'Французька', + filter_lang_ga: 'Ірландська', + filter_lang_gl: 'Галісійська', + filter_lang_gn: 'Гуарані', + filter_lang_he: 'Іврит', + filter_lang_hi: 'Хінді', + filter_lang_hr: 'Хорватська', + filter_lang_hu: 'Угорська', + filter_lang_hy: 'Вірменська', + filter_lang_id: 'Індонезійська', + filter_lang_is: 'Ісландська', + filter_lang_it: 'Італійська', + filter_lang_ja: 'Японська', + filter_lang_ka: 'Грузинська', + filter_lang_kk: 'Казахська', + filter_lang_ko: 'Корейська', + filter_lang_ks: 'Кашмірі', + filter_lang_ku: 'Курдська', + filter_lang_ky: 'Киргизька', + filter_lang_lt: 'Литовська', + filter_lang_lv: 'Латишська', + filter_lang_mi: 'Маорі', + filter_lang_mk: 'Македонська', + filter_lang_mn: 'Монгольська', + filter_lang_mt: 'Мальтійська', + filter_lang_ne: 'Непальська', + filter_lang_nl: 'Нідерландська', + filter_lang_no: 'Норвезька', + filter_lang_pa: 'Пенджабська', + filter_lang_pl: 'Польська', + filter_lang_ps: 'Пушту', + filter_lang_pt: 'Португальська', + filter_lang_ro: 'Румунська', + filter_lang_ru: 'Російська', + filter_lang_si: 'Сінгальська', + filter_lang_sk: 'Словацька', + filter_lang_sl: 'Словенська', + filter_lang_sm: 'Самоанська', + filter_lang_so: 'Сомалійська', + filter_lang_sq: 'Албанська', + filter_lang_sr: 'Сербська', + filter_lang_sv: 'Шведська', + filter_lang_sw: 'Суахілі', + filter_lang_ta: 'Тамільська', + filter_lang_tg: 'Таджицька', + filter_lang_th: 'Тайська', + filter_lang_tk: 'Туркменська', + filter_lang_tr: 'Турецька', + filter_lang_tt: 'Татарська', + filter_lang_ur: 'Урду', + filter_lang_uk: 'Українська', + filter_lang_uz: 'Узбецька', + filter_lang_vi: 'В\'єтнамська', + filter_lang_yi: 'Ідиш', + filter_lang_zh: 'Китайська', + filter_genre_ac: 'Бойовик', + filter_genre_ad: 'Пригоди', + filter_genre_mv: 'Мультфільм', + filter_genre_cm: 'Комедія', + filter_genre_cr: 'Кримінал', + filter_genre_dc: 'Документальний', + filter_genre_dr: 'Драма', + filter_genre_fm: 'Сімейний', + filter_genre_fe: 'Фентезі', + filter_genre_hi: 'Історія', + filter_genre_ho: 'Жахи', + filter_genre_mu: 'Музика', + filter_genre_de: 'Детектив', + filter_genre_md: 'Мелодрама', + filter_genre_fa: 'Фантастика', + filter_genre_tv: 'Телевізійний фільм', + filter_genre_tr: 'Трилер', + filter_genre_mi: 'Військовий', + filter_genre_ve: 'Вестерн', + filter_genre_aa: 'Бойовик та Пригоди', + filter_genre_ch: 'Дитячий', + filter_genre_nw: 'Новини', + filter_genre_rs: 'Реаліті шоу', + filter_genre_hf: 'НФ та Фентезі', + filter_genre_op: 'Мильна опера', + filter_genre_tc: 'Ток шоу', + filter_genre_mp: 'Війна та Політика', + empty_title: 'Пусто', + empty_text: 'За вашим фільтром нічого не знайшлося, уточніть фільтр.', + empty_title_two: 'Тут порожньо', + empty_text_two: 'На даний момент список порожній', + menu_main: 'Головна', + menu_movies: 'Фільми', + menu_tv: 'Серіали', + menu_catalog: 'Каталог', + menu_filter: 'Фільтр', + menu_collections: 'Добірки', + menu_relises: 'Релізи', + menu_anime: 'Аніме', + menu_bookmark: 'Закладки', + menu_like: 'Подобається', + menu_time: 'Пізніше', + menu_history: 'Історія', + menu_timeline: 'Розклад', + menu_torrents: 'Торренти', + menu_settings: 'Налаштування', + menu_about: 'Інформація', + menu_console: 'Консоль', + menu_multmovie: 'Мультфільми', + menu_multtv: 'Мультсеріали', + menu_feed: 'Стрічка', + lampa_movie_title: 'Лампове кіно', + lampa_movie_descr: 'Слідкуйте за новинками на своєму смартфоні.
    Телеграм: @lampa_movie', + plugins_catalog_work: 'Робочі плагіни', + plugins_catalog_work_descr: 'Плагіни, які точно працюють у лампі.', + plugins_catalog_popular: 'Популярні плагіни серед користувачів', + plugins_catalog_popular_descr: 'Встановлення з невідомих джерел може призвести до некоректної роботи програми.', + plugins_online: 'Перегляд онлайн', + plugins_check_fail: 'Не вдалося перевірити працездатність плагіна. Однак це не означає, що плагін не працює. Перезавантажте програму для з\'ясування, чи завантажується плагін.', + plugins_need_reload: 'Для застосування плагіна необхідно перезавантажити програму', + plugins_install: 'Встановити', + plugins_install_ready: 'Цей плагін вже встановлено.', + plugins_installed: 'Установок', + plugins_load_from: 'Завантажено із CUB', + plugins_ok_for_check: 'Натисніть (OK), щоб перевірити плагін', + plugins_no_loaded: 'При завантаженні програми частина плагінів не вдалося завантажити', + time_viewed: 'Переглянуто', + time_from: 'з', + time_reset: 'Скинути тайм-код', + settings_clear_cache: 'Кеш та дані очищені', + settings_user_links: 'Користувальницьке посилання', + settings_for_local: 'Для локального TorrServer', + settings_add: 'Додати', + settings_remove: 'Вилучити', + settings_this_value: 'поточне значення', + settings_added: 'Додано', + settings_removed: 'Вилучено', + settings_param_player_inner: 'Вбудований', + settings_param_player_outside: 'Зовнішній', + settings_param_player_inner_tvos: 'Вбудований', + settings_param_yes: 'Так', + settings_param_no: 'Ні', + settings_param_interface_size_small: 'Менше', + settings_param_interface_size_normal: 'Нормальний', + settings_param_interface_size_bigger: 'Більше', + settings_param_poster_quality_low: 'Низьке', + settings_param_poster_quality_average: 'Середнє', + settings_param_poster_quality_high: 'Висока', + settings_param_parse_directly: 'Безпосередньо', + settings_param_parse_api: 'Через API сайту', + settings_param_background_complex: 'Складний', + settings_param_background_simple: 'Простий', + settings_param_background_image: 'Картинка', + settings_param_link_use_one: 'Основну', + settings_param_link_use_two: 'Додаткову', + settings_param_link_use_both: 'Обидві', + settings_param_subtitles_size_small: 'Маленькі', + settings_param_subtitles_size_normal: 'Звичайні', + settings_param_subtitles_size_bigger: 'Великі', + settings_param_screensaver_nature: 'Природа', + settings_param_torrent_lang_orig: 'Оригінал', + settings_param_torrent_lang_ru: 'Русский', + settings_param_player_timecode_again: 'Почати спочатку', + settings_param_player_timecode_continue: 'Продовжити', + settings_param_player_timecode_ask: 'Запитувати', + settings_param_player_scale_method: 'Розрахувати', + settings_param_player_hls_app: 'Системний', + settings_param_player_hls_js: 'Програмний', + settings_param_card_view_load: 'Підвантажувати', + settings_param_card_view_all: 'Показати все', + settings_param_navigation_remote: 'Пульт', + settings_param_navigation_mouse: 'Пульт з мишкою', + settings_param_keyboard_lampa: 'Вбудована', + settings_param_keyboard_system: 'Системна', + helper_keyboard: 'Після введення значення натисніть кнопку «Назад», щоб зберегти', + helper_torrents: 'Утримуйте клавішу (OK), щоб викликати контекстне меню', + helper_cleared: 'Успішно підказки будуть показані заново.', + helper_torrents_view: 'Щоб скинути тайм-код та виклик меню, утримуйте (OK).', + fav_sync_title: 'Синхронізація закладок', + fav_sync_text: 'Ваші улюблені закладки разом із Вами. Підключіть синхронізацію та переглядайте на будь-якому пристрої.

    Для цього зареєструйтесь на сайті {site}, створіть профіль та авторизуйтесь у додаток.', + fav_sync_site: 'Сайт', + fav_remove_title: 'Видалити з історії', + fav_remove_descr: 'Видалити виділену картку', + fav_clear_title: 'Очистити історію', + fav_clear_descr: 'Видалити всі картки з історії', + fav_clear_label_title: 'Очистити мітки', + fav_clear_label_descr: 'Очистити мітки про перегляд', + fav_clear_time_title: 'Очистити тайм-коди', + fav_clear_time_descr: 'Очистити всі тайм-коди', + fav_label_cleared: 'Відмітки очищені', + fav_time_cleared: 'Тайм-коди очищені', + timetable_empty: 'У цьому розділі відображатимуться дати виходу нових серій', + player_quality: 'Якість', + player_flow: 'Потік', + player_tracks: 'Аудіодоріжки', + player_disabled: 'Вимкнено', + player_unknown: 'Невідомо', + player_subs: 'Субтитри', + player_size_default_title: 'За замовчуванням', + player_size_default_descr: 'Розмір відео за замовчуванням', + player_size_cover_title: 'Розширити', + player_size_cover_descr: 'Розширює відео на весь екран', + player_size_fill_title: 'Заповнити', + player_size_fill_descr: 'Помістити відео на весь екран', + player_size_s115_title: 'Збільшити 115%', + player_size_s115_descr: 'Збільшити відео на 115%', + player_size_s130_title: 'Збільшити 130%', + player_size_s130_descr: 'Збільшити відео на 130%', + player_size_v115_title: 'По вертикалі 115%', + player_size_v115_descr: 'Збільшити відео на 115%', + player_size_v130_title: 'По вертикалі 130%', + player_size_v130_descr: 'Збільшити відео на 130%', + player_video_size: 'Розмір відео', + player_playlist: 'Плейлист', + player_error_one: 'Не вдалося декодувати відео', + player_error_two: 'Відео не знайдено або пошкоджено', + player_start_from: 'Продовжити перегляд з', + player_not_found: 'Плеєр не знайдено', + player_lauch: 'Запустити плеєр', + player_speed_default_title: 'Звичайна', + player_speed_two_descr: 'Відтворення без звуку', + player_video_speed: 'Швидкість відтворення', + player_share_title: 'Поділитися', + player_share_descr: 'Запустити це відео на іншому пристрої', + player_normalization_power_title: 'Сила нормалізації', + player_normalization_smooth_title: 'Швидкість нормалізації', + player_normalization_step_low: 'Низьке', + player_normalization_step_medium: 'Середнє', + player_normalization_step_hight: 'Висока', + player_youtube_no_played: 'На жаль, це відео не доступне у вашому регіоні, можливо, воно було заблоковане або видалено.', + player_youtube_start_play: 'Для початку відтворення відео, натисніть кнопку "Плей"', + broadcast_open: 'Відкрити картку на іншому пристрої', + broadcast_play: 'Виберіть пристрій, на якому дивитися', + card_new_episode: 'Нова серія', + card_book_remove: 'Прибрати із закладок', + card_book_add: 'В закладки', + card_book_descr: 'Дивіться у меню (Закладки)', + card_like_remove: 'Прибрати з уподобаних', + card_like_add: 'Подобається', + card_like_descr: 'Дивіться у меню (Подобається)', + card_wath_remove: 'Прибрати з очікуваних', + card_wath_add: 'Дивитися пізніше', + card_wath_descr: 'Дивіться в меню (Пізніше)', + card_history_remove: 'Прибрати з історії', + card_history_add: 'В історію', + card_history_descr: 'Дивіться у меню (Історія)', + keyboard_listen: 'Кажіть, я слухаю...', + keyboard_nomic: 'Немає доступу до мікрофону', + notice_new_quality: 'Доступна нова якість', + notice_quality: 'Якість', + notice_new_episode: 'Нова серія', + notice_none: 'У вас ще немає жодних повідомлень, зареєструйтесь на сайті {site}, щоб стежити за новими серіями та релізами.', + notice_in_quality: 'В якості', + copy_link: 'Копіювати посилання на відео', + copy_secuses: 'Посилання скопійоване в буфер обміну', + copy_error: 'Помилка під час копіювання посилання', + account_sync_to_profile: 'Усі закладки будуть перенесені до профілю', + account_sync_secuses: 'Усі закладки успішно перенесені', + account_profiles: 'Профілі', + account_profiles_empty: 'Неможливо отримати список профілів', + account_authorized: 'Авторизовані', + account_logged_in: 'Ви увійшли під обліковий запис', + account_login_failed: 'Вхід не виконано', + account_login_wait: 'Очікуємо входу до облікового запису', + account_profile_main: 'Загальний', + account_export_secuses: 'Експорт успішно завершено', + account_export_fail: 'Помилка під час експорту', + account_import_secuses: 'Імпорт успішно завершено', + account_import_fail: 'Помилка при імпорті', + account_imported: 'імпортовано', + account_reload_after: 'перезавантаження через 5 с.', + account_create: 'Відкрийте більше можливостей з облікового запису CUB. Зареєструйтесь на сайті та отримайте доступ до синхронізації ваших закладок, тайм-кодів та інших можливостей облікового запису CUB.', + account_premium: 'Розкрийте нові горизонти з обліковим записом CUB Premium! Насолоджуйтесь збільшеними лімітами та збагаченим функціоналом сервісу. Перейдіть на сайт та дізнайтесь більше про переваги преміум акаунту.', + account_premium_more: 'Докладніше про CUB Premium', + account_limited: 'Ви досягли максимального ліміту. Збільште ліміт з обліковим записом CUB Premium. Докладніше на сайті ', + account_premium_include_1: 'Збільшення кількості закладок', + account_premium_include_2: 'Збільшення історії переглядів', + account_premium_include_3: 'Збільшення кількості тайм-кодів', + account_premium_include_4: 'Кількість профілів на обліковий запис', + account_premium_include_5: 'Повідомлення', + account_premium_include_6: 'Синхронізація даних', + account_premium_include_text_1: 'Більше закладок – більше можливостей! Зберігайте свої улюблені фільми та серіали, створюйте списки перегляду та насолоджуйтесь переглядом у будь-який зручний час.', + account_premium_include_text_2: 'Збільште історію переглядів у програмі та стежте за тим, що вже подивилися. Легко знаходите та переглядайте свої улюблені фільми та серіали.', + account_premium_include_text_3: 'Не бійтеся пропустити жодну важливу сцену! Збільште кількість тайм-кодів у додатку та легко відстежуйте, де зупинилися у перегляді улюблених фільмів та серіалів.', + account_premium_include_text_4: 'Отримайте більше свободи з нашим преміум-доступом! Збільште кількість профілів на обліковому записі та дозвольте своїм друзям та близьким насолоджуватися фільмами та серіалами разом з вами. Жодних обмежень - насолоджуйтесь переглядом з коханими людьми.', + account_premium_include_text_5: 'Не пропустіть жодної нової серії чи перекладу! Отримуйте сповіщення вчасно та будьте в курсі всіх оновлень. Збільште свій кінопотік разом з нами та отримуйте повідомлення про вихід нових серій та перекладів прямо на свій смартфон.', + account_premium_include_text_6: 'Синхронізуйте дані між пристроями з преміум-доступом! Більше не потрібно гаяти час на пошук останнього епізоду, на якому ви зупинилися. З нашим преміум доступом ви можете синхронізувати свої дані між пристроями, щоб продовжувати перегляд з місця, де ви зупинилися, на будь-якому пристрої, де встановлено програму.', + + account_code_enter: 'Введіть шестизначний код', + account_code_error: 'Можливо, ви ввели невірний або застарілий код', + account_code_wrong: 'Можливо, ви вказали неправильний формат', + account_code_where: 'Перейдіть на сайт та введіть вказаний там код.', + account_code_input: 'Ввести код', + settings_cub_signin_button: 'Увійти', + + network_noconnect: 'Немає підключення до мережі', + network_404: 'Запрошеної сторінки не знайдено. [404]', + network_401: 'Авторизація не вдалася', + network_500: 'Внутрішня помилка сервера. [500]', + network_parsererror: 'Запитаний синтаксичний аналіз JSON завершився невдало.', + network_timeout: 'Час запиту минув.', + network_abort: 'Запит було перервано.', + network_error: 'Невідома помилка', + size_zero: '0 Байт', + size_byte: 'Байт', + size_kb: 'КБ', + size_mb: 'МБ', + size_gb: 'ГБ', + size_tb: 'ТБ', + size_pp: 'ПБ', + speed_bit: 'біт/c', + speed_kb: 'Кбіт/c', + speed_mb: 'Мбіт/c', + speed_gb: 'Гбіт/c', + speed_tb: 'Тбіт/c', + speed_pp: 'Пбіт/c', + month_1: 'Січень', + month_2: 'Лютий', + month_3: 'Березень', + month_4: 'Квітень', + month_5: 'Травень', + month_6: 'Червень', + month_7: 'Липня', + month_8: 'Серпень', + month_9: 'Вересень', + month_10: 'Жовтень', + month_11: 'Листопад', + month_12: 'Грудень', + day_1: 'Понеділок', + day_2: 'Вівторок', + day_3: 'Середа', + day_4: 'Четвер', + day_5: 'П\'ятниця', + day_6: 'Субота', + day_7: 'Неділя', + month_1_e: 'Січня', + month_2_e: 'Лютого', + month_3_e: 'Березня', + month_4_e: 'Квітня', + month_5_e: 'Травня', + month_6_e: 'Червня', + month_7_e: 'Липня', + month_8_e: 'Серпня', + month_9_e: 'Вересня', + month_10_e: 'Жовтня', + month_11_e: 'Листопада', + month_12_e: 'Грудня', + week_1: 'Пн', + week_2: 'Вт', + week_3: 'Ср', + week_4: 'Чт', + week_5: 'Пт', + week_6: 'Сб', + week_7: 'Нд', + notice_none_account: 'У вас ще немає жодних повідомлень, додайте серіали в закладки та чекайте на повідомлення про нові серії.', + notice_none_system: 'На даний момент у вас відсутні повідомлення. Ми обов\'язково повідомимо вас, коли з\'являться нові повідомлення.', + torrent_parser_no_responce: 'Парсер не відповідає на запит', + extensions_enable: 'Увімкнути', + extensions_disable: 'Вимкнути', + extensions_check: 'Перевірити статус', + extensions_install: 'Встановити', + extensions_info: 'Інформація', + extensions_edit: 'Редагувати', + extensions_change_name: 'Змінити назву', + extensions_change_link: 'Змінити посилання', + extensions_remove: 'Вилучити', + extensions_set_name: 'Введіть назву плагіна', + extensions_set_url: 'Введіть адресу плагіна', + extensions_ready: 'Цей плагін вже встановлено', + extensions_no_info: 'Без інформації', + extensions_no_name: 'Без назви', + extensions_worked: 'Робочий', + extensions_no_plugin: 'Плагін не підтверджений', + extensions_add: 'Додати плагін', + extensions_from_memory: 'Встановлені в пам\'ять', + extensions_from_cub: 'Встановлені з CUB', + extensions_from_popular: 'Популярні плагіни', + extensions_from_lib: 'Бібліотека плагінів', + extensions_from_connected: 'Підключені плагіни', + + settings_webos_launcher: 'Запуск програми', + settings_webos_launcher_add_device: 'Встановити як стартове', + settings_webos_launcher_remove_device: 'Прибрати зі стартових додатків', + player_normalization: 'Нормалізація', + change_source_on_cub: 'Змінити джерело на CUB', + settings_param_jackett_interview_all: 'Всі', + settings_param_jackett_interview_healthy: 'Тільки доступні', + settings_parser_jackett_interview: 'Опитувати трекери', + title_ongoing: 'Онгоїнги', + title_pgrating: 'Вікове обмеження', + + settings_interface_card_interfice: 'Інтерфейс карток', + settings_interface_card_poster: 'Показати постер', + title_card: 'Картка', + settings_param_card_interface_old: 'Старий', + settings_param_card_interface_new: 'Новий', + title_seasons: 'Сезони', + title_episodes: 'Серії', + title_rewiews: 'Відгуки', + settings_interface_glass: 'Скло', + settings_interface_glass_descr: 'Показувати інтерфейс у склоподібному стилі', + settings_interface_black_style: 'Чорний стиль', + + plugins_remove: 'Видалити плагіни', + plugins_add_success: 'Плагін успішно підключений', + settings_reset: 'Скидання налаштувань', + title_channel: 'Канал', + + input_detection_touch: 'Бажаєте переключити на сенсорне керування?', + input_detection_mouse: 'Бажаєте переключити на керування мишею?', + input_detection_remote: 'Бажаєте переключити на керування пультом?', + + settings_interface_hide_outside_the_screen: 'Приховувати картки поза екраном', + settings_interface_hide_outside_the_screen_descr: 'Це прискорить рендер інтерфейсу та покращить продуктивність', + + https_text: 'Використовуйте протокол HTTPS, в цьому протоколі лампа працює некоректно. Для коректної роботи лампи використовуйте адресу з протоколом HTTP', + + extensions_hpu_best: 'Популярні', + extensions_hpu_recomend: 'Рекомендуємо', + extensions_hpu_theme: 'Теми', + extensions_hpu_screensaver: 'Скрінсейвер', + extensions_hpu_video: 'Відео', + extensions_hpu_control: 'Управління', + extensions_hpu_other: 'Різне', + extensions_hpu_: 'Решта', + + title_author: 'Автор', + + title_buffer: 'Буфер', + settings_rest_screensaver_time: 'Через скільки хвилин запустити скрінсейвер', + + time_h: 'г.', + time_m: 'х.', + time_s: 'с.', + + settings_param_glass_easy: 'Прозора', + settings_param_glass_medium: 'Напівпрозора', + settings_param_glass_blacked: 'Затемнена', + + settings_interface_glass_opacity: 'Прозорість скла', + torrent_error_check_no_auth: 'Сервер відповів на запит, але не вдалося пройти авторизацію', + settings_interface_card_cover: 'Показати обкладинку', + + title_upcoming_episodes: 'Найближчі виходи епізодів', + title_recent_episodes: 'Нещодавні виходи епізодів', + settings_rest_cache_images: 'Кеш зображень', + settings_rest_cache_images_descr: 'Кешувати постери та фони у локальне сховище', + + settings_player_rewind_title: 'Перемотування', + settings_player_rewind_descr: 'Інтервал перемотування за секунди', + + settings_interface_card_reactions: 'Показати реакції', + title_look: 'Дивлюся', + title_scheduled: 'Заплановано', + title_viewed: 'Переглянуто', + title_thrown: 'Відкинуто', + title_reactions: 'Реакції', + reactions_none: 'Немає реакцій', + reactions_fire: 'Супер', + reactions_nice: 'Непогано', + reactions_think: 'Цікаво', + reactions_bore: 'Нудно', + reactions_shit: 'Погано', + reactions_ready: 'Ви вже залишили реакцію', + settings_player_launch_trailers: 'Плеєр для трейлерів', + title_continued: 'Далі буде', + title_language_short: 'Мова', + + speedtest_connect: 'підключення', + speedtest_test: 'тестування', + speedtest_ready: 'готово', + speedtest_button: 'Тестувати швидкість', + + termsofuse_t_01: 'Умови використання', + termsofuse_t_02: 'Lampa - це зручний інструмент для ознайомлення з новинками кіноіндустрії, включаючи фільми, серіали, мультфільми та іншу інформацію. Для отримання інформації про фільми використовується відкритий джерело - веб-сайт themoviedb.org', + termsofuse_t_03: 'Контент', + termsofuse_t_04: 'Lampa використовує API (інтерфейс програмування додатків) від каталогу themoviedb.org для отримання інформації про фільми та телесеріали, а також для перегляду пов\'язаних з ними медіа-файлів, таких як постери, трейлери та інше.', + termsofuse_t_05: 'API від themoviedb.org дозволяє додатку Lampa отримувати доступ до бази даних фільмів та телесеріалів, забезпечуючи можливість пошуку та перегляду інформації про медіа-файли.', + termsofuse_t_06: 'Взаємодія між додатком Lampa та themoviedb.org відбувається через запити API, які відправляються з додатку Lampa на сервери themoviedb.org для отримання інформації та медіа-файлів. Themoviedb.org обробляє запити і надсилає запрошені дані назад до додатку Lampa.', + termsofuse_t_07: 'Таким чином, завдяки використанню API від themoviedb.org, додаток Lampa надає користувачам доступ до обширної бази даних фільмів та телесеріалів, дотримуючись при цьому умов використання та обмежень, встановлених правовласником.', + termsofuse_t_08: 'Розширення', + termsofuse_t_09: 'Розширення - це потужний інструмент, наданий для додатку Lampa, що дозволяє користувачам розширити його можливості, додати додатковий функціонал та змінити контент згідно зі своїми потребами.', + termsofuse_t_10: 'Однак, варто зазначити, що користувачі встановлюють розширення на свій ризик. Всі наслідки, що виникають в результаті використання розширень, несе користувач. Рекомендується користувачам бути обережними під час встановлення та використання розширень, ретельно оцінюючи їх надійність та безпеку.', + termsofuse_t_11: 'Порушення авторських прав', + termsofuse_t_12: 'Якщо ви виявили порушення авторських прав у додатку Lampa, вам слід зв\'язатися з розробниками додатку Lampa. Для цього ви можете скористатися контактами в додатку Lampa. Однак, важливо враховувати, що додаток Lampa використовує API від каталогу themoviedb.org, який надає відкритий доступ до інформації про фільми та серіали. Це означає, що інформація, яка відображається в додатку Lampa, є загальнодоступною та не порушує авторських прав.', + termsofuse_t_13: 'Якщо ви вважаєте, що в додатку Lampa все ж таки є контент, який порушує ваші авторські права, ви можете звернутися до правовласника цього контенту та попросити його видалити зі сторінок сайту themoviedb.org. З свого боку, додаток Lampa може видалити контент при отриманні відповідного повідомлення про порушення авторських прав.', + settings_rest_protocol_use: 'Безпечне з\'єднання', + settings_rest_protocol_descr: 'Використати протокол HTTPS', + install_app_apk_title: 'Як встановити Lampa на Android', + install_app_apk_text: 'Ми помітили, що для запуску Lampa на Android ви використовуєте MediaStationX. Ми рекомендуємо вам встановити Lampa як APK-додатки. Це забезпечить більш стабільну роботу та доступ до всіх функцій програми.

    Перейдіть до групи у Телеграмі, щоб скачати останню версію APK та інструкції з встановлення.', + install_app_apk_qr: 'Відскануйте QR-код, щоб скачати Lampa APK', + copy_link_buffer: 'Скопіювати посилання', + + tv_status_returning_series: 'Онгоїнг', + tv_status_planned: 'Заплановано', + tv_status_in_production: 'У виробництві', + tv_status_ended: 'Завершено', + tv_status_canceled: 'Скасовано', + tv_status_pilot: 'Пілотний', + + tv_status_released: 'Випущено', + tv_status_rumored: 'За чутками', + tv_status_post_production: 'Незабаром', + full_keywords: 'Теги', + title_last_year: 'Минулий рік', + + title_reset: 'Перезавантажити', + back_to_card: 'Повернутись до картки', + + premiere_author_recomend_1: 'Замовте піцу та підготуйтеся до драйву.', + premiere_author_recomend_2: 'Вечірка тільки починається.', + premiere_author_recomend_3: 'Підготуйтесь до адреналіну.', + premiere_author_recomend_4: 'Готові до незабутнього вечора?', + premiere_author_recomend_5: 'Я рекомендую його подивитися.', + premiere_title: 'Прем\'єра', + + settings_clear_cache_only: 'Кеш очищено', + settings_rest_cache_only: 'Лише кеш', + settings_rest_cache_only_descr: 'Базові налаштування залишаться', + settings_rest_cache_all: 'Кеш та дані', + settings_rest_cache_all_descr: 'Будуть очищені всі налаштування та дані', + settings_rest_cache_calculate: 'Скільки залишилося пам\'яті', + + title_left:'Залишилось', + + account_export_fail_500: 'Невідома помилка', + account_export_fail_610: 'Ви вичерпали ліміт на сьогодні', + account_export_fail_200: 'Помилка бази даних, спробуйте пізніше', + account_export_fail_600: 'Помилка, не вдалося завантажити файл', + account_export_fail_620: 'Помилка, файл не передано', + + title_parental_control: 'Батьківський контроль', + settings_parental_control_param_time_always: 'Завжди', + settings_parental_control_param_time_once: 'Одного разу', + settings_parental_control_param_time_10: 'Через 10 хвилин', + settings_parental_control_param_time_20: 'Через 20 хвилин', + settings_parental_control_param_time_30: 'Через 30 хвилин', + settings_parental_control_param_time_60: 'Через 1 годину', + settings_parental_control_param_time_120: 'Через 2 години', + settings_parental_control_change_pin: 'Змінити PIN-код', + settings_parental_control_demand_title: 'Коли запитувати', + settings_parental_control_demand_descr: 'Через який час запитувати PIN-код', + settings_parental_control_enabled: 'Увімкнено', + settings_parental_control_disabled: 'Вимкнено', + parental_control_input_new_code: 'Введіть новий PIN-код', + parental_control_confirm_new_code: 'Повторіть PIN-код', + parental_control_no_match_code: 'PIN-код не збігається з попереднім кодом', + parental_control_input_code: 'Введіть PIN-код', + parental_control_input_error: 'Ви ввели неправильний PIN-код', + title_worth_rewatch: 'Варто переглянути', + + ad_disable: 'Підписавшись на CUB Premium, ви забудете про рекламу.', + ad_after: 'Реклама через', + ad: 'Реклама', + ad_skip: 'Пропустити', + ad_continue_after: 'Перегляд розпочнеться через', + settings_parser_prowlarr_link_descr: 'Вкажіть посилання на сервер Prowlarr', + settings_parser_prowlarr_key_descr: 'Знаходиться у вкладці налаштувань Prowlarr у категорії основне', + settings_player_torrent_type: 'Тип плеєра для торентів', + settings_player_torrent_type_descr: 'Яким плеєром відтворювати торренти', + + full_crew: 'Ще', + full_editing: 'Редагування', + full_creator: 'Творець', + player_normalization_step_none: 'Нульова', + + settings_cub_backup_export_descr: 'Зберегти налаштування у хмару', + settings_cub_backup_import_descr: 'Відновити налаштування з хмари', + + settings_interface_sound: 'Системні звуки', + settings_interface_sound_play: 'Переходи', + settings_interface_sound_level: 'Рівень гучності', + settings_interface_advanced_animation: 'Просунута анімація', + + discuss_rules_title: 'Дотримуйтесь правил і поважайте інших — створюємо комфорт разом!', + discuss_rules_rule_1: 'Не використовуйте слова, що складаються тільки з цифр.', + discuss_rules_rule_2: 'Пишіть однією мовою, використовуйте слова з 5 і більше літер.', + discuss_rules_rule_3: 'Використовуйте розділові знаки і завершуйте речення крапками.', + discuss_rules_rule_4: 'Уникайте незрозумілих символів !?#%', + discuss_rules_rule_5: 'Пишіть повні речення, використовуйте речення з 5 і більше слів.', + discuss_rules_rule_6: 'Не використовуйте занадто довгі слова.', + discuss_rules_rule_7: 'Намагайтеся вкластися в 300 символів.', + discuss_voited: 'Дякую за вашу оцінку! Ваш голос допомагає покращувати контент.', + + confirm_open_player: 'Інший пристрій запитує доступ до програвача. Бажаєте відтворити відео?', + + pincode_use_remote: 'Використовуйте пульт для введення коду, натискаючи стрілки, щоб вибрати потрібну цифру.', + pincode_use_toggle: 'Натисніть та утримуйте кнопку OK, щоб змінити розкладку.', + + settings_parental_control_where: 'Де запитати PIN-код', + title_fire: 'Вогонь!', + title_top_100: 'Топ 100', + + player_normalization_type_title: 'Тип нормалізації', + player_normalization_type_all: 'Усі', + player_normalization_type_up: 'Тільки підвищення', + player_normalization_type_down: 'Тільки зниження', + storage_quota_exceeded: 'Перевищено ліміт сховища. Очистіть кеш і спробуйте ще раз.', + settings_cub_domain: 'Основний домен', + + title_ai_assistant: 'AI-асистент', + title_facts: 'Цікаві факти', + ai_search_start_typing: 'Запитайте у AI-асистента, які фільми ви хочете знайти. Наприклад: "Фільми про космос"', + ai_search_limit: 'Ліміт запитів перевищено. Спробуйте повторити запит пізніше. З підпискою CUB Premium ліміти будуть збільшені, і вам не доведеться чекати!', + ai_subscribe_title: 'Відкрийте більше можливостей з AI', + ai_subscribe_descr: 'Оформіть підписку CUB Premium та збільшіть кількість запитів до AI. Разом з AI ми підберемо для вас найкращі фільми, які тільки зможемо.', + + dmca_title: 'Контент заблоковано', + dmca_descr: 'Цей матеріал недоступний для перегляду. Він був заблокований на прохання правовласника відповідно до законодавства про авторські права.', + + loading_progress_step_0: 'Підготовка', + loading_progress_step_1: 'Завантаження мов', + loading_progress_step_2: 'Пошук дзеркал', + loading_progress_step_3: 'Підготовка розширень', + loading_progress_step_4: 'Майже готово', + loading_progress_step_5: 'Вже скоро', + + install_extension_rule_1: 'Встановлення стороннього плагіна', + install_extension_rule_2: 'Плагіни створюються незалежними розробниками, і LAMPA не перевіряє їхній вміст. Встановлюючи їх, ви погоджуєтеся з тим, що:', + install_extension_rule_3: '- Деякі плагіни можуть запитувати доступ до ваших даних або працювати з неперевіреними джерелами.', + install_extension_rule_4: '- Якщо встановлений вами плагін порушує авторські права або інші закони, уся відповідальність за його використання лежить на вас.', + install_extension_rule_5: '- Встановлюйте лише плагіни з довірених джерел. Якщо ви сумніваєтеся у безпеці або законності плагіна, краще відмовтеся від його встановлення.', + install_extension_rule_6: 'LAMPA не підтримує і не схвалює плагіни, пов’язані з піратським контентом.', + install_extension_rule_7: 'Продовжуючи, ви підтверджуєте, що розумієте ці ризики.', + ad_plugin: 'Реклама від плагіна', + + terminal_title: 'Термінал', + terminal_no_access: 'Без доступу', + terminal_confirm: 'Дозволити', + terminal_deny: 'Заборонити', + terminal_update: 'Оновити', + terminal_code: 'Код доступу', + terminal_text: 'Ви запитуєте доступ до терміналу. Розробники можуть отримати доступ до вашого пристрою та керувати ним. Це може бути корисно для діагностики та усунення проблем, але також може становити ризик безпеки. Будь ласка, переконайтеся, що ви довіряєте розробникам, перш ніж надавати доступ.

    Ви можете будь-коли вимкнути цю функцію, натиснувши кнопку "Заборонити".', + + title_anons: 'Анонс', + title_developer: 'Розробник', + title_navigation: 'Навігація', + title_page: 'Сторінка', + title_person_about: 'Про актора', + account_qr_premium: 'Скануйте QR-код, щоб дізнатися більше про CUB Premium', + account_qr_code: 'Скануйте QR-код, щоб отримати код для прив’язки пристрою', + account_qr_create: 'Скануйте QR-код, щоб створити обліковий запис', + account_add_device_title: 'Додати пристрій', + account_add_device_text: 'Перейдіть на , щоб отримати код для додавання пристрою.', + account_none_title: 'Ще не маєте облікового запису?', + account_none_include_1: 'Закладки та історія переглядів зберігаються у хмарі', + account_none_include_2: 'Синхронізація між пристроями', + account_none_include_3: 'Сповіщення про нові серії та релізи', + account_none_include_4: 'Створюйте кілька профілів в одному обліковому записі', + account_premium_include_1: 'Збільшена кількість закладок', + account_premium_include_2: 'Розширена історія переглядів', + account_premium_include_3: 'Більше таймкодів доступно', + account_premium_include_4: 'Кількість профілів на один обліковий запис', + empty_subscribes_title: 'Ваші підписки на переклади', + empty_subscribes_text: 'Просто підпишіться на улюблений переклад, і ми повідомимо вас, коли вийде нова серія.', + empty_history_title: 'Ваша історія переглядів', + empty_history_text: 'Ваша історія переглядів з’явиться тут.', + empty_bookmark_title: 'Ваші улюблені', + empty_bookmark_text: 'Додавайте фільми та серіали, які вам подобаються, до улюблених, щоб швидко знаходити їх у цьому розділі.', + empty_mytorrents_title: 'Ваші торенти', + empty_mytorrents_text: 'Торенти, завантажені через TorServer, з’являться тут.', + developer_param_enabled: 'Режим розробника', + developer_param_nopremium: 'Вимкнути CUB Premium', + developer_param_nodemo: 'Вимкнути демо-режим', + developer_param_ads: 'Показувати рекламу', + developer_param_fps: 'Показувати FPS', + developer_trigger_help_1: 'Майже вгадали :)', + developer_trigger_help_2: 'Ще трохи :)', + developer_trigger_help_3: 'Ви впевнені, що хочете увійти в режим розробника?', + developer_trigger_help_4: 'Режим розробника активовано', + settings_param_navigation_touch: 'Сенсор', + account_discuss_add_qr: 'Скануйте QR-код', + account_discuss_add_title: 'Хочете залишити коментар?', + account_discuss_add_text: 'Скануйте QR-код, щоб перейти до застосунку та залишити коментар до цього фільму чи серіалу.

    - Візьміть телефон або планшет
    - Відкрийте камеру
    - Наведіть на QR-код
    - Перейдіть за посиланням, що з’явиться на екрані', + account_discuss_added: 'Дякуємо за ваш коментар!', + account_discuss_added_ready: 'Ви вже залишали коментар до цього фільму чи серіалу.', + remote_helper_long: 'Утримуйте кнопку (OK), щоб відкрити меню', + account_premium: 'Відкрийте нові горизонти з обліковим записом CUB Premium! Насолоджуйтесь збільшеними лімітами та розширеними можливостями сервісу. Відвідайте , щоб дізнатися більше про переваги преміум-акаунта.', + player_segments_title: 'Сегменти', + player_segments_descr: 'Пропуск вступу та інших частин відео', + player_segments_ad_title: 'Реклама', + player_segments_skip_title: 'Вступ та інше', + player_segments_value_none: 'Не пропускати', + player_segments_value_auto: 'Автоматично пропускати', + player_segments_value_user: 'Користувацький', + player_segments_skiped: 'Сегмент пропущено', + player_segments_skip_now: 'Пропустити', + player_segments_skip_in: 'Пропуск через', + player_segments_skip_intro: 'Пропустити заставку', + player_segments_next: 'Наступна серія', + player_segments_next_in: 'Наступна серія через', + subscribe_info: 'У розділі «Підписки» ви побачите всі свої підписки на переклади. Ви отримаєте сповіщення, коли вийде нова серія з вибраним перекладом.', + no_watch_history: 'Немає історії перегляду', + + settings_request_caching_use: 'Кешування запитів', + settings_request_caching_descr: 'Зберігати відповіді на запити для прискорення роботи додатку', + + account_profile_child: 'Дитячий', + account_profile_add: 'Додати профіль', + account_profile_name: 'Ім\'я профілю', + account_profile_created: 'Профіль успішно створено', + account_profile_limited: 'Досягнуто максимальний ліміт профілів: {count}', + account_profile_info: 'Ви можете керувати профілями в налаштуваннях облікового запису, для цього перейдіть на сайт ', + player_youtube_no_support: 'Ваш пристрій не підтримує відтворення відео з YouTube, перевірте інтернет-з’єднання.', + title_channels: 'Канали', + title_in_high_quality: 'У високій якості', + title_best_of_2000: 'Золоті 2000-ті', + title_best_of_2010: 'Хіти 2010-х', + title_best_of_2015: 'Сучасна класика', + title_comedy_of_2000: 'Сміх 2000-х', + title_comedy_of_2010: 'Гумор 2010-х', + title_comedy_of_2015: 'Сучасні комедії', + + filter_keyword_sequel: 'Сіквел', + filter_keyword_based_comic: 'За коміксами', + filter_keyword_space: 'Космос', + filter_keyword_survival: 'Виживання', + filter_keyword_zombie: 'Зомбі', + filter_keyword_school: 'Школа', + filter_keyword_revenge: 'Помста', + filter_keyword_detective: 'Детектив', + filter_keyword_robots: 'Роботи', + filter_keyword_vampires: 'Вампіри', + filter_keyword_aliens: 'Інопланетяни', + filter_keyword_police: 'Поліція', + filter_keyword_reincarnation: 'Переродження', + filter_keyword_spy: 'Шпигун', + filter_keyword_disaster: 'Катастрофа', + filter_keyword_christmas: 'Різдво', + + dmca_title_lgbt: 'Контент обмежений', + dmca_descr_lgbt: 'Перегляд недоступний у вашому регіоні, оскільки, можливо, містить ЛГБТ-контент. У деяких країнах такі матеріали можуть бути заборонені або обмежені.', + + settings_lgbt_content_block: 'Блокувати ЛГБТ контент', + + // todo: + adult_content_title: 'Контент для дорослих', + adult_content_text_warning: 'Контент може містити матеріали для дорослих, які можуть бути неприйнятними для деяких глядачів.', + adult_content_text_modal: 'Цей фільм або серіал позначений як такий, що містить контент для дорослих. Для перегляду цього матеріалу вам має бути 18 років або більше. Будь ласка, підтвердіть, що ви досягли повноліття, щоб продовжити перегляд.', + + adult_content_confirm: 'Мені 18 років або більше', + adult_content_deny: 'Мені менше 18 років', + + inner_player_disclaimer_title: 'Дисклеймер плеєра', + inner_player_disclaimer_text: 'Я розумію, що запускаю плеєр, який має не повну підтримку, також розумію, що це може призводити до нетипової поведінки на пристрої. Оптимально перейти на плеєри сімейства tvOS або інші альтернативи.', + + inner_player_disclaimer_change_player: 'Змінити плеєр', + remote_configuration_settings_title: 'Віддалена конфігурація', + remote_configuration_registration_text: 'Віддалена конфігурація надає тимчасовий доступ до вашого додатку, інший додаток зможе встановлювати розширення та налаштовувати параметри.', + remote_configuration_waite_text: 'Тепер ви можете передати цей код іншому додатку, щоб надати доступ до налаштувань.', + remote_configuration_open_button: 'Відкрити доступ', + remote_configuration_code_life: 'Код дійсний', + remote_configuration_notice_nocode: 'Не вдалося відкрити доступ', + + settings_server_gts: 'Перекодування', + settings_server_gts_descr: 'Автоматично конвертувати відео у сумісний формат за потреби.', + settings_server_tracktimecode: 'Увімкнути TrackTimecode', + settings_server_tracktimecode_descr: 'Зберігає прогрес відтворення фільмів і серіалів на сервері TorrServer. Для роботи цю опцію також необхідно увімкнути в TorrServer.', + + title_metadata: 'Метадані', + title_moods: 'Настрої', + title_meta_violence: 'Насильство', + title_meta_fear: 'Страх', + title_meta_profanity: 'Лексика', + title_meta_sadness: 'Смуток', + title_meta_sex: 'Сексуальність', + player_pip: 'Зменшити', + player_volume: 'Гучність', + player_time_end: 'Кінець о', + player_ai_agent_info: 'Хочете дізнатися більше про відео? Запитайте AI-асистента, і він надасть вам графік настроїв, короткий сюжет та цікаві моменти.', + player_ai_agent_ask_plot: 'Коротко про сюжет', + player_ai_agent_ask_moods: 'Показати графік', + player_ai_agent_ask_highlights: 'Цікаві моменти', + player_ai_agent_ask: 'Запитати', + player_ai_agent_processing: 'Аналізую...', + player_ai_agent_no_data: 'Немає даних для показу.', + player_ai_agent_no_analysis: 'Не вдалося провести аналіз відео.', + player_ai_agent_quota: 'Ліміт запитів перевищено. Спробуйте повторити запит пізніше.', + player_ai_agent_working: 'Я ще працюю над цим...', + title_meta_humor: 'Гумор', + title_meta_tension: 'Напруга', + title_meta_romance: 'Романтика', + title_meta_pace: 'Темп', + title_meta_importance: 'Важливі сцени', + title_meta_action: 'Екшн' +} diff --git a/lampa-main/lang/zh.js b/lampa-main/lang/zh.js new file mode 100644 index 0000000..016e35a --- /dev/null +++ b/lampa-main/lang/zh.js @@ -0,0 +1,1313 @@ +export default { + lang_choice_title: '欢迎', + lang_choice_subtitle: '选择你的语言', + close_app_modal: '您确定要离开该应用程序吗?', + connected_seeds: '连接的', + back: '后退', + more: '更多', + ready: '准备好', + show_more: '显示更多', + more_results: '显示更多结果', + loading: '加载中', + nofind_movie: '找不到电影。', + noname: '无标题', + nochoice: '未选择', + cancel: '取消', + confirm: '我确认', + sure: '你确定吗?', + nodata: '无数据', + search: '搜索', + search_input: '输入文本', + search_empty: '搜索历史为空。', + search_delete: '左 - 删除', + search_start_typing: '开始输入搜索文本。', + search_searching: '搜索中...', + search_start: '开始搜索', + search_nofound: '根据您的要求没有找到相关内容。', + global_search: '全局搜索', + full_genre: '类型', + full_production: '出品公司', + full_date_of_release: '发布日期', + full_budget: '预算', + full_countries: '国家', + full_like: '喜欢', + full_torrents: '种子', + full_trailers: '预告片', + full_detail: '详细', + full_notext: '无描述。', + full_series_release: '系列发布', + full_next_episode: '下一集', + full_episode_days_left: '剩余天数', + full_trailer_official: '官方', + full_trailer_no_official: '非正式', + full_season: '季', + full_episode: '剧集', + full_directing: '导演', + settings_cub_sync: '同步', + settings_cub_sync_descr: '与 CUB 服务同步:同步您的书签、浏览历史、标签和时间码。', + settings_cub_account: '帐户', + settings_cub_logged_in_as: '登录身份', + settings_cub_profile: '个人资料', + settings_cub_sync_btn: '同步', + settings_cub_sync_btn_descr: '将本地书签保存到 CUB 帐户', + settings_cub_backup: '备份', + settings_cub_backup_descr: '保存或加载备份数据', + settings_cub_logout: '注销', + settings_cub_signin: '授权', + settings_cub_not_specified: '未指定', + settings_cub_password: '密码', + settings_cub_status: '状态', + settings_cub_backup_import: '导入', + settings_cub_backup_export: '导出', + settings_cub_sync_filters: '筛选同步', + settings_cub_sync_calendar: '日历同步', + settings_cub_sync_quality: '标记同步(质量)', + settings_cub_sync_search: '检索历史同步', + settings_cub_sync_recomends: '推荐同步', + settings_cub_sync_timecodes: '时间码同步', + settings_input_links: '收藏夹', + settings_interface_type: '精简版', + settings_interface_size: '界面大小', + settings_interface_menu_always: 'Always show the left menu', + settings_interface_background: '背景', + settings_interface_background_use: '显示背景', + settings_interface_background_type: '背景类型', + settings_interface_performance: '性能', + settings_interface_animation: '动画', + settings_interface_animation_descr: '卡片和内容的动画', + settings_interface_attenuation: '淡入淡出', + settings_interface_attenuation_descr: '从下方和上方平滑淡入卡片', + settings_interface_scroll: '滚动类型', + settings_interface_view_card: '卡片视图类型', + settings_interface_view_card_descr: '当您滚动时,卡片将逐渐加载或全部加载', + settings_interface_lang: '界面语言', + settings_interface_lang_reload: '需要重启应用,点击“确定”重启。', + settings_main_account: '帐户', + settings_main_interface: '界面', + settings_main_player: '播放器', + settings_main_parser: '解析器', + settings_main_torrserver: 'TorrServer', + settings_main_plugins: '扩展', + settings_main_rest: '其他', + settings_rest_start: '起始页', + settings_rest_start_descr: '启动时要启动的页面', + settings_rest_source: '源', + settings_rest_source_use: '主要来源', + settings_rest_source_descr: '从何处获取有关电影的信息', + settings_rest_tmdb_lang: '从 TMDB 显示数据的语言', + settings_rest_tmdb_prox: '代理 TMDB', + settings_rest_tmdb_prox_auto: '自动启用代理', + settings_rest_tmdb_posters: 'TMDB 海报的分辨率', + settings_rest_screensaver: '屏幕保护程序', + settings_rest_screensaver_use: '空闲时启动屏保', + settings_rest_screensaver_type: '屏幕保护类型', + settings_rest_helper: '提示', + settings_rest_helper_use: '显示提示', + settings_rest_helper_reset: '再次显示提示', + settings_rest_pages: '要在内存中保留多少页', + settings_rest_pages_descr: '将页面保持在您离开它们的状态', + settings_rest_time: '移位时间', + settings_rest_navigation: '导航类型', + settings_rest_keyboard: '键盘类型', + settings_rest_device: '设备名称', + settings_rest_device_placeholder: '例如:我的Lampa', + settings_rest_cache: '清除缓存', + settings_rest_cache_descr: '所有设置和数据将被清除', + settings_rest_tmdb_example: '例如:', + settings_rest_tmdb_api_descr: '获取数据', + settings_rest_tmdb_image_descr: '获取图像', + settings_rest_card_quality: '质量标志', + settings_rest_card_quality_descr: '在卡片上显示质量标记', + settings_rest_card_episodes: '剧集标记', + settings_rest_card_episodes_descr: '在卡片上显示剧集标记', + settings_parser_use: '使用解析器', + settings_parser_use_descr: '在此,您同意接受所有使用责任用于查看 种子和在线内容的公共链接。', + settings_parser_type: '种子的解析器类型', + settings_parser_jackett_placeholder: '例如:192.168.x', + settings_parser_jackett_link: '链接', + settings_parser_jackett_link_descr: '提供Jackett脚本的链接', + settings_parser_jackett_key_placeholder: '例如:sa0sk83d..', + settings_parser_jackett_key: 'Api key', + settings_parser_jackett_key_descr: '位于Jackett', + settings_parser_torlook_type: 'TorLook网站解析方法', + settings_parser_scraperapi_placeholder: '例如:scraperapi.com', + settings_parser_scraperapi_link: '链接到站点解析器', + settings_parser_scraperapi_descr: '在网站 scraperapi.com 上注册,输入链接 api.scraperapi.com?api_key=...&url={q}
    W41.torlook.info 将发送到 {q}', + settings_parser_search: '搜索', + settings_parser_search_descr: '用什么语言搜索?', + settings_parser_in_search: '在搜索中显示种子结果', + settings_parser_in_search_descr: '显示搜索结果?', + settings_parser_timeout_title: '解析器超时', + settings_parser_timeout_descr: '等待服务器响应的时间(以秒为单位)', + settings_player_type: '播放器类型', + settings_player_type_descr: '用哪个播放器', + settings_infuse_launch_mode: 'Infuse 启动方式', + settings_infuse_launch_mode_descr: '在 Infuse 中打开视频时的操作。种子始终立即播放', + settings_infuse_launch_ask: '启动时询问', + settings_infuse_launch_play: '播放', + settings_infuse_launch_save_and_play: '保存并播放', + settings_player_iptv_type: 'IPTV播放器类型', + settings_player_iptv_type_descr: '哪个播放器播放IPTV频道', + settings_player_reset: '重置默认播放器', + settings_player_reset_descr: '重置应用程序中选定的Android播放器', + settings_player_path: '播放器路径', + settings_player_path_descr: '指定播放器.exe的路径', + settings_player_external_header: '外部播放器', + settings_player_external_fullscreen: '以全屏模式运行', + settings_player_normalization: '声音标准化', + settings_player_normalization_descr: '将声音标准化为一级,降低响亮的声音并增强安静的', + settings_player_next_episode: '下一集', + settings_player_next_episode_descr: '当前一集结束后自动切换到下一个系列', + settings_player_timecode: '时间码', + settings_player_timecode_descr: '从上次播放的位置继续', + settings_player_scale: '缩放方法', + settings_player_scale_descr: '如何计算视频缩放', + settings_player_subs: '字幕', + settings_player_subs_use: '启用', + settings_player_subs_use_descr: '开始视频后总是打开字幕', + settings_player_subs_lang: '字幕语言', + settings_player_subs_lang_descr: '有多种语言可用时自动开启哪种字幕', + settings_param_subtitles_lang_auto: '界面语言', + settings_player_subs_size: '大小', + settings_player_subs_size_descr: '字幕屏幕大小', + settings_player_subs_stroke_use: '使用边缘', + settings_player_subs_stroke_use_descr: '字幕将用黑色勾勒以提高可读性', + settings_player_subs_backdrop_use: '使用底衬', + settings_player_subs_backdrop_use_descr: '字幕将显示在半透明背景上以提高可读性', + settings_player_quality: '默认视频质量', + settings_player_quality_descr: '首选视频质量观看', + settings_player_hls_title: '处理.m3u8流媒体', + settings_player_hls_descr: '如果您不知道为什么,请不要修改此参数。', + settings_plugins_notice: '要应用插件,你需要重新启动应用程序', + settings_plugins_add: '添加插件', + settings_plugins_add_descr: '要删除添加的插件,请按住或双击其上的(确定)键', + settings_plugins_install: '安装插件', + settings_plugins_install_descr: '从可用列表中安装插件', + settings_server_link: '使用链接', + settings_server_links: '链接', + settings_server_placeholder: '例如:192.168.X', + settings_server_link_one: '主链接', + settings_server_link_one_descr: '指定TorrServer脚本的主链接', + settings_server_link_two: '额外链接', + settings_server_link_two_descr: '提供TorrServer脚本的额外链接', + settings_server_additionally: '高级', + settings_server_client: '内置客户端', + settings_server_client_descr: '使用内置的TorrServer JS客户端,否则系统启动。', + settings_server_base: '保存到数据库', + settings_server_base_descr: 'torrent 将被添加到 TorrServer 数据库', + settings_server_preload: '使用预取缓冲区', + settings_server_preload_descr: '播放前等待TorrServer的预加载缓冲区填满', + settings_server_auth: '授权', + settings_server_password_use: '密码登录', + settings_server_login: '登录', + settings_server_password: '密码', + settings_server_not_specified: '未指定', + settings_server_search_type: '搜索类型', + settings_server_search_type_descr: '在哪里搜索种子:内置 rutor、TorrServer 中的 Torznab 索引器,或两者同时使用。', + settings_param_torrserver_search_rutor: 'Rutor', + settings_param_torrserver_search_torznab: 'Torznab', + settings_param_torrserver_search_both: 'Rutor + Torznab', + torent_nohash_reasons: '原因', + torent_nohash_reason_one: 'TorServer 无法下载 torrent 文件', + torent_nohash_reason_two: '来自 TorServer 的回复', + torent_nohash_reason_three: '链接', + torent_nohash_do: '怎么办?', + torent_nohash_do_one: '检查是否正确配置了 Jackett', + torent_nohash_do_two: '私人来源可能没有提供文件的链接', + torent_nohash_do_three: '确保 Jackett 可以下载文件也是', + torent_nohash_do_four: '写信给我们的电报群组:@lampa_group', + torent_nohash_do_five: '指定哪部电影,哪个发行版,如果可能,请注明发行版的照片', + torrent_error_text: '无法连接到 TorrServer。让我们快速浏览可能的问题列表并检查所有内容。', + torrent_error_step_1: 'TorrServer 是否正在运行', + torrent_error_step_2: '动态 IP', + torrent_error_step_3: '协议和端口', + torrent_error_step_4: '防病毒阻止', + torrent_error_step_5: '检查可用性', + torrent_error_step_6: '仍然无法工作', + torrent_error_info_1: '确保您已在安装 TorrServer 的设备上启动。', + torrent_error_info_2: '一个常见的错误,带有 TorrServer 的设备的 IP 地址已更改。确保您输入的 IP 地址 - {ip} - 与安装了 TorrServer 的设备的地址匹配。', + torrent_error_info_3: '要连接到 TorrServer,地址开头必须指定协议http://,结尾指定端口:8090。确保IP地址后面有一个端口,你当前的地址是{ip}', + torrent_error_info_4: '频繁出现,杀毒或防火墙可以通过 IP 地址阻止访问,尝试禁用防病毒和防火墙。', + torrent_error_info_5: '在同一网络上的任何其他设备上,在浏览器中打开 {ip} 地址并检查 TorrServer Web 界面是否可用。', + torrent_error_info_6: '如果在所有检查后仍然出现连接错误,请尝试重新启动 TorrServer 和 Internet 适配器。', + torrent_error_info_7: '如果问题仍然存在,请使用文本写入 Telegram 组@lampa_group(Lampa 在所有检查后未连接到 TorrServer ,当前地址是{ip})', + torrent_error_start: '开始验证', + torrent_error_nomatrix: '验证Matrix版本失败', + torrent_error_made: '执行', + torrent_error_from: '片长', + torrent_error_next: '进一步', + torrent_error_complite: '要完成', + torrent_error_connect: '连接错误', + torrent_install_need: '需要 TorrServer', + torrent_install_text: 'TorrServer 是一个允许您在线查看 torrent 文件内容的应用程序。

    有关安装的更多详细信息可以在下面的电报组中找到。', + torrent_install_contact: '电报组', + torrent_item_bitrate: '比特率', + torrent_item_seeds: '种子', + torrent_item_grabs: 'Leechers', + torrent_item_mb: 'Mbps', + torrent_serial_episode: '剧集', + torrent_serial_season: '季', + torrent_serial_date: '推出', + torrent_get_magnet: '请求磁力链接', + torrent_remove_title: '删除', + torrent_remove_descr: '种子将从您的列表中删除', + torrent_parser_any_one: '任何', + torrent_parser_any_two: '任何', + torrent_parser_no_choice: '未选择', + torrent_parser_yes: '是', + torrent_parser_no: '否', + torrent_parser_quality: '质量', + torrent_parser_subs: '字幕', + torrent_parser_voice: '翻译', + torrent_parser_tracker: '跟踪器', + torrent_parser_year: '年份', + torrent_parser_season: '季', + torrent_parser_sort_by_seeders: '按种子数', + torrent_parser_sort_by_size: '按大小', + torrent_parser_sort_by_name: '按名称', + torrent_parser_sort_by_tracker: '按来源', + torrent_parser_sort_by_date: '按日期', + torrent_parser_sort_by_viewed: '已查看', + torrent_parser_voice_dubbing: '配音', + torrent_parser_voice_polyphonic: '复音', + torrent_parser_voice_two: '双声部', + torrent_parser_voice_amateur: '业余', + torrent_parser_reset: '重置筛选', + torrent_parser_empty: '获取结果失败', + torrent_parser_no_hash: '获取HASH失败,请尝试重新加载TorrServer', + torrent_parser_added_to_mytorrents: '添加到“我的种子”', + torrent_parser_add_to_mytorrents: '添加到“我的种子”', + torrent_parser_label_title: '标记', + torrent_parser_label_descr: '用旗帜标记(查看)', + torrent_parser_label_cancel_title: '取消选中', + torrent_parser_label_cancel_descr: '从分发中删除标记(已查看)', + torrent_parser_timeout: '超时', + torrent_parser_nofiles: '提取合适文件失败', + torrent_parser_set_link: '指定解析链接', + torrent_parser_request_error: '请求错误', + torrent_parser_magnet_error: '获取磁力链接失败', + torrent_parser_torlook_fallback_search_notification: 'Jackett 解析器不可用或连接设置不正确。 正在搜索 Torlook...', + torrent_parser_no_responce: '解析器没有响应请求', + about_text: '应用完全免费,使用公共链接获取有关视频、新版本、热门电影等的信息。所有可用信息仅用于教育目的,该应用程序不使用自己的服务器分发信息。', + about_channel: '我们的频道', + about_group: '组', + about_version: '版本', + about_donate: '捐赠', + title_language: '原始语言', + title_watched: '你看过', + title_settings: '设置', + title_collections: '合集', + title_company: '公司', + title_actors: '演员', + title_actor: '演员', + title_actress: '女演员', + title_person: '演员', + title_persons: '演员', + title_comments: '评论', + title_torrents: '种子', + title_trailers: '预告片', + title_watch: '观看', + title_error: '错误', + title_links: '链接', + title_choice: '选择', + title_main: '首页', + title_book: '书签', + title_like: '喜欢', + title_wath: '稍后', + title_history: '浏览历史', + title_mytorrents: '我的种子', + title_last: '最后', + title_action: '动作', + title_action_infuse: 'Infuse 操作', + title_producer: '制片人', + title_collection: '合集', + title_recomendations: '推荐', + title_similar: '类似', + title_about: '关于应用程序', + title_timetable: '日历', + title_relises: '数字版本', + title_catalog: '目录', + title_category: '类别', + title_parser: '解析器', + title_type: '类型', + title_rating: '评级', + title_country: '国家', + title_year: '年份', + title_genre: '类型', + title_filter: '筛选', + title_notice: '通知', + title_files: '文件', + title_now_watch: '正在观看', + title_latest: '最后添加', + title_continue: '继续浏览', + title_recomend_watch: '我们推荐看', + title_new_episodes: '新剧集', + title_popular: '热门', + title_popular_movie: '热门电影', + title_popular_tv: '热门电视节目', + title_new_this_year: '今年新', + title_hight_voite: '高度评价', + title_new: '新', + title_trend_day: '今日趋势', + title_trend_week: '本周趋势', + title_upcoming: '在电影院观看', + title_top_movie: '热门电影', + title_top_tv: '热门系列', + title_tv_today: '今天播出', + title_this_week: '本周', + title_in_top: '热门', + title_out: '退出', + title_out_confirm: '是的,退出', + title_continue_two: '继续', + title_choice_language: '选择一种语言', + title_subscribe: '订阅', + title_subscribes: '订阅', + title_unsubscribe: '退订', + subscribe_success: '您已成功订阅', + subscribe_error: '订阅时出错,请稍后重试', + subscribe_noinfo: '检索信息失败,请稍后重试', + company_headquarters: '总部', + company_homepage: '网站', + company_country: '国家', + country_ad: '安道尔', + country_ae: '阿联酋', + country_af: '阿富汗', + country_al: '阿尔巴尼亚', + country_am: '亚美尼亚', + country_ao: '安哥拉', + country_ar: '阿根廷', + country_at: '奥地利', + country_au: '澳大利亚', + country_aw: '阿鲁巴', + country_az: '阿塞拜疆', + country_bа: '波黑', + country_bd: '孟加拉国', + country_be: '比利时', + country_bg: '保加利亚', + country_bh: '巴林', + country_bi: '布隆迪', + country_bj: '贝宁', + country_bo: '玻利维亚', + country_br: '巴西', + country_bs: '巴哈马', + country_bt: '不丹', + country_bw: '博茨瓦纳', + country_by: '白俄罗斯', + country_ca: '加拿大', + country_ch: '瑞士', + country_cl: '智利', + country_cm: '喀麦隆', + country_cn: '中国', + country_co: '哥伦比亚', + country_cr: '哥斯达黎加', + country_cu: '古巴', + country_cv: '佛得角', + country_cy: '塞浦路斯', + country_cz: '捷克', + country_de: '德国', + country_dj: '吉布提', + country_dk: '丹麦', + country_do: '多米尼加', + country_dz: '阿尔及利亚', + country_ec: '厄瓜多尔', + country_ee: '爱沙尼亚', + country_eg: '埃及', + country_es: '西班牙', + country_et: '埃塞俄比亚', + country_fi: '芬兰', + country_fo: '法罗群岛', + country_fr: '法国', + country_ga: '加蓬', + country_gb: '英国', + country_ge: '格鲁吉亚', + country_gh: '加纳', + country_gl: '格陵兰', + country_gp: '瓜德罗普', + country_gr: '希腊', + country_gt: '危地马拉', + country_hk: '香港', + country_hr: '克罗地亚', + country_ht: '海地', + country_hu: '匈牙利', + country_id: '印度尼西亚', + country_ie: '爱尔兰', + country_il: '以色列', + country_in: '印度', + country_iq: '伊拉克', + country_ir: '伊朗', + country_is: '冰岛', + country_it: '意大利', + country_jm: '牙买加', + country_jo: '约旦', + country_jp: '日本', + country_ke: '肯尼亚', + country_kg: '吉尔吉斯斯坦', + country_kh: '柬埔寨', + country_kp: '朝鲜', + country_kr: '韩国', + country_kz: '哈萨克斯坦', + country_kw: '科威特', + country_la: '老挝', + country_lb: '黎巴嫩', + country_li: '列支敦士登', + country_lk: '斯里兰卡', + country_lr: '利比里亚', + country_lt: '立陶宛', + country_lu: '卢森堡', + country_lv: '拉脱维亚', + country_ly: '利比亚', + country_ma: '摩洛哥', + country_mc: '摩纳哥', + country_md: '摩尔多瓦', + country_me: '黑山', + country_mk: '北马其顿', + country_mm: '缅甸', + country_mn: '蒙古', + country_mo: '澳门', + country_mt: '马耳他', + country_mu: '毛里求斯', + country_mv: '马尔代夫', + country_mw: '马拉维', + country_mx: '墨西哥', + country_my: '马来西亚', + country_mz: '莫桑比克', + country_na: '纳米比亚', + country_ne: '尼日尔', + country_ng: '尼日利亚', + country_ni: '尼加拉瓜', + country_nl: '荷兰', + country_no: '挪威', + country_np: '尼泊尔', + country_nz: '新西兰', + country_om: '阿曼', + country_pa: '巴拿马', + country_pe: '秘鲁', + country_pg: '巴布亚新几内亚', + country_ph: '菲律宾', + country_pk: '巴基斯坦', + country_pl: '波兰', + country_pr: '波多黎各', + country_ps: '巴勒斯坦', + country_pt: '葡萄牙', + country_py: '巴拉圭', + country_qa: '卡塔尔', + country_ro: '罗马尼亚', + country_rs: '塞尔维亚', + country_ru: '俄罗斯', + country_rw: '卢旺达', + country_sa: '沙特阿拉伯', + country_sd: '苏丹', + country_se: '瑞典', + country_sg: '新加坡', + country_si: '斯洛文尼亚', + country_sk: '斯洛伐克', + country_sn: '塞内加尔', + country_su: '苏联', + country_sv: '萨尔瓦多', + country_sy: '叙利亚', + country_th: '泰国', + country_tj: '塔吉克斯坦', + country_tm: '土库曼斯坦', + country_tn: '突尼斯', + country_tr: '土耳其', + country_tw: '台湾', + country_tz: '坦桑尼亚', + country_ua: '乌克兰', + country_ug: '乌干达', + country_us: '美国', + country_uy: '乌拉圭', + country_uz: '乌兹别克斯坦', + country_ve: '委内瑞拉', + country_vn: '越南', + country_ws: '萨摩亚', + country_xk: '科索沃', + country_ye: '也门', + country_yu: '南斯拉夫', + country_za: '南非', + country_zm: '赞比亚', + country_zw: '津巴布韦', + filter_clarify: '优化', + filter_clarify_two: '优化搜索', + filter_set_name: '指定标题', + filter_sorted: '排序', + filter_filtred: '筛选', + filter_any: '任何', + filter_combinations: '组合', + filter_alt_names: '其他名称', + filter_rating_from: '从', + filter_rating_to: '到', + filter_genre_ac: '动作', + filter_genre_ad: '冒险', + filter_genre_mv: '卡通', + filter_genre_cm: '喜剧', + filter_genre_cr: '犯罪', + filter_genre_dc: '纪录片', + filter_genre_dr: '戏剧', + filter_genre_fm: '首页', + filter_genre_fe: '奇幻', + filter_genre_hi: '故事', + filter_genre_ho: '恐怖', + filter_genre_mu: '音乐', + filter_genre_de: '侦探', + filter_genre_md: '情节剧', + filter_genre_fa: '小说', + filter_genre_tv: '电视电影', + filter_genre_tr: '惊悚片', + filter_genre_mi: '军事', + filter_genre_ve: '西部', + filter_genre_aa: '动作与冒险', + filter_genre_ch: '儿童', + filter_genre_nw: '新闻', + filter_genre_rs: '真人秀', + filter_genre_hf: '科幻与奇幻', + filter_genre_op: '肥皂剧', + filter_genre_tc: '脱口秀', + filter_genre_mp: '战争与政治', + + filter_lang_af: '南非荷兰语', + filter_lang_ar: '阿拉伯语', + filter_lang_az: '阿塞拜疆语', + filter_lang_ba: '巴什基尔语', + filter_lang_be: '白俄罗斯语', + filter_lang_bg: '保加利亚语', + filter_lang_bn: '孟加拉语', + filter_lang_bs: '波斯尼亚语', + filter_lang_ca: '加泰罗尼亚语', + filter_lang_ce: '车臣语', + filter_lang_cs: '捷克语', + filter_lang_da: '丹麦语', + filter_lang_de: '德语', + filter_lang_el: '希腊语', + filter_lang_en: '英语', + filter_lang_es: '西班牙语', + filter_lang_et: '爱沙尼亚语', + filter_lang_fa: '波斯语', + filter_lang_fi: '芬兰语', + filter_lang_fr: '法语', + filter_lang_ga: '爱尔兰语', + filter_lang_gl: '加利西亚语', + filter_lang_gn: '瓜拉尼语', + filter_lang_he: '希伯来语', + filter_lang_hi: '印地语', + filter_lang_hr: '克罗地亚语', + filter_lang_hu: '匈牙利语', + filter_lang_hy: '亚美尼亚语', + filter_lang_id: '印度尼西亚语', + filter_lang_is: '冰岛语', + filter_lang_it: '意大利语', + filter_lang_ja: '日语', + filter_lang_ka: '格鲁吉亚语', + filter_lang_kk: '哈萨克语', + filter_lang_ko: '韩语', + filter_lang_ks: '克什米尔语', + filter_lang_ku: '库尔德语', + filter_lang_ky: '吉尔吉斯语', + filter_lang_lt: '立陶宛语', + filter_lang_lv: '拉脱维亚语', + filter_lang_mi: '毛利语', + filter_lang_mk: '马其顿语', + filter_lang_mn: '蒙古语', + filter_lang_mt: '马耳他语', + filter_lang_ne: '尼泊尔语', + filter_lang_nl: '荷兰语', + filter_lang_no: '挪威语', + filter_lang_pa: '旁遮普语', + filter_lang_pl: '波兰语', + filter_lang_ps: '普什图语', + filter_lang_pt: '葡萄牙语', + filter_lang_ro: '罗马尼亚语', + filter_lang_ru: '俄语', + filter_lang_si: '僧伽罗语', + filter_lang_sk: '斯洛伐克语', + filter_lang_sl: '斯洛文尼亚语', + filter_lang_sm: '萨摩亚语', + filter_lang_so: '索马里语', + filter_lang_sq: '阿尔巴尼亚语', + filter_lang_sr: '塞尔维亚语', + filter_lang_sv: '瑞典语', + filter_lang_sw: '斯瓦希里语', + filter_lang_ta: '泰米尔语', + filter_lang_tg: '塔吉克语', + filter_lang_th: '泰语', + filter_lang_tk: '土库曼语', + filter_lang_tr: '土耳其语', + filter_lang_tt: '鞑靼语', + filter_lang_ur: '乌尔都语', + filter_lang_uk: '乌克兰语', + filter_lang_uz: '乌兹别克语', + filter_lang_vi: '越南语', + filter_lang_yi: '意第绪语', + filter_lang_zh: '中文', + + empty_title: '空', + empty_text: '没有找到适合您的筛选,请优化您的筛选。', + empty_title_two: '此处为空', + empty_text_two: '列表当前为空。', + menu_main: '首页', + menu_movies: '电影', + menu_tv: '剧集', + menu_catalog: '目录', + menu_filter: '筛选', + menu_collections: '合集', + menu_relises: '发布', + menu_anime: '动漫', + menu_bookmark: '书签', + menu_like: '喜欢', + menu_time: '稍后', + menu_history: '历史', + menu_timeline: '日历', + menu_torrents: '种子', + menu_settings: '设置', + menu_about: '关于', + menu_console: '日志', + menu_multmovie: '卡通', + menu_multtv: '动画系列', + plugins_catalog_work: '工作插件', + plugins_catalog_work_descr: '完全在Lampa中工作的插件。', + plugins_catalog_popular: '用户中流行的插件', + plugins_catalog_popular_descr: '从未知来源安装可能导致应用程序无法正常工作。', + plugins_online: '在线查看', + plugins_check_fail: '插件功能测试失败。但这并不代表插件不起作用。重新加载应用看看插件是否在加载中。', + plugins_need_reload: '要应用插件,需要重新启动应用程序', + plugins_install: '安装', + plugins_install_ready: '这个插件已经安装了。', + plugins_installed: '安装ations', + plugins_load_from: '从CUB中加载', + plugins_ok_for_check: '点击(OK)测试插件', + plugins_no_loaded: '加载应用时,有些插件无法安装已加载', + time_viewed: '看至', + time_from: '片长', + time_reset: '重置时间码', + settings_clear_cache: '缓存和数据清除', + settings_user_links: '自定义链接', + settings_for_local: '对于本地 TorrServer', + settings_add: '添加', + settings_remove: '删除', + settings_this_value: '当前值', + settings_added: '添加', + settings_removed: '已删除', + settings_param_player_inner: 'Lampa', + settings_param_player_outside: '外部', + settings_param_player_inner_tvos: '内部的', + settings_param_yes: '是', + settings_param_no: '否', + settings_param_interface_size_small: '较小', + settings_param_interface_size_normal: '正常', + settings_param_interface_size_bigger: '更多的', + settings_param_poster_quality_low: '低', + settings_param_poster_quality_average: '中', + settings_param_poster_quality_high: '高', + settings_param_parse_directly: '直接', + settings_param_parse_api: '通过网站 API', + settings_param_background_complex: '复杂', + settings_param_background_simple: '简单', + settings_param_background_image: '图片', + settings_param_link_use_one: '主要', + settings_param_link_use_two: '额外', + settings_param_link_use_both: '两者', + settings_param_subtitles_size_small: '小', + settings_param_subtitles_size_normal: '普通', + settings_param_subtitles_size_bigger: '大', + settings_param_screensaver_nature: '自然', + settings_param_torrent_lang_orig: '原始', + settings_param_torrent_lang_ru: '俄语', + settings_param_player_timecode_again: '重新开始', + settings_param_player_timecode_continue: '继续', + settings_param_player_timecode_ask: '询问', + settings_param_player_scale_method: '计算', + settings_param_player_hls_app: 'Systemic', + settings_param_player_hls_js: 'Program', + settings_param_card_view_load: '预加载', + settings_param_card_view_all: '显示全部', + settings_param_navigation_remote: '遥控器', + settings_param_navigation_mouse: '用鼠标遥控', + settings_param_keyboard_lampa: 'Lampa', + settings_param_keyboard_system: '系统', + helper_keyboard: '输入数值后按"返回"键保存', + helper_torrents: '按住(OK)键调出上下文菜单', + helper_cleared: '成功,将再次显示工具提示。', + helper_torrents_view: '按住(OK)键重置时间码并显示菜单', + fav_sync_title: '书签同步', + fav_sync_text: '您最喜欢的书签。连接同步并在任何设备上查看。

    为此,请在网站 {site} 上注册,创建个人资料并登录应用程序.', + fav_sync_site: '网站', + fav_remove_title: '从历史记录中删除', + fav_remove_descr: '删除所选卡片', + fav_clear_title: '清除历史记录', + fav_clear_descr: '从历史记录中删除所有卡片', + fav_clear_label_title: '清除标签', + fav_clear_label_descr: '清除查看标签', + fav_clear_time_title: '清除时间码', + fav_clear_time_descr: '清除所有时间码', + fav_label_cleared: '清除标记', + fav_time_cleared: '清除时间码', + timetable_empty: '此部分将显示新剧集的发布日期。', + player_quality: '质量', + player_flow: '流动', + player_tracks: '音轨', + player_disabled: '已禁用', + player_unknown: '未知', + player_subs: '字幕', + player_size_default_title: '默认', + player_size_default_descr: '默认视频大小', + player_size_cover_title: '扩展', + player_size_cover_descr: '将视频扩展到全屏', + player_size_fill_title: '填充', + player_size_fill_descr: '使视频适合全屏', + player_size_s115_title: '缩放 115%', + player_size_s115_descr: '将视频放大 115%', + player_size_s130_title: '缩放 130%', + player_size_s130_descr: '将视频放大 130%', + player_size_v115_title: '垂直 115%', + player_size_v115_descr: '放大视频 115%', + player_size_v130_title: '垂直 130%', + player_size_v130_descr: '将视频放大 130%', + player_video_size: '视频大小', + player_playlist: '播放列表', + player_error_one: '视频解码失败', + player_error_two: '视频未找到或损坏', + player_start_from: '继续浏览', + player_not_found: '找不到播放器', + player_lauch: '启动播放器', + player_speed_default_title: '普通', + player_speed_two_descr: '无声播放', + player_video_speed: '播放速度', + player_share_title: '分享', + player_share_descr: '在另一台设备上播放此视频', + player_normalization_power_title: '标准化功率', + player_normalization_smooth_title: '标准化速度', + player_normalization_step_low: '低的', + player_normalization_step_medium: '平均', + player_normalization_step_hight: '高', + player_youtube_no_played: '抱歉,该视频在您所在的地区不可用,可能已被屏蔽或删除。', + player_youtube_start_play: '要开始播放视频,请单击“播放”按钮', + broadcast_open: '在另一台设备上打开卡片', + broadcast_play: '选择要观看的设备', + card_new_episode: '新系列', + card_book_remove: '从书签中删除', + card_book_add: '到书签', + card_book_descr: '查看菜单(书签)', + card_like_remove: '从收藏夹中删除', + card_like_add: '喜欢', + card_like_descr: '查看菜单(喜欢)', + card_wath_remove: '从预期中删除', + card_wath_add: '稍后观看', + card_wath_descr: '查看菜单(稍后)', + card_history_remove: '从历史记录中删除', + card_history_add: '走进历史', + card_history_descr: '查看在菜单(历史)中', + keyboard_listen: '说话,我在听...', + keyboard_nomic: '没有麦克风访问权限', + notice_new_quality: '新质量可用', + notice_quality: '质量', + notice_new_episode: '新系列', + notice_none: '您还没有任何通知,请在 {site} 注册关注新剧集和发布。', + notice_in_quality: 'As', + notice_none_account: '你还没有任何通知,收藏该系列并等待新剧集的通知。', + notice_none_system: '您目前没有任何通知。 当有新通知可用时,我们一定会通知您。', + copy_link: '复制视频链接', + copy_secuses: '链接复制到剪贴板', + copy_error: '复制链接时出错', + account_sync_to_profile: '所有书签将被移动到个人资料', + account_sync_secuses: '所有书签已成功转移', + account_profiles: '个人资料', + account_profiles_empty: '无法获取个人资料列表', + account_authorized: '已授权', + account_logged_in: '您已登录', + account_login_failed: '登录失败', + account_login_wait: '等待登录', + account_profile_main: '常规', + account_export_secuses: '导出成功', + account_export_fail: '导出错误', + account_import_secuses: '导入成功', + account_import_fail: '导入错误', + account_imported: '导入', + account_reload_after: '5 秒后重启', + account_create: '使用 CUB 帐户发现更多机会。 在 注册并获得同步您的书签、时间码和其他 CUB 帐户功能的权限。', + account_premium: '使用 CUB Premium 账户开启新视野!享受更高的限额和更强大的服务功能。访问 了解更多高级账户的权益。', + account_premium_more: '了解有关 CUB 高级版的更多信息', + + account_code_enter: '请输入六位验证码', + account_code_error: '可能您输入了错误或已过期的验证码', + account_code_wrong: '可能您输入了错误的格式', + account_code_where: '请前往网站,并输入该网站上提供的验证码。', + account_code_input: '输入验证码', + settings_cub_signin_button: '登录', + + account_limited: '您已达到最大限制。 使用 CUB Premium 帐户提高限制。 在 了解更多信息', + network_noconnect: '没有网络连接', + network_404: '未找到请求的页面。[404]', + network_401: '授权失败', + network_500: '内部服务器错误。[500]', + network_parsererror: '请求的 JSON 解析失败。', + network_timeout: '请求超时。', + network_abort: '请求已中止。', + network_error: '未知错误', + size_zero: '0 字节', + size_byte: '字节', + size_kb: 'KB', + size_mb: 'MB', + size_gb: 'GB', + size_tb: 'TB', + size_pp: 'PB', + speed_bit: 'bps', + speed_kb: 'Kbps', + speed_mb: 'Mbps', + speed_gb: 'Gbps', + speed_tb: 'Tbps', + speed_pp: 'Pbps', + month_1: '一月', + month_2: '二月', + month_3: '三月', + month_4: '四月', + month_5: '五月', + month_6: '六月', + month_7: '七月', + month_8: '八月', + month_9: '九月', + month_10: '十月', + month_11: '十一月', + month_12: '十二月', + day_1: '星期一', + day_2: '星期二', + day_3: '星期三', + day_4: '星期四', + day_5: '星期五', + day_6: '星期六', + day_7: '星期日', + month_1_e: '一月', + month_2_e: '二月', + month_3_e: '三月', + month_4_e: '四月', + month_5_e: '五月', + month_6_e: '六月', + month_7_e: '七月', + month_8_e: '八月', + month_9_e: '九月', + month_10_e: '十月', + month_11_e: '十一月', + month_12_e: '十二月', + week_1: '星期一', + week_2: '星期二', + week_3: '星期三', + week_4: '星期四', + week_5: '星期五', + week_6: '星期六', + week_7: '星期天', + extensions_enable: '启用', + extensions_disable: '禁用', + extensions_check: '检查状态', + extensions_install: '安装', + extensions_info: '关于', + extensions_edit: '编辑', + extensions_change_name: '更改名称', + extensions_change_link: '更改链接', + extensions_remove: '删除', + extensions_set_name: '输入插件名称', + extensions_set_url: '输入插件网址', + extensions_ready: '此插件已安装', + extensions_no_info: '无信息', + extensions_no_name: '无标题', + extensions_worked: '工作中', + extensions_no_plugin: '插件未验证', + extensions_add: '添加插件', + extensions_from_memory: '安装在内存中', + extensions_from_cub: '从 CUB 安装', + extensions_from_popular: '流行插件', + extensions_from_lib: '插件库', + extensions_from_connected: '已连接插件', + + settings_webos_launcher: '应用程序启动', + settings_webos_launcher_add_device: '设置为开始', + settings_webos_launcher_remove_device: '从入门应用程序中删除', + player_normalization: '正常化', + change_source_on_cub: '将源更改为 CUB', + settings_param_jackett_interview_all: '全部', + settings_param_jackett_interview_healthy: '仅提供', + settings_parser_jackett_interview: '投票跟踪器', + title_ongoing: '进行中', + title_pgrating: '年龄限制', + + settings_interface_card_interfice: '卡片界面', + settings_interface_card_poster: '展示海报', + title_card: '卡片', + settings_param_card_interface_old: '老界面', + settings_param_card_interface_new: '新界面', + title_seasons: '季', + title_episodes: '集', + title_rewiews: '评论', + settings_interface_glass: '玻璃', + settings_interface_glass_descr: '以玻璃风格显示界面', + settings_interface_black_style: '黑色风格', + + plugins_remove: '删除插件', + plugins_add_success: '插件连接成功', + settings_reset: '重置', + title_channel: '渠道', + + input_detection_touch: '想切换到触摸控制?', + input_detection_mouse: '想切换到鼠标控制?', + input_detection_remote: '想切换到遥控器控制?', + + settings_interface_hide_outside_the_screen: '在屏幕外隐藏卡片', + settings_interface_hide_outside_the_screen_descr: '这将加快 UI 渲染并提高性能。', + + https_text: '您使用的是 HTTPS 协议,在此协议下灯无法正常工作。 为了灯的正确操作,请使用具有 HTTP 协议的地址', + + extensions_hpu_best: '受欢迎的', + extensions_hpu_recomend: '受到推崇的', + extensions_hpu_theme: '主题', + extensions_hpu_screensaver: '屏幕保护程序', + extensions_hpu_video: '视频', + extensions_hpu_control: '控制', + extensions_hpu_other: '各种各样的', + extensions_hpu_: '休息', + + title_author: '作者', + + title_buffer: '缓冲', + settings_rest_screensaver_time: '多少分钟后启动屏保', + + time_h: 'h.', + time_m: 'm.', + time_s: 's.', + + settings_param_glass_easy: '透明的', + settings_param_glass_medium: '半透明', + settings_param_glass_blacked: '黑屏了', + + settings_interface_glass_opacity: '玻璃透明度', + torrent_error_check_no_auth: '服务器响应请求,但授权失败。', + settings_interface_card_cover: '显示封面', + + title_upcoming_episodes: '即将发布的剧集', + title_recent_episodes: '最近发布的剧集', + settings_rest_cache_images: '图片缓存', + settings_rest_cache_images_descr: '将海报和背景缓存到本地存储', + + settings_player_rewind_title: '倒带', + settings_player_rewind_descr: '以秒为单位的倒带间隔', + + settings_interface_card_reactions: '显示反应', + title_look: '正在观看', + title_scheduled: '计划', + title_viewed: '已查看', + title_thrown: '丢弃', + title_reactions: '反馈', + reactions_none: '无反馈', + reactions_fire: '棒极了', + reactions_nice: '不错', + reactions_think: '值得一看', + reactions_bore: '无聊', + reactions_shit: '糟糕', + reactions_ready: '您已经留下了反馈', + settings_player_launch_trailers: '预告片播放器', + title_continued: '待续', + title_language_short: '语言', + + speedtest_connect: '连接', + speedtest_test: '测试', + speedtest_ready: '准备就绪', + speedtest_button: '测试速度', + + termsofuse_t_01: '使用条款', + termsofuse_t_02: 'Lampa是一个方便的工具,用于了解电影行业的最新动态,包括电影、电视剧、动画片和其他信息。获取电影信息使用的是一个开放的来源- themoviedb.org 网站。', + termsofuse_t_03: '内容', + termsofuse_t_04: 'Lampa使用themoviedb.org目录的API(应用程序编程接口)来获取有关电影和电视剧的信息,并查看与其相关的媒体文件,如海报、预告片等。', + termsofuse_t_05: 'themoviedb.org的API允许Lampa应用程序访问电影和电视剧的数据库,提供搜索和查看媒体文件信息的功能。', + termsofuse_t_06: 'Lampa应用程序与themoviedb.org之间的交互是通过API请求进行的,这些请求从Lampa应用程序发送到themoviedb.org服务器以获取信息和媒体文件。themoviedb.org处理请求并将请求的数据发送回Lampa应用程序。', + termsofuse_t_07: '因此,通过使用themoviedb.org的API,Lampa应用程序为用户提供了访问广泛的电影和电视剧数据库的能力,并遵守权利持有人设定的使用条款和限制。', + termsofuse_t_08: '扩展', + termsofuse_t_09: '扩展是为Lampa应用程序提供的强大工具,允许用户扩展其功能,添加附加功能,并根据其需求修改内容。', + termsofuse_t_10: '然而,值得注意的是,用户自行承担安装扩展的风险。使用扩展带来的所有后果由用户承担。建议用户在安装和使用扩展时要谨慎,仔细评估其可靠性和安全性。', + termsofuse_t_11: '侵犯版权', + termsofuse_t_12: '如果您在Lampa应用程序中发现任何侵犯版权的行为,您应该联系Lampa应用程序的开发人员。您可以使用Lampa应用程序中提供的联系方式进行联系。然而,重要的是要注意,Lampa应用程序使用的是themoviedb.org目录的API,该API提供了有关电影和电视剧的开放访问。这意味着在Lampa应用程序中显示的信息是公开可访问的,并且不侵犯版权。', + termsofuse_t_13: '如果您认为Lampa应用程序仍然包含侵犯您版权的内容,您可以联系该内容的权利持有人,并要求他们从themoviedb.org网站上删除该内容。与此同时,Lampa应用程序在收到相应的侵权通知后可以删除该内容。', + settings_rest_protocol_use: '安全连接', + settings_rest_protocol_descr: '使用HTTPS协议', + + install_app_apk_title: '如何在安卓设备上安装 Lampa', + install_app_apk_text: '我们注意到您使用 MediaStationX 在安卓设备上运行 Lampa。我们建议您将 Lampa 安装为 APK 应用。这将确保更稳定的运行,并让您能够访问应用的所有功能。

    前往 Telegram 群组下载最新 APK 文件和安装说明。', + install_app_apk_qr: '扫描二维码下载 Lampa APK', + copy_link_buffer: '复制链接', + + tv_status_returning_series: '连载中', + tv_status_planned: '计划中', + tv_status_in_production: '制作中', + tv_status_ended: '已结束', + tv_status_canceled: '已取消', + tv_status_pilot: '试播', + + tv_status_released: '已发布', + tv_status_rumored: '传闻中', + tv_status_post_production: '即将发布', + full_keywords: '标签', + title_last_year: '去年', + + title_reset: '重启', + back_to_card: '返回卡', + + premiere_author_recomend_1: '订披萨,准备好迎接刺激。', + premiere_author_recomend_2: '派对刚刚开始。', + premiere_author_recomend_3: '准备迎接肾上腺素。', + premiere_author_recomend_4: '准备好度过难忘的夜晚了吗?', + premiere_author_recomend_5: '我推荐观看它。', + premiere_title: '首映', + + settings_clear_cache_only: '清除缓存', + settings_rest_cache_only: '仅清除缓存', + settings_rest_cache_only_descr: '基本设置将被保留', + settings_rest_cache_all: '清除缓存和数据', + settings_rest_cache_all_descr: '所有设置和数据将被清除', + settings_rest_cache_calculate: '还剩多少内存', + + title_left:'左边', + + account_export_fail_500: '未知错误', + account_export_fail_610: '您已超过今天的限制', + account_export_fail_200: '数据库错误,请稍后重试', + account_export_fail_600: '错误,无法上传文件', + account_export_fail_620: '错误,文件未传送', + + title_parental_control: '家长控制', + settings_parental_control_param_time_always: '始终', + settings_parental_control_param_time_once: '一次', + settings_parental_control_param_time_10: '10分钟后', + settings_parental_control_param_time_20: '20分钟后', + settings_parental_control_param_time_30: '30分钟后', + settings_parental_control_param_time_60: '1小时后', + settings_parental_control_param_time_120: '2小时后', + settings_parental_control_change_pin: '更改PIN码', + settings_parental_control_demand_title: '何时要求', + settings_parental_control_demand_descr: '多久后要求PIN码', + settings_parental_control_enabled: '已启用', + settings_parental_control_disabled: '已禁用', + parental_control_input_new_code: '输入新的PIN码', + parental_control_confirm_new_code: '确认PIN码', + parental_control_no_match_code: 'PIN码与先前的代码不匹配', + parental_control_input_code: '输入PIN码', + parental_control_input_error: '您输入了错误的PIN码', + title_worth_rewatch: '值得再看一遍', + + ad_disable: '通过订阅 CUB Premium,您将不受广告打扰。', + ad_after: '广告通过', + ad: '广告', + ad_skip: '跳过', + ad_continue_after: '观看将于', + settings_parser_prowlarr_link_descr: '提供 Prowlarr 服务器的链接', + settings_parser_prowlarr_key_descr: '位于常规类别中的 Prowlarr 设置选项卡中', + settings_player_torrent_type: '种子播放器类型', + settings_player_torrent_type_descr: '哪个播放器可以播放种子中的视频', + + full_crew: '更多', + full_editing: '编辑', + full_creator: '创建者', + player_normalization_step_none: '零', + + settings_cub_backup_export_descr: '将设置保存到云端', + settings_cub_backup_import_descr: '从云端恢复设置', + + settings_interface_sound: '系统声音', + settings_interface_sound_play: '过渡', + settings_interface_sound_level: '音量级别', + settings_interface_advanced_animation: '高级动画', + + confirm_open_player: '另一台设备正在请求访问播放器。想播放视频吗?', + + pincode_use_remote: '使用遥控器输入代码,按箭头选择所需的号码。', + pincode_use_toggle: '按住“确定”按钮可更改布局。', + + settings_parental_control_where: '在哪里请求 PIN 码', + title_fire: '火!', + title_top_100: '前100名', + + player_normalization_type_title: '标准化类型', + player_normalization_type_all: '全部', + player_normalization_type_up: '仅提升', + player_normalization_type_down: '仅降低', + storage_quota_exceeded: '存储配额已超出。清除缓存后重试。', + settings_cub_domain: '主域', + + title_ai_assistant: 'AI助手', + title_facts: '有趣的事实', + ai_search_start_typing: '向AI助手询问您想查找的电影。例如:“关于太空的电影”', + ai_search_limit: '请求次数已超出限制。请稍后再试。有了CUB Premium订阅,请求限制将增加,您无需等待!', + ai_subscribe_title: '解锁更多AI功能', + ai_subscribe_descr: '订阅CUB Premium,增加与AI的交互请求次数。与AI一起,我们将为您推荐最佳电影。', + + dmca_title: '内容被阻止', + dmca_descr: '该材料无法查看。该视频是根据版权法依据版权所有者的要求而被屏蔽的。', + + loading_progress_step_0: '准备', + loading_progress_step_1: '加载语言', + loading_progress_step_2: '搜索镜像', + loading_progress_step_3: '准备扩展', + loading_progress_step_4: '快完成了', + loading_progress_step_5: '即将完成', + + install_extension_rule_1: '安装第三方插件', + install_extension_rule_2: '插件由独立开发者创建,LAMPA 不会审核其内容。安装插件即表示您同意以下内容:', + install_extension_rule_3: '- 某些插件可能会请求访问您的数据或使用未经验证的来源。', + install_extension_rule_4: '- 如果您安装的插件侵犯了版权或其他法律,您需自行承担全部责任。', + install_extension_rule_5: '- 仅安装来自可信来源的插件。如果您对插件的安全性或合法性存有疑虑,建议不要安装。', + install_extension_rule_6: 'LAMPA 不支持或认可与盗版内容相关的插件。', + install_extension_rule_7: '继续操作即表示您确认理解这些风险。', + ad_plugin: '插件广告', + terminal_title: '终端', + terminal_no_access: '无访问权限', + terminal_confirm: '允许', + terminal_deny: '拒绝', + terminal_update: '更新', + terminal_code: '访问码', + terminal_text: '您正在请求访问终端。开发者可能会访问您的设备并进行控制。这对于诊断和排除问题很有用,但也可能带来安全风险。请确保您信任开发者后再授权访问。

    您可以随时点击“拒绝”按钮关闭此功能。', + + title_anons: '公告', + title_developer: '开发者', + title_navigation: '导航', + title_page: '页面', + title_person_about: '关于', + account_qr_premium: '扫描二维码以了解更多关于 CUB Premium 的信息', + account_qr_code: '扫描二维码以获取设备绑定代码', + account_qr_create: '扫描二维码以创建账户', + account_add_device_title: '添加设备', + account_add_device_text: '前往 获取添加设备的代码。', + account_none_title: '还没有账户?', + account_none_include_1: '书签和观看历史保存在云端', + account_none_include_2: '多设备同步', + account_none_include_3: '新剧集和新片发布通知', + account_none_include_4: '一个账户可创建多个个人资料', + account_premium_include_1: '增加书签数量', + account_premium_include_2: '扩展的观看历史', + account_premium_include_3: '更多可用的时间码', + account_premium_include_4: '每个账户的个人资料数量', + empty_subscribes_title: '您的翻译订阅', + empty_subscribes_text: '只需订阅您喜欢的翻译,我们会在新剧集发布时通知您。', + empty_history_title: '您的观看历史', + empty_history_text: '您的观看历史将显示在这里。', + empty_bookmark_title: '您的收藏', + empty_bookmark_text: '将您喜欢的电影和电视剧添加到收藏,以便在此部分快速找到。', + empty_mytorrents_title: '您的种子', + empty_mytorrents_text: '通过 TorServer 下载的种子文件将显示在这里。', + developer_param_enabled: '开发者模式', + developer_param_nopremium: '禁用 CUB Premium', + developer_param_nodemo: '禁用演示模式', + developer_param_ads: '显示广告', + developer_param_fps: '显示 FPS', + developer_trigger_help_1: '差一点就猜到了 :)', + developer_trigger_help_2: '再接近一点 :)', + developer_trigger_help_3: '您确定要进入开发者模式吗?', + developer_trigger_help_4: '开发者模式已激活', + settings_param_navigation_touch: '触控', + account_discuss_add_qr: '扫描二维码', + account_discuss_add_title: '想要发表评论吗?', + account_discuss_add_text: '扫描二维码进入应用程序,为此电影或电视剧添加评论。

    - 拿起您的手机或平板
    - 打开相机
    - 对准二维码
    - 点击屏幕上出现的链接', + account_discuss_added: '感谢您的评论!', + account_discuss_added_ready: '您已经为此电影或电视剧发表过评论。', + remote_helper_long: '长按 (OK) 键打开菜单', + account_premium: '通过 CUB Premium 账户解锁新体验!享受更高的限制和更强大的功能。访问 了解更多高级账户的优势。', + player_segments_title: '片段', + player_segments_descr: '跳过片头和视频的其他部分', + player_segments_ad_title: '广告', + player_segments_skip_title: '片头及其他', + player_segments_value_none: '不跳过', + player_segments_value_auto: '自动跳过', + player_segments_value_user: '自定义', + player_segments_skiped: '片段已跳过', + player_segments_skip_now: '跳过', + player_segments_skip_in: '跳过倒计时', + player_segments_skip_intro: '跳过片头', + player_segments_next: '下一集', + player_segments_next_in: '下一集倒计时', + subscribe_info: '在“订阅”部分,您可以查看所有翻译订阅。当您选择的翻译发布新剧集时,您将收到通知。', + no_watch_history: '没有浏览历史记录', + + settings_request_caching_use: '请求缓存', + settings_request_caching_descr: '缓存来自网络的请求以加快应用程序速度。', + + account_profile_child: '子账户', + account_profile_add: '添加账户', + account_profile_name: '账户名称', + account_profile_created: '账户创建成功', + account_profile_limited: '账户数量已达上限:{count}', + account_profile_info: '您可以在账户设置中管理账户。为此,请访问', + player_youtube_no_support: '您的设备不支持播放 YouTube 视频,请检查您的互联网连接。', + title_channels: '频道', + title_best_of_2000: '黄金2000年代', + title_best_of_2010: '2010年代热门影片', + title_best_of_2015: '现代经典', + title_comedy_of_2000: '2000年代的欢笑', + title_comedy_of_2010: '2010年代的幽默', + title_comedy_of_2015: '现代喜剧', + + filter_keyword_sequel: '续集', + filter_keyword_based_comic: '改编自漫画', + filter_keyword_space: '太空', + filter_keyword_survival: '生存', + filter_keyword_zombie: '僵尸', + filter_keyword_school: '学校', + filter_keyword_revenge: '复仇', + filter_keyword_detective: '侦探', + filter_keyword_robots: '机器人', + filter_keyword_vampires: '吸血鬼', + filter_keyword_aliens: '外星人', + filter_keyword_police: '警察', + filter_keyword_reincarnation: '转世', + filter_keyword_spy: '间谍', + filter_keyword_disaster: '灾难', + filter_keyword_christmas: '圣诞节', + + dmca_title_lgbt: '内容受限', + dmca_descr_lgbt: '由于内容可能包含 LGBT 内容,您所在地区无法观看。此类内容在某些国家/地区可能被禁止或限制。', + + settings_lgbt_content_block: '阻止 LGBT 内容', + + // todo: + adult_content_title: '成人内容', + adult_content_text_warning: '内容可能包含不适合部分观众的成人内容。', + adult_content_text_modal: '该影片或剧集被标记为含有成人内容。您必须年满18岁才能观看此内容。请确认您已达到法定年龄以继续观看。', + + adult_content_confirm: '我已满18岁', + adult_content_deny: '我未满18岁', + + inner_player_disclaimer_title: '播放器免责声明', + inner_player_disclaimer_text: '我理解我正在启动一个支持不完整的播放器,并且我理解这可能会导致设备出现非典型行为。建议切换到 tvOS 系列播放器或其他替代方案。', + + inner_player_disclaimer_change_player: '更换播放器', + remote_configuration_settings_title: '远程配置', + remote_configuration_registration_text: '远程配置提供对您应用程序的临时访问,其他应用程序将能够安装扩展并配置参数。', + remote_configuration_waite_text: '您现在可以将此代码传递给另一个应用程序,以授予对设置的访问权限。', + remote_configuration_open_button: '开放访问', + remote_configuration_code_life: '代码有效', + remote_configuration_notice_nocode: '无法开放访问', + + settings_server_gts: '转码', + settings_server_gts_descr: '必要时自动将视频转换为兼容格式。', + settings_server_tracktimecode: '启用 TrackTimecode', + settings_server_tracktimecode_descr: '将电影和电视剧的播放进度保存到 TorrServer。要使此功能正常工作,还需要在 TorrServer 中启用此选项。', + + title_metadata: '元数据', + title_moods: '情绪', + title_meta_violence: '暴力', + title_meta_fear: '恐惧', + title_meta_profanity: '粗口', + title_meta_sadness: '悲伤', + title_meta_sex: '性', + player_pip: '最小化', + player_volume: '音量', + player_time_end: '结束于', + player_ai_agent_info: '想了解更多关于视频的信息吗?请AI助手为您提供情绪图表、简短情节摘要和精彩时刻。', + player_ai_agent_ask_plot: '情节简介', + player_ai_agent_ask_moods: '显示图表', + player_ai_agent_ask_highlights: '精彩时刻', + player_ai_agent_ask: '询问', + player_ai_agent_processing: '分析中...', + player_ai_agent_no_data: '没有数据可显示。', + player_ai_agent_no_analysis: '无法分析视频。', + player_ai_agent_quota: '请求限制已超出。请稍后再试。', + player_ai_agent_working: '仍在处理中...', + title_meta_humor: '幽默', + title_meta_tension: '紧张', + title_meta_romance: '浪漫', + title_meta_pace: '节奏', + title_meta_importance: '关键场景', + title_meta_action: '动作' +} diff --git a/lampa-main/msx-logo.png b/lampa-main/msx-logo.png new file mode 100644 index 0000000..b08fe9c Binary files /dev/null and b/lampa-main/msx-logo.png differ diff --git a/lampa-main/msx/lang/ru.json b/lampa-main/msx/lang/ru.json new file mode 100644 index 0000000..43adcbf --- /dev/null +++ b/lampa-main/msx/lang/ru.json @@ -0,0 +1,284 @@ +{ + "name": "Русский/Russian", + "author": "DevelopGin", + "version": "1.0.0", + "properties": { + "format:date": "dd/mm/yy", + "format:day": "D dd/mm", + "format:full_day": "DD dd/mm/yyyy", + "format:long_date": "MM d, yyyy", + "format:long_day": "D mm/dd/yyyy", + "format:long_time": "h:mm:ss/ampm", + "format:separator": ", ", + "format:time": "h:mm/ampm", + "label:about": "О программе", + "label:animations": "Анимация", + "label:application": "Приложение", + "label:apply": "Применить", + "label:audio": "Звук", + "label:auto": "Авто", + "label:auto_and_fixed": "Автоматически & Фиксировано", + "label:cancel": "Отмена", + "label:clear": "Очистить", + "label:click_and_swipe": "Нажатия & Жесты", + "label:client": "Клиент", + "label:complete_start_parameter": "Установить плейлист", + "label:complex": "Комплексный", + "label:config_error": "Ошибка Конфигурационного Файла", + "label:config_not_available": "Конфигурационный Файл Недоступен", + "label:contact": "Контакты", + "label:content_guide": "Для Начинающих", + "label:content_info": "Плейлист", + "label:content_not_available": "Нет Контента", + "label:content_server": "Сервер", + "label:continue": "Продолжить", + "label:copyright": "Сopyright", + "label:current_time": "Текущее Время", + "label:data_load_error": "Ошибка загрузки данных", + "label:debug": "Отладка", + "label:default": "По Умолчанию", + "label:detected": "Определено", + "label:detected_and_fixed": "Определено & Зафиксировано", + "label:device": "Устройство", + "label:dictionary": "Перевод", + "label:drag_and_drop": "Drag & Drop", + "label:error": "{ico:msx-red:error} Ошибка", + "label:exit": "Выход", + "label:extended_information": "Дополнительная Информация", + "label:fast": "Быстро", + "label:fixed": "Зафиксировано", + "label:framework": "Framework", + "label:fullscreen": "Во весь экран", + "label:home": "Главная", + "label:host_server": "Хост Сервер", + "label:hover_effect": "Эффект наведения", + "label:info": "{ico:msx-blue:info} Информация", + "label:input_type": "Тип Ввода", + "label:layout": "Разрешение", + "label:leave": "Выйти", + "label:link_validation": "Подтверждение Ссылок", + "label:load_error": "Ошибка загрузки", + "label:log": "Журнал Событий", + "label:menu": "Меню", + "label:menu_button": "Кнопка Меню", + "label:menu_not_available": "Меню Не Доступно", + "label:minimalistic": "Минимум", + "label:name": "Имя", + "label:navigation_frame": "Навигационное окно", + "label:no": "Нет", + "label:none": "Не задано", + "label:normal": "Нормально", + "label:not_available": "Не доступно", + "label:not_fixed": "Не Зафиксировано", + "label:off": "Выкл.", + "label:ok": "OK", + "label:on": "Вкл.", + "label:options": "Настройки", + "label:parameter": "Параметр", + "label:platform": "Платформа", + "label:platform_options": "Настройки Платформы", + "label:player": "Плеер", + "label:random_playback": "Случайное Воспроизведение", + "label:reload": "Перезагрузка", + "label:remote_control": "Удаленное Воспроизведение", + "label:remote_only": "Удаленно", + "label:reset": "Сбросить", + "label:reset_settings": "Сбросить Настройки", + "label:reset_start_parameter": "Сбросить Плейлист", + "label:restart": "Перезапуск", + "label:scale": "Масштаб", + "label:settings": "Настройки", + "label:setup": "Установка", + "label:setup_start_parameter": "Установить Плейлист", + "label:slideshow_interval": "Интервал Слайдшоу", + "label:slow": "Медленно", + "label:start_data_not_available": "Данные Плейлиста Недоступны", + "label:start_error": "Ошибка Плейлиста", + "label:start_parameter": "Плейлист", + "label:success": "{ico:msx-green:check-circle} Успешно", + "label:transformations": "Трасформации", + "label:tv_control": "Управление ТВ", + "label:unknown": "Неизвестно", + "label:url_parameters": "Параметры URL", + "label:user_agent": "User Agent", + "label:validate_links": "Подтверждение Ссылок", + "label:version": "Версия", + "label:very_fast": "Очень быстро", + "label:very_slow": "Очень медленно", + "label:video": "Видео", + "label:video_speed": "Скорость воспроизведения", + "label:volume": "Громкость", + "label:warning": "{ico:msx-yellow:warning} Внимание", + "label:web": "Сайт", + "label:welcome": "Приветствие", + "label:yes": "Да", + "label:zoom": "Зум", + "list:day_long_names": "Воскресенье,Понедельник,Вторник,Среда,Четверг,Пятница,Суббота", + "list:day_names": "Вс,Пон,Вт,Ср,Чт,Пт,Суб", + "list:month_long_names": "Январь,Февраль,Март,Апрель,Май,Июнь,Июль,Август,Сентябрь,Октябрь,Ноябрь,Декабрь", + "list:month_names": "Янв,Фев,Мар,Апр,Май,Июн,Июл,Авг,Сент,Окт,Ноя,Дек", + "message:action_error_1": "Ошибка исполнения: Code is invalid.", + "message:action_error_2": "Ошибка исполнения: Action is missing or empty.", + "message:action_not_available": "Не задано действие.", + "message:action_not_available_for_platform": "Текущая платформа не поддерживает это действие.", + "message:action_warning_1": "Skip action '{ACTION}', because max action call stack has been reached.", + "message:action_warning_2": "Unknown action: '{ACTION}'.", + "message:action_warning_3": "Live action is invalid in this context.", + "message:action_warning_4": "Invalid data action: Data is missing.", + "message:action_warning_5": "Invalid data action: Actions are missing.", + "message:action_warning_6": "Unknown logger action: '{ACTION}'.", + "message:action_warning_7": "Invalid trigger action: '{ACTION}'.", + "message:action_warning_8": "Unknown system action: '{ACTION}'.", + "message:action_warning_9": "Unknown history action: '{ACTION}'.", + "message:action_warning_10": "Unknown settings action: '{ACTION}'.", + "message:action_warning_11": "Unknown volume action: '{ACTION}'.", + "message:action_warning_12": "Unknown player action: '{ACTION}'.", + "message:action_warning_13": "Unknown player progress action: '{ACTION}'.", + "message:action_warning_14": "Unknown player label action: '{ACTION}'.", + "message:action_warning_15": "Unknown player commit action: '{ACTION}'.", + "message:action_warning_16": "Unknown player speed action: '{ACTION}'.", + "message:action_warning_17": "Unknown busy action: '{ACTION}'.", + "message:action_warning_18": "Unknown invalidate action: '{ACTION}'.", + "message:action_warning_19": "Unknown update action: '{ACTION}'.", + "message:action_warning_20": "Unknown reload action: '{ACTION}'.", + "message:action_warning_21": "Unknown resume action: '{ACTION}'.", + "message:action_warning_22": "Unknown ticking action: '{ACTION}'.", + "message:action_warning_23": "Unknown release action: '{ACTION}'.", + "message:action_warning_24": "Unknown time action: '{ACTION}'.", + "message:action_warning_25": "Unknown slider action: '{ACTION}'.", + "message:action_warning_26": "Unknown slider labels action: '{ACTION}'.", + "message:action_warning_27": "Unknown interaction action: '{ACTION}'.", + "message:action_warning_28": "Unknown interaction commit action: '{ACTION}'.", + "message:action_warning_29": "Unknown log action: '{ACTION}'.", + "message:action_warning_30": "Unknown player button action: '{ACTION}'.", + "message:action_warning_31": "Invalid player button action: '{ACTION}'.", + "message:animate_info": "Тип анимации. {dic:submessage:performance_info} {dic:submessage:preset_recommended}", + "message:animate_set": "Анимация установлена: {txt:msx-white:{ANIMATE}}.", + "message:animate_set_error": "Set animations failed: Invalid value: {txt:msx-white:'{ANIMATE}'}.", + "message:audio_not_available": "Audio is not available.", + "message:audio_url_missing": "Audio URL is missing.", + "message:complete_start_parameter_info": "Start parameter successfully loaded. Do you want to set it up and reload the application?", + "message:config_error_1": "Invalid config data.", + "message:config_error_2": "Missing config data.", + "message:content_missing": "Content is missing.", + "message:content_not_available": "No content available.", + "message:content_warning_1": "Maximum page offset reached: {POSITION}.", + "message:content_warning_2": "{ITEM}[{REF}] ID is already registered: '{ID}'.", + "message:content_warning_3": "{ITEM}[{REF}] ID is invalid: '{ID}'.", + "message:content_warning_4": "{ITEM}[{REF}] type is invalid: '{TYPE}': For the overlay/underlay page, only items of type 'space' are allowed.", + "message:content_warning_5": "{ITEM}[{REF}] layout is invalid: '{LAYOUT}': Position is already registered.", + "message:content_warning_6": "{ITEM}[{REF}] layout is invalid: '{LAYOUT}': Values are out of range.", + "message:content_warning_7": "{ITEM}[{REF}] layout is invalid: '{LAYOUT}': Some values are invalid.", + "message:content_warning_8": "{ITEM}[{REF}] layout is invalid: '{LAYOUT}'.", + "message:content_warning_9": "{ITEM}[{REF}] layout is missing.", + "message:content_warning_10": "Page[{PAGE_INDEX}] has no selectable items.", + "message:content_warning_11": "Content has no selectable items.", + "message:data_load_error": "Data could not be loaded.", + "message:dialog_warning": "Unknown dialog: '{DIALOG}'.", + "message:exit_info": "Do you want to exit the application?", + "message:feature_not_available": "This feature is not yet available.", + "message:hover_effect_info": "Indicates whether a hover effect should be used. If you control the application with a pointer device, this effect helps you to select items. You can ignore this settings if you control the application with a physical remote control or with touch.", + "message:hover_effect_set": "Hover effect has been set to: {txt:msx-white:{HOVER_EFFECT}}.", + "message:hover_effect_set_error": "Set hover effect failed: Invalid value: {txt:msx-white:'{HOVER_EFFECT}'}.", + "message:image_list_missing": "Image list is missing.", + "message:input_info": "Управление через интерфейс. Если вы управляете через пульт можете игнорировать эту настройку. {dic:submessage:reload_required}", + "message:input_set": "Input type has been set to: {txt:msx-white:{INPUT}}.{br}{dic:submessage:submessage:reload_request}", + "message:input_set_error": "Set input type failed: Invalid value: {txt:msx-white:'{INPUT}'}.", + "message:interaction_commit_error": "Commit interaction data failed.", + "message:interaction_commit_warning": "Commit interaction data is not possible, because no interaction plugin is loaded.", + "message:interaction_error": "Invalid interaction URL: '{SOURCE}': URL must be a valid HTTP(S) URL.", + "message:interaction_info": "No interaction plugin loaded, please load one to use interaction functions.", + "message:key_warning_1": "Unknown key: '{KEY}'.", + "message:key_warning_2": "Invalid key code: '{CODE}'.", + "message:layout_info": "The resolution of the layout. {dic:submessage:performance_info} {dic:submessage:reload_required} {dic:submessage:preset_recommended}", + "message:layout_set": "Layout has been set to: {txt:msx-white:{LAYOUT}}.{br}{dic:submessage:submessage:reload_request}", + "message:layout_set_error": "Set layout failed: Invalid value: {txt:msx-white:'{LAYOUT}'}.", + "message:live_action_not_available": "No live action available.", + "message:menu_button_info": "The menu button is used to quickly access all major controls. By default, the menu {ico:msx-white:menu} and the blue {ico:msx-blue:stop} button is mapped to this function. Additionally, you can define an extra button here. Press {txt:msx-white:OK} to reset the entry.", + "message:menu_button_set": "Menu button has been set to: {txt:msx-white:{MENU_BUTTON}}.", + "message:menu_button_set_error_1": "Set menu button failed: Invalid action value: {txt:msx-white:'{MENU_BUTTON_ACTION}'}.", + "message:menu_button_set_error_2": "Set menu button failed: Invalid key code value: {txt:msx-white:'{MENU_BUTTON_KEY_CODE}'}.", + "message:menu_missing": "Menu is missing.", + "message:menu_warning_1": "Maximum menu position reached: {POSITION}.", + "message:menu_warning_2": "Menu item ID is already registered: '{ID}'.", + "message:menu_warning_3": "Menu item ID is invalid: '{ID}'.", + "message:menu_warning_4": "Menu has no selectable items.", + "message:player_commit_error": "Commit player data failed.", + "message:player_commit_warning": "Commit player data is not supported.", + "message:player_error_1": "Video or audio file could not be played:{br}{CONTEXT}", + "message:player_error_2": "Loading of video or audio file has been aborted:{br}{CONTEXT}", + "message:player_error_3": "Video or audio file could not be played, because of network issues:{br}{CONTEXT}", + "message:player_error_4": "An error has occured while playing the video or audio file:{br}{CONTEXT}", + "message:player_error_5": "Video or audio file could not be played, because the source is not supported:{br}{CONTEXT}", + "message:player_info_1": "No video or audio file loaded, please load one to open the player.", + "message:player_info_2": "No video or audio file loaded, please load one to use player functions.", + "message:playlist_empty": "Playlist is empty.", + "message:playlist_missing": "Playlist is missing.", + "message:random_playback_info": "Indicates whether playlist items are played in random order.", + "message:random_playback_set": "Random playback has been set to: {txt:msx-white:{RANDOM_PLAYBACK}}.", + "message:random_playback_set_error": "Set random playback failed: Invalid value: {txt:msx-white:'{RANDOM_PLAYBACK}'}.", + "message:reload_info": "Do you want to reload the application?", + "message:remote_info": "The type of the on-screen remote control. If you control the application with a physical remote control, you can ignore this settings. {dic:submessage:reload_required}", + "message:remote_set": "Remote control has been set to: {txt:msx-white:{REMOTE}}.{br}{dic:submessage:submessage:reload_request}", + "message:remote_set_error": "Set remote control failed: Invalid value: {txt:msx-white:'{REMOTE}'}.", + "message:reset_settings_info": "Do you want to reset settings and reload the application?", + "message:reset_start_parameter_info": "Do you want to reset the start parameter and reload the application?", + "message:restart_info": "Do you want to restart the application?", + "message:scale_info": "The scale factor of the layout. By default, this is detected automatically. Depending on the platform, the auto-detection may not work correctly. If the layout does not fit into the screen, you can set this factor to a fixed value. {dic:submessage:reload_required}", + "message:scale_set": "Scale factor has been set to: {txt:msx-white:'{SCALE}'}.{br}{dic:submessage:submessage:reload_request}", + "message:scale_set_error": "Set scale factor failed: Invalid value: {txt:msx-white:'{SCALE}'}.", + "message:see_log": "Please see log for further details.", + "message:setup_start_parameter_info": "Do you want to set up the following start parameter and reload the application?", + "message:slider_info": "No slideshow loaded, please load one to use slider functions.", + "message:slider_warning": "Image list has no visible items.", + "message:slideshow_interval_info": "The time until the next image is changed in the slideshow.", + "message:slideshow_interval_set": "Slideshow interval has been set to: {txt:msx-white:{SLIDESHOW_INTERVAL}}.", + "message:slideshow_interval_set_error": "Set slideshow interval failed: Invalid value: {txt:msx-white:'{SLIDESHOW_INTERVAL}'}.", + "message:start_parameter_error_1": "Invalid start parameter: '{PARAMETER}'.{br}Parameter must start with 'menu:' or 'content:'.", + "message:start_parameter_error_2": "Invalid start parameter: '{PARAMETER}'.{br}Parameter must be a full string.", + "message:start_parameter_error_3": "Missing start parameter.", + "message:start_parameter_error_4": "Invalid start parameter name: '{NAME}'.{br}Start parameter name must be a full string.", + "message:start_parameter_error_5": "Missing start parameter name.", + "message:start_parameter_error_6": "Invalid start parameter version: '{VERSION}'.{br}Start parameter version must be a full string.", + "message:start_parameter_error_7": "Missing start parameter version.", + "message:start_parameter_error_8": "Missing start data.", + "message:start_parameter_info": "The start parameter specifies which menu or content is loaded at startup. Once you have completed the start parameter setup, your content is loaded every time you start the application. For more information, please visit {txt:msx-white:http://msx.benzac.de/info/}.", + "message:start_parameter_warning": "Start parameter must be loaded via HTTPS, because the application was loaded in a secure context.{br}Please set the security lock and try it again.", + "message:start_parameter_welcome_info_1": "{ico:msx-blue:info} This start parameter is also set as welcome pages start action in the settings.", + "message:start_parameter_welcome_info_2": "{ico:msx-blue:info} This start parameter is also set as welcome pages content in the settings.", + "message:start_parameter_welcome_info_3": "{ico:msx-blue:info} The start parameter {col:msx-white}{NAME} {VERSION}{col} is also set as welcome pages start action in the settings.", + "message:start_parameter_welcome_info_4": "{ico:msx-blue:info} The start parameter {col:msx-white}{NAME} {VERSION}{col} is also set as welcome pages content in the settings.", + "message:template_warning_1": "Template area is invalid: '{AREA}': Values are out of range.", + "message:template_warning_2": "Template area is invalid: '{AREA}': Some values are invalid.", + "message:template_warning_3": "Template layout is invalid: '{LAYOUT}': Values are out of range.", + "message:template_warning_4": "Template layout is invalid: '{LAYOUT}': Some values are invalid.", + "message:template_warning_5": "Template layout is invalid: '{LAYOUT}'.", + "message:template_warning_6": "Template layout is missing.", + "message:time_success": "Time initialization completed.", + "message:time_warning_1": "Unexpected timestamp difference: {DIFF}. A time offset is applied to fix this issue.", + "message:time_warning_2": "Unexpected time zone: {CLIENT} != {SERVER}. A time zone offset is applied to fix this issue.", + "message:transform_info": "Тип трансформации. {dic:submessage:performance_info} {dic:submessage:reload_required} {dic:submessage:preset_recommended}", + "message:transform_set": "Тип трансформации установлен: {txt:msx-white:{TRANSFORM}}.{br}{dic:submessage:submessage:reload_request}", + "message:transform_set_error": "Set transformations failed: Invalid value: {txt:msx-white:'{TRANSFORM}'}.", + "message:validate_link": "A link is opened. This can freeze the application, because not every link is suitable for each platform. Additionally, it may happen that it is not possible to return to the current page. Please validate the link and press continue if you want to open it.{br}{br}Link: {str:msx-white:{LINK}}", + "message:validate_links_info": "Indicates whether links should be checked with a short validation panel. Opening links can freeze the application, because not every link is suitable for each platform. Additionally, it may happen that it is not possible to return to the current page. Therefore, it is recommended to validate links, before they are opened.", + "message:validate_links_set": "Validate links has been set to: {txt:msx-white:{VALIDATE_LINKS}}.", + "message:validate_links_set_error": "Set validate links failed: Invalid value: {txt:msx-white:'{VALIDATE_LINKS}'}.", + "message:video_not_available": "Видео не доступно.", + "message:video_url_missing": "Нет ссылки на видео.", + "message:zoom_info": "The zoom factor of the layout. By default, the resolution of the layout is set via the {txt:msx-white:Layout} settings and no additional zooming is performed. If the layout does not fit into the screen, you can set this factor to {txt:msx-white:Auto}. {dic:submessage:reload_required}", + "message:zoom_set": "Zoom factor has been set to: {txt:msx-white:'{ZOOM}'}.{br}{dic:submessage:submessage:reload_request}", + "message:zoom_set_error": "Set zoom factor failed: Invalid value: {txt:msx-white:'{ZOOM}'}.", + "submessage:performance_info": "Зависит от платформы, изменение этого параметра может ускорить или замедлить работу приложения", + "submessage:preset_recommended": "Лучше оставлять значение по умолчанию.", + "submessage:reload_request": "Перезагрузите приложение для применения настроек.", + "submessage:reload_required": "Для применения настроек надо перезагрузить приложение.", + "unit:am": " AM", + "unit:day": " д", + "unit:days": " д", + "unit:hours": " ч", + "unit:minutes": " мин", + "unit:pm": " PM", + "unit:seconds": " сек" + } +} diff --git a/lampa-main/msx/start.json b/lampa-main/msx/start.json new file mode 100644 index 0000000..ad36151 --- /dev/null +++ b/lampa-main/msx/start.json @@ -0,0 +1,6 @@ +{ + "name": "Lampa", + "version": "latest", + "parameter": "content:{PREFIX}{domain}/msx/start.json", + "action": "link:{PREFIX}{domain}" +} \ No newline at end of file diff --git a/lampa-main/og.png b/lampa-main/og.png new file mode 100644 index 0000000..e91ab94 Binary files /dev/null and b/lampa-main/og.png differ diff --git a/lampa-main/personal.lampa b/lampa-main/personal.lampa new file mode 100644 index 0000000..e69de29 diff --git a/lampa-main/plugins/modification.js b/lampa-main/plugins/modification.js new file mode 100644 index 0000000..e69de29 diff --git a/lampa-main/plugins_black_list.json b/lampa-main/plugins_black_list.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/lampa-main/plugins_black_list.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/lampa-main/sound/bell.ogg b/lampa-main/sound/bell.ogg new file mode 100644 index 0000000..d272df6 Binary files /dev/null and b/lampa-main/sound/bell.ogg differ diff --git a/lampa-main/sound/hover.ogg b/lampa-main/sound/hover.ogg new file mode 100644 index 0000000..f37b0e7 Binary files /dev/null and b/lampa-main/sound/hover.ogg differ diff --git a/lampa-main/tree b/lampa-main/tree new file mode 100644 index 0000000..e5261de --- /dev/null +++ b/lampa-main/tree @@ -0,0 +1 @@ +0f50f0c4cb3f602ecaff84925dca07f96bbd38a8 \ No newline at end of file diff --git a/lampa-main/vender/dash/dash.js b/lampa-main/vender/dash/dash.js new file mode 100644 index 0000000..e270067 --- /dev/null +++ b/lampa-main/vender/dash/dash.js @@ -0,0 +1,19 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.dashjs=t():e.dashjs=t()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=108)}([function(e,t,n){"use strict";function r(e,t){for(var n=0;n0&&(r+=" ");for(var s=arguments.length,u=new Array(s>2?s-2:0),l=2;l=e&&g[e](r),p&&p.get().debug.dispatchEvent&&h.trigger(i.a.LOG,{message:r,level:e})}return t={getLogger:function(e){return{fatal:y.bind(e),error:E.bind(e),warn:_.bind(e),info:T.bind(e),debug:v.bind(e)}},setLogTimestampVisible:function(e){n=e},setCalleeNameVisible:function(e){a=e}},n=!0,a=!0,f=(new Date).getTime(),"undefined"!=typeof window&&window.console&&(g[o]=m(window.console.error),g[s]=m(window.console.error),g[u]=m(window.console.warn),g[l]=m(window.console.info),g[c]=m(window.console.debug)),t}f.__dashjs_factory_name="Debug";var d=a.a.getSingletonFactory(f);d.LOG_LEVEL_NONE=0,d.LOG_LEVEL_FATAL=o,d.LOG_LEVEL_ERROR=s,d.LOG_LEVEL_WARNING=u,d.LOG_LEVEL_INFO=l,d.LOG_LEVEL_DEBUG=c,a.a.updateSingletonFactory(f.__dashjs_factory_name,d),t.a=d},function(e,t,n){"use strict";var r=n(3),i=n(4);function a(){var e={};function t(t,n,r){var i=-1;return e[t]?(e[t].some((function(e,t){if(e&&e.callback===n&&(!r||r===e.scope))return i=t,!0})),i):i}return{on:function(n,r,i){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(!n)throw new Error("event type cannot be null or undefined");if(!r||"function"!=typeof r)throw new Error("listener must be a function: "+r);var o=a.priority||0;if(!(t(n,r,i)>=0)){e[n]=e[n]||[];var s={callback:r,scope:i,priority:o};i&&i.getStreamId&&(s.streamId=i.getStreamId()),i&&i.getType&&(s.mediaType=i.getType()),a&&a.mode&&(s.mode=a.mode);var u=e[n].some((function(t,r){if(t&&o>t.priority)return e[n].splice(r,0,s),!0}));u||e[n].push(s)}},off:function(n,r,i){if(n&&r&&e[n]){var a=t(n,r,i);a<0||(e[n][a]=null)}},trigger:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(t&&e[t]){if((n=n||{}).hasOwnProperty("type"))throw new Error("'type' is a reserved word for event dispatching");n.type=t,r.streamId&&(n.streamId=r.streamId),r.mediaType&&(n.mediaType=r.mediaType),e[t].filter((function(e){return!!e&&((!r.streamId||!e.streamId||e.streamId===r.streamId)&&((!r.mediaType||!e.mediaType||e.mediaType===r.mediaType)&&!(r.mode&&e.mode&&e.mode!==r.mode||!e.mode&&r.mode&&r.mode===i.a.EVENT_MODE_ON_RECEIVE)))})).forEach((function(e){return e&&e.callback.call(e.scope,n)}))}},reset:function(){e={}}}}a.__dashjs_factory_name="EventBus";var o=r.a.getSingletonFactory(a);o.EVENT_PRIORITY_LOW=0,o.EVENT_PRIORITY_HIGH=5e3,r.a.updateSingletonFactory(a.__dashjs_factory_name,o),t.a=o},function(e,t,n){"use strict";var r=n(3),i={DEFAULT:.5,STRONG:1,WEAK:0};function a(e,t,n){return{quality:void 0===e?-1:e,reason:void 0===t?null:t,priority:function(e){var t=i.DEFAULT;return e!==i.DEFAULT&&e!==i.STRONG&&e!==i.WEAK||(t=e),t}(n)}}a.__dashjs_factory_name="SwitchRequest";var o=r.a.getClassFactory(a);o.NO_CHANGE=-1,o.PRIORITY=i,r.a.updateClassFactory(a.__dashjs_factory_name,o),t.a=o},function(e,t,n){"use strict";function r(e,t){for(var n=0;nr&&o=a)}return!0}function c(e,t,n,r){var i,a,o;i=n.segmentDuration,isNaN(i)&&(i=n.adaptation.period.duration),a=parseFloat((n.adaptation.period.start+r*i).toFixed(5)),o=parseFloat((a+i).toFixed(5));var s=u(n,i,a,e.calcMediaTimeFromPresentationTime(a,n),e,o,t,r);return l(e,n,s,t)?s:null}function f(e,t,n,r,i,a,o,c,f,d){var h,p,g=r/a,m=i/a;return h=e.calcPresentationTimeFromMediaTime(g,n),l(e,n,p=u(n,m,h,g,e,h+m,t,f),t)?(p.replacementTime=d||r,o=s(o,"Number",p.replacementNumber),o=s(o,"Time",p.replacementTime),p.media=o,p.mediaRange=c,p):null}},function(e,t,n){"use strict";var r=n(3);function i(){var e,t=/^[a-z][a-z0-9+\-_.]*:/i,n=/^https?:\/\//i,r=/^https:\/\//i,i=/^([a-z][a-z0-9+\-_.]*:\/\/[^\/]+)\/?/i,a=function(e,t){try{return new window.URL(e,t).toString()}catch(t){return e}},o=function(e,t){var n=s;if(!t)return e;if(!c(e))return e;f(e)&&(n=u),d(e)&&(n=l);var r=n(t),i="/"!==r.charAt(r.length-1)&&"/"!==e.charAt(0)?"/":"";return[r,e].join(i)};function s(e){var t=e.indexOf("/"),n=e.lastIndexOf("/");return-1!==t?n===t+1?e:(-1!==e.indexOf("?")&&(e=e.substring(0,e.indexOf("?"))),e.substring(0,n+1)):""}function u(e){var t=e.match(i);return t?t[1]:""}function l(e){var n=e.match(t);return n?n[0]:""}function c(e){return!t.test(e)}function f(e){return c(e)&&"/"===e.charAt(0)}function d(e){return 0===e.indexOf("//")}return function(){try{new window.URL("x","http://y");e=a}catch(e){}finally{e=e||o}}(),{parseBaseUrl:s,parseOrigin:u,parseScheme:l,isRelative:c,isPathAbsolute:f,isSchemeRelative:d,isHTTPURL:function(e){return n.test(e)},isHTTPS:function(e){return r.test(e)},removeHostname:function(e){return/^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(e)[2].substring(1)},resolve:function(t,n){return e(t,n)}}}i.__dashjs_factory_name="DefaultURLUtils";var a=r.a.getSingletonFactory(i);function o(){var e,t=[],n=this.context;function r(n,r,i){var a=function(n){var r;for(r=0;r0&&(t[a.substring(0,o)]=a.substring(o+2))}return t}},{key:"generateUuid",value:function(){var e=(new Date).getTime();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var n=(e+16*Math.random())%16|0;return e=Math.floor(e/16),("x"==t?n:3&n|8).toString(16)}))}},{key:"generateHashCode",value:function(e){var t=0;if(0===e.length)return t;for(var n=0;n=e-n}))}function m(e,t){t<=e+.5||(r=r.filter((function(n){var r=p(n);return isNaN(n.startTime)||n.startTime>=t-r||isNaN(n.duration)||n.startTime+n.duration<=e+r})))}function y(e,t,n){for(var r=e.length-1;r>=0;r--){var i=e[r],a=i.startTime,o=a+i.duration;if(n=isNaN(n)?p(i):n,!isNaN(a)&&!isNaN(o)&&t+n>=a&&t-n0&&m(n,t)}else g()},abortRequests:function(){n.debug("abort requests"),l.abort(),a=[]},executeRequest:function(e){switch(e.action){case i.a.ACTION_DOWNLOAD:E(e,"loading"),a.push(e),function(e){o.trigger(s.FRAGMENT_LOADING_STARTED,{request:e},{streamId:f.id,mediaType:d}),l.load(e)}(e);break;default:n.warn("Unknown request action.")}},reset:function(){o.off(s.LOADING_COMPLETED,_,this),o.off(s.LOADING_DATA_PROGRESS,T,this),o.off(s.LOADING_ABANDONED,v,this),l&&l.reset(),S()},resetInitialSettings:S,addExecutedRequest:function(e){r.push(e)}},n=c.getLogger(t),S(),o.on(s.LOADING_COMPLETED,_,t),o.on(s.LOADING_DATA_PROGRESS,T,t),o.on(s.LOADING_ABANDONED,v,t),t}a.__dashjs_factory_name="FragmentModel";var o=r.a.getClassFactory(a);o.FRAGMENT_MODEL_LOADING="loading",o.FRAGMENT_MODEL_EXECUTED="executed",o.FRAGMENT_MODEL_CANCELED="canceled",o.FRAGMENT_MODEL_FAILED="failed",r.a.updateClassFactory(a.__dashjs_factory_name,o),t.a=o},function(e,t,n){"use strict";var r=n(3),i=n(46);function a(e){e=e||{};var t,n,r=this.context;return t=Object(i.a)(r).getInstance(),{load:function(i){if(!n){var a=t.getLoader(i&&i.request?i.request.url:null);n=a(r).create({errHandler:e.errHandler,mediaPlayerModel:e.mediaPlayerModel,requestModifier:e.requestModifier,dashMetrics:e.dashMetrics,boxParser:e.boxParser?e.boxParser:null,constants:e.constants?e.constants:null,dashConstants:e.dashConstants?e.dashConstants:null,urlUtils:e.urlUtils?e.urlUtils:null,requestTimeout:isNaN(e.requestTimeout)?0:e.requestTimeout,errors:e.errors})}n.load(i)},abort:function(){n&&n.abort()}}}a.__dashjs_factory_name="URLLoader";var o=r.a.getClassFactory(a);t.a=o},function(e,t,n){"use strict";var r=n(6);function i(e,t){for(var n=0;n0?n[n.length-1]:null}}}s.__dashjs_factory_name="IsoFile";var u=o.a.getClassFactory(s),l=n(24),c=n.n(l);var f=function e(t,n,r){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.lastCompletedOffset=t,this.found=n,this.size=r};function d(){var e,t,n=this.context;function i(e){if(!e)return null;void 0===e.fileStart&&(e.fileStart=0);var t=c.a.parseBuffer(e),r=u(n).create();return r.setData(t),r}function a(e,t){return e[t+3]>>>0|e[t+2]<<8>>>0|e[t+1]<<16>>>0|e[t]<<24>>>0}function o(e,t){return String.fromCharCode(e[t++])+String.fromCharCode(e[t++])+String.fromCharCode(e[t++])+String.fromCharCode(e[t])}return t={parse:i,findLastTopIsoBoxCompleted:function(e,t,n){if(void 0===n&&(n=0),!t||n+8>=t.byteLength)return new f(0,!1);for(var r,i=t instanceof ArrayBuffer?new Uint8Array(t):t,s=0;n=0?r=new f(n,!0,u):s=n+u),n+=u}return r||new f(s,!1)},getMediaTimescaleFromMoov:function(e){var t=i(e),n=t?t.getBox("mdhd"):void 0;return n?n.timescale:NaN},getSamplesInfo:function(e){if(!e||0===e.byteLength)return{sampleList:[],lastSequenceNumber:NaN,totalDuration:NaN,numSequences:NaN};var t,n,r,a,o,s,u,l,c,f,d,h,p,g,m,y,E=i(e),_=E.getBoxes("moof"),T=E.getBoxes("mfhd");m=E.getBoxes("moof").length,g=T[T.length-1].sequence_number,n=0,o=[];var v=-1,S=-1;for(f=0;f<_.length;f++){var A=_[f],b=A.getChildBoxes("traf");for(l=0;lS&&(v++,S+=M.entries[v].sample_delta),u==S){O.subSizes=[];var P=M.entries[v];for(h=0;h=t.byteLength)return new f(0,!1);for(var r,i=t instanceof ArrayBuffer?new Uint8Array(t):t,s=0;n=0?r=new f(n,!0,u,l):s=n+u),n+=u}return r||new f(s,!1)}},e=Object(r.a)(n).getInstance().getLogger(t),t}d.__dashjs_factory_name="BoxParser";t.a=o.a.getSingletonFactory(d)},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){ +/*! codem-isoboxer v0.3.6 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */ +var r={parseBuffer:function(e){return new i(e).parse()},addBoxProcessor:function(e,t){"string"==typeof e&&"function"==typeof t&&(a.prototype._boxProcessors[e]=t)},createFile:function(){return new i},createBox:function(e,t,n){var r=a.create(e);return t&&t.append(r,n),r},createFullBox:function(e,t,n){var i=r.createBox(e,t,n);return i.version=0,i.flags=0,i},Utils:{}};r.Utils.dataViewToString=function(e,t){var n=t||"utf-8";if("undefined"!=typeof TextDecoder)return new TextDecoder(n).decode(e);var r=[],i=0;if("utf-8"===n)for(;i>6),t.push(128|63&r)):r<65536?(t.push(224|r>>12),t.push(128|63&r>>6),t.push(128|63&r)):(t.push(240|r>>18),t.push(128|63&r>>12),t.push(128|63&r>>6),t.push(128|63&r))}return t},r.Utils.appendBox=function(e,t,n){if(t._offset=e._cursor.offset,t._root=e._root?e._root:e,t._raw=e._raw,t._parent=e,-1!==n)if(null!=n){var r,i=-1;if("number"==typeof n)i=n;else{if("string"==typeof n)r=n;else{if("object"!=typeof n||!n.type)return void e.boxes.push(t);r=n.type}for(var a=0;a>3,t},a.prototype._readUint=function(e){var t,n,r=null,i=this._cursor.offset-this._raw.byteOffset;switch(e){case 8:r=this._raw.getUint8(i);break;case 16:r=this._raw.getUint16(i);break;case 24:r=((t=this._raw.getUint16(i))<<8)+(n=this._raw.getUint8(i+2));break;case 32:r=this._raw.getUint32(i);break;case 64:t=this._raw.getUint32(i),n=this._raw.getUint32(i+4),r=t*Math.pow(2,32)+n}return this._cursor.offset+=e>>3,r},a.prototype._readString=function(e){for(var t="",n=0;n0?e:this._raw.byteLength-(this._cursor.offset-this._offset);if(t>0){var n=new Uint8Array(this._raw.buffer,this._cursor.offset,t);return this._cursor.offset+=t,n}return null},a.prototype._readUTF8String=function(){var e=this._raw.byteLength-(this._cursor.offset-this._offset),t=null;return e>0&&(t=new DataView(this._raw.buffer,this._cursor.offset,e),this._cursor.offset+=e),t?r.Utils.dataViewToString(t):t},a.prototype._parseBox=function(){if(this._parsing=!0,this._cursor.offset=this._offset,this._offset+8>this._raw.buffer.byteLength)this._root._incomplete=!0;else{switch(this._procField("size","uint",32),this._procField("type","string",4),1===this.size&&this._procField("largesize","uint",64),"uuid"===this.type&&this._procFieldArray("usertype",16,"uint",8),this.size){case 0:this._raw=new DataView(this._raw.buffer,this._offset,this._raw.byteLength-this._cursor.offset+8);break;case 1:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.largesize);break;default:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.size)}this._incomplete||(this._boxProcessors[this.type]&&this._boxProcessors[this.type].call(this),-1!==this._boxContainers.indexOf(this.type)?this._parseContainerBox():this._data=this._readData())}},a.prototype._parseFullBox=function(){this.version=this._readUint(8),this.flags=this._readUint(24)},a.prototype._parseContainerBox=function(){for(this.boxes=[];this._cursor.offset-this._raw.byteOffset>3}else this.size+=e>>3},a.prototype._writeUint=function(e,t){if(this._rawo){var n,r,i=this._cursor.offset-this._rawo.byteOffset;switch(e){case 8:this._rawo.setUint8(i,t);break;case 16:this._rawo.setUint16(i,t);break;case 24:n=(16776960&t)>>8,r=255&t,this._rawo.setUint16(i,n),this._rawo.setUint8(i+2,r);break;case 32:this._rawo.setUint32(i,t);break;case 64:r=t-(n=Math.floor(t/Math.pow(2,32)))*Math.pow(2,32),this._rawo.setUint32(i,n),this._rawo.setUint32(i+4,r)}this._cursor.offset+=e>>3}else this.size+=e>>3},a.prototype._writeString=function(e,t){for(var n=0;n>10&31),96+(this.language>>5&31),96+(31&this.language))),this._procField("pre_defined","uint",16)},a.prototype._boxProcessors.mehd=function(){this._procFullBox(),this._procField("fragment_duration","uint",1==this.version?64:32)},a.prototype._boxProcessors.mfhd=function(){this._procFullBox(),this._procField("sequence_number","uint",32)},a.prototype._boxProcessors.mfro=function(){this._procFullBox(),this._procField("mfra_size","uint",32)},a.prototype._boxProcessors.mp4a=a.prototype._boxProcessors.enca=function(){this._procFieldArray("reserved1",6,"uint",8),this._procField("data_reference_index","uint",16),this._procFieldArray("reserved2",2,"uint",32),this._procField("channelcount","uint",16),this._procField("samplesize","uint",16),this._procField("pre_defined","uint",16),this._procField("reserved3","uint",16),this._procField("samplerate","template",32),this._procField("esds","data",-1)},a.prototype._boxProcessors.mvhd=function(){this._procFullBox(),this._procField("creation_time","uint",1==this.version?64:32),this._procField("modification_time","uint",1==this.version?64:32),this._procField("timescale","uint",32),this._procField("duration","uint",1==this.version?64:32),this._procField("rate","template",32),this._procField("volume","template",16),this._procField("reserved1","uint",16),this._procFieldArray("reserved2",2,"uint",32),this._procFieldArray("matrix",9,"template",32),this._procFieldArray("pre_defined",6,"uint",32),this._procField("next_track_ID","uint",32)},a.prototype._boxProcessors.payl=function(){this._procField("cue_text","utf8")},a.prototype._boxProcessors.pssh=function(){this._procFullBox(),this._procFieldArray("SystemID",16,"uint",8),this._procField("DataSize","uint",32),this._procFieldArray("Data",this.DataSize,"uint",8)},a.prototype._boxProcessors.schm=function(){this._procFullBox(),this._procField("scheme_type","uint",32),this._procField("scheme_version","uint",32),1&this.flags&&this._procField("scheme_uri","string",-1)},a.prototype._boxProcessors.sdtp=function(){this._procFullBox();var e=-1;this._parsing&&(e=this._raw.byteLength-(this._cursor.offset-this._raw.byteOffset)),this._procFieldArray("sample_dependency_table",e,"uint",8)},a.prototype._boxProcessors.sidx=function(){this._procFullBox(),this._procField("reference_ID","uint",32),this._procField("timescale","uint",32),this._procField("earliest_presentation_time","uint",1==this.version?64:32),this._procField("first_offset","uint",1==this.version?64:32),this._procField("reserved","uint",16),this._procField("reference_count","uint",16),this._procEntries("references",this.reference_count,(function(e){this._parsing||(e.reference=(1&e.reference_type)<<31,e.reference|=2147483647&e.referenced_size,e.sap=(1&e.starts_with_SAP)<<31,e.sap|=(3&e.SAP_type)<<28,e.sap|=268435455&e.SAP_delta_time),this._procEntryField(e,"reference","uint",32),this._procEntryField(e,"subsegment_duration","uint",32),this._procEntryField(e,"sap","uint",32),this._parsing&&(e.reference_type=e.reference>>31&1,e.referenced_size=2147483647&e.reference,e.starts_with_SAP=e.sap>>31&1,e.SAP_type=e.sap>>28&7,e.SAP_delta_time=268435455&e.sap)}))},a.prototype._boxProcessors.smhd=function(){this._procFullBox(),this._procField("balance","uint",16),this._procField("reserved","uint",16)},a.prototype._boxProcessors.ssix=function(){this._procFullBox(),this._procField("subsegment_count","uint",32),this._procEntries("subsegments",this.subsegment_count,(function(e){this._procEntryField(e,"ranges_count","uint",32),this._procSubEntries(e,"ranges",e.ranges_count,(function(e){this._procEntryField(e,"level","uint",8),this._procEntryField(e,"range_size","uint",24)}))}))},a.prototype._boxProcessors.stsd=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procSubBoxes("entries",this.entry_count)},a.prototype._boxProcessors.subs=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procEntries("entries",this.entry_count,(function(e){this._procEntryField(e,"sample_delta","uint",32),this._procEntryField(e,"subsample_count","uint",16),this._procSubEntries(e,"subsamples",e.subsample_count,(function(e){this._procEntryField(e,"subsample_size","uint",1===this.version?32:16),this._procEntryField(e,"subsample_priority","uint",8),this._procEntryField(e,"discardable","uint",8),this._procEntryField(e,"codec_specific_parameters","uint",32)}))}))},a.prototype._boxProcessors.tenc=function(){this._procFullBox(),this._procField("default_IsEncrypted","uint",24),this._procField("default_IV_size","uint",8),this._procFieldArray("default_KID",16,"uint",8)},a.prototype._boxProcessors.tfdt=function(){this._procFullBox(),this._procField("baseMediaDecodeTime","uint",1==this.version?64:32)},a.prototype._boxProcessors.tfhd=function(){this._procFullBox(),this._procField("track_ID","uint",32),1&this.flags&&this._procField("base_data_offset","uint",64),2&this.flags&&this._procField("sample_description_offset","uint",32),8&this.flags&&this._procField("default_sample_duration","uint",32),16&this.flags&&this._procField("default_sample_size","uint",32),32&this.flags&&this._procField("default_sample_flags","uint",32)},a.prototype._boxProcessors.tfra=function(){this._procFullBox(),this._procField("track_ID","uint",32),this._parsing||(this.reserved=0,this.reserved|=(48&this.length_size_of_traf_num)<<4,this.reserved|=(12&this.length_size_of_trun_num)<<2,this.reserved|=3&this.length_size_of_sample_num),this._procField("reserved","uint",32),this._parsing&&(this.length_size_of_traf_num=(48&this.reserved)>>4,this.length_size_of_trun_num=(12&this.reserved)>>2,this.length_size_of_sample_num=3&this.reserved),this._procField("number_of_entry","uint",32),this._procEntries("entries",this.number_of_entry,(function(e){this._procEntryField(e,"time","uint",1===this.version?64:32),this._procEntryField(e,"moof_offset","uint",1===this.version?64:32),this._procEntryField(e,"traf_number","uint",8*(this.length_size_of_traf_num+1)),this._procEntryField(e,"trun_number","uint",8*(this.length_size_of_trun_num+1)),this._procEntryField(e,"sample_number","uint",8*(this.length_size_of_sample_num+1))}))},a.prototype._boxProcessors.tkhd=function(){this._procFullBox(),this._procField("creation_time","uint",1==this.version?64:32),this._procField("modification_time","uint",1==this.version?64:32),this._procField("track_ID","uint",32),this._procField("reserved1","uint",32),this._procField("duration","uint",1==this.version?64:32),this._procFieldArray("reserved2",2,"uint",32),this._procField("layer","uint",16),this._procField("alternate_group","uint",16),this._procField("volume","template",16),this._procField("reserved3","uint",16),this._procFieldArray("matrix",9,"template",32),this._procField("width","template",32),this._procField("height","template",32)},a.prototype._boxProcessors.trex=function(){this._procFullBox(),this._procField("track_ID","uint",32),this._procField("default_sample_description_index","uint",32),this._procField("default_sample_duration","uint",32),this._procField("default_sample_size","uint",32),this._procField("default_sample_flags","uint",32)},a.prototype._boxProcessors.trun=function(){this._procFullBox(),this._procField("sample_count","uint",32),1&this.flags&&this._procField("data_offset","int",32),4&this.flags&&this._procField("first_sample_flags","uint",32),this._procEntries("samples",this.sample_count,(function(e){256&this.flags&&this._procEntryField(e,"sample_duration","uint",32),512&this.flags&&this._procEntryField(e,"sample_size","uint",32),1024&this.flags&&this._procEntryField(e,"sample_flags","uint",32),2048&this.flags&&this._procEntryField(e,"sample_composition_time_offset",1===this.version?"int":"uint",32)}))},a.prototype._boxProcessors["url "]=a.prototype._boxProcessors["urn "]=function(){this._procFullBox(),"urn "===this.type&&this._procField("name","string",-1),this._procField("location","string",-1)},a.prototype._boxProcessors.vlab=function(){this._procField("source_label","utf8")},a.prototype._boxProcessors.vmhd=function(){this._procFullBox(),this._procField("graphicsmode","uint",16),this._procFieldArray("opcolor",3,"uint",16)},a.prototype._boxProcessors.vttC=function(){this._procField("config","utf8")},a.prototype._boxProcessors.vtte=function(){}},function(e,t){var n,r,i=e.exports={};function a(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function s(e){if(n===setTimeout)return setTimeout(e,0);if((n===a||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:a}catch(e){n=a}try{r="function"==typeof clearTimeout?clearTimeout:o}catch(e){r=o}}();var u,l=[],c=!1,f=-1;function d(){c&&u&&(c=!1,u.length?l=u.concat(l):f=-1,l.length&&h())}function h(){if(!c){var e=s(d);c=!0;for(var t=l.length;t;){for(u=l,l=[];++f1)for(var n=1;n0&&r[e.mediaType].ignoreCount--}return t={getMaxIndex:function(e){var t=Object(i.a)(s).create();if(!e||!e.hasOwnProperty("getMediaType"))return t;!function(){if(!h||!h.hasOwnProperty("getCurrentBufferLevel")||!h.hasOwnProperty("getCurrentBufferState"))throw new Error(a.a.MISSING_CONFIG_ERROR)}();var u=e.getMediaType(),l=h.getCurrentBufferState(u),c=e.getRepresentationInfo().fragmentDuration,f=e.getStreamInfo(),d=f?f.id:null,p=e.getScheduleController(),g=f&&f.manifestInfo&&f.manifestInfo.isDynamic;if(function(e,t){return!e&&r[t].ignoreCount>0}(p.getPlaybackController().getLowLatencyModeEnabled(),u)||!c)return t;if(l&&l.state===o.a.BUFFER_EMPTY)n.debug("["+u+"] Switch to index 0; buffer is empty."),t.quality=0,t.reason="InsufficientBufferRule: Buffer is empty";else{var m=e.getMediaInfo(),y=e.getAbrController(),E=y.getThroughputHistory(),_=h.getCurrentBufferLevel(u),T=E.getAverageThroughput(u,g),v=E.getAverageLatency(u),S=T*(_/c)*.5;t.quality=y.getQualityForBitrate(m,S,d,v),t.reason="InsufficientBufferRule: being conservative to avoid immediate rebuffering"}return t},reset:function(){p(),u.off(d.a.PLAYBACK_SEEKING,g,t),u.off(c.a.BYTES_APPENDED_END_FRAGMENT,m,t)}},n=Object(f.a)(s).getInstance().getLogger(t),p(),u.on(d.a.PLAYBACK_SEEKING,g,t),u.on(c.a.BYTES_APPENDED_END_FRAGMENT,m,t),t}h.__dashjs_factory_name="InsufficientBufferRule";var p=r.a.getClassFactory(h);function g(e){e=e||{};var t,n,r,a,o,s=this.context,u=e.mediaPlayerModel,l=e.dashMetrics,c=e.settings;function d(){r={},a={},o=[]}return t={shouldAbandon:function(e){var t=Object(i.a)(s).create(i.a.NO_CHANGE,{name:g.__dashjs_factory_name});if(!(e&&e.hasOwnProperty("getMediaInfo")&&e.hasOwnProperty("getMediaType")&&e.hasOwnProperty("getCurrentRequest")&&e.hasOwnProperty("getRepresentationInfo")&&e.hasOwnProperty("getAbrController")))return t;var f,d,h=e.getMediaInfo(),p=e.getMediaType(),m=e.getStreamInfo(),y=m?m.id:null,E=e.getCurrentRequest();if(!isNaN(E.index)){f=p,d=E.index,r[f]=r[f]||{},r[f][d]=r[f][d]||{};var _=u.getStableBufferTime();if(l.getCurrentBufferLevel(p)>_)return t;var T=r[p][E.index];if(null===T||null===E.firstByteDate||a.hasOwnProperty(T.id))return t;if(void 0===T.firstByteTime&&(o[p]=[],T.firstByteTime=E.firstByteDate.getTime(),T.segmentDuration=E.duration,T.bytesTotal=E.bytesTotal,T.id=E.index),T.bytesLoaded=E.bytesLoaded,T.elapsedTime=(new Date).getTime()-T.firstByteTime,T.bytesLoaded>0&&T.elapsedTime>0&&function(e,t){o[e]=o[e]||[],o[e].push(t)}(p,Math.round(8*T.bytesLoaded/T.elapsedTime)),o[p].length>=5&&T.elapsedTime>500&&T.bytesLoadedT.bytesTotal*b[N].bitrate/b[S.getQualityFor(p,y)].bitrate&&(t.quality=N,t.reason.throughput=T.measuredBandwidthInKbps,t.reason.fragmentID=T.id,a[T.id]=T,n.debug("["+p+"] frag id",T.id," is asking to abandon and switch to quality to ",N," measured bandwidth was",T.measuredBandwidthInKbps),delete r[p][T.id])}}else T.bytesLoaded===T.bytesTotal&&delete r[p][T.id]}return t},reset:d},n=Object(f.a)(s).getInstance().getLogger(t),d(),t}g.__dashjs_factory_name="AbandonRequestsRule";var m=r.a.getClassFactory(g);function y(){var e,t,n=this.context;return e={getMaxIndex:function(e){var r=Object(i.a)(n).create();if(!e||!e.hasOwnProperty("getDroppedFramesHistory"))return r;var a=e.getDroppedFramesHistory(),o=e.getStreamInfo().id;if(a){var s=a.getFrameHistory(o);if(!s||0===s.length)return r;for(var u=0,l=0,c=i.a.NO_CHANGE,f=1;f375&&u/l>.15)){c=f-1,t.debug("index: "+c+" Dropped Frames: "+u+" Total Frames: "+l);break}return Object(i.a)(n).create(c,{droppedFrames:u})}return r}},t=Object(f.a)(n).getInstance().getLogger(e),e}y.__dashjs_factory_name="DroppedFramesRule";var E=r.a.getClassFactory(y);function _(){var e,t,n=this.context;return e={getMaxIndex:function(e){for(var r=e?e.getSwitchHistory():null,a=r?r.getSwitchRequests():[],o=0,s=0,u=0,l=Object(i.a)(n).create(),c=0;c=6&&o/s>.075)){l.quality=c>0&&a[c].drops>0?c-1:c,l.reason={index:l.quality,drops:o,noDrops:s,dropSize:u},t.debug("Switch history rule index: "+l.quality+" samples: "+(o+s)+" drops: "+o);break}return l}},t=Object(f.a)(n).getInstance().getLogger(e),e}_.__dashjs_factory_name="SwitchHistoryRule";var T=r.a.getClassFactory(_),v=n(5);function S(e){e=e||{};var t,n,r,s=this.context,u=e.dashMetrics,h=e.mediaPlayerModel,p=Object(l.a)(s).getInstance();function g(e,t,n){var r=n.reduce((function(e,t,r){return t>n[e]?r:e}),0);if(0===r)return null;var i=Math.max(e,10+2*t.length),a=(n[r]-1)/(i/10-1);return{gp:a,Vp:10/a}}function m(e){var t={},n=e.getMediaInfo().bitrateList.map((function(e){return e.bandwidth})),r=function(e){return e.map((function(e){return Math.log(e)}))}(n);r=r.map((function(e){return e-r[0]+1}));var i=h.getStableBufferTime(),a=g(i,n,r);return a?(t.state=1,t.bitrates=n,t.utilities=r,t.stableBufferTime=i,t.Vp=a.Vp,t.gp=a.gp,t.lastQuality=0,y(t)):t.state=0,t}function y(e){e.placeholderBuffer=0,e.mostAdvancedSegmentStart=NaN,e.lastSegmentWasReplacement=!1,e.lastSegmentStart=NaN,e.lastSegmentDurationS=NaN,e.lastSegmentRequestTimeMs=NaN,e.lastSegmentFinishTimeMs=NaN}function E(e,t){var n=h.getStableBufferTime();if(e.stableBufferTime!==n){var r=g(n,e.bitrates,e.utilities);if(r.Vp!==e.Vp||r.gp!==e.gp){var i=u.getCurrentBufferLevel(t),a=i+e.placeholderBuffer;a-=10,a*=r.Vp/e.Vp,a+=10,e.stableBufferTime=n,e.Vp=r.Vp,e.gp=r.gp,e.placeholderBuffer=Math.max(0,a-i)}}}function _(e,t){return e.Vp*(e.utilities[t]+e.gp)}function T(e,t){for(var n=e.bitrates[t],r=e.utilities[t],i=0,a=t-1;a>=0;--a)if(e.utilities[a]t.mostAdvancedSegmentStart?(t.mostAdvancedSegmentStart=n,t.lastSegmentWasReplacement=!1):t.lastSegmentWasReplacement=!0,t.lastSegmentStart=n,t.lastSegmentDurationS=e.chunk.duration,t.lastQuality=e.chunk.quality,R(t,e.chunk.mediaInfo.type)}}}function I(e){if(e&&e.metric===o.a.HTTP_REQUEST&&e.value&&e.value.type===v.a.MEDIA_SEGMENT_TYPE&&e.value.trace&&e.value.trace.length){var t=r[e.mediaType];t&&0!==t.state&&(t.lastSegmentRequestTimeMs=e.value.trequest.getTime(),t.lastSegmentFinishTimeMs=e.value._tfinish.getTime(),R(t,e.mediaType))}}function R(e,t){if(!isNaN(e.lastSegmentStart)&&!isNaN(e.lastSegmentRequestTimeMs)&&!isNaN(e.placeholderBuffer)){if(e.placeholderBuffer*=.99,!isNaN(e.lastSegmentFinishTimeMs)){var n=u.getCurrentBufferLevel(t)+.001*(e.lastSegmentFinishTimeMs-e.lastSegmentRequestTimeMs),r=_(e,e.lastQuality),i=Math.max(0,r-n);e.placeholderBuffer=Math.min(i,e.placeholderBuffer)}e.lastSegmentWasReplacement&&!isNaN(e.lastSegmentDurationS)&&(e.placeholderBuffer+=e.lastSegmentDurationS),e.lastSegmentStart=NaN,e.lastSegmentRequestTimeMs=NaN}}function N(e){if(e){var t=r[e.mediaType];t&&0!==t.state&&(t.abrQuality=e.newQuality)}}function C(e){if(e){var t=r[e.mediaType];if(t&&0!==t.state){var n,i=u.getCurrentBufferLevel(e.mediaType);n=t.abrQuality>0?T(t,t.abrQuality):10;var a=Math.max(0,n-i);t.placeholderBuffer=Math.min(t.placeholderBuffer,a)}}}function D(){r={}}return t={getMaxIndex:function(e){var t=Object(i.a)(s).create();if(!(e&&e.hasOwnProperty("getMediaInfo")&&e.hasOwnProperty("getMediaType")&&e.hasOwnProperty("getScheduleController")&&e.hasOwnProperty("getStreamInfo")&&e.hasOwnProperty("getAbrController")&&e.hasOwnProperty("useBufferOccupancyABR")))return t;var a=e.getMediaInfo(),o=e.getMediaType(),l=e.getScheduleController(),c=e.getStreamInfo(),f=e.getAbrController(),d=f.getThroughputHistory(),h=c?c.id:null,p=c&&c.manifestInfo&&c.manifestInfo.isDynamic,g=e.useBufferOccupancyABR();if(t.reason=t.reason||{},!g)return t;l.setTimeToLoadDelay(0);var v=function(e){var t=e.getMediaType(),n=r[t];return n?0!==n.state&&E(n,t):(n=m(e),r[t]=n),n}(e);if(0===v.state)return t;var S,A=u.getCurrentBufferLevel(o),b=d.getAverageThroughput(o,p),I=d.getSafeAverageThroughput(o,p),R=d.getAverageLatency(o);if(t.reason.state=v.state,t.reason.throughput=b,t.reason.latency=R,isNaN(b))return t;switch(v.state){case 1:S=f.getQualityForBitrate(a,I,h,R),t.quality=S,t.reason.throughput=I,v.placeholderBuffer=Math.max(0,T(v,S)-A),v.lastQuality=S,!isNaN(v.lastSegmentDurationS)&&A>=v.lastSegmentDurationS&&(v.state=2);break;case 2:!function(e,t){var n=Date.now();if(isNaN(e.lastSegmentFinishTimeMs)){if(!isNaN(e.lastCallTimeMs)){var r=.001*(n-e.lastCallTimeMs);e.placeholderBuffer+=Math.max(0,r)}}else{var i=.001*(n-e.lastSegmentFinishTimeMs);e.placeholderBuffer+=Math.max(0,i)}e.lastCallTimeMs=n,e.lastSegmentStart=NaN,e.lastSegmentRequestTimeMs=NaN,e.lastSegmentFinishTimeMs=NaN,E(e,t)}(v,o),S=function(e,t){for(var n=e.bitrates.length,r=NaN,i=NaN,a=0;a=i)&&(i=o,r=a)}return r}(v,A+v.placeholderBuffer);var N=f.getQualityForBitrate(a,I,h,R);S>v.lastQuality&&S>N&&(S=Math.max(N,v.lastQuality));var C=Math.max(0,A+v.placeholderBuffer-_(v,S));C<=v.placeholderBuffer?(v.placeholderBuffer-=C,C=0):(C-=v.placeholderBuffer,v.placeholderBuffer=0,St.mostAdvancedSegmentStart?(t.mostAdvancedSegmentStart=a,t.lastSegmentWasReplacement=!1):t.lastSegmentWasReplacement=!0,t.lastSegmentStart=a,t.lastSegmentDurationS=e.chunk.duration,t.lastQuality=e.chunk.quality,_(t,i)}}}function E(e){if(e&&e.metric===o.a.HTTP_REQUEST&&e.value&&e.value.type===v.a.MEDIA_SEGMENT_TYPE&&e.value.trace&&e.value.trace.length){var t=n[e.mediaType],i=r[e.mediaType];t&&0!==t.state&&(t.lastSegmentRequestTimeMs=e.value.trequest.getTime(),t.lastSegmentFinishTimeMs=e.value._tfinish.getTime(),_(t,i))}}function _(e,t){isNaN(e.lastSegmentStart)||isNaN(e.lastSegmentRequestTimeMs)||(t.segment_request_start_s=.001*e.lastSegmentRequestTimeMs,t.segment_download_finish_s=.001*e.lastSegmentFinishTimeMs,e.lastSegmentStart=NaN,e.lastSegmentRequestTimeMs=NaN)}function T(e){if(e&&e.mediaType){var t=n[e.mediaType];t&&0!==t.state&&(t.abrQuality=e.newQuality)}}function S(e,t){if(e.length!==t.length)return-1;for(var n=0,r=0;r=O.B_target){w.state=2,O.Q=l;for(var M=0;Mx&&(B=-1),O.w[k]=O.prev_w[k]+B*(U/(2*c))*((O.Q+l)*(D*m[k]/x));O.w=function(e){for(var t=e.length,n=!1,r=[],i=0;i=a[l+1]){n=!0;break}n||(s=(o+a[t-1]-1)/t);for(var c=0;cw.lastQuality&&m[w.lastQuality+1]<=x&&(t=w.lastQuality+1),m[t]>=x&&(O.Q=2*Math.max(l,O.Q)),o.quality=t,o.reason.throughput=N,o.reason.latency=C,o.reason.bufferLevel=I,w.lastQuality=o.quality;break;default:s.debug("L2A ABR rule invoked in bad state."),o.quality=T.getQualityForBitrate(f,R,_.id,C),o.reason.state=w.state,o.reason.throughput=R,o.reason.latency=C,w.state=1,g(w)}return o},reset:function(){A(),h.off(c.a.PLAYBACK_SEEKING,m,t),h.off(c.a.MEDIA_FRAGMENT_LOADED,y,t),h.off(c.a.METRIC_ADDED,E,t),h.off(c.a.QUALITY_CHANGE_REQUESTED,T,t)}},s=Object(f.a)(u).getInstance().getLogger(t),A(),h.on(c.a.PLAYBACK_SEEKING,m,t),h.on(c.a.MEDIA_FRAGMENT_LOADED,y,t),h.on(c.a.METRIC_ADDED,E,t),h.on(c.a.QUALITY_CHANGE_REQUESTED,T,t),t}b.__dashjs_factory_name="L2ARule";var I=r.a.getClassFactory(b),R="manual_weight_selection",N="random_weight_selection",C="dynamic_weight_selection";function D(){var e,t,n,r,i,a,o,s,u,l=this.context;function c(){n=null,r=1,i=100,a=0,o=null,s=null,u=C}function d(){var e=0;if(n)for(var t=0;te&&(e=r.state.throughput)}return e}function h(e,t,n){var r=e.map((function(e,r){return n[r]*Math.pow(e-t[r],2)})).reduce((function(e,t){return e+t}));return(r<0?-1:1)*Math.sqrt(Math.abs(r))}function p(e,t){return h([e.state.throughput,e.state.latency,e.state.rebuffer,e.state.switch],[t.state.throughput,t.state.latency,t.state.rebuffer,t.state.switch],[1,1,1,1])}function g(e,t,n){for(var r=0;ro)&&(a=u,o=l)}t.push(a)}for(var p=null,g=null,m=0;mp)&&(p=y,g=m)}var _=[];_.push(t[g]),t.splice(g,1);for(;t.length>0;){for(var T=null,v=null,S=0;S1&&(A=d()),c/=i,t.debug("getNextQuality called throughput:".concat(A," latency:").concat(c," bufferSize:").concat(f," currentQualityIndex:").concat(m," playbackRate:").concat(p));var b=S[m],I=b.bitrate*E.getSegmentDuration()/v,D=Math.max(0,I-T);if(T-In?e-n:e+n-t}return t={getMinBuffer:function(){return s},getSegmentDuration:c,getNextBufferWithBitrate:function(e,t,n){return f(t,e*u/n)},getNextBuffer:f,findWeightVector:function(e,t,i,a,c,d){var h=null,p=null,g=null,m=Math.abs(t-r);return e.forEach((function(e){n.forEach((function(n){n[0];var r=n[1],a=n[2],y=(n[3],e.bitrate*u/c),E=f(i,y),_=(0===a?10:1/a)*Math.max(1e-5,y-E),T=(0===r?10:1/r)*e.state.latency,v=l.calculateSingleUseQoe(e.bitrate,_,T,d);(null===h||v>h)&&function(e,t,n){if(e>o+n)return!1;return t>=s}(t,E,m)&&(h=v,p=n,g=e.bitrate)}))})),null===p&&null===g&&(p=-1),r=t,p}},i=[.2,.4,.6,.8,1],a=4,n=function e(t,n,r){if(r===n)return t;for(var a=t.length,o=0;oR?R=C:Cb?O-b:0;s.setupPerSegmentQoe(b,R,I),s.logSegmentMetrics(D,M,T,v);var P=F(l).create({targetLatency:1.5,bufferMin:.3,segmentDuration:b,qoeEvaluator:s});return n.quality=r.getNextQuality(p,1e3*S,T,y,v,h,P),n.reason={throughput:S,latency:T},n.priority=i.a.PRIORITY.STRONG,m.setTimeToLoadDelay(0),n.quality!==h&&console.log("[TgcLearningRule]["+c+"] requesting switch to index: ",n.quality,"Average throughput",Math.round(S),"kbps"),n}catch(e){throw e}},reset:function(){r.reset(),s.reset()}},t=Object(f.a)(l).getInstance().getLogger(n),r=w(l).create(),s=P(l).create(),n}x.__dashjs_factory_name="LoLPRule";var U=r.a.getClassFactory(x);function B(e){e=e||{};var t,n,r=this.context,o=e.mediaPlayerModel,s=e.customParametersModel,l=e.dashMetrics,c=e.settings;function f(e){return e.filter((function(e){return e.quality>i.a.NO_CHANGE}))}function d(e){var t,n,a,o,s,u={},l=null;if(0!==e.length){for(u[i.a.PRIORITY.STRONG]={quality:i.a.NO_CHANGE,reason:null},u[i.a.PRIORITY.WEAK]={quality:i.a.NO_CHANGE,reason:null},u[i.a.PRIORITY.DEFAULT]={quality:i.a.NO_CHANGE,reason:null},t=0,n=e.length;ta.quality)&&(u[a.priority].quality=a.quality,u[a.priority].reason=a.reason||null);return u[i.a.PRIORITY.WEAK].quality!==i.a.NO_CHANGE&&(l=u[i.a.PRIORITY.WEAK]),u[i.a.PRIORITY.DEFAULT].quality!==i.a.NO_CHANGE&&(l=u[i.a.PRIORITY.DEFAULT]),u[i.a.PRIORITY.STRONG].quality!==i.a.NO_CHANGE&&(l=u[i.a.PRIORITY.STRONG]),l&&(o=l.quality,s=l.reason),Object(i.a)(r).create(o,s)}}return{initialize:function(){t=[],n=[],c.get().streaming.abr.useDefaultABRRules&&(c.get().streaming.abr.ABRStrategy===a.a.ABR_STRATEGY_L2A?t.push(I(r).create({dashMetrics:l,settings:c})):c.get().streaming.abr.ABRStrategy===a.a.ABR_STRATEGY_LoLP?t.push(U(r).create({dashMetrics:l})):(t.push(A(r).create({dashMetrics:l,mediaPlayerModel:o,settings:c})),t.push(u(r).create({dashMetrics:l})),c.get().streaming.abr.additionalAbrRules.insufficientBufferRule&&t.push(p(r).create({dashMetrics:l,settings:c})),c.get().streaming.abr.additionalAbrRules.switchHistoryRule&&t.push(T(r).create()),c.get().streaming.abr.additionalAbrRules.droppedFramesRule&&t.push(E(r).create()),c.get().streaming.abr.additionalAbrRules.abandonRequestsRule&&n.push(m(r).create({dashMetrics:l,mediaPlayerModel:o,settings:c})))),s.getAbrCustomRules().forEach((function(e){"qualitySwitchRules"===e.type&&t.push(e.rule(r).create()),"abandonFragmentRules"===e.type&&n.push(e.rule(r).create())}))},reset:function(){[t,n].forEach((function(e){e&&e.length&&e.forEach((function(e){return e.reset&&e.reset()}))})),t=[],n=[]},getMaxQuality:function(e){return d(f(t.map((function(t){return t.getMaxIndex(e)}))))||Object(i.a)(r).create()},getMinSwitchRequest:d,shouldAbandonFragment:function(e,t){return d(f(n.map((function(n){return n.shouldAbandon(e,t)}))))||Object(i.a)(r).create()},getQualitySwitchRules:function(){return t}}}B.__dashjs_factory_name="ABRRulesCollection";var k=r.a.getClassFactory(B);k.QUALITY_SWITCH_RULES="qualitySwitchRules",k.ABANDON_FRAGMENT_RULES="abandonFragmentRules",r.a.updateSingletonFactory(B.__dashjs_factory_name,k);t.a=k},function(e,t,n){"use strict";function r(e,t){for(var n=0;n=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,o=!0,s=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,a=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw a}}}}function b(e){return function(e){if(Array.isArray(e))return R(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||I(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function I(e,t){if(e){if("string"==typeof e)return R(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?R(e,t):void 0}}function R(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&S.a.indexOf(n[0].schemeIdUri)>=0)return t===r.a.IMAGE}if(e.ContentComponent_asArray&&e.ContentComponent_asArray.length>0){if(e.ContentComponent_asArray.length>1)return t===r.a.MUXED;if(e.ContentComponent_asArray[0].contentType===t)return!0}var a=t===r.a.TEXT?new RegExp("(ttml|vtt|wvtt|stpp)"):new RegExp(t);if(e.Representation_asArray&&e.Representation_asArray.length){var o=e.Representation_asArray[0].codecs;if(a.test(o))return!0}if(e.hasOwnProperty(i.a.MIME_TYPE))return a.test(e.mimeType);if(e.Representation_asArray)for(var s,u=0;u0){var t=e.Representation_asArray[0];if(t.hasOwnProperty(i.a.SEGMENT_TEMPLATE)||t.hasOwnProperty(i.a.SEGMENT_TIMELINE)||t.hasOwnProperty(i.a.SEGMENT_LIST)||t.hasOwnProperty(i.a.SEGMENT_BASE))return!0}return!1}function C(e){return R(e,r.a.AUDIO)}function D(e){return R(e,r.a.VIDEO)}function w(e){return R(e,r.a.TEXT)}function O(e){return R(e,r.a.IMAGE)}function M(){return function(e,t){return e.bandwidth-t.bandwidth}}function P(e){return e&&Array.isArray(e.Representation_asArray)&&e.Representation_asArray.sort((function(e,t){return e.bandwidth-t.bandwidth})),e}function L(e,t){return e&&e.Period_asArray&&I(t)&&e.Period_asArray[t]?e.Period_asArray[t].AdaptationSet_asArray:[]}function F(e){return e&&e.Period_asArray?e.Period_asArray:[]}function x(e){var t=!1;return e&&e.hasOwnProperty("type")&&(t=e.type===i.a.DYNAMIC),t}function U(e){return e&&e.EssentialProperty_asArray&&e.EssentialProperty_asArray.length?e.EssentialProperty_asArray.map((function(e){return{schemeIdUri:e.schemeIdUri,value:e.value}})):null}function B(e){if(!e||!e.S_asArray)return NaN;var t=e.S_asArray[0],n=e.S_asArray[1];return t.hasOwnProperty("d")?t.d:n.t-t.t}function k(e,t){if(!e)throw new Error("Period cannot be null or undefined");var n=l.DEFAULT_ID+"_"+t;return e.hasOwnProperty(i.a.ID)&&e.id.length>0&&"__proto__"!==e.id&&(n=e.id),n}function G(e,t,n){var a,o=[];if(!e)return o;for(a=0;a0&&I(e)?r[e]:null},getIndexForAdaptation:function(e,t,n){if(!e)return-1;for(var r=L(t,n),i=0;i0&&I(e)?n[e]:null},getCodec:function(e,t,n){var r=null;if(e&&e.Representation_asArray&&e.Representation_asArray.length>0){var i=I(t)&&t>=0&&t0?e.Representation_asArray[0].mimeType:null},getKID:function(e){return e&&e.hasOwnProperty(i.a.CENC_DEFAULT_KID)?e[i.a.CENC_DEFAULT_KID]:null},getLabelsForAdaptation:function(e){if(!e||!Array.isArray(e.Label_asArray))return[];for(var t=[],n=0;n0&&(n=-1!==e.profiles.indexOf(t)),n},getDuration:function(e){return e&&e.hasOwnProperty(i.a.MEDIA_PRESENTATION_DURATION)?e.mediaPresentationDuration:e&&"dynamic"==e.type?Number.POSITIVE_INFINITY:Number.MAX_SAFE_INTEGER||Number.MAX_VALUE},getBandwidth:function(e){return e&&e.bandwidth?e.bandwidth:NaN},getManifestUpdatePeriod:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=NaN;return e&&e.hasOwnProperty(i.a.MINIMUM_UPDATE_PERIOD)&&(n=e.minimumUpdatePeriod),isNaN(n)?n:Math.max(n-t,1)},getPublishTime:function(e){return e&&e.hasOwnProperty(i.a.PUBLISH_TIME)?new Date(e[i.a.PUBLISH_TIME]):null},getRepresentationCount:function(e){return e&&Array.isArray(e.Representation_asArray)?e.Representation_asArray.length:0},getBitrateListForAdaptation:function(e){var t=P(e);return(t&&Array.isArray(t.Representation_asArray)?t.Representation_asArray:[]).map((function(e){return{bandwidth:e.bandwidth,width:e.width||0,height:e.height||0,scanType:e.scanType||null,id:e.id||null}}))},getRepresentationFor:function(e,t){return t&&t.Representation_asArray&&t.Representation_asArray.length>0&&I(e)?t.Representation_asArray[e]:null},getRepresentationsForAdaptation:function(e){var t,n,r,a,s=[],u=function(e){if(e&&e.period&&I(e.period.index)){var t=e.period.mpd.manifest.Period_asArray[e.period.index];if(t&&t.AdaptationSet_asArray&&I(e.index))return P(t.AdaptationSet_asArray[e.index])}}(e);if(u&&u.Representation_asArray){if(e&&e.period&&I(e.period.index)){var l=j(e.period.mpd.manifest);l&&(n=l[0])}for(var c=0,f=u.Representation_asArray.length;c=0&&e.value){var t=e.value.split("x");2!==t.length||isNaN(t[0])||isNaN(t[1])||(r.tilesHor=parseInt(t[0],10),r.tilesVert=parseInt(t[1],10))}})),t?m.updateSegmentData(e).then((function(t){!function(e,t,n){var r=[],i=function(e,t){var n,r,i,a,o=[],s=0;for(n=0,r=e.segments.length;ne)return i=t.url,!0})),i?n(i):t.segments.some((function(i){if(i.mediaStartTime<=e&&i.mediaStartTime+i.duration>e){var a=v.resolve(t.path);return y.load({method:"get",url:a.url,request:{range:i.mediaRange,responseType:"arraybuffer"},onload:function(e){var t=E.getSamplesInfo(e.target.response),a=new Blob([e.target.response.slice(t.sampleList[0].offset,t.sampleList[0].offset+t.sampleList[0].size)],{type:"image/jpeg"}),o=window.URL.createObjectURL(a);r.push({start:i.mediaStartTime,end:i.mediaStartTime+i.duration,url:o}),n&&n(o)}}),!0}}))}}(r,e,t)})):(r.startNumber=e.startNumber,r.segmentDuration=e.segmentDuration,r.timescale=e.timescale,r.templateUrl=function(e){var t=C.isRelative(e.media)?C.resolve(e.media,v.resolve(e.path).url):e.media;if(!t)return"";return Object(u.c)(t,e.id)}(e)),r.tilesHor>0&&r.tilesVert>0&&(r.widthPerTile=r.width/r.tilesHor,r.heightPerTile=r.height/r.tilesVert,n.push(r))}function w(){n=[],p=-1,g=null}return t={getTracks:function(){return n},addTracks:function(){if(S&&T&&(g=T.getMediaInfoForType(S,r.a.IMAGE))){var e=T.getVoRepresentations(g);e&&e.length>0&&e.forEach((function(e){(e.segmentInfoType===i.a.SEGMENT_TEMPLATE&&e.segmentDuration>0&&e.media||e.segmentInfoType===i.a.SEGMENT_TIMELINE)&&D(e),e.segmentInfoType===i.a.SEGMENT_BASE&&D(e,!0)})),n.length>0&&n.sort((function(e,t){return e.bitrate-t.bitrate}))}},reset:w,setTrackByIndex:function(e){n&&0!==n.length&&(e>=n.length&&(e=n.length-1),p=e)},getCurrentTrack:function(){return p<0?null:n[p]},getCurrentTrackIndex:function(){return p},getThumbnailRequestForTime:function(e){for(var t,r=T.getVoRepresentations(g),i=0;i=0;r--){var i=e[r];"."===i?e.splice(r,1):".."===i?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!i;a--){var o=a>=0?arguments[a]:e.cwd();if("string"!=typeof o)throw new TypeError("Arguments to path.resolve must be strings");o&&(t=o+"/"+t,i="/"===o.charAt(0))}return(i?"/":"")+(t=n(r(t.split("/"),(function(e){return!!e})),!i).join("/"))||"."},t.normalize=function(e){var a=t.isAbsolute(e),o="/"===i(e,-1);return(e=n(r(e.split("/"),(function(e){return!!e})),!a).join("/"))||a||(e="."),e&&o&&(e+="/"),(a?"/":"")+e},t.isAbsolute=function(e){return"/"===e.charAt(0)},t.join=function(){var e=Array.prototype.slice.call(arguments,0);return t.normalize(r(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},t.relative=function(e,n){function r(e){for(var t=0;t=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=t.resolve(e).substr(1),n=t.resolve(n).substr(1);for(var i=r(e.split("/")),a=r(n.split("/")),o=Math.min(i.length,a.length),s=o,u=0;u=1;--a)if(47===(t=e.charCodeAt(a))){if(!i){r=a;break}}else i=!1;return-1===r?n?"/":".":n&&1===r?"/":e.slice(0,r)},t.basename=function(e,t){var n=function(e){"string"!=typeof e&&(e+="");var t,n=0,r=-1,i=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!i){n=t+1;break}}else-1===r&&(i=!1,r=t+1);return-1===r?"":e.slice(n,r)}(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},t.extname=function(e){"string"!=typeof e&&(e+="");for(var t=-1,n=0,r=-1,i=!0,a=0,o=e.length-1;o>=0;--o){var s=e.charCodeAt(o);if(47!==s)-1===r&&(i=!1,r=o+1),46===s?-1===t?t=o:1!==a&&(a=1):-1!==t&&(a=-1);else if(!i){n=o+1;break}}return-1===t||-1===r||0===a||1===a&&t===r-1&&t===n+1?"":e.slice(t,r)};var i="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,n(25))},function(e,t,n){"use strict";var r=n(17),i=n(5),a=n(3),o=n(4),s=n(12),u=n(0);function l(e){var t,n,a,l,c,f=(e=e||{}).eventBus,d=e.debug,h=e.urlUtils,p=e.type,g=e.streamInfo,m=e.segmentsController,y=e.timelineConverter,E=e.baseURLController;function _(){return p}function T(){a=null}function v(e,t,n){var r,i,a=E.resolve(n.path);return a&&t!==a.url&&h.isRelative(t)?(r=a.url,i=a.serviceLocation,t&&(r=h.resolve(t,r))):r=t,!h.isRelative(r)&&(e.url=r,e.serviceLocation=i,!0)}function S(e,t){if(null==t)return null;var n=new r.a,a=t.representation,o=a.adaptation.period.mpd.manifest.Period_asArray[a.adaptation.period.index].AdaptationSet_asArray[a.adaptation.index].Representation_asArray[a.index].bandwidth,u=t.media;return u=Object(s.d)(u,"Number",t.replacementNumber),u=Object(s.d)(u,"Time",t.replacementTime),u=Object(s.d)(u,"Bandwidth",o),u=Object(s.c)(u,a.id),u=Object(s.e)(u),n.mediaType=_(),n.type=i.a.MEDIA_SEGMENT_TYPE,n.range=t.mediaRange,n.startTime=t.presentationStartTime,n.mediaStartTime=t.mediaStartTime,n.duration=t.duration,n.timescale=a.timescale,n.availabilityStartTime=t.availabilityStartTime,n.availabilityEndTime=t.availabilityEndTime,n.availabilityTimeComplete=a.availabilityTimeComplete,n.wallStartTime=t.wallStartTime,n.quality=a.index,n.index=t.index,n.mediaInfo=e,n.adaptationIndex=a.adaptation.index,n.representationId=a.id,v(n,u,a)?n:void 0}function A(e,t,r){var i=null;if(!t||!t.segmentInfoType)return i;var o=m.getSegmentByTime(t,r);return o&&(a=o,n.debug("Index for time "+r+" is "+o.index),i=S(e,o)),i}function b(){n.debug("Dynamic stream complete"),c=!0}return t={initialize:function(e){l=e,c=!1,m.initialize(e)},getStreamId:function(){return g.id},getType:_,getStreamInfo:function(){return g},getInitRequest:function(e,t){return t?function(e,t,n){var a=new r.a,o=t.adaptation.period,u=o.start;if(a.mediaType=n,a.type=i.a.INIT_SEGMENT_TYPE,a.range=t.range,a.availabilityStartTime=y.calcAvailabilityStartTimeFromPresentationTime(u,t,l),a.availabilityEndTime=y.calcAvailabilityEndTimeFromPresentationTime(u+o.duration,t,l),a.quality=t.index,a.mediaInfo=e,a.representationId=t.id,v(a,t.initialization,t))return a.url=Object(s.d)(a.url,"Bandwidth",t.bandwidth),a}(e,t,_()):null},getSegmentRequestForTime:A,getCurrentIndex:function(){return a?a.index:-1},getNextSegmentRequest:function(e,t){var r=null;if(!t||!t.segmentInfoType)return null;var i=a?a.index+1:0,o=m.getSegmentByIndex(t,i,a?a.mediaStartTime:-1);if(o)r=S(e,o),a=o;else{if(l&&!c)return n.debug(_()+" No segment found at index: "+i+". Wait for next loop"),null;c=!0}return r},isLastSegmentRequested:function(e,t){if(!e||!a)return!1;if(c)return!0;if(!isFinite(e.adaptation.period.duration))return!1;if(a.presentationStartTime+a.duration>t)return!1;if(e.mediaFinishedInformation&&!isNaN(e.mediaFinishedInformation.numberOfSegments)&&!isNaN(a.index)&&a.index>=e.mediaFinishedInformation.numberOfSegments-1){if(!l||e.segmentInfoType===u.a.SEGMENT_TEMPLATE)return!0;if(l&&e.segmentInfoType===u.a.SEGMENT_LIST&&e.adaptation.period.nextPeriodId)return!0}return!!(l&&e.adaptation.period.nextPeriodId&&e.segmentInfoType===u.a.SEGMENT_TIMELINE&&e.mediaFinishedInformation&&!isNaN(e.mediaFinishedInformation.mediaTimeOfLastSignaledSegment)&&a&&!isNaN(a.mediaStartTime)&&!isNaN(a.duration)&&a.mediaStartTime+a.duration>=e.mediaFinishedInformation.mediaTimeOfLastSignaledSegment-.05)},reset:function(){T(),f.off(o.a.DYNAMIC_TO_STATIC,b,t)},getNextSegmentRequestIdempotent:function(e,t){var n=a?a.index+1:0,r=m.getSegmentByIndex(t,n,a?a.mediaStartTime:-1);return r?S(e,r):null},getValidTimeCloseToTargetTime:function(e,t,n,r){try{if(isNaN(e)||!t||!n)return NaN;if(e<0&&(e=0),isNaN(r)&&(r=.5),A(t,n,e))return e;for(var i=n.adaptation.period.start,a=n.adaptation.period.start+n.adaptation.period.duration,o=Math.min(e+r,a),s=Math.max(e-r,i),u=NaN,l=null;o<=a||s>=i;){var c=null,f=null;if(o<=a&&(c=A(t,n,o)),s>=i&&(f=A(t,n,s)),f){u=s,l=f;break}if(c){u=o,l=c;break}o+=r,s-=r}if(l){var d=l.startTime+l.duration;return e>=l.startTime&&d-e>r?e:e=s.startTime&&l-e>r?e:e=i*f-.5*c.d&&(l=!0),!1})),u},getSegmentByTime:function(e,r){if(o(),!e)return null;void 0===r&&(r=null);var i=null,u=n.calcMediaTimeFromPresentationTime(r,e);return s(e,(function(r,o,s,l,c,f,d){var h=parseFloat((u*c).toPrecision(15));if(h=r){var p=o.media,g=l.mediaRange;return s&&(p=s[d].media||"",g=s[d].mediaRange),i=Object(a.b)(n,t,e,r,l.d,c,p,g,f,l.tManifest),!0}return!1})),i},getMediaFinishedInformation:function(e){if(!e)return 0;var t,n,r,i,a,o,s,l=(e.adaptation.period.mpd.manifest.Period_asArray[e.adaptation.period.index].AdaptationSet_asArray[e.adaptation.index].Representation_asArray[e.index].SegmentTemplate||e.adaptation.period.mpd.manifest.Period_asArray[e.adaptation.period.index].AdaptationSet_asArray[e.adaptation.index].Representation_asArray[e.index].SegmentList).SegmentTimeline,c=0,f=0,d=0;for(s=e.timescale,i=(t=l.S_asArray).length,r=0;r0)for(o=0;o=i&&t-n=n&&console.log(this.time+" ["+e+"] "+t)}},l=function(e){for(var t=[],n=0;n32&&(u.log("ERROR","Too large cursor position "+this.pos),this.pos=32)},moveCursor:function(e){var t=this.pos+e;if(e>1)for(var n=this.pos+1;n=144&&this.backSpace();var t=n(e);this.pos>=32?u.log("ERROR","Cannot insert "+e.toString(16)+" ("+t+") at position "+this.pos+". Skipping it!"):(this.chars[this.pos].setChar(t,this.currPenState),this.moveCursor(1))},clearFromPos:function(e){var t;for(t=e;t<32;t++)this.chars[t].reset()},clear:function(){this.clearFromPos(0),this.pos=0,this.currPenState.reset()},clearToEndOfRow:function(){this.clearFromPos(this.pos)},getTextString:function(){for(var e=[],t=!0,n=0;n<32;n++){var r=this.chars[n].uchar;" "!==r&&(t=!1),e.push(r)}return t?"":e.join("")},setPenStyles:function(e){this.currPenState.setStyles(e),this.chars[this.pos].setPenState(this.currPenState)}};var h=function(){this.rows=[];for(var e=0;e<15;e++)this.rows.push(new d);this.currRow=14,this.nrRollUpRows=null,this.reset()};h.prototype={reset:function(){for(var e=0;e<15;e++)this.rows[e].clear();this.currRow=14},equals:function(e){for(var t=!0,n=0;n<15;n++)if(!this.rows[n].equals(e.rows[n])){t=!1;break}return t},copy:function(e){for(var t=0;t<15;t++)this.rows[t].copy(e.rows[t])},isEmpty:function(){for(var e=!0,t=0;t<15;t++)if(!this.rows[t].isEmpty()){e=!1;break}return e},backSpace:function(){this.rows[this.currRow].backSpace()},clearToEndOfRow:function(){this.rows[this.currRow].clearToEndOfRow()},insertChar:function(e){this.rows[this.currRow].insertChar(e)},setPen:function(e){this.rows[this.currRow].setPenStyles(e)},moveCursor:function(e){this.rows[this.currRow].moveCursor(e)},setCursor:function(e){u.log("INFO","setCursor: "+e),this.rows[this.currRow].setCursor(e)},setPAC:function(e){u.log("INFO","pacData = "+JSON.stringify(e));var t=e.row-1;this.nrRollUpRows&&t0&&(n=e?"["+t.join(" | ")+"]":t.join("\n")),n},getTextAndFormat:function(){return this.rows}};var p=function(e,t){this.chNr=e,this.outputFilter=t,this.mode=null,this.verbose=0,this.displayedMemory=new h,this.nonDisplayedMemory=new h,this.lastOutputScreen=new h,this.currRollUpRow=this.displayedMemory.rows[14],this.writeScreen=this.displayedMemory,this.mode=null,this.cueStartTime=null};p.prototype={modes:["MODE_ROLL-UP","MODE_POP-ON","MODE_PAINT-ON","MODE_TEXT"],reset:function(){this.mode=null,this.displayedMemory.reset(),this.nonDisplayedMemory.reset(),this.lastOutputScreen.reset(),this.currRollUpRow=this.displayedMemory.rows[14],this.writeScreen=this.displayedMemory,this.mode=null,this.cueStartTime=null,this.lastCueEndTime=null},getHandler:function(){return this.outputFilter},setHandler:function(e){this.outputFilter=e},setPAC:function(e){this.writeScreen.setPAC(e)},setBkgData:function(e){this.writeScreen.setBkgData(e)},setMode:function(e){e!==this.mode&&(this.mode=e,u.log("INFO","MODE="+e),"MODE_POP-ON"==this.mode?this.writeScreen=this.nonDisplayedMemory:(this.writeScreen=this.displayedMemory,this.writeScreen.reset()),"MODE_ROLL-UP"!==this.mode&&(this.displayedMemory.nrRollUpRows=null,this.nonDisplayedMemory.nrRollUpRows=null),this.mode=e)},insertChars:function(e){for(var t=0;t=46,t.italics)t.foreground="white";else{var n=Math.floor(e/2)-16;t.foreground=["white","green","blue","cyan","red","yellow","magenta"][n]}u.log("INFO","MIDROW: "+JSON.stringify(t)),this.writeScreen.setPen(t)},outputDataUpdate:function(){var e=u.time;null!==e&&this.outputFilter&&(this.outputFilter.updateData&&this.outputFilter.updateData(e,this.displayedMemory),null!==this.cueStartTime||this.displayedMemory.isEmpty()?this.displayedMemory.equals(this.lastOutputScreen)||(this.outputFilter.newCue&&this.outputFilter.newCue(this.cueStartTime,e,this.lastOutputScreen),this.cueStartTime=this.displayedMemory.isEmpty()?null:e):this.cueStartTime=e,this.lastOutputScreen.copy(this.displayedMemory))},cueSplitAtTime:function(e){this.outputFilter&&(this.displayedMemory.isEmpty()||(this.outputFilter.newCue&&this.outputFilter.newCue(this.cueStartTime,e,this.displayedMemory),this.cueStartTime=e))}};var g=function(e,t,n){this.field=e||1,this.outputs=[t,n],this.channels=[new p(1,t),new p(2,n)],this.currChNr=-1,this.lastCmdA=null,this.lastCmdB=null,this.bufferedData=[],this.startTime=null,this.lastTime=null,this.dataCounters={padding:0,char:0,cmd:0,other:0}};g.prototype={getHandler:function(e){return this.channels[e].getHandler()},setHandler:function(e,t){this.channels[e].setHandler(t)},addData:function(e,t){var n,r,i,a=!1;this.lastTime=e,u.setTime(e);for(var o=0;o=16&&r<=31&&r===this.lastCmdA&&i===this.lastCmdB)this.lastCmdA=null,this.lastCmdB=null,u.log("DEBUG","Repeated command ("+l([r,i])+") is dropped");else if(0!==r||0!==i){if(u.log("DATA","["+l([t[o],t[o+1]])+"] -> ("+l([r,i])+")"),(n=this.parseCmd(r,i))||(n=this.parseMidrow(r,i)),n||(n=this.parsePAC(r,i)),n||(n=this.parseBackgroundAttributes(r,i)),!n)if(a=this.parseChars(r,i))if(this.currChNr&&this.currChNr>=0)this.channels[this.currChNr-1].insertChars(a);else u.log("WARNING","No channel found yet. TEXT-MODE?");n?this.dataCounters.cmd+=2:a?this.dataCounters.char+=2:(this.dataCounters.other+=2,u.log("WARNING","Couldn't parse cleaned data "+l([r,i])+" orig: "+l([t[o],t[o+1]])))}else this.dataCounters.padding+=2},parseCmd:function(e,t){var n=null;if(!((20===e||21===e||28===e||29===e)&&32<=t&&t<=47)&&!((23===e||31===e)&&33<=t&&t<=35))return!1;n=20===e||21===e||23===e?1:2;var r=this.channels[n-1];return 20===e||21===e||28===e||29===e?32===t?r.cc_RCL():33===t?r.cc_BS():34===t?r.cc_AOF():35===t?r.cc_AON():36===t?r.cc_DER():37===t?r.cc_RU(2):38===t?r.cc_RU(3):39===t?r.cc_RU(4):40===t?r.cc_FON():41===t?r.cc_RDC():42===t?r.cc_TR():43===t?r.cc_RTD():44===t?r.cc_EDM():45===t?r.cc_CR():46===t?r.cc_ENM():47===t&&r.cc_EOC():r.cc_TO(t-32),this.lastCmdA=e,this.lastCmdB=t,this.currChNr=n,!0},parseMidrow:function(e,t){var n=null;if((17===e||25===e)&&32<=t&&t<=47){if((n=17===e?1:2)!==this.currChNr)return u.log("ERROR","Mismatch channel in midrow parsing"),!1;var r=this.channels[n-1];return r.insertChars([32]),r.cc_MIDROW(t),u.log("DEBUG","MIDROW ("+l([e,t])+")"),this.lastCmdA=e,this.lastCmdB=t,!0}return!1},parsePAC:function(e,t){var n,s=null;if(!((17<=e&&e<=23||25<=e&&e<=31)&&64<=t&&t<=127)&&!((16===e||24===e)&&64<=t&&t<=95))return!1;n=e<=23?1:2,s=64<=t&&t<=95?1===n?r[e]:a[e]:1===n?i[e]:o[e];var u=this.interpretPAC(s,t);return this.channels[n-1].setPAC(u),this.lastCmdA=e,this.lastCmdB=t,this.currChNr=n,!0},interpretPAC:function(e,t){var n=t,r={color:null,italics:!1,indent:null,underline:!1,row:e};return n=t>95?t-96:t-64,r.underline=1==(1&n),n<=13?r.color=["white","green","blue","cyan","red","yellow","magenta","white"][Math.floor(n/2)]:n<=15?(r.italics=!0,r.color="white"):r.indent=4*Math.floor((n-16)/2),r},parseChars:function(e,t){var r=null,i=null,a=null;if(e>=25?(r=2,a=e-8):(r=1,a=e),17<=a&&a<=19){var o=t;o=17===a?t+80:18===a?t+112:t+144,u.log("INFO","Special char '"+n(o)+"' in channel "+r),i=[o],this.lastCmdA=e,this.lastCmdB=t}else 32<=e&&e<=127&&(i=0===t?[e]:[e,t],this.lastCmdA=null,this.lastCmdB=null);if(i){var s=l(i);u.log("DEBUG","Char codes = "+s.join(","))}return i},parseBackgroundAttributes:function(e,t){var n,r,i;return((16===e||24===e)&&32<=t&&t<=47||(23===e||31===e)&&45<=t&&t<=47)&&(n={},16===e||24===e?(r=Math.floor((t-32)/2),n.background=s[r],t%2==1&&(n.background=n.background+"_semi")):45===t?n.background="transparent":(n.foreground="black",47===t&&(n.underline=!0)),i=e<24?1:2,this.channels[i-1].setBkgData(n),this.lastCmdA=e,this.lastCmdB=t,!0)},reset:function(){for(var e=0;e=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,o=!0,s=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,a=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw a}}}}function h(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n/g,">").replace(/"/g,""").replace(/'/g,"'"):e}function u(e,t,n,r){for(var i=0;i0&&u(e.arrayAccessFormPaths,t,n,r)&&(t[n]=[t[n]])}function c(e){var t=e.split(/[-T:+Z]/g),n=new Date(t[0],t[1]-1,t[2]),r=t[5].split(".");if(n.setHours(t[3],t[4],r[0]),r.length>1&&n.setMilliseconds(r[1]),t[6]&&t[7]){var i=60*t[6]+Number(t[7]);i=0+("-"==(/\d\d-\d\d:\d\d$/.test(e)?"-":"+")?-1*i:i),n.setMinutes(n.getMinutes()-i-n.getTimezoneOffset())}else-1!==e.indexOf("Z",e.length-1)&&(n=new Date(Date.UTC(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours(),n.getMinutes(),n.getSeconds(),n.getMilliseconds())));return n}function f(n,r,i,a){return!(r==t&&e.xmlElementsFilter.length>0)||u(e.xmlElementsFilter,n,i,a)}function d(s,h){if(s.nodeType==a){for(var p=new Object,g=s.childNodes,m=0;m0){var i=r.split(".#")[0];return u(e.datetimeAccessFormPaths,t,n,i)?c(t):t}return t}(p.__text,_,h+"."+_)),null!=p["#cdata-section"]&&(p.__cdata=p["#cdata-section"],delete p["#cdata-section"],"property"==e.arrayAccessForm&&delete p["#cdata-section_asArray"]),0==p.__cnt&&"text"==e.emptyNodeForm?p="":1==p.__cnt&&null!=p.__text?p=p.__text:1!=p.__cnt||null==p.__cdata||e.keepCData?p.__cnt>1&&null!=p.__text&&e.skipEmptyTextNodesForObj&&(e.stripWhitespaces&&""==p.__text||""==p.__text.trim())&&delete p.__text:p=p.__cdata,delete p.__cnt,!e.enableToStringFunc||null==p.__text&&null==p.__cdata||(p.toString=function(){return(null!=this.__text?this.__text:"")+(null!=this.__cdata?this.__cdata:"")}),p}if(s.nodeType==n||s.nodeType==r)return s.nodeValue}function h(t,n,r,i){var a="<"+(null!=t&&null!=t.__prefix?t.__prefix+":":"")+n;if(null!=r)for(var o=0;o":">"}function p(e,t){return""}function g(t,n){return"property"==e.arrayAccessForm&&(r=n.toString(),i="_asArray",-1!==r.indexOf(i,r.length-i.length))||0==n.toString().indexOf(e.attributePrefix)||0==n.toString().indexOf("__")||t[n]instanceof Function;var r,i}function m(e){var t=0;if(e instanceof Object)for(var n in e)g(e,n)||t++;return t}function y(t,n,r){return 0==e.jsonPropertiesFilter.length||""==r||u(e.jsonPropertiesFilter,t,n,r)}function E(t){var n=[];if(t instanceof Object)for(var r in t)-1==r.toString().indexOf("__")&&0==r.toString().indexOf(e.attributePrefix)&&n.push(r);return n}function _(t){var n="";return t instanceof Object?n+=function(t){var n="";return null!=t.__cdata&&(n+=""),null!=t.__text&&(e.escapeMode?n+=s(t.__text):n+=t.__text),n}(t):null!=t&&(e.escapeMode?n+=s(t):n+=t),n}function T(e,t){return""===e?t:e+"."+t}function v(e,t,n,r){var i="";if(0==e.length)i+=h(e,t,n,!0);else for(var a=0;a0)for(var r in e)if(!g(e,r)&&(""==t||y(e,r,T(t,r)))){var i=e[r],a=E(i);if(null==i||null==i)n+=h(i,r,a,!0);else if(i instanceof Object)if(i instanceof Array)n+=v(i,r,a,t);else if(i instanceof Date)n+=h(i,r,a,!1),n+=i.toISOString(),n+=p(i,r);else{m(i)>0||null!=i.__text||null!=i.__cdata?(n+=h(i,r,a,!1),n+=S(i,T(t,r)),n+=p(i,r)):n+=h(i,r,a,!0)}else n+=h(i,r,a,!1),n+=_(i),n+=p(i,r)}return n+=_(e)}this.parseXmlString=function(e){var t;window.ActiveXObject||window;if(void 0===e)return null;if(window.DOMParser){var n=new window.DOMParser;try{(t=n.parseFromString(e,"text/xml")).getElementsByTagNameNS("*","parsererror").length>0&&(t=null)}catch(e){t=null}}else 0==e.indexOf("")+2)),(t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e);return t},this.asArray=function(e){return void 0===e||null==e?[]:e instanceof Array?e:[e]},this.toXmlDateTime=function(e){return e instanceof Date?e.toISOString():"number"==typeof e?new Date(e).toISOString():null},this.asDateTime=function(e){return"string"==typeof e?c(e):e},this.xml2json=function(e){return d(e)},this.xml_str2json=function(e){var t=this.parseXmlString(e);return null!=t?this.xml2json(t):null},this.json2xml_str=function(e){return S(e,"")},this.json2xml=function(e){var t=this.json2xml_str(e);return this.parseXmlString(t)},this.getVersion=function(){return"1.2.0"}}},function(e,t,n){"use strict";var r=n(3),i=n(29),a=n(16),o=n(1);function s(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var n=[],r=!0,i=!1,a=void 0;try{for(var o,s=e[Symbol.iterator]();!(r=(o=s.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{r||null==s.return||s.return()}finally{if(i)throw a}}return n}(e,t)||u(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e,t){if(e){if("string"==typeof e)return l(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(e,t):void 0}}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nt/4/e.length}))).length>1){var n=0,r=(e[e.length-1].ts-e[0].ts)/e.length;return e.forEach((function(t,i){var a=e[i+1];if(a){var o=a.ts-t.ts;n+=o=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,o=!0,s=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,a=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw a}}}}(r.headers.keys());try{for(p.s();!(a=p.n()).done;){var g=a.value;c+=g+": "+r.headers.get(g)+"\r\n"}}catch(e){p.e(e)}finally{p.f()}if(e.response.responseHeaders=c,!r.body)return r.arrayBuffer().then((function(t){e.response.response=t;var n={loaded:t.byteLength,total:t.byteLength,stream:!1};e.progress(n),e.onload(),e.onend()}));var m,y,v=parseInt(r.headers.get("Content-Length"),10),S=0,A=!1,b=new Uint8Array,I=0;if(E===o.a.ABR_FETCH_THROUGHPUT_CALCULATION_AAST&&i){var R=n,N=0,C=s(r.body.tee(),2),D=C[0],w=C[1];m=D.getReader(),y=[],m.read().then((function r(a){var o=a.value,s=a.done;if(N=Date.now(),o&&o.length){var u=N-R,l=o.length;y.push({chunkDownloadTimeRelativeMS:N-n,chunkDownloadDurationMS:u,chunkBytes:l,kbps:Math.round(8*l/(u/1e3)),bufferLevel:t.getCurrentBufferLevel(h.mediaType)})}if(s){var f=N-n,d=y.reduce((function(e,t){return e+t.chunkBytes}),0);return i.addMeasurement(h,f,y,_,T,c),void e.progress({loaded:d,total:d,lengthComputable:!0,time:i.getEstimatedDownloadDurationMS(h),stream:!0})}return R=Date.now(),m.read().then(r)})),e.reader=w.getReader()}else e.reader=r.body.getReader();var O=[],M=[],P=[],L=!0;f(e,(function t(n){var r=n.value;if(n.done){if(b){if(E!==o.a.ABR_FETCH_THROUGHPUT_CALCULATION_AAST){var i=null,a=null;E===o.a.ABR_FETCH_THROUGHPUT_CALCULATION_MOOF_PARSING?(i=function(e,t){try{var n,r;n=e.filter((function(t,n){return n1){for(var a=0,o=0,s=0;s1)i.push(8*r[s].bytes/u);else{0===o&&(o=n[s].ts);var l=r[s].ts-o;l>1?(i.push(8*a/l),a=0,o=0):a+=r[s].bytes}}if(i.length>0)return i.reduce((function(e,t){return e+t}),0)/i.length}return null}catch(e){return null}}(M,P))&&(a=8*S/i):E===o.a.ABR_FETCH_THROUGHPUT_CALCULATION_DOWNLOADED_DATA&&(a=d(O,S)),e.progress({loaded:S,total:isNaN(v)?S:v,lengthComputable:!0,time:a,stream:!0})}e.response.response=b.buffer}return e.onload(),void e.onend()}if(r&&r.length>0){if(b=function(e,t){if(0===e.length)return t;var n=new Uint8Array(e.length+t.length);return n.set(e),n.set(t,e.length),n}(b,r),S+=r.length,O.push({ts:Date.now(),bytes:r.length}),E===o.a.ABR_FETCH_THROUGHPUT_CALCULATION_MOOF_PARSING&&L)l.findLastTopIsoBoxCompleted(["moof"],b,I).found&&(L=!1,M.push({ts:performance.now(),bytes:r.length}));var s=l.findLastTopIsoBoxCompleted(["moov","mdat"],b,I);if(s.found){var u,c=s.lastCompletedOffset+s.size;E!==o.a.ABR_FETCH_THROUGHPUT_CALCULATION_MOOF_PARSING||L||(L=!0,P.push({ts:performance.now(),bytes:b.length})),c===b.length?(u=b,b=new Uint8Array):(u=new Uint8Array(b.subarray(0,c)),b=b.subarray(c)),e.progress({data:u.buffer,lengthComputable:!1,noTrace:!0}),I=0}else I=s.lastCompletedOffset,A||(e.progress({lengthComputable:!1,noTrace:!0}),A=!0)}f(e,t)}))})).catch((function(t){e.onerror&&e.onerror(t)}))}))},abort:function(e){if(e.abortController)e.abortController.abort();else if(e.reader)try{e.reader.cancel(),e.onabort()}catch(e){}},calculateDownloadedTime:d,setup:function(e){t=e.dashMetrics}}}c.__dashjs_factory_name="FetchLoader";var f=r.a.getClassFactory(c),d=n(5),h=n(10),p=n(42),g=n(15),m=n(6),y=n(7),E=n(2);function _(){var e,t,n=this.context,r={};function i(){t=Object(m.a)(n).getInstance().getLogger(e)}function a(e){for(var t={},n=0,r=0,i=0,a=0,o=e.length,s=0;se.bitrate&&(n=!1):t=e.bitrate})),n}return e={setup:i,addMeasurement:function(e,t,n,i,o){e&&e.mediaType&&!r[e.mediaType]&&(r[e.mediaType]=[]);var s=e.mediaInfo.bitrateList.find((function(t){return t.id===e.representationId}));r[e.mediaType].push({index:e.index,repId:e.representationId,mediaType:e.mediaType,requestTimeMS:i,adjustedAvailabilityStartTimeMS:e.availabilityStartTime.getTime(),segDurationMS:1e3*e.duration,chunksDurationMS:n.reduce((function(e,t){return e+t.chunkDownloadDurationMS}),0),segmentBytes:n.reduce((function(e,t){return e+t.chunkBytes}),0),bitrate:s&&s.bandwidth,bitrateList:e.mediaInfo.bitrateList,chunkMeasurements:n,fetchDownloadDurationMS:t,throughputCapacityDelayMS:o,getEstimatedBufferLevel:a(n.slice(1))}),r[e.mediaType].length>10&&r[e.mediaType].shift()},getThroughputCapacityDelayMS:function(e,t){var n=r[e.mediaType]&&r[e.mediaType].slice(-3);return!n||n.length<3?0:o(n)?t/4>250?250:t/4:0},getEstimatedDownloadDurationMS:function(e){var n=r[e.mediaType].slice(-1).pop(),i=r[e.mediaType].slice(-3),a=n.chunkMeasurements.slice(-1).pop().chunkDownloadTimeRelativeMS;n.bufferLevelAtSegmentStart=n.getEstimatedBufferLevel(a/2),n.bufferLevelAtSegmentEnd=n.getEstimatedBufferLevel(a);var s=o(i),u=s?.6:.8;if(n.isBufferStable&&1.05*n.segDurationMS.2*n.chunkMeasurements.length){var g=c/f,m=n.segmentBytes/g;return n.fetchDownloadDurationMSn.bitrate)return y=e.bandwidth,!0})),y===n.bitrate?n.fetchDownloadDurationMS*u:u*n.segmentBytes*8*1e3/y}},i(),e}_.__dashjs_factory_name="LowLatencyThroughputModel";var T=r.a.getSingletonFactory(_),v=n(31);function S(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function A(e){e=e||{};var t,n,r,s,u,l,c,_,A,b,I=this.context,R=e.errHandler,N=e.dashMetrics,C=e.mediaPlayerModel,D=e.requestModifier,w=e.boxParser,O=e.errors,M=e.requestTimeout||0,P=Object(y.a)(I).getInstance(),L=Object(a.a)(I).getInstance();function F(e,t){var a,p=e.request,m=[],y=!0,T=!0,v=new Date,S=v,b=0,O=null;if(!D||!N||!R)throw new Error("config object is not correct or missing");var x,U=function(e){if(T=!1,p.requestStartDate=v,p.requestEndDate=new Date,p.firstByteDate=p.firstByteDate||v,p.fileLoaderType=O,!p.checkExistenceOnly){var t=a.response?a.response.responseURL:null,n=a.response?a.response.status:null,r=a.response&&a.response.getAllResponseHeaders?a.response.getAllResponseHeaders():a.response?a.response.responseHeaders:[];N.addHttpRequest(p,t,n,r,e?m:null),p.type===d.a.MPD_TYPE&&N.addManifestUpdate(p)}},B=function(){if(-1!==n.indexOf(a)&&(n.splice(n.indexOf(a),1),T))if(U(!1),t>0){try{if(L.get().streaming.utcSynchronization.enableBackgroundSyncAfterSegmentDownloadError&&p.type===d.a.MEDIA_SEGMENT_TYPE)C.getRetryAttemptsForType(d.a.MEDIA_SEGMENT_TYPE)===t&&P.trigger(E.a.ATTEMPT_BACKGROUND_SYNC)}catch(e){}t--;var r={config:e};s.push(r),r.timeout=setTimeout((function(){-1!==s.indexOf(r)&&(s.splice(s.indexOf(r),1),F(e,t))}),C.getRetryIntervalsForType(p.type))}else{if(p.type===d.a.MSS_FRAGMENT_INFO_SEGMENT_TYPE)return;R.error(new h.a(u[p.type],p.url+" is not available",{request:p,response:a.response})),e.error&&e.error(p,"error",a.response.statusText),e.complete&&e.complete(p,a.response.statusText)}};p.hasOwnProperty("availabilityTimeComplete")&&!1===p.availabilityTimeComplete&&window.fetch&&"arraybuffer"===p.responseType&&p.type===d.a.MEDIA_SEGMENT_TYPE?((x=f(I).create({requestModifier:D,lowLatencyThroughputModel:_,boxParser:w})).setup({dashMetrics:N}),O=o.a.FILE_LOADER_TYPES.FETCH):(x=Object(i.a)(I).create({requestModifier:D}),O=o.a.FILE_LOADER_TYPES.XHR);var k=null,G=D.modifyRequestURL(p.url);if(L.get().streaming.cmcd&&L.get().streaming.cmcd.enabled){var j=L.get().streaming.cmcd.mode;if(j===o.a.CMCD_MODE_QUERY){var Y=function(e){try{var t=[],n=l.getQueryParameter(e);return n&&t.push(n),t}catch(e){return[]}}(p);G=g.a.addAditionalQueryParameterToUrl(G,Y)}else j===o.a.CMCD_MODE_HEADER&&(k=l.getHeaderParameters(p))}p.url=G;var H=p.checkExistenceOnly?d.a.HEAD:d.a.GET,V=c.getXHRWithCredentialsForType(p.type);a={url:G,method:H,withCredentials:V,request:p,onload:function(){a.response.status>=200&&a.response.status<=299&&(U(!0),e.success&&e.success(a.response.response,a.response.statusText,a.response.responseURL),e.complete&&e.complete(p,a.response.statusText))},onend:B,onerror:B,progress:function(t){var n=new Date;y&&(y=!1,(!t.lengthComputable||t.lengthComputable&&t.total!==t.loaded)&&(p.firstByteDate=n)),t.lengthComputable&&(p.bytesLoaded=t.loaded,p.bytesTotal=t.total),t.noTrace||(m.push({s:S,d:t.time?t.time:n.getTime()-S.getTime(),b:[t.loaded?t.loaded-b:0]}),S=n,b=t.loaded),e.progress&&t&&e.progress(t)},onabort:function(){e.abort&&e.abort(p)},ontimeout:function(e){var t;if(e.lengthComputable){var n=e.loaded/e.total*100;t="Request timeout: loaded: "+e.loaded+", out of: "+e.total+" : "+n.toFixed(3)+"% Completed"}else t="Request timeout: non-computable download size";A.warn(t)},loader:x,timeout:M,headers:k};var K=(new Date).getTime();if(isNaN(p.delayLoadingTime)||K>=p.delayLoadingTime)n.push(a),x.load(a);else{var q={httpRequest:a};r.push(q),q.delayTimeout=setTimeout((function(){if(-1!==r.indexOf(q)){r.splice(r.indexOf(q),1);try{v=new Date,S=v,n.push(q.httpRequest),x.load(q.httpRequest)}catch(e){q.httpRequest.onerror()}}}),p.delayLoadingTime-K)}}return t={load:function(e){e.request?F(e,C.getRetryAttemptsForType(e.request.type)):e.error&&e.error(e.request,"error")},abort:function(){s.forEach((function(e){clearTimeout(e.timeout),e.config.request&&e.config.abort&&e.config.abort(e.config.request)})),s=[],r.forEach((function(e){return clearTimeout(e.delayTimeout)})),r=[],n.forEach((function(e){e.request.type!==d.a.MSS_FRAGMENT_INFO_SEGMENT_TYPE&&(e.onloadend=e.onerror=e.onprogress=void 0,e.loader.abort(e))})),n=[]}},A=Object(m.a)(I).getInstance().getLogger(t),n=[],r=[],s=[],l=Object(p.a)(I).getInstance(),_=T(I).getInstance(),c=Object(v.a)(I).getInstance(),S(b={},d.a.MPD_TYPE,O.DOWNLOAD_ERROR_ID_MANIFEST_CODE),S(b,d.a.XLINK_EXPANSION_TYPE,O.DOWNLOAD_ERROR_ID_XLINK_CODE),S(b,d.a.INIT_SEGMENT_TYPE,O.DOWNLOAD_ERROR_ID_INITIALIZATION_CODE),S(b,d.a.MEDIA_SEGMENT_TYPE,O.DOWNLOAD_ERROR_ID_CONTENT_CODE),S(b,d.a.INDEX_SEGMENT_TYPE,O.DOWNLOAD_ERROR_ID_CONTENT_CODE),S(b,d.a.BITSTREAM_SWITCHING_SEGMENT_TYPE,O.DOWNLOAD_ERROR_ID_CONTENT_CODE),S(b,d.a.OTHER_TYPE,O.DOWNLOAD_ERROR_ID_CONTENT_CODE),u=b,t}A.__dashjs_factory_name="HTTPLoader";var b=r.a.getClassFactory(A);function I(){var e;function t(){e={}}function n(){t()}return n(),{getLoader:function(t){for(var n in e)if(e.hasOwnProperty(n)&&t.startsWith(n))return e[n];return b},registerLoader:function(t,n){e[t]=n},unregisterLoader:function(t){e[t]&&delete e[t]},unregisterAllLoader:t,reset:n}}I.__dashjs_factory_name="SchemeLoaderFactory";var R=r.a.getSingletonFactory(I);t.a=R},function(e,t,n){(function(e){function n(e){return Object.prototype.toString.call(e)}t.isArray=function(e){return Array.isArray?Array.isArray(e):"[object Array]"===n(e)},t.isBoolean=function(e){return"boolean"==typeof e},t.isNull=function(e){return null===e},t.isNullOrUndefined=function(e){return null==e},t.isNumber=function(e){return"number"==typeof e},t.isString=function(e){return"string"==typeof e},t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=function(e){return void 0===e},t.isRegExp=function(e){return"[object RegExp]"===n(e)},t.isObject=function(e){return"object"==typeof e&&null!==e},t.isDate=function(e){return"[object Date]"===n(e)},t.isError=function(e){return"[object Error]"===n(e)||e instanceof Error},t.isFunction=function(e){return"function"==typeof e},t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=e.isBuffer}).call(this,n(64).Buffer)},function(e,t,n){t.generateISD=n(78).generateISD,t.fromXML=n(79).fromXML,t.renderHTML=n(95).render},function(e,t,n){"use strict";var r=n(3),i=n(14);function a(){return{customTimeRangeArray:[],length:0,add:function(e,t){var n=0;for(n=0;nthis.customTimeRangeArray[n].start;n++);for(this.customTimeRangeArray.splice(n,0,{start:e,end:t}),n=0;n=this.customTimeRangeArray[n].end)this.customTimeRangeArray.splice(n,1),n--;else{if(e>this.customTimeRangeArray[n].start&&tthis.customTimeRangeArray[n].start&&ethis.customTimeRangeArray[n].start&&t=this.customTimeRangeArray.length||e<0?NaN:this.customTimeRangeArray[e].start},end:function(e){return Object(i.a)(e),e>=this.customTimeRangeArray.length||e<0?NaN:this.customTimeRangeArray[e].end}}}a.__dashjs_factory_name="CustomTimeRanges",t.a=r.a.getClassFactory(a)},function(e,t,n){"use strict";n.d(t,"b",(function(){return s}));var r=n(3),i=n(34),a=n(1),o=[{codec:"avc1",compatibleCodecs:["avc3"]},{codec:"avc3",compatibleCodecs:["avc1"]}];function s(){var e="WebKitMediaSource"in window,t="MediaSource"in window;return e||t}function u(){var e,t,n;return e={setConfig:function(e){e&&e.settings&&(t=e.settings)},supportsMediaSource:s,supportsEncryptedMedia:function(){return n},supportsCodec:function(e,n){return n!==a.a.AUDIO&&n!==a.a.VIDEO?Promise.resolve(!0):function(e,n){return t.get().streaming.capabilities.useMediaCapabilitiesApi&&navigator.mediaCapabilities&&navigator.mediaCapabilities.decodingInfo&&(e.codec&&n===a.a.AUDIO||n===a.a.VIDEO&&e.codec&&e.width&&e.height&&e.bitrate&&e.framerate)}(e,n)?function(e,t){return new Promise((function(n){if(e&&e.codec){var r={type:"media-source"};r[t]={},r[t].contentType=e.codec,r[t].width=e.width,r[t].height=e.height,r[t].bitrate=parseInt(e.bitrate),r[t].framerate=parseFloat(e.framerate),navigator.mediaCapabilities.decodingInfo(r).then((function(e){n(e.supported)})).catch((function(){n(!1)}))}else n(!1)}))}(e,n):function(e){return new Promise((function(t){if(e&&e.codec){var n=e.codec;e.width&&e.height&&(n+=';width="'+e.width+'";height="'+e.height+'"'),"MediaSource"in window&&MediaSource.isTypeSupported(n)||"WebKitMediaSource"in window&&WebKitMediaSource.isTypeSupported(n)?t(!0):t(!1)}else t(!1)}))}(e)},setEncryptedMediaSupported:function(e){n=e},supportsEssentialProperty:function(e){try{return-1!==i.a.indexOf(e.schemeIdUri)}catch(e){return!0}},codecRootCompatibleWithCodec:function(e,t){for(var n,r=e.split(".")[0],i=0===t.indexOf(r),a=0;a0&&void 0!==arguments[0]?arguments[0]:null;return parseFloat((P(e)-U()).toFixed(5))}function P(e){var t=e||m;return t.start+t.duration}function L(){m&&c&&c.getElement()?c.play():E=!0}function F(){m&&c&&c.pause()}function x(e,n,r){m&&c&&(e!==(isNaN(A)?c.getTime():A)&&((b=!0===r)||(A=e),t.info("Requesting seek to time: "+e+(b?" (internal)":"")),c.setCurrentTime(e,n)))}function U(){return m&&c?c.getTime():null}function B(){return m&&c?c.isPaused():null}function k(){return m&&c?c.isSeeking():null}function G(){return m&&c?c.isStalled():null}function j(){return m&&c?c.getPlaybackRate():null}function Y(){return m&&c?c.getEnded():null}function H(){return y}function V(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(!B()&&y&&0!==c.getReadyState()&&!k()&&!R){e||(e=n.hasVideoTrack()?a.a.VIDEO:a.a.AUDIO);var r=U(),i=K(r,e),o=!isNaN(i)&&i!==r;o&&!k()&&(G()||I||1===c.getReadyState())&&(t.debug("UpdateCurrentTime: Seek to actual time: ".concat(i," from currentTime: ").concat(r)),x(i,!1,!1))}}function K(e,t){var n=i.getCurrentDVRInfo(t),r=n?n.range:null;return r?e>r.end?Math.max(r.end-g,r.start):e>0&&e+.25_+500)&&(_=e,ie())):V())}),C.get().streaming.wallclockTimeUpdateInterval))}function W(){clearInterval(p),p=null}function z(e){var t=o.convertRepresentationToRepresentationInfo(e.currentRepresentation),n=t?t.mediaInfo.streamInfo:null;null!==n&&m.id===n.id&&(m=n)}function X(){w.trigger(l.a.CAN_PLAY)}function Q(){w.trigger(l.a.CAN_PLAY_THROUGH)}function $(e){e.streamId===n.getActiveStreamInfo().id&&(I=e.state===s.a.BUFFER_EMPTY,C.get().streaming.buffer.setStallState&&c.setStallState(e.mediaType,e.state===s.a.BUFFER_EMPTY))}function Z(){t.info("Native video element event: play"),V(),q(),w.trigger(l.a.PLAYBACK_STARTED,{startTime:U()})}function J(){t.info("Native video element event: waiting"),w.trigger(l.a.PLAYBACK_WAITING,{playingTime:U()})}function ee(){t.info("Native video element event: playing"),b=!1,w.trigger(l.a.PLAYBACK_PLAYING,{playingTime:U()})}function te(){t.info("Native video element event: pause"),w.trigger(l.a.PLAYBACK_PAUSED,{ended:Y()})}function ne(){if(!b){var e=U();isNaN(A)||A===e||(e=A),A=NaN,t.info("Seeking to: "+e),q(),w.trigger(l.a.PLAYBACK_SEEKING,{seekTime:e,streamId:m.id})}}function re(){t.info("Native video element event: seeked"),b=!1,w.trigger(l.a.PLAYBACK_SEEKED)}function ie(){m&&w.trigger(l.a.PLAYBACK_TIME_UPDATED,{timeToEnd:M(),time:U(),streamId:m.id})}function ae(){w.trigger(l.a.PLAYBACK_PROGRESS,{streamId:m.id})}function oe(){var e=j();t.info("Native video element event: ratechange: ",e),w.trigger(l.a.PLAYBACK_RATE_CHANGED,{playbackRate:e})}function se(){t.info("Native video element event: loadedmetadata"),w.trigger(l.a.PLAYBACK_METADATA_LOADED),q()}function ue(){t.info("Native video element event: loadeddata"),w.trigger(l.a.PLAYBACK_LOADED_DATA)}function le(){t.info("Native video element event: ended"),F(),W();var e=n?n.getActiveStreamInfo():null;e&&w.trigger(l.a.PLAYBACK_ENDED,{isLast:e.isLast})}function ce(){w.trigger(l.a.PLAYBACK_VOLUME_CHANGED)}function fe(e){if(p&&e.isLast){t.info("onPlaybackEnded -- PLAYBACK_ENDED but native video element didn't fire ended");var n=e.seekTime?e.seekTime:P();c.setCurrentTime(n),F(),W()}}function de(e){var t=e.target||e.srcElement;w.trigger(l.a.PLAYBACK_ERROR,{error:t.error})}function he(e){if(!1===e.stream&&S&&!isNaN(e.request.duration)){var n=1.2*e.request.duration;n>g&&(t.warn("Browser does not support fetch API with StreamReader. Increasing live delay to be 20% higher than segment duration:",n.toFixed(2)),g=n)}}function pe(e){w.trigger(l.a.PLAYBACK_STALLED,{e:e})}function ge(e){var n;(n=e.mediaInfo)&&n.supplementalProperties&&"true"===n.supplementalProperties[a.a.SUPPLEMENTAL_PROPERTY_DVB_LL_SCHEME]&&(t.debug("Low Latency critical SupplementalProperty set: Enabling low Latency"),S=!0)}function me(e){var t=n.getActiveStreamInfo();e&&t&&e.currentRepresentation&&e.streamId&&e.streamId===t.id&&e.mediaType&&(e.mediaType===a.a.VIDEO||e.mediaType===a.a.AUDIO)&&(v=e.currentRepresentation.availabilityTimeComplete,(S=!v)&&!N&&(N=!0))}function ye(){R=!0}function Ee(){R=!1}return e={initialize:function(t,n){m=t,!0!==n&&(c.addEventListener("canplay",X),c.addEventListener("canplaythrough",Q),c.addEventListener("play",Z),c.addEventListener("waiting",J),c.addEventListener("playing",ee),c.addEventListener("pause",te),c.addEventListener("error",de),c.addEventListener("seeking",ne),c.addEventListener("seeked",re),c.addEventListener("timeupdate",ie),c.addEventListener("progress",ae),c.addEventListener("ratechange",oe),c.addEventListener("loadedmetadata",se),c.addEventListener("loadeddata",ue),c.addEventListener("stalled",pe),c.addEventListener("ended",le),c.addEventListener("volumechange",ce),y=m.manifestInfo.isDynamic,I=!1,b=!1,w.on(l.a.DATA_UPDATE_COMPLETED,z,e),w.on(l.a.LOADING_PROGRESS,he,e),w.on(l.a.MANIFEST_UPDATED,ye,e),w.on(l.a.STREAMS_COMPOSED,Ee,e),w.on(d.a.PLAYBACK_ENDED,fe,e,{priority:u.a.EVENT_PRIORITY_HIGH}),w.on(d.a.STREAM_INITIALIZING,ge,e),w.on(d.a.REPRESENTATION_SWITCH,me,e),w.on(d.a.BUFFER_LEVEL_STATE_CHANGED,$,e),E&&(E=!1,L()))},setConfig:function(e){e&&(e.streamController&&(n=e.streamController),e.serviceDescriptionController&&(r=e.serviceDescriptionController),e.dashMetrics&&(i=e.dashMetrics),e.adapter&&(o=e.adapter),e.videoModel&&(c=e.videoModel),e.timelineConverter&&(h=e.timelineConverter),e.settings&&(C=e.settings))},getTimeToStreamEnd:M,getBufferLevel:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=null;return n.getActiveStreamProcessors().forEach((function(n){if(!e||0===e.length||-1===e.indexOf(n.getType())){var r=n.getBufferLevel();t=null===t?r:Math.min(t,r)}})),t},getPlaybackStalled:function(){return I},getTime:U,getLowLatencyModeEnabled:function(){return S},getInitialCatchupModeActivated:function(){return N},getIsManifestUpdateInProgress:function(){return R},getPlaybackRate:j,getPlayedRanges:function(){return m&&c?c.getPlayedRanges():null},getEnded:Y,getIsDynamic:H,getStreamController:function(){return n},computeAndSetLiveDelay:function(e,t){var n,i,a,s=!isNaN(e)&&isFinite(e)?e:NaN,u=o.getSuggestedPresentationDelay(),l=r.getServiceDescriptionSettings();return n=isNaN(C.get().streaming.delay.liveDelay)?null===C.get().streaming.delay.liveDelayFragmentCount||isNaN(C.get().streaming.delay.liveDelayFragmentCount)||isNaN(s)?l&&!isNaN(l.liveDelay)&&l.liveDelay>0?l.liveDelay:!0===C.get().streaming.delay.useSuggestedPresentationDelay&&null!==u&&!isNaN(u)&&u>0?u:isNaN(s)?t&&!isNaN(t.minBufferTime)?4*t.minBufferTime:4*m.manifestInfo.minBufferTime:4*s:s*C.get().streaming.delay.liveDelayFragmentCount:C.get().streaming.delay.liveDelay,null!==(a=o.getAvailabilityStartTime())&&(T=a),i=t&&t.dvrWindowSize>0?Math.min(n,t.dvrWindowSize):n,g=i,i},getLiveDelay:function(){return g},getCurrentLiveLatency:function(){if(!y||isNaN(T))return NaN;var e=U();if(isNaN(e)||0===e)return 0;var t=(new Date).getTime()+1e3*h.getClientTimeOffset();return Math.max(((t-T-1e3*e)/1e3).toFixed(3),0)},play:L,isPaused:B,isStalled:G,pause:F,isSeeking:k,getStreamEndTime:P,seek:x,reset:O,updateCurrentTime:V,getAvailabilityStartTime:function(){return T}},t=Object(f.a)(D).getInstance().getLogger(e),O(),e}h.__dashjs_factory_name="PlaybackController";var p=c.a.getSingletonFactory(h),g=n(20),m=n(10),y=n(11),E=n(16),_=n(5);function T(e){var t,n,r,i,o,s,u=this.context,c=Object(E.a)(u).getInstance(),d=e.textController,h=e.eventBus,p=[],g=[],T=!1,v=e.mediaSource,S=null;function A(e){return new Promise((function(t){P((function(){i.changeType&&i.changeType(e),t()}))}))}function b(e){return i=d.getTextSourceBuffer(e),Promise.resolve()}function I(){if("function"==typeof i.addEventListener)try{i.addEventListener("updateend",O,!1),i.addEventListener("error",M,!1),i.addEventListener("abort",M,!1)}catch(e){s=setInterval(O,50)}else s=setInterval(O,50)}function R(e){return new Promise((function(t){i&&c.get().streaming.buffer.useAppendWindow?P((function(){try{if(!i)return void t();var n=v.duration,a=0;e&&!isNaN(e.start)&&!isNaN(e.duration)&&isFinite(e.duration)&&(n=e.start+e.duration),e&&!isNaN(e.start)&&(a=e.start),i.appendWindowEnd===n&&i.appendWindowStart===a||(i.appendWindowStart=0,i.appendWindowEnd=n+.01,i.appendWindowStart=Math.max(a-.1,0),r.debug("Updated append window for ".concat(o.type,". Set start to ").concat(i.appendWindowStart," and end to ").concat(i.appendWindowEnd))),t()}catch(e){r.warn("Failed to set append window"),t()}})):t()}))}function N(e){return new Promise((function(t){i?P((function(){try{i.timestampOffset===e||isNaN(e)||(i.timestampOffset=e,r.debug("Set MSE timestamp offset to ".concat(e))),t()}catch(e){t()}})):t()}))}function C(){return new Promise((function(e){P((function(){var t=i.appendWindowStart,n=i.appendWindowEnd;i&&(i.abort(),i.appendWindowStart=t,i.appendWindowEnd=n),e()}))}))}function D(){if(!T&&g.length>0){T=!0;var e=g[0];g.splice(0,1);var t=function(){T=!1,g.length>0&&D.call(this),e&&e.data&&e.data.segmentType&&e.data.segmentType!==_.a.INIT_SEGMENT_TYPE&&delete e.data.bytes,e.promise.resolve({chunk:e.data})};try{S=e.request,0===e.data.bytes.byteLength?t.call(this):(i.appendBuffer?i.appendBuffer(e.data.bytes):i.append(e.data.bytes,e.data),P(t.bind(this)))}catch(t){r.fatal('SourceBuffer append failed "'+t+'"'),g.length>0?D():T=!1,delete e.data.bytes,e.promise.reject({chunk:e.data,error:new m.a(t.code,t.message)})}}}function w(){p.length>0&&(i.updating||(p.shift()(),w()))}function O(){i.updating||w()}function M(e){var t,r,i=e.target||{};t=l.a.SOURCE_BUFFER_ERROR,r={error:i,lastRequestAppended:S}||{},h.trigger(t,r,{streamId:o.streamInfo.id,mediaType:n})}function P(e){p.push(e),i.updating||w()}return t={getType:function(){return n},getAllBufferRanges:function(){try{return i.buffered}catch(e){return r.error("getAllBufferRanges exception: "+e.message),null}},getBuffer:function(){return i},append:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return new Promise((function(r,i){e?(g.push({data:e,promise:{resolve:r,reject:i},request:n}),P(D.bind(t))):i({chunk:e,error:new m.a(y.a.APPEND_ERROR_CODE,y.a.APPEND_ERROR_MESSAGE)})}))},remove:function(e){return new Promise((function(t,n){var r=e.start,a=e.end;r>=0&&a>r?P((function(){try{i.remove(r,a),P((function(){t({from:r,to:a,unintended:!1}),e.resolve&&e.resolve()}))}catch(t){n({from:r,to:a,unintended:!1,error:new m.a(y.a.REMOVE_ERROR_CODE,y.a.REMOVE_ERROR_MESSAGE)}),e.reject&&e.reject(t)}})):t()}))},abort:function(){return new Promise((function(e){try{g=[],"open"===v.readyState?P((function(){try{i&&i.abort(),e()}catch(t){e()}})):i&&i.setTextTrack&&"ended"===v.readyState?(i.abort(),e()):e()}catch(t){e()}}))},reset:function(){if(i){try{p=[],function(){try{"function"==typeof i.removeEventListener&&(i.removeEventListener("updateend",O,!1),i.removeEventListener("error",M,!1),i.removeEventListener("abort",M,!1)),clearInterval(s)}catch(e){r.error(e)}}(),T=!1,g=[],i.getClassName&&"TextSourceBuffer"===i.getClassName()||(r.debug("Removing sourcebuffer from media source"),v.removeSourceBuffer(i))}catch(e){}i=null}S=null},updateTimestampOffset:N,initializeForStreamSwitch:function(e,t,r){n=(o=e).type;var a=o.codec;!function(e){i=e.getBuffer()}(r),I();var s=[];return s.push(C),s.push(R(o.streamInfo)),s.push(A(a)),t&&void 0!==t.MSETimeOffset&&s.push(N(t.MSETimeOffset)),Promise.all(s)},initializeForFirstUse:function(e,t,r){n=(o=t).type;var s=o.codec;try{if(s.match(/application\/mp4;\s*codecs="(stpp|wvtt).*"/i))return b(e);i=v.addSourceBuffer(s),I();var u=[];return u.push(R(o.streamInfo)),r&&void 0!==r.MSETimeOffset&&u.push(N(r.MSETimeOffset)),Promise.all(u)}catch(t){return o.type==a.a.TEXT&&!o.isFragmented||-1!==s.indexOf('codecs="stpp')||-1!==s.indexOf('codecs="vtt')?b(e):Promise.reject(t)}},updateAppendWindow:R,changeType:A},r=Object(f.a)(u).getInstance().getLogger(t),t}T.__dashjs_factory_name="SourceBufferSink";var v=c.a.getClassFactory(T);function S(){var e={};return{save:function(t){var n=t.streamId,r=t.representationId;e[n]=e[n]||{},e[n][r]=t},extract:function(t,n){return e&&e[t]&&e[t][n]?e[t][n]:null},reset:function(){e={}}}}S.__dashjs_factory_name="InitCache";var A=c.a.getSingletonFactory(S);function b(e){e=e||{};var t,n,r,i,o,c,h,p,E,T,S,b,I,R,N,C,D,w,O=this.context,M=Object(u.a)(O).getInstance(),P=e.errHandler,L=e.fragmentModel,F=e.representationController,x=e.adapter,U=e.textController,B=e.abrController,k=e.playbackController,G=e.streamInfo,j=e.type,Y=e.settings;function H(e){c=e}function V(e){return x.convertRepresentationToRepresentationInfo(F.getRepresentationForQuality(e))}function K(e,t,n){var r=V(n);return t&&t[j]&&(j===a.a.VIDEO||j===a.a.AUDIO)?E.initializeForStreamSwitch(e,r,t[j]):E.initializeForFirstUse(G,e,r)}function q(e){Y.get().streaming.cacheInitSegments&&(n.info("Init fragment finished loading saving to",j+"'s init cache"),N.save(e.chunk)),n.debug("Append Init fragment",j," with representationId:",e.chunk.representationId," and quality:",e.chunk.quality,", data size:",e.chunk.bytes.byteLength),z(e.chunk)}function W(e){z(e.chunk,e.request)}function z(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;E.append(e,t).then((function(e){Q(e)})).catch((function(e){Q(e)})),e.mediaInfo.type===a.a.VIDEO&&Ee(l.a.VIDEO_CHUNK_RECEIVED,{chunk:e})}function X(e){if(e&&e.length>0)for(var t=0,r=e.length;t0){var e=Math.max(.2*o,1),t=o-e,r=Math.min(Y.get().streaming.buffer.bufferTimeAtTopQuality,.9*t),i=Math.min(Y.get().streaming.buffer.bufferTimeAtTopQualityLongForm,.9*t),a={streaming:{buffer:{bufferToKeep:parseFloat(e.toFixed(5)),bufferTimeAtTopQuality:parseFloat(r.toFixed(5)),bufferTimeAtTopQualityLongForm:parseFloat(i.toFixed(5))}}};Y.update(a)}}(),void(22!==e.error.code&&ye()||(n.warn("Clearing playback buffer to overcome quota exceed situation"),Ee(l.a.QUOTA_EXCEEDED,{criticalBufferLevel:o,quotaExceededTime:e.chunk.start}),ue(se())));if(E&&(re(),R=!1,(S=e.chunk)&&S.endFragment)){S&&!isNaN(S.index)&&(h=Math.max(S.index,h),ie());var t=E.getAllBufferRanges();S.segmentType===_.a.MEDIA_SEGMENT_TYPE&&(X(t),J(),function(){if(isNaN(w))return;if(j!==a.a.AUDIO&&j!==a.a.VIDEO)return void(w=NaN);var e=k.getTime(),t=ne(e,0),n=ne(w,0);if(t&&n&&t.start===n.start)return void(w=NaN);var r=F.getCurrentRepresentation().segmentDuration,i=ne(w,r);if(!i)return;Y.get().streaming.buffer.enableSeekDecorrelationFix&&Math.abs(e-w)>r?w<=i.end&&k.seek(Math.max(w,i.start),!1,!0):en){var i=Math.max(0,e-n),a=L.getRequests({state:g.a.FRAGMENT_MODEL_EXECUTED,time:e,threshold:.01})[0];if(a&&(i=Math.min(a.startTime,i)),i>0)return{start:r,end:i}}return null}(e,n),i=function(e,t){var n=t.end(t.length-1)+.5,r=G.manifestInfo.duration>=Y.get().streaming.buffer.longFormContentDurationThreshold?Y.get().streaming.buffer.bufferTimeAtTopQualityLongForm:Y.get().streaming.buffer.bufferTimeAtTopQuality;if(n-e>r){var i=e+r,a=L.getRequests({state:g.a.FRAGMENT_MODEL_EXECUTED,time:e,threshold:.01})[0];if(a&&(i=Math.max(a.startTime+a.duration,i)),i=a&&e=p-1,t=k.getTimeToStreamEnd(G)-i<1e-5;!e&&!t||r||(ge(!0),n.debug("checkIfBufferingCompleted trigger BUFFERING_COMPLETED for stream id ".concat(G.id," and type ").concat(j)))}function ae(){j!==a.a.AUDIO&&j!==a.a.VIDEO||((!k.getLowLatencyModeEnabled()&&i=Y.get().streaming.buffer.stallThreshold||k.getLowLatencyModeEnabled()&&i>0)&&oe(s.a.BUFFER_LOADED))}function oe(e){T===e||e===s.a.BUFFER_EMPTY&&0===k.getTime()||j===a.a.TEXT&&!U.isTextEnabled()||(T=e,Ee(l.a.BUFFER_LEVEL_STATE_CHANGED,{state:e}),Ee(e===s.a.BUFFER_LOADED?l.a.BUFFER_LOADED:l.a.BUFFER_EMPTY),n.debug(e===s.a.BUFFER_LOADED?"Got enough buffer to start":"Waiting for more buffer before starting playback"))}function se(){var e=[],t=E.getAllBufferRanges();if(!t||0===t.length)return e;var n=k.getTime(),r=Math.max(0,n-Y.get().streaming.buffer.bufferToKeep),i=L.getRequests({state:g.a.FRAGMENT_MODEL_EXECUTED,time:n,threshold:.01})[0];if(i)r=Math.min(i.startTime,r);else if(0===n&&k.getIsDynamic())return[];if(t.start(0)<=r){for(var a={start:0,end:r},o=0;o=Y.get().streaming.buffer.bufferPruningInterval&&(b=0,E&&j!==a.a.TEXT&&(r||ue(se())))}function pe(){ae()}function ge(e){r!==e&&((r=e)?Ee(l.a.BUFFERING_COMPLETED):p=Number.POSITIVE_INFINITY)}function me(){try{var e,t,n=E.getAllBufferRanges(),r=0;if(!n)return r;for(t=0,e=n.length;t1&&void 0!==arguments[1]?arguments[1]:[];return new Promise((function(r,i){if(N&&e&&c){var a=B.getQualityFor(j,G.id);E=v(O).create({mediaSource:c,textController:U,eventBus:M}),K(e,t,a).then((function(){return fe(V(a))})).then((function(){r(E)})).catch((function(e){n.fatal("Caught error on create SourceBuffer: "+e),P.error(new m.a(y.a.MEDIASOURCE_TYPE_UNSUPPORTED_CODE,y.a.MEDIASOURCE_TYPE_UNSUPPORTED_MESSAGE+j)),i(e)}))}else r(null)}))},getBuffer:function(){return E},getBufferLevel:function(){return i},getRangeAt:ne,setMediaSource:H,getMediaSource:function(){return c},appendInitSegmentFromCache:function(e){var t=N.extract(G.id,e);return!!t&&(n.info("Append Init fragment",j," with representationId:",t.representationId," and quality:",t.quality,", data size:",t.bytes.byteLength),z(t),!0)},getIsBufferingCompleted:function(){return r},setIsBufferingCompleted:ge,getIsPruningInProgress:function(){return I},reset:function(e,t){M.off(l.a.INIT_FRAGMENT_LOADED,q,this),M.off(l.a.MEDIA_FRAGMENT_LOADED,W,this),M.off(l.a.WALLCLOCK_TIME_UPDATED,he,this),M.off(d.a.PLAYBACK_PLAYING,te,this),M.off(d.a.PLAYBACK_PROGRESS,J,this),M.off(d.a.PLAYBACK_TIME_UPDATED,J,this),M.off(d.a.PLAYBACK_RATE_CHANGED,pe,this),M.off(d.a.PLAYBACK_STALLED,ee,this),_e(e,t)},prepareForPlaybackSeek:function(){return r&&ge(!1),E.abort()},prepareForReplacementTrackSwitch:function(e){return new Promise((function(t,n){E.abort().then((function(){return de()})).then((function(){return E.changeType(e)})).then((function(){return $()})).then((function(){ge(!1),t()})).catch((function(e){n(e)}))}))},prepareForNonReplacementTrackSwitch:function(e){return new Promise((function(t,n){de().then((function(){return E.changeType(e)})).then((function(){t()})).catch((function(e){n(e)}))}))},prepareForReplacementQualitySwitch:function(){return new Promise((function(e,t){E.abort().then((function(){return de()})).then((function(){return $()})).then((function(){ge(!1),e()})).catch((function(e){t(e)}))}))},updateAppendWindow:de,getAllRangesWithSafetyFactor:Z,getContinuousBufferTimeForTargetTime:function(e){try{var t=e,n=E.getAllBufferRanges();if(!n||0===n.length)return NaN;for(var r=0;t===e&&r=i&&t<=a&&(t=a),r+=1}return t===e?NaN:t}catch(e){}},clearBuffers:ue,pruneAllSafely:$,updateBufferTimestampOffset:fe,setSeekTarget:function(e){w=e},segmentRequestingCompleted:function(e){isNaN(e)||(p=e,ie())}},n=Object(f.a)(O).getInstance().getLogger(t),N=A(O).getInstance(),_e(),t}b.__dashjs_factory_name="BufferController";var I=c.a.getClassFactory(b);function R(e){e=e||{};var t,n,r,i,a,o,s=this.context,c=Object(u.a)(s).getInstance(),f=e.textController,d=e.errHandler,h=e.streamInfo,p=e.type;function g(e){i=e}function E(e){var t,r,i;n!==e&&((n=e)&&(t=l.a.BUFFERING_COMPLETED,i=r||{},c.trigger(t,i,{streamId:h.id,mediaType:p})))}function _(e){e.chunk.bytes&&!n&&(o.save(e.chunk),a.append(e.chunk),E(!0))}return t={initialize:function(e){g(e)},getStreamId:function(){return h.id},getType:function(){return p},getBufferControllerType:function(){return"NotFragmentedTextBufferController"},createBufferSink:function(e){return new Promise((function(t,n){try{(a=v(s).create({mediaSource:i,textController:f,eventBus:c})).initializeForFirstUse(h,e),r||(a.getBuffer()&&"function"==typeof a.getBuffer().initialize&&a.getBuffer().initialize(),r=!0),t(a)}catch(e){d.error(new m.a(y.a.MEDIASOURCE_TYPE_UNSUPPORTED_CODE,y.a.MEDIASOURCE_TYPE_UNSUPPORTED_MESSAGE+p)),n(e)}}))},getBuffer:function(){return a},getBufferLevel:function(){return 0},getRangeAt:function(){return null},getAllRangesWithSafetyFactor:function(){return[]},getContinuousBufferTimeForTargetTime:function(){return Number.POSITIVE_INFINITY},setMediaSource:g,getMediaSource:function(){return i},appendInitSegmentFromCache:function(e){return null!==o.extract(h.id,e)},getIsBufferingCompleted:function(){return n},setIsBufferingCompleted:E,getIsPruningInProgress:function(){return!1},reset:function(e){c.off(l.a.INIT_FRAGMENT_LOADED,_,t),!e&&a&&(a.abort(),a.reset(),a=null)},clearBuffers:function(){return Promise.resolve()},prepareForPlaybackSeek:function(){return Promise.resolve()},prepareForReplacementTrackSwitch:function(){return n=!1,Promise.resolve()},setSeekTarget:function(){},updateAppendWindow:function(){return Promise.resolve()},pruneAllSafely:function(){return Promise.resolve()},updateBufferTimestampOffset:function(){return Promise.resolve()},segmentRequestingCompleted:function(){}},r=!1,i=null,n=!1,o=A(s).getInstance(),c.on(l.a.INIT_FRAGMENT_LOADED,_,t),t}R.__dashjs_factory_name="NotFragmentedTextBufferController";var N=c.a.getClassFactory(R);function C(e){e=e||{};var t,n,r,i,o,c,h,p,m,y,E,_,T,v=this.context,S=Object(u.a)(v).getInstance(),A=e.dashMetrics,b=e.mediaPlayerModel,I=e.fragmentModel,R=e.abrController,N=e.playbackController,C=e.textController,D=e.type,w=e.bufferController,O=e.settings;function M(e){if(!w.getIsBufferingCompleted()){P();var t=isNaN(e)?0:e;c=setTimeout(L,t)}}function P(){c&&(clearTimeout(c),c=null)}function L(){try{if(function(){try{return D===a.a.TEXT&&!C.isTextEnabled()||N.isPaused()&&(!N.getStreamController().getInitialPlayback()||!N.getStreamController().getAutoPlay())&&!O.get().streaming.scheduling.scheduleWhilePaused}catch(e){return!1}}())return void P();if(function(){try{return i&&(isNaN(y)||E||(e=n.id,t=R.getMaxAllowedIndexFor(D,e),!(!isNaN(m)&&m==t||(r.info("Top quality "+D+" index has changed from "+m+" to "+t),m=t,0)))||function(){if(!D||!i)return!0;return A.getCurrentBufferLevel(D)=O.get().streaming.buffer.longFormContentDurationThreshold?O.get().streaming.buffer.bufferTimeAtTopQualityLongForm:O.get().streaming.buffer.bufferTimeAtTopQuality:b.getStableBufferTime()}catch(e){return b.getStableBufferTime()}}():e}function x(){U(!0)}function U(e){if(N&&I){var t=I.getRequests({state:g.a.FRAGMENT_MODEL_EXECUTED,time:N.getTime(),threshold:0})[0];t&&N.getTime()>=t.startTime&&((!p.mediaInfo||t.mediaInfo.type===p.mediaInfo.type&&t.mediaInfo.id!==p.mediaInfo.id)&&e&&S.trigger(l.a.TRACK_CHANGE_RENDERED,{mediaType:D,oldMediaInfo:p.mediaInfo,newMediaInfo:t.mediaInfo,streamId:n.id}),t.quality===p.quality&&t.adaptationIndex===p.adaptationIndex||!e||(r.debug("Quality change rendered for streamId ".concat(n.id," and type ").concat(D)),S.trigger(l.a.QUALITY_CHANGE_RENDERED,{mediaType:D,oldQuality:p.quality,newQuality:t.quality,streamId:n.id})),p={mediaInfo:t.mediaInfo,quality:t.quality,adaptationIndex:t.adaptationIndex})}}function B(e){r.debug("Appended bytes for ".concat(e.mediaType," and stream id ").concat(n.id)),(isNaN(e.index)||isNaN(y))&&(y=e.quality,r.info("["+D+"] lastInitializedRepresentationInfo changed to "+e.quality)),M(0)}function k(){I.abortRequests(),P()}function G(){O.get().streaming.scheduling.scheduleWhilePaused||M()}function j(e){A.updatePlayListTraceMetrics({playbackspeed:e.playbackRate.toString()})}function Y(){T=!0,o=0,y=NaN,p={mediaInfo:void 0,quality:NaN,adaptationIndex:NaN},m=NaN,E=!1,_=!1}return t={initialize:function(e){h=e,S.on(l.a.BYTES_APPENDED_END_FRAGMENT,B,t),S.on(l.a.URL_RESOLUTION_FAILED,k,t),S.on(d.a.PLAYBACK_STARTED,G,t),S.on(d.a.PLAYBACK_RATE_CHANGED,j,t),S.on(d.a.PLAYBACK_TIME_UPDATED,x,t)},getType:function(){return D},getStreamId:function(){return n.id},setCurrentRepresentation:function(e){i=e},setTimeToLoadDelay:function(e){o=e},getTimeToLoadDelay:function(){return o},setSwitchTrack:function(e){E=e},getSwitchStrack:function(){return E},startScheduleTimer:M,clearScheduleTimer:P,reset:function(){S.off(l.a.BYTES_APPENDED_END_FRAGMENT,B,t),S.off(l.a.URL_RESOLUTION_FAILED,k,t),S.off(d.a.PLAYBACK_STARTED,G,t),S.off(d.a.PLAYBACK_RATE_CHANGED,j,t),S.off(d.a.PLAYBACK_TIME_UPDATED,x,t),P(),U(!1),Y(),n=null},getBufferTarget:F,getPlaybackController:function(){return N},setCheckPlaybackQuality:function(e){T=e},setInitSegmentRequired:function(e){_=e}},r=Object(f.a)(v).getInstance().getLogger(t),Y(),n=e.streamInfo,t}C.__dashjs_factory_name="ScheduleController";var D=c.a.getClassFactory(C),w=n(58),O=n(14),M=n(37),P=n(26),L=n(13),F=n(22);function x(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var U=function e(){x(this,e),this.start=null,this.mstart=null,this.starttype=null,this.trace=[]};U.INITIAL_PLAYOUT_START_REASON="initial_playout",U.SEEK_START_REASON="seek",U.RESUME_FROM_PAUSE_START_REASON="resume",U.METRICS_COLLECTION_START_REASON="metrics_collection_start";var B=function e(){x(this,e),this.representationid=null,this.subreplevel=null,this.start=null,this.mstart=null,this.duration=null,this.playbackspeed=null,this.stopreason=null};B.REPRESENTATION_SWITCH_STOP_REASON="representation_switch",B.REBUFFERING_REASON="rebuffering",B.USER_REQUEST_STOP_REASON="user_request",B.END_OF_PERIOD_STOP_REASON="end_of_period",B.END_OF_CONTENT_STOP_REASON="end_of_content",B.METRICS_COLLECTION_STOP_REASON="metrics_collection_end",B.FAILURE_STOP_REASON="failure";var k=n(38);function G(e){e=e||{};var t,n,r,i,c,d,h,p,E,T,v,S,A,b=this.context,R=Object(u.a)(b).getInstance(),C=e.streamInfo,x=e.type,U=e.errHandler,G=e.mimeType,j=e.timelineConverter,Y=e.adapter,H=e.manifestModel,V=e.mediaPlayerModel,K=e.fragmentModel,q=e.abrController,W=e.playbackController,z=e.mediaController,X=e.textController,Q=e.dashMetrics,$=e.settings,Z=e.boxParser,J=e.segmentBlacklistController;function ee(){return C.id}function te(){return x}function ne(){return Y.getIsTextTrack(p.getData())}function re(){c=[],i=null,A=0,E=!1,T=!1}function ie(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(e.sender)if(W.getIsManifestUpdateInProgress())le();else if((!ne()||X.isTextEnabled())&&d&&e.representationId&&!d.appendInitSegmentFromCache(e.representationId)){var n=p.getCurrentRepresentation();if(0===n.range)return void ae();var r=v?v.getInitRequest(i,n):null;r?K.executeRequest(r):t&&(h.setInitSegmentRequired(!0),le())}}function ae(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(W.getIsManifestUpdateInProgress()||d.getIsPruningInProgress())le();else{var n=ue();n?(E=!1,oe(n)):se(t)}}function oe(e){isNaN(e.startTime+e.duration)||(A=e.startTime+e.duration),e.delayLoadingTime=(new Date).getTime()+h.getTimeToLoadDelay(),h.setTimeToLoadDelay(0),!function(e){var t=e.url;e.range&&(t=t.concat("_",e.range));return J.contains(t)}(e)?(n.debug("Next fragment request url for stream id ".concat(C.id," and media type ").concat(x," is ").concat(e.url)),K.executeRequest(e)):(n.warn("Fragment request url ".concat(e.url," for stream id ").concat(C.id," and media type ").concat(x," is on the ignore list and will be skipped")),le())}function se(e){var t,a=p.getCurrentRepresentation();if($.get().streaming.gaps.enableSeekFix&&(E||0===W.getTime())&&(r?r&&a.segmentInfoType===o.a.SEGMENT_TIMELINE&&(t=v.getValidTimeAheadOfTargetTime(A,i,a,$.get().streaming.gaps.threshold)):t=v.getValidTimeAheadOfTargetTime(A,i,a,$.get().streaming.gaps.threshold),!isNaN(t)&&t!==A))return void(W.isSeeking()||0===W.getTime()?(n.warn("Adjusting playback time ".concat(t," because of gap in the manifest. Seeking by ").concat(t-A)),W.seek(t,!1,!1)):(n.warn("Adjusting buffering time ".concat(t," because of gap in the manifest. Adjusting time by ").concat(t-A)),De(t),e&&le()));if(v.isLastSegmentRequested(a,A)){var s=v.getCurrentIndex();return n.debug("Segment requesting for stream ".concat(C.id," has finished")),R.trigger(l.a.STREAM_REQUESTING_COMPLETED,{segmentIndex:s},{streamId:C.id,mediaType:x}),d.segmentRequestingCompleted(s),void h.clearScheduleTimer()}e&&le()}function ue(){var e,t=Ae();if(isNaN(A)||te()===a.a.TEXT&&!X.isTextEnabled())return null;var n=E;if(v){var r=p&&t?p.getRepresentationForQuality(t.quality):null;e=n?v.getSegmentRequestForTime(i,r,A):v.getNextSegmentRequest(i,r)}return e}function le(){h.startScheduleTimer(W.getLowLatencyModeEnabled()?$.get().streaming.scheduling.lowLatencyTimeout:$.get().streaming.scheduling.defaultTimeout)}function ce(e){e.error||(h.setCurrentRepresentation(Y.convertRepresentationToRepresentationInfo(e.currentRepresentation)),d.getIsBufferingCompleted()||d.updateBufferTimestampOffset(e.currentRepresentation))}function fe(e){Q.addBufferState(x,e.state,h.getBufferTarget()),e.state!==s.a.BUFFER_EMPTY||W.isSeeking()||(n.info("Buffer is empty! Stalling!"),Q.pushPlayListTraceMetrics(new Date,B.REBUFFERING_REASON))}function de(e){K.syncExecutedRequestsWithBufferedRange(d.getBuffer().getAllBufferRanges(),C.duration),e.quotaExceeded&&e.from>W.getTime()&&De(e.from),e.hasEnoughSpaceToAppend&&e.quotaExceeded&&h.startScheduleTimer()}function he(e){if(e&&e.lastRequestAppended&&e.lastRequestAppended.url){var t=e.lastRequestAppended.url;e.lastRequestAppended.range&&(t=t.concat("_",e.lastRequestAppended.range)),n.warn("Blacklisting segment with url ".concat(t)),J.add(t)}}function pe(){Ne(),T=!1}function ge(e){n.info("onFragmentLoadingAbandoned request: "+e.request.url+" has been aborted"),W.isSeeking()||h.getSwitchStrack()||T||(n.info("onFragmentLoadingAbandoned request: "+e.request.url+" has to be downloaded again, origin is not seeking process or switch track call"),e.request&&e.request.isInitializationRequest()?h.setInitSegmentRequired(!0):De(e.request.startTime+e.request.duration/2),h.startScheduleTimer(0))}function me(e){n.info("OnFragmentLoadingCompleted for stream id "+C.id+" and media type "+x+" - Url:",e.request?e.request.url:"undefined",e.request.range?", Range:"+e.request.range:""),ne()&&h.startScheduleTimer(0),e.error&&e.request.serviceLocation&&function(e){if(n.info("Fragment loading completed with an error"),!e||!e.request||!e.request.type)return;e.request.type===_.a.INIT_SEGMENT_TYPE?ie({representationId:e.request.representationId,sender:{}},!1):e.request.type===_.a.MEDIA_SEGMENT_TYPE&&(De(e.request.startTime+e.request.duration/2),ae({},!1))}(e)}function ye(){De(W.getTime()),Se().startScheduleTimer()}function Ee(e){var t=e.currentTrackInfo;if(t){var n=c.find((function(e){return e.index===t.index&&e.lang===t.lang}));n&&ve(n).then((function(){d.setIsBufferingCompleted(!1),De(W.getTime()),h.setInitSegmentRequired(!0),h.startScheduleTimer()}))}}function _e(e){De(e.quotaExceededTime),h.clearScheduleTimer()}function Te(){return d?d.getBuffer():null}function ve(e){e===i||e&&i&&e.type!==i.type||(i=e);var t=Y.getRealAdaptation(C,i),n=Y.getVoRepresentations(i);if(p){var o,s=p.getData(),u=q.getMaxAllowedIndexFor(x,C.id),l=q.getMinAllowedIndexFor(x,C.id),c=null;return null!==s&&s.id===t.id||x===a.a.TEXT?o=q.getQualityFor(x,C.id):(c=q.getThroughputHistory().getAverageThroughput(x,r)||q.getInitialBitrateFor(x,C.id),o=q.getQualityForBitrate(i,c,C.id)),void 0!==l&&ou&&(o=u),p.updateData(t,n,x,i.isFragmented,o)}return Promise.resolve()}function Se(){return h}function Ae(e){var t;return void 0!==e?(Object(O.a)(e),t=p?p.getRepresentationForQuality(e):null):t=p?p.getCurrentRepresentation():null,Y.convertRepresentationToRepresentationInfo(t)}function be(){return!!d&&d.getIsBufferingCompleted()}function Ie(e){var t=e.chunk,n=t.bytes,r=t.quality,i=Ae(r),a=p&&i?p.getRepresentationForQuality(i.quality):null;if(i&&a){var o=Y.getEventsFor(i.mediaInfo,null,C),s=Y.getEventsFor(i,a,C);if(o&&o.length>0||s&&s.length>0){var u=function(e,t,n,r){try{for(var i={},a=[],o=n.concat(r),s=0,u=o.length;s$.get().streaming.buffer.stallThreshold;if(d.getIsBufferingCompleted()&&!t)return d.prepareForNonReplacementTrackSwitch(i.codec).then((function(){R.trigger(l.a.BUFFERING_COMPLETED,{},{streamId:C.id,mediaType:x})})).catch((function(){R.trigger(l.a.BUFFERING_COMPLETED,{},{streamId:C.id,mediaType:x})})),void e();h.clearScheduleTimer(),h.setSwitchTrack(!0),t?(R.trigger(l.a.BUFFER_REPLACEMENT_STARTED,{mediaType:x,streamId:C.id},{mediaType:x,streamId:C.id}),K.abortRequests(),d.prepareForReplacementTrackSwitch(i.codec).then((function(){var e=Ae();return d.updateBufferTimestampOffset(e)})).then((function(){Re(),e()})).catch((function(){Re(),e()}))):d.prepareForNonReplacementTrackSwitch(i.codec).then((function(){Ne(),e()})).catch((function(){Ne(),e()}))}))},prepareQualityChange:function(e){n.debug("Preparing quality switch for type ".concat(x));var t=e.newQuality;T=!0,h.clearScheduleTimer();var r=Ae(t);h.setCurrentRepresentation(r),p.prepareQualityChange(t),K.abortRequests(),d.updateBufferTimestampOffset(r).then((function(){e.reason&&e.reason.forceReplace?(R.trigger(l.a.BUFFER_REPLACEMENT_STARTED,{mediaType:x,streamId:C.id},{mediaType:x,streamId:C.id}),d.prepareForReplacementQualitySwitch().then((function(){Re(),T=!1})).catch((function(){Re(),T=!1}))):$.get().streaming.buffer.fastSwitchEnabled?function(e){var t=W.getTime(),n=K.getRequests({state:g.a.FRAGMENT_MODEL_EXECUTED,time:t+1.5,threshold:0})[0];if(n&&!ne()){var r=d.getBufferLevel(),i=q.getAbandonmentStateFor(C.id,x);if(n.quality=1.5&&i!==s.a.ABANDON_LOAD)De(t+1.5),h.setCheckPlaybackQuality(!1),h.startScheduleTimer();else pe()}else h.startScheduleTimer();T=!1}(r):pe(),Q.pushPlayListTraceMetrics(new Date,B.REPRESENTATION_SWITCH_STOP_REASON),Q.createPlaylistTraceMetrics(r.id,1e3*W.getTime(),W.getPlaybackRate())}))},getMediaInfo:function(){return i},getMediaSource:function(){return d.getMediaSource()},setMediaSource:function(e){d.setMediaSource(e)},getBuffer:Te,setExplicitBufferingTime:De,finalisePlayList:function(e,t){Q.pushPlayListTraceMetrics(e,t)},probeNextRequest:function(){var e=Ae(),t=p&&e?p.getRepresentationForQuality(e.quality):null;return v.getNextSegmentRequestIdempotent(i,t)},prepareInnerPeriodPlaybackSeeking:function(e){return new Promise((function(t){h.clearScheduleTimer(),K.abortRequests(),d.prepareForPlaybackSeek().then((function(){var t=d.getAllRangesWithSafetyFactor(e.seekTime);return d.clearBuffers(t)})).then((function(){var n=d.getContinuousBufferTimeForTargetTime(e.seekTime);if(!isNaN(n)&&!isNaN(C.duration)&&isFinite(C.duration)&&n>=C.start+C.duration)d.setIsBufferingCompleted(!0),t();else{var r=isNaN(n)?e.seekTime:n;De(r),d.setSeekTarget(r);var i=[];i.push(d.updateAppendWindow());var a=Ae();i.push(d.updateBufferTimestampOffset(a)),Promise.all(i).then((function(){h.setInitSegmentRequired(!0),h.setCheckPlaybackQuality(!1),h.startScheduleTimer(),t()}))}})).catch((function(e){n.error(e)}))}))},prepareOuterPeriodPlaybackSeeking:function(){return new Promise((function(e,t){try{h.clearScheduleTimer(),K.abortRequests(),d.prepareForPlaybackSeek().then((function(){return d.pruneAllSafely()})).then((function(){e()}))}catch(e){t(e)}}))},reset:function(e,n){v&&v.reset(),d&&(d.reset(e,n),d=null),h&&(h.reset(),h=null),p&&(p.reset(),p=null),S&&(S=null),q&&q.unRegisterStreamType(ee(),x),R.off(l.a.DATA_UPDATE_COMPLETED,ce,t),R.off(l.a.INIT_FRAGMENT_NEEDED,ie,t),R.off(l.a.MEDIA_FRAGMENT_NEEDED,ae,t),R.off(l.a.MEDIA_FRAGMENT_LOADED,Ie,t),R.off(l.a.BUFFER_LEVEL_STATE_CHANGED,fe,t),R.off(l.a.BUFFER_CLEARED,de,t),R.off(l.a.SEEK_TARGET,Ce,t),R.off(l.a.FRAGMENT_LOADING_ABANDONED,ge,t),R.off(l.a.FRAGMENT_LOADING_COMPLETED,me,t),R.off(l.a.SET_FRAGMENTED_TEXT_AFTER_DISABLED,ye,t),R.off(l.a.SET_NON_FRAGMENTED_TEXT,Ee,t),R.off(l.a.QUOTA_EXCEEDED,_e,t),R.off(l.a.SOURCE_BUFFER_ERROR,he,t),re(),x=null,C=null}},n=Object(f.a)(b).getInstance().getLogger(t),re(),R.on(l.a.DATA_UPDATE_COMPLETED,ce,t,{priority:u.a.EVENT_PRIORITY_HIGH}),R.on(l.a.INIT_FRAGMENT_NEEDED,ie,t),R.on(l.a.MEDIA_FRAGMENT_NEEDED,ae,t),R.on(l.a.MEDIA_FRAGMENT_LOADED,Ie,t),R.on(l.a.BUFFER_LEVEL_STATE_CHANGED,fe,t),R.on(l.a.BUFFER_CLEARED,de,t),R.on(l.a.SEEK_TARGET,Ce,t),R.on(l.a.FRAGMENT_LOADING_ABANDONED,ge,t),R.on(l.a.FRAGMENT_LOADING_COMPLETED,me,t),R.on(l.a.QUOTA_EXCEEDED,_e,t),R.on(l.a.SET_FRAGMENTED_TEXT_AFTER_DISABLED,ye,t),R.on(l.a.SET_NON_FRAGMENTED_TEXT,Ee,t),R.on(l.a.SOURCE_BUFFER_ERROR,he,t),t}G.__dashjs_factory_name="StreamProcessor";var j=c.a.getClassFactory(G),Y=n(59),H=n(62);function V(e){e=e||{};var t,n,r,i=this.context,o=Object(u.a)(i).getInstance(),s=e.errHandler,c=e.mediaPlayerModel,h=e.dashMetrics,p=Object(f.a)(i).getInstance(),m=e.streamInfo;function E(){return m.id}function _(){for(var e in r)r[e].reset();r={}}function T(e){if(e.sender){var t=e.request,r=e.response,i=t.isInitializationRequest(),s=t.mediaInfo.streamInfo;if(e.error&&(t.mediaType===a.a.AUDIO||t.mediaType===a.a.VIDEO||t.mediaType===a.a.TEXT&&t.mediaInfo.isFragmented)&&o.trigger(l.a.SERVICE_LOCATION_BLACKLIST_ADD,{entry:e.request.serviceLocation}),r&&s){var u=function(e,t,n,r){var i=new Y.a;return i.streamId=n,i.mediaInfo=t.mediaInfo,i.segmentType=t.type,i.start=t.startTime,i.duration=t.duration,i.end=i.start+i.duration,i.bytes=e,i.index=t.index,i.quality=t.quality,i.representationId=t.representationId,i.endFragment=r,i}(r,t,m.id,e.type!==l.a.FRAGMENT_LOADING_PROGRESS);o.trigger(i?l.a.INIT_FRAGMENT_LOADED:l.a.MEDIA_FRAGMENT_LOADED,{chunk:u,request:t},{streamId:s.id,mediaType:t.mediaType})}else n.warn("No "+t.mediaType+" bytes to push or stream is inactive.")}}return t={getStreamId:E,getModel:function(t){var n=r[t];return n||(n=Object(g.a)(i).create({streamInfo:m,type:t,dashMetrics:h,fragmentLoader:Object(H.a)(i).create({dashMetrics:h,mediaPlayerModel:c,errHandler:s,requestModifier:Object(P.a)(i).getInstance(),settings:e.settings,boxParser:e.boxParser,eventBus:o,events:l.a,errors:y.a,dashConstants:e.dashConstants,urlUtils:e.urlUtils,streamId:E()}),debug:p,eventBus:o,events:l.a}),r[t]=n),n},reset:function(){o.off(d.a.FRAGMENT_LOADING_COMPLETED,T,this),o.off(d.a.FRAGMENT_LOADING_PROGRESS,T,this),_()}},n=p.getLogger(t),_(),o.on(d.a.FRAGMENT_LOADING_COMPLETED,T,t),o.on(d.a.FRAGMENT_LOADING_PROGRESS,T,t),t}V.__dashjs_factory_name="FragmentController";var K=c.a.getClassFactory(V);var q=function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.url=null,this.width=null,this.height=null,this.x=null,this.y=null},W=n(34);var z=function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.mediaType=null,this.bitrate=null,this.width=null,this.height=null,this.scanType=null,this.qualityIndex=NaN},X=n(12);function Q(e){var t,n,r=this.context,i=e.streamInfo;function o(e){n.setTrackByIndex(e)}function s(){n&&n.reset()}return t={getStreamId:function(){return i.id},initialize:function(){n.addTracks();var e=n.getTracks();e&&e.length>0&&o(0)},provide:function(e,t){if("function"==typeof t){var r,i,a=n.getCurrentTrack();if(!a||a.segmentDuration<=0||null==e)t(null);else{(i=n.getThumbnailRequestForTime(e))&&(a.segmentDuration=i.duration),r=e%a.segmentDuration;var o=Math.floor(r*a.tilesHor*a.tilesVert/a.segmentDuration),s=new q;if(s.width=Math.floor(a.widthPerTile),s.height=Math.floor(a.heightPerTile),s.x=Math.floor(o%a.tilesHor)*a.widthPerTile,s.y=Math.floor(o/a.tilesHor)*a.heightPerTile,"readThumbnail"in a)return a.readThumbnail(e,(function(e){s.url=e,t(s)}));if(i)s.url=i.url,a.segmentDuration=NaN;else{var u=Math.floor(e/a.segmentDuration);s.url=function(e,t){var n=t+e.startNumber,r=Object(X.d)(e.templateUrl,"Number",n);return r=Object(X.d)(r,"Time",(n-1)*e.segmentDuration*e.timescale),r=Object(X.d)(r,"Bandwidth",e.bandwidth),Object(X.e)(r)}(a,u)}t(s)}}},setTrackByIndex:o,getCurrentTrackIndex:function(){return n.getCurrentTrackIndex()},getBitrateList:function(){var e=n.getTracks(),t=0;return e.map((function(e){var n=new z;return n.mediaType=a.a.IMAGE,n.qualityIndex=t++,n.bitrate=e.bitrate,n.width=e.width,n.height=e.height,n}))},reset:s},s(),n=Object(W.b)(r).create({streamInfo:i,adapter:e.adapter,baseURLController:e.baseURLController,timelineConverter:e.timelineConverter,debug:e.debug,eventBus:e.eventBus,events:e.events,dashConstants:e.dashConstants,dashMetrics:e.dashMetrics,segmentBaseController:e.segmentBaseController}),t}Q.__dashjs_factory_name="ThumbnailController";var $=c.a.getClassFactory(Q);function Z(e){var t;e=e||{};var n=[],r=Object(u.a)(this.context).getInstance(),i=e.updateEventName,a=e.addBlacklistEventName;function o(e){-1===n.indexOf(e)&&(n.push(e),r.trigger(i,{entry:e}))}function s(e){o(e.entry)}return t={add:o,contains:function(e){return!!(n.length&&e&&e.length)&&-1!==n.indexOf(e)},reset:function(){n=[]}},a&&r.on(a,s,t),t}Z.__dashjs_factory_name="BlackListController";var J=c.a.getClassFactory(Z),ee=[a.a.VIDEO,a.a.AUDIO,a.a.TEXT,a.a.MUXED,a.a.IMAGE];function te(e){e=e||{};var t,n,r,i,s,c,d,h,p,g,E,_,T,v,S,A,b,I,R=this.context,N=Object(u.a)(R).getInstance(),C=Object(L.a)(R).getInstance(),D=e.manifestModel,w=e.mediaPlayerModel,O=e.dashMetrics,M=e.manifestUpdater,P=e.adapter,x=e.timelineConverter,U=e.capabilities,B=e.errHandler,k=e.abrController,G=e.playbackController,Y=e.eventController,H=e.mediaController,V=e.protectionController,q=e.textController,W=e.videoModel,z=e.streamInfo,X=e.settings;function Q(t,i){return new Promise((function(s,u){se(),g=!0,le();var c,f=W.getElement();ee.forEach((function(i){(i!==a.a.VIDEO||!f||f&&/^VIDEO$/i.test(f.nodeName))&&function(t,i){var s,u=P.getAllMediaInfoForType(z,t),c=[],f=null;if(!u||0===u.length)return void n.info("No "+t+" data.");t===a.a.VIDEO&&(d=!0);t===a.a.AUDIO&&(h=!0);for(var p=0,g=u.length;p0&&(H.setInitialMediaSettingsForType(t,z),q.setInitialSettings(H.getInitialSettings(t)),q.addMediaInfosToBuffer(z,t,c));if(0===(u=u.filter((function(e){return!e.isEmbedded}))).length)return;if(t===a.a.IMAGE)return void(_=$(R).create({streamInfo:z,adapter:P,baseURLController:e.baseURLController,timelineConverter:e.timelineConverter,debug:A,eventBus:N,events:l.a,dashConstants:o.a,dashMetrics:e.dashMetrics,segmentBaseController:e.segmentBaseController})).initialize();N.trigger(l.a.STREAM_INITIALIZING,{streamInfo:z,mediaInfo:f}),H.setInitialMediaSettingsForType(t,z);var m=function(t,n){var i=t&&t.length>0?t[0]:null,o=E.getModel(i?i.type:null),s=i?i.type:null,u=i?i.mimeType:null,l=i?i.isFragmented:null,c=j(R).create({streamInfo:z,type:s,mimeType:u,timelineConverter:x,adapter:P,manifestModel:D,mediaPlayerModel:w,fragmentModel:o,dashMetrics:e.dashMetrics,baseURLController:e.baseURLController,segmentBaseController:e.segmentBaseController,abrController:k,playbackController:G,mediaController:H,textController:q,errHandler:B,settings:X,boxParser:S,segmentBlacklistController:T});c.initialize(n,d,l),r.push(c);for(var f=0;f0&&Y.addInlineEvents(e,z.id)}}function ce(){for(var e=r.length,t=!!p.audio||!!p.video?new m.a(y.a.DATA_UPDATE_FAILED_ERROR_CODE,y.a.DATA_UPDATE_FAILED_ERROR_MESSAGE):null,n=0;n0&&e.Representation[0].ContentProtection)}function _e(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(!e||!e.hasOwnProperty("getStreamInfo"))return!1;var r=e.getStreamInfo(),i=n?n.getStreamInfo():oe();if(!r||!i)return!1;var a=P.getAdaptationForType(r.index,t,r),o=P.getAdaptationForType(i.index,t,i);if(!a||!o)return!a&&!o;var s=a&&o&&a.mimeType===o.mimeType,u=o.Representation_asArray.map((function(e){return e.codecs})),l=a.Representation_asArray.map((function(e){return e.codecs})),c=l.some((function(e){return u.indexOf(e)>-1})),f=l.some((function(e){return u.some((function(t){return U.codecRootCompatibleWithCodec(t,e)}))}));return c||f&&s}function Te(e){v=e}function ve(){return v}return t={initialize:function(){N.on(l.a.BUFFERING_COMPLETED,fe,t),N.on(l.a.DATA_UPDATE_COMPLETED,de,t),N.on(l.a.INBAND_EVENTS,he,t),V&&(N.on(l.a.KEY_ERROR,ue,t),N.on(l.a.SERVER_CERTIFICATE_UPDATED,ue,t),N.on(l.a.LICENSE_REQUEST_COMPLETE,ue,t),N.on(l.a.KEY_SYSTEM_SELECTED,ue,t),N.on(l.a.KEY_SESSION_CREATED,ue,t),N.on(l.a.KEY_STATUSES_CHANGED,ue,t)),q.initializeForStream(z),N.trigger(l.a.STREAM_UPDATED,{streamInfo:z})},getStreamId:function(){return z?z.id:null},activate:function(e,t){return new Promise((function(n,r){if(!s)return ve()?(s=!0,N.trigger(l.a.STREAM_ACTIVATED,{streamInfo:z}),void n(t)):void function(e,t){return Q(e,t)}(e,t).then((function(e){s=!0,N.trigger(l.a.STREAM_ACTIVATED,{streamInfo:z}),n(e)})).catch((function(e){r(e)}));n(t)}))},deactivate:te,getIsActive:function(){return s},getDuration:function(){return z?z.duration:NaN},getStartTime:ie,getId:ae,getStreamInfo:oe,getHasAudioTrack:function(){return h},getHasVideoTrack:function(){return d},startPreloading:function(e,t){return new Promise((function(i,a){ve()?a():(n.info("[startPreloading] Preloading next stream with id ".concat(ae())),Te(!0),Q(e,t).then((function(){for(var e=0;e0;){var e=I.pop(),t=e.newMediaInfo,r=pe(e.oldMediaInfo);if(!r)return;n.push(r.prepareTrackSwitch()),r.selectMediaInfo(t)}return Promise.all(n)})).then((function(){g=!1,ce(),N.trigger(l.a.STREAM_UPDATED,{streamInfo:z}),t()}))}))},reset:function(e){E&&(E.reset(),E=null),k&&z&&k.clearDataForStream(z.id),T&&(T.reset(),T=null),ne(e),z=null,N.off(l.a.DATA_UPDATE_COMPLETED,de,t),N.off(l.a.BUFFERING_COMPLETED,fe,t),N.off(l.a.INBAND_EVENTS,he,t),V&&(N.off(l.a.KEY_ERROR,ue,t),N.off(l.a.SERVER_CERTIFICATE_UPDATED,ue,t),N.off(l.a.LICENSE_REQUEST_COMPLETE,ue,t),N.off(l.a.KEY_SYSTEM_SELECTED,ue,t),N.off(l.a.KEY_SESSION_CREATED,ue,t),N.off(l.a.KEY_STATUSES_CHANGED,ue,t))},getProcessors:me,setMediaSource:function(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:null;return _e(e,a.a.VIDEO,t)&&_e(e,a.a.AUDIO,t)},isProtectionCompatible:function(e){return!e||ye(a.a.VIDEO,e)&&ye(a.a.AUDIO,e)},getPreloaded:ve,getIsEndedEventSignaled:function(){return b},setIsEndedEventSignaled:re,getAdapter:function(){return P},getHasFinishedBuffering:function(){return c},setPreloaded:Te,startScheduleControllers:function(){for(var e=r.length,t=0;t0&&void 0!==arguments[0]&&arguments[0];s=!0;var t=h.getValue(),n=t.url,r=p.getPatchLocation(t),i=p.getLocation(t);r&&!e?n=r:i&&(n=i),T.isRelative(n)&&(n=T.resolve(n,t.url)),c.load(n)}function I(e){if(e){if(p.getIsPatch(e)){var r=e;e=h.getValue();var u=p.isPatchValid(e,r),c=u;if(u){var f=p.getPublishTime(e);c=p.applyPatchToManifest(e,r);var d=p.getPublishTime(e);c=f.getTime()!=d.getTime()}if(!c)return t.debug("Patch provided is invalid, performing full manifest refresh"),void b(!0);e.loadedTime=new Date}}else(e=h.getValue()).loadedTime=new Date;if(h.getValue()&&h.getValue().type===o.a.DYNAMIC&&e.type===o.a.STATIC)return _.trigger(l.a.DYNAMIC_TO_STATIC),s=!1,void(a=!0);h.setValue(e);var g=new Date,m=(g.getTime()-e.loadedTime.getTime())/1e3;1e3*(n=p.getManifestUpdatePeriod(e,m))>2147483647&&(n=2147483.647),_.trigger(l.a.MANIFEST_UPDATED,{manifest:e}),t.info("Manifest has been refreshed at "+g+"["+g.getTime()/1e3+"] "),i||A()}function R(){i||(s?A(m.get().streaming.manifestUpdateRetryInterval):b())}function N(e){e.error?e.error.code===y.a.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE&&g.error(e.error):I(e.manifest)}function C(){i=!1,A()}function D(){(i=!m.get().streaming.scheduling.scheduleWhilePaused)&&S()}function w(){s=!1}return e={initialize:function(){v(),_.on(l.a.STREAMS_COMPOSED,w,this),_.on(d.a.PLAYBACK_STARTED,C,this),_.on(d.a.PLAYBACK_PAUSED,D,this),_.on(l.a.INTERNAL_MANIFEST_LOADED,N,this)},setManifest:function(e){I(e)},refreshManifest:b,getIsUpdating:function(){return s},setConfig:function(e){e&&(e.manifestModel&&(h=e.manifestModel),e.adapter&&(p=e.adapter),e.manifestLoader&&(c=e.manifestLoader),e.errHandler&&(g=e.errHandler),e.settings&&(m=e.settings))},reset:function(){_.off(d.a.PLAYBACK_STARTED,C,this),_.off(d.a.PLAYBACK_PAUSED,D,this),_.off(l.a.STREAMS_COMPOSED,w,this),_.off(l.a.INTERNAL_MANIFEST_LOADED,N,this),v()}},t=Object(f.a)(E).getInstance().getLogger(e),e}re.__dashjs_factory_name="ManifestUpdater";var ie=c.a.getClassFactory(re);function ae(){var e,t,n,r,i,a,o,s,c,d,h,p,g,E,T,v,S=this.context,A=Object(u.a)(S).getInstance(),b=Object(L.a)(S).getInstance();function I(){s=[],c=[],d=null,h=null,g=null,p=NaN,n=!1,r=!1,E=i.get().streaming.utcSynchronization.timeBetweenSyncAttempts}function R(){i.get().streaming.utcSynchronization.enabled&&!n&&!r&&g&&g.value&&g.schemeIdUri&&!isNaN(p)&&!isNaN(i.get().streaming.utcSynchronization.backgroundAttempts)&&(h&&(Date.now()-h)/1e3<30||(s=[],r=!0,function e(t){try{if(t<=0)return void k();var n=Date.now();a[g.schemeIdUri](g.value,(function(r){var i=Date.now(),a=N(n,i,r);s.push(a),e(t-1)}),(function(){k()}))}catch(e){k()}}(isNaN(i.get().streaming.utcSynchronization.backgroundAttempts)?2:i.get().streaming.utcSynchronization.backgroundAttempts)))}function N(e,t,n){return n-(t-(t-e)/2)}function C(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:NaN,t=isNaN(e);t&&i.get().streaming.utcSynchronization.useManifestDateHeaderTimeSource?U():B(t,e)}function D(e){var t=Date.parse(e);return isNaN(t)&&(t=function(e){var t,n,r=/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+\-])([0-9]{2})([0-9]{2}))?/.exec(e);return t=Date.UTC(parseInt(r[1],10),parseInt(r[2],10)-1,parseInt(r[3],10),parseInt(r[4],10),parseInt(r[5],10),r[6]&&(parseInt(r[6],10)||0),r[7]&&1e3*parseFloat(r[7])||0),r[9]&&r[10]&&(n=60*parseInt(r[9],10)+parseInt(r[10],10),t+=("+"===r[8]?-1:1)*n*60*1e3),new Date(t).getTime()}(e)),t}function w(e){return Date.parse(e)}function O(e){return Date.parse(e)}function M(e,t,n){n()}function P(e,t,n){var r=D(e);isNaN(r)?n():t(r)}function F(e,t,n,r,i){var a,o,s=!1,u=new XMLHttpRequest,l=i?_.a.HEAD:_.a.GET,c=t.match(/\S+/g);if(t=c.shift(),a=function(){s||(s=!0,c.length?F(e,c.join(" "),n,r,i):r())},o=function(){var t,r;200===u.status&&(t=i?u.getResponseHeader("Date"):u.response,r=e(t),isNaN(r)||(n(r),s=!0))},b.isRelative(t)){var f=v.resolve();f&&(t=b.resolve(t,f.url))}u.open(l,t),u.timeout=5e3,u.onload=o,u.onloadend=a,u.send()}function x(e,t,n){F(O,e,t,n,!0)}function U(){var e=o.getLatestMPDRequestHeaderValueByID("Date"),t=null!==e?new Date(e).getTime():Number.NaN;isNaN(t)?B(!0):B(!1,t-Date.now())}function B(e,r){if(isNaN(p)||isNaN(r)||e||function(e){try{var n,r=G(e),a=isNaN(E)?30:E,o=isNaN(i.get().streaming.utcSynchronization.timeBetweenSyncAttemptsAdjustmentFactor)?2:i.get().streaming.utcSynchronization.timeBetweenSyncAttemptsAdjustmentFactor,s=isNaN(i.get().streaming.utcSynchronization.maximumTimeBetweenSyncAttempts)?600:i.get().streaming.utcSynchronization.maximumTimeBetweenSyncAttempts,u=isNaN(i.get().streaming.utcSynchronization.minimumTimeBetweenSyncAttempts)?2:i.get().streaming.utcSynchronization.minimumTimeBetweenSyncAttempts;r?(n=Math.min(a*o,s),t.debug("Increasing timeBetweenSyncAttempts to ".concat(n))):(n=Math.max(a/o,u),t.debug("Decreasing timeBetweenSyncAttempts to ".concat(n))),E=n}catch(e){}}(r),!e&&!isNaN(r)){d=Date.now(),n=!1;var a=isNaN(p);p=r,a&&R(),t.debug("Completed UTC sync. Setting client - server offset to ".concat(r))}e&&(g=null,n=!1,T.error(new m.a(y.a.TIME_SYNC_FAILED_ERROR_CODE,y.a.TIME_SYNC_FAILED_ERROR_MESSAGE))),A.trigger(l.a.UPDATE_TIME_SYNC_OFFSET,{offset:r}),A.trigger(l.a.TIME_SYNCHRONIZATION_COMPLETED)}function k(){if(s&&0!==s.length){var e=s.reduce((function(e,t){return e+t}),0)/s.length;G(e)?t.debug("Completed background UTC sync. Offset is within allowed threshold and is not adjusted."):(t.debug("Completed background UTC sync. Setting client - server offset to ".concat(e)),p=e,A.trigger(l.a.UPDATE_TIME_SYNC_OFFSET,{offset:p})),r=!1,h=Date.now()}}function G(e){try{if(isNaN(p))return!0;var t=i.get().streaming.utcSynchronization.maximumAllowedDrift&&!isNaN(i.get().streaming.utcSynchronization.maximumAllowedDrift)?i.get().streaming.utcSynchronization.maximumAllowedDrift:100;return e>=p-t&&e<=p+t}catch(e){return!0}}return e={initialize:function(){I(),a={"urn:mpeg:dash:utc:http-head:2014":x,"urn:mpeg:dash:utc:http-xsdate:2014":F.bind(null,D),"urn:mpeg:dash:utc:http-iso:2014":F.bind(null,w),"urn:mpeg:dash:utc:direct:2014":P,"urn:mpeg:dash:utc:http-head:2012":x,"urn:mpeg:dash:utc:http-xsdate:2012":F.bind(null,D),"urn:mpeg:dash:utc:http-iso:2012":F.bind(null,w),"urn:mpeg:dash:utc:direct:2012":P,"urn:mpeg:dash:utc:http-ntp:2014":M,"urn:mpeg:dash:utc:ntp:2014":M,"urn:mpeg:dash:utc:sntp:2014":M}},attemptSync:function(e,t){c=e,n||(!function(e){try{if(!e||!i.get().streaming.utcSynchronization.enabled)return!1;var t=isNaN(E)?30:E;return!(d&&t&&!isNaN(t))||(Date.now()-d)/1e3>=t}catch(e){return!0}}(t)?A.trigger(l.a.TIME_SYNCHRONIZATION_COMPLETED):(n=!0,function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=t||0;if(!c||0===c.length||n>=c.length)return void C();var r=c[n];if(r)if(a.hasOwnProperty(r.schemeIdUri)){var i=(new Date).getTime();a[r.schemeIdUri](r.value,(function(e){var t=(new Date).getTime(),n=N(i,t,e);g=r,C(n)}),(function(){e(n+1)}))}else e(n+1);else C()}()))},setConfig:function(e){e&&(e.dashMetrics&&(o=e.dashMetrics),e.baseURLController&&(v=e.baseURLController),e.errHandler&&(T=e.errHandler),e.settings&&(i=e.settings))},reset:function(){I(),A.off(l.a.ATTEMPT_BACKGROUND_SYNC,R,e)}},t=Object(f.a)(S).getInstance().getLogger(e),A.on(l.a.ATTEMPT_BACKGROUND_SYNC,R,e),e}ae.__dashjs_factory_name="TimeSyncController";var oe=c.a.getSingletonFactory(ae);oe.HTTP_TIMEOUT_MS=5e3,c.a.updateSingletonFactory(ae.__dashjs_factory_name,oe);var se=oe;function ue(){var e,t,n,r=this.context;return e={createMediaSource:function(){var e="WebKitMediaSource"in window;return"MediaSource"in window?t=new MediaSource:e&&(t=new WebKitMediaSource),t},attachMediaSource:function(e){var n=window.URL.createObjectURL(t);return e.setSource(n),n},detachMediaSource:function(e){e.setSource(null)},setDuration:function e(r){t&&"open"===t.readyState&&(null===r&&isNaN(r)||t.duration!==r&&(!function(e){for(var t=e.sourceBuffers,n=0;n=0&&e0?Math.max(0,i):0,A(r,i,e),A(n,i,e),b(r),b(n),a=e,c=!1}}catch(e){c=!1,t.error(e)}}function A(e,n,r){try{C(e,(function(i){if(void 0!==i){var a=isNaN(i.duration)?0:i.duration;i.calculatedPresentationTime<=r&&i.calculatedPresentationTime+n+a>=r?w(i,d.a.EVENT_MODE_ON_START):(D(r,a+n,i.calculatedPresentationTime)||function(e){try{var n=e.eventStream.period.start+e.eventStream.period.duration;return e.calculatedPresentationTime>n}catch(e){return t.error(e),!1}}(i))&&(t.debug("Removing event ".concat(i.id," from period ").concat(i.eventStream.period.id," as it is expired or invalid")),function(e,n){try{var r=n.eventStream.schemeIdUri,i=n.eventStream.period.id,a=n.eventStream.value,o=n.id;e[i][r]=e[i][r].filter((function(e){return a&&e.eventStream.value&&e.eventStream.value!==a||e.id!==o})),0===e[i][r].length&&delete e[i][r]}catch(e){t.error(e)}}(e,i))}}))}catch(e){t.error(e)}}function b(e){try{for(var n in e)e.hasOwnProperty(n)&&0===Object.keys(e[n]).length&&delete e[n]}catch(e){t.error(e)}}function I(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=e.eventStream.schemeIdUri,i=e.eventStream.value,a=e.id,o=p;t[r]||(t[r]=[]);var s=t[r].findIndex((function(e){return(!i||e.eventStream.value&&e.eventStream.value===i)&&e.id===a}));if(-1===s)t[r].push(e),e.triggeredReceivedEvent=!1,e.triggeredStartEvent=!1,o=m;else if(n){var u=t[r][s];e.triggeredReceivedEvent=u.triggeredReceivedEvent,e.triggeredStartEvent=u.triggeredStartEvent,t[r][s]=e,o=g}return o}function R(e){try{if(1==e.eventStream.value){var n,r=e.calculatedPresentationTime;n=4294967295==e.calculatedPresentationTime?NaN:e.calculatedPresentationTime+e.duration,E.trigger(d.a.MANIFEST_VALIDITY_CHANGED,{id:e.id,validUntil:r,newDuration:n,newManifestValidAfter:NaN},{mode:d.a.EVENT_MODE_ON_START})}}catch(e){t.error(e)}}function N(e){try{var n=s.getTime();C(e,(function(e){var t=e.eventStream&&e.eventStream.period&&!isNaN(e.eventStream.period.duration)?e.eventStream.period.duration:NaN,r=e.eventStream&&e.eventStream.period&&!isNaN(e.eventStream.period.start)?e.eventStream.period.start:NaN;if(!isNaN(t)&&!isNaN(r)){var i=e.calculatedPresentationTime;Math.abs(i-n)<300&&w(e,d.a.EVENT_MODE_ON_START)}}))}catch(e){t.error(e)}}function C(e,n){try{if(e)for(var r=Object.keys(e),i=0;ir}catch(e){return t.error(e),!1}}function w(e,n){try{var r=s.getTime(),i=e.id;if(n===d.a.EVENT_MODE_ON_RECEIVE&&!e.triggeredReceivedEvent)return t.debug("Received event ".concat(i)),e.triggeredReceivedEvent=!0,void E.trigger(e.eventStream.schemeIdUri,{event:e},{mode:n});e.triggeredStartEvent||("urn:mpeg:dash:event:2012"===e.eventStream.schemeIdUri&&1==e.eventStream.value?0===e.duration&&0===e.presentationTimeDelta||(t.debug("Starting manifest refresh event ".concat(i," at ").concat(r)),function(){try{_(),o.refreshManifest()}catch(e){t.error(e)}}()):"urn:mpeg:dash:event:callback:2015"===e.eventStream.schemeIdUri&&1==e.eventStream.value?(t.debug("Starting callback event ".concat(i," at ").concat(r)),function(e){try{Object(ce.a)(y).create({}).load({method:"get",url:e,request:{responseType:"arraybuffer"}})}catch(e){t.error(e)}}(e.messageData)):(t.debug("Starting event ".concat(i," from period ").concat(e.eventStream.period.id," at ").concat(r)),E.trigger(e.eventStream.schemeIdUri,{event:e},{mode:n})),e.triggeredStartEvent=!0)}catch(e){t.error(e)}}return e={addInlineEvents:function(e,r){try{if(_(),n[r]||(n[r]={}),e)for(var i=0;ie.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&p.updateManifestUpdateInfo({currentTime:V.getTime(),buffered:H.getBufferRange(),presentationStartTime:e[0].start,clientTimeOffset:D.getClientTimeOffset()}),w.length>0&&function(e){if(0===e.length)return void t.warn("No periods included in the current manifest. Skipping the filtering of outdated stream objects.");w=w.filter((function(n){var r=e.filter((function(e){return e.id===n.getId()})).length>0||n.getId()===O.getId();return r||(t.debug("Removing stream ".concat(n.getId())),n.reset(!0)),r}))}(e);for(var n=[],r=0,i=e.length;r0&&t[n[0]].getBuffer().changeType&&(J=!0),$=t}isNaN(e)||(ce.trigger(l.a.SEEK_TARGET,{time:e},{streamId:O.getId()}),V.seek(e,!1,!0),O.startScheduleControllers()),k=!1,ce.trigger(l.a.PERIOD_SWITCH_COMPLETED,{toStreamInfo:Ze()})}))}function Se(e){var t=V.getTime(),n=e.seekTime,r=Ce(n);r&&r!==O?r&&r!==O&&(Ae(t,n,r),function(e,t){var n=e&&!isNaN(e.seekTime)?e.seekTime:NaN,r=O.getProcessors().map((function(t){return t.prepareOuterPeriodPlaybackSeeking(e)}));Promise.all(r).then((function(){_e(t,O,n)})).catch((function(e){C.error(e)}))}(e,r)):(Ae(t,n),function(e){O.getProcessors().forEach((function(t){return t.prepareInnerPeriodPlaybackSeeking(e)})),Xe(B.USER_REQUEST_STOP_REASON)}(e)),Qe(U.SEEK_START_REASON)}function Ae(e,t){be()}function be(){Z&&Z.length>0&&(Z.forEach((function(e){e.deactivate(!0)})),Z=[])}function Ie(e){e.newMediaInfo.streamInfo.id===O.getId()&&(be(),O.prepareTrackChange(e))}function Re(e,t){try{return ee.get().streaming.buffer.reuseExistingSourceBuffers&&(t.isProtectionCompatible(e)||te)&&(J||t.isMediaCodecCompatible(e,t))}catch(e){return!1}}function Ne(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(Y&&!e.getPreloaded()){var n=Re(e,t);n&&e.startPreloading(Y,$).then((function(){Z.push(e)}))}}function Ce(e){if(isNaN(e))return null;for(var t=w.length,n=0;nV.getLiveDelay())&&(X=!1,Qe(U.INITIAL_PLAYOUT_START_REASON),V.play())}e&&e.mediaType&&p.addBufferLevel(e.mediaType,new Date,1e3*e.bufferLevel)}function Oe(e){e.streamInfo.id===O.getId()&&e.reason&&e.reason.forceReplace&&be(),Je(e.streamInfo.id).prepareQualityChange(e)}function Me(){if(h.getIsDynamic()&&0!==V.getLiveDelay()){var e=h.getStreamsInfo();if(e.length>0){var t=e[0].manifestInfo,n=Ke(e,t);V.computeAndSetLiveDelay(n,t)}}}function Pe(){if(We()){var e=H.getPlaybackQuality();e&&p.addDroppedFrames(e)}}function Le(){t.debug("[onPlaybackStarted]"),!X&&z&&Qe(U.RESUME_FROM_PAUSE_START_REASON),X&&(X=!1),z=!1}function Fe(e){t.debug("[onPlaybackPaused]"),e.ended||(z=!0,Xe(B.USER_REQUEST_STOP_REASON))}function xe(e){t.debug("Stream with id ".concat(e.streamInfo.id," finished buffering"));var n=e.streamInfo.isLast;Y&&n?(t.info("[onStreamBufferingCompleted] calls signalEndOfStream of mediaSourceController."),g.signalEndOfStream(Y)):Ue()}function Ue(){if(O&&O.getHasFinishedBuffering())for(var e=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;try{var t=e||(O||null);if(t){var n=t.getStreamInfo();return w.filter((function(e){var t=e.getStreamInfo();return t.start>n.start&&n.id!==t.id}))}}catch(e){return[]}}(O),t=0;t0&&void 0!==arguments[0]?arguments[0]:null,t=e||(O||null);if(!t)return null;var n=t.getStreamInfo(),r=n.start,i=0,a=-1,o=NaN;for(;i0&&(isNaN(o)||l=0)return w[a];return null}();n?(t.debug("StreamController onEnded, found next stream with id ".concat(n.getStreamInfo().id,". Switching from ").concat(O.getStreamInfo().id," to ").concat(n.getStreamInfo().id)),_e(n,O,NaN)):(t.debug("StreamController no next stream found"),O.setIsEndedEventSignaled(!1)),Xe(n?B.END_OF_PERIOD_STOP_REASON:B.END_OF_CONTENT_STOP_REASON)}e&&e.isLast&&Be()}function je(e){var t=e||Ze().manifestInfo.duration;g.setDuration(t)}function Ye(e){var t=v.getURIFragmentData();if(!t||!t.t)return NaN;var n=it()[0].getStreamInfo().start;return t.t=t.t.split(",")[0],Ve(e,t.t,n)}function He(e,t){var n=0;e||(n=it()[0].getStreamInfo().start);return Ve(e,t,n)}function Ve(e,t,n){var r=h.getRegularPeriods()[0],i=t.toString(),a=-1!==i.indexOf("posix:")?"now"===i.substring(6)?Date.now()/1e3:parseFloat(i.substring(6)):NaN;return e&&!isNaN(a)?D.calcPresentationTimeFromWallTime(new Date(1e3*a),r):parseFloat(i)+n}function Ke(e,t){try{var n=NaN;if(t&&!isNaN(t.maxFragmentDuration)&&isFinite(t.maxFragmentDuration))return t.maxFragmentDuration;if(e&&1===e.length){var r=e[0],i=[a.a.VIDEO,a.a.AUDIO,a.a.TEXT].reduce((function(e,t){var n=h.getMediaInfoForType(r,t);return n&&!1!==n.isFragmented&&e.push(n),e}),[]).reduce((function(e,t){var n=h.getVoRepresentations(t);return n&&n.length>0&&n.forEach((function(t){t&&e.push(t)})),e}),[]).reduce((function(e,t){var n=h.convertRepresentationToRepresentationInfo(t);return n&&n.fragmentDuration&&!isNaN(n.fragmentDuration)&&e.push(n.fragmentDuration),e}),[]);n=Math.max.apply(Math,pe(i))}return isFinite(n)?n:NaN}catch(e){return NaN}}function qe(e){if(e.error)j=!0,nt();else{t.info("Manifest updated... updating data system wide.");var n=e.manifest;h.updatePeriods(n);var i=h.getUTCTimingSources();!h.getIsDynamic()||i&&0!==i.length||ce.trigger(d.a.CONFORMANCE_VIOLATION,{level:he.LEVELS.WARNING,event:he.EVENTS.NO_UTC_TIMING_ELEMENT});var a=h.getIsDynamic()?i.concat(W.getUTCTimingSources()):i,o=N.isHTTPS(e.manifest.url);a.forEach((function(e){e.value.replace(/.*?:\/\//g,"")===ee.get().streaming.utcSynchronization.defaultTimingSource.value.replace(/.*?:\/\//g,"")&&(e.value=e.value.replace(o?new RegExp(/^(http:)?\/\//i):new RegExp(/^(https:)?\/\//i),o?"https://":"http://"),t.debug("Matching default timing source protocol to manifest protocol: ",e.value))})),r.filterUnsupportedFeatures(n).then((function(){_.initialize(n),E.attemptSync(a,h.getIsDynamic())}))}}function We(){return!!O&&O.getHasVideoTrack()}function ze(){return!!O&&O.getHasAudioTrack()}function Xe(e,t){t=t||new Date,ke().forEach((function(n){n.finalisePlayList(t,e)})),p.addPlayList()}function Qe(e){p.createPlaylistMetrics(1e3*V.getTime(),e)}function $e(e){if(e.error){var n="";switch(e.error.code){case 1:n="MEDIA_ERR_ABORTED";break;case 2:n="MEDIA_ERR_NETWORK";break;case 3:n="MEDIA_ERR_DECODE",oe.counts.mediaErrorDecode+=1;break;case 4:n="MEDIA_ERR_SRC_NOT_SUPPORTED";break;case 5:n="MEDIA_ERR_ENCRYPTED";break;default:n="UNKNOWN"}"MEDIA_ERR_DECODE"===n&&ee.get().errors.recoverAttempts.mediaErrorDecode>=oe.counts.mediaErrorDecode?function(){t.warn("A MEDIA_ERR_DECODE occured: Resetting the MediaSource");var e=V.getTime();O.deactivate(!1),t.warn("MediaSource has been resetted. Resuming playback from time ".concat(e)),Te(e,!1)}():(G=!0,e.error.message&&(n+=" ("+e.error.message+")"),e.error.msExtendedCode&&(n+=" (0x"+(e.error.msExtendedCode>>>0).toString(16).toUpperCase()+")"),t.fatal("Video Element Error: "+n),e.error&&t.fatal(e.error),C.error(new m.a(e.error.code,n)),nt())}}function Ze(){return O?O.getStreamInfo():null}function Je(e){for(var t=0,n=w.length;t1&&void 0!==arguments[1]?arguments[1]:NaN;fe(),ae=t,o.load(e)},loadWithManifest:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:NaN;ge(),ae=t,i.setManifest(e)},getActiveStreamProcessors:ke,setConfig:function(e){e&&(e.capabilities&&(n=e.capabilities),e.capabilitiesFilter&&(r=e.capabilitiesFilter),e.manifestLoader&&(o=e.manifestLoader),e.manifestModel&&(c=e.manifestModel),e.mediaPlayerModel&&(q=e.mediaPlayerModel),e.customParametersModel&&(W=e.customParametersModel),e.protectionController&&(M=e.protectionController),e.adapter&&(h=e.adapter),e.dashMetrics&&(p=e.dashMetrics),e.errHandler&&(C=e.errHandler),e.timelineConverter&&(D=e.timelineConverter),e.videoModel&&(H=e.videoModel),e.playbackController&&(V=e.playbackController),e.serviceDescriptionController&&(K=e.serviceDescriptionController),e.textController&&(P=e.textController),e.abrController&&(S=e.abrController),e.mediaController&&(b=e.mediaController),e.settings&&(ee=e.settings),e.baseURLController&&(_=e.baseURLController),e.uriFragmentModel&&(v=e.uriFragmentModel),e.segmentBaseController&&(T=e.segmentBaseController))},setProtectionData:function(e){F=e,M&&M.setProtectionData(F)},getIsStreamSwitchInProgress:function(){return k},switchToVideoElement:function(e){O&&(V.initialize(Ze()),Te(e,!1))},getHasMediaOrInitialisationError:function(){return G||j},getStreams:it,getActiveStream:function(){return O},getInitialPlayback:function(){return X},getAutoPlay:function(){return x},reset:nt},t=Object(f.a)(ue).getInstance().getLogger(e),E=se(ue).getInstance(),g=le(ue).getInstance(),R=A(ue).getInstance(),N=Object(L.a)(ue).getInstance(),tt(),e}me.__dashjs_factory_name="StreamController";var ye=c.a.getSingletonFactory(me);function Ee(){var e,t,n,r,i,a,o,s,c,d,h,p,g=this.context,m=Object(u.a)(g).getInstance();function y(){p.debug("Stopping the gap controller"),i&&(clearInterval(i),i=null),function(){m.off(l.a.WALLCLOCK_TIME_UPDATED,S,this),m.off(l.a.INITIAL_STREAM_SWITCH,v,this),m.off(l.a.PLAYBACK_SEEKING,E,this),m.off(l.a.BUFFER_REPLACEMENT_STARTED,_,e),m.off(l.a.TRACK_CHANGE_RENDERED,T,e)}(),i=null,a=NaN,r=0,d=null,h={}}function E(){d&&(clearTimeout(d),d=null)}function _(e){try{if(e.streamId!==s.getActiveStreamInfo().id||!e.mediaType)return;e.streamId===s.getActiveStreamInfo().id&&(h[e.mediaType]=!0)}catch(e){p.error(e)}}function T(e){e&&e.mediaType&&(h[e.mediaType]=!1)}function v(){i||function(){try{i||(p.debug("Starting the gap controller"),i=setInterval((function(){A()&&N(o.getTime())}),100))}catch(e){}}()}function S(){if(A(n.get().streaming.gaps.enableSeekFix)&&++r>=10){var e=o.getTime();t===e?N(e,!0):(t=e,a=NaN),r=0}}function A(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(!s.getActiveStream())return!1;var t=Object.keys(h).some((function(e){return h[e]})),r=!!e&&b();return!t&&n.get().streaming.gaps.jumpGaps&&s.getActiveStreamProcessors().length>0&&(!o.isSeeking()||r)&&!o.isPaused()&&!s.getIsStreamSwitchInProgress()&&!s.getHasMediaOrInitialisationError()}function b(){var e=s.getActiveStream(),t=parseFloat((e.getStartTime()+e.getDuration()).toFixed(5));return o.getTime()+n.get().streaming.gaps.threshold>=t}function I(e,t){try{if(!e||e.length<=1&&t>0)return NaN;for(var r=NaN,i=0;isNaN(r)&&i0?e.end(i-1):0;t=e.start(n)&&t<=e.end(n))return!0;return!1}function N(e){var t,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=n.get().streaming.gaps.enableStallFix,u=n.get().streaming.gaps.stallSeek,l=n.get().streaming.gaps.smallGapLimit,f=n.get().streaming.gaps.jumpLargeGaps,h=c.getBufferRange(),g=NaN,m=!1;if(t=I(h,e),!isNaN(t)){var y=h.start(t),E=y-e;E>0&&(E<=l||f)&&(g=y)}var _=o.getTimeToStreamEnd();if(isNaN(g)&&r&&isFinite(_)&&!isNaN(_)&&_0&&a!==g&&g>e&&!d){var T=g-e;if(m){var v=s.getStreamForTime(g),S=v&&!!v.getPreloaded();p.warn("Jumping to end of stream because of gap from ".concat(e," to ").concat(g,". Gap duration: ").concat(T)),o.seek(g,!0,S)}else{var A=o.getIsDynamic(),b=t>0?h.end(t-1):e,N=A?1e3*Math.max(0,T-.1):0;d=window.setTimeout((function(){o.seek(g,!0,!0),p.warn("Jumping gap occuring in period ".concat(s.getActiveStream().getStreamId()," starting at ").concat(b," and ending at ").concat(g,". Jumping by: ").concat(g-b)),d=null}),N)}a=g}}return e={reset:y,setConfig:function(e){e&&(e.settings&&(n=e.settings),e.playbackController&&(o=e.playbackController),e.streamController&&(s=e.streamController),e.videoModel&&(c=e.videoModel))},initialize:function(){!function(){m.on(l.a.WALLCLOCK_TIME_UPDATED,S,this),m.on(l.a.INITIAL_STREAM_SWITCH,v,this),m.on(l.a.PLAYBACK_SEEKING,E,this),m.on(l.a.BUFFER_REPLACEMENT_STARTED,_,e),m.on(l.a.TRACK_CHANGE_RENDERED,T,e)}()}},p=Object(f.a)(g).getInstance().getLogger(e),y(),e}Ee.__dashjs_factory_name="GapController";var _e=c.a.getSingletonFactory(Ee);function Te(){var e,t,n,r,i,o,c,h,p,g,m,y=this.context,E=Object(u.a)(y).getInstance();function _(){t=!1;var e="undefined"!=typeof navigator?navigator.userAgent.toLowerCase():"",r=/safari/.test(e)&&!/chrome/.test(e);n=r?.25:.02}function T(){t=!1}function v(e){if(e.streamId===o.getActiveStreamInfo().id&&g){var t=c.getLiveDelay();c.getBufferLevel()>t/2&&(g=!1)}}function S(e){e.streamId===o.getActiveStreamInfo().id&&(g=e.state===s.a.BUFFER_EMPTY)}function A(){h.getCatchupModeEnabled()||r.setPlaybackRate(1)}function b(){c.getIsDynamic()&&h.getCatchupModeEnabled()&&h.getCatchupPlaybackRate()>0&&!c.isPaused()&&!c.isSeeking()&&function(){try{var e=h.getLiveCatchupLatencyThreshold();if(!c.getTime()>0||t||!isNaN(e)&&c.getCurrentLiveLatency()>=e)return!1;if(R()===a.a.LIVE_CATCHUP_MODE_LOLP){var n=c.getBufferLevel(),r=i.get().streaming.liveCatchup.playbackBufferMin;return function(e,t){try{return Math.abs(I())>0||e0}catch(e){return!1}}()}catch(e){return!1}}()&&function(){if(t)return;if(r){var e,s=r.getPlaybackRate(),u=h.getCatchupPlaybackRate(),l=c.getBufferLevel(),f=I(),d=h.getCatchupMaxDrift();if(!isNaN(d)&&d>0&&f>d)m.info("[CatchupController]: Low Latency catchup mechanism. Latency too high, doing a seek to live point"),t=!0,T=o&&o.hasVideoTrack()?a.a.VIDEO:a.a.AUDIO,v=p.getCurrentDVRInfo(T),(S=v?v.range:null)&&!isNaN(S.end)&&c.seek(S.end-c.getLiveDelay(),!0,!1);else{var y=c.getCurrentLiveLatency(),E=c.getLiveDelay();if(R()===a.a.LIVE_CATCHUP_MODE_LOLP){var _=i.get().streaming.liveCatchup.playbackBufferMin;e=function(e,t,r,i,a,o){var s,u=e;if(a0&&(f=1);Math.abs(a-f)<=n&&(f=null);return f}(u,y,E,l,s);e&&(m.debug("[CatchupController]: Setting playback rate to ".concat(e)),r.setPlaybackRate(e))}}var T,v,S}()}function I(){return c.getCurrentLiveLatency()-c.getLiveDelay()}function R(){var e=i.get().streaming.liveCatchup.playbackBufferMin;return i.get().streaming.liveCatchup.mode!==a.a.LIVE_CATCHUP_MODE_LOLP||null===e||isNaN(e)?a.a.LIVE_CATCHUP_MODE_DEFAULT:a.a.LIVE_CATCHUP_MODE_LOLP}return e={reset:function(){E.off(d.a.BUFFER_LEVEL_UPDATED,v,e),E.off(d.a.BUFFER_LEVEL_STATE_CHANGED,S,e),E.off(d.a.PLAYBACK_PROGRESS,b,e),E.off(d.a.PLAYBACK_TIME_UPDATED,b,e),E.off(d.a.PLAYBACK_SEEKED,b,e),E.off(l.a.SETTING_UPDATED_CATCHUP_ENABLED,A,e),_(),r.setPlaybackRate(1,!0)},setConfig:function(e){e&&(e.settings&&(i=e.settings),e.videoModel&&(r=e.videoModel),e.streamController&&(o=e.streamController),e.playbackController&&(c=e.playbackController),e.dashMetrics&&(p=e.dashMetrics),e.mediaPlayerModel&&(h=e.mediaPlayerModel))},initialize:function(){E.on(d.a.BUFFER_LEVEL_UPDATED,v,e),E.on(d.a.BUFFER_LEVEL_STATE_CHANGED,S,e),E.on(d.a.PLAYBACK_PROGRESS,b,e),E.on(d.a.PLAYBACK_TIME_UPDATED,b,e),E.on(d.a.PLAYBACK_SEEKED,T,e),E.on(l.a.SETTING_UPDATED_CATCHUP_ENABLED,A,e)}},m=Object(f.a)(y).getInstance().getLogger(e),_(),e}Te.__dashjs_factory_name="CatchupController";var ve=c.a.getSingletonFactory(Te),Se=[a.a.SERVICE_DESCRIPTION_DVB_LL_SCHEME],Ae="video",be="audio",Ie="any",Re="all";function Ne(){var e,t,n,r,i,s=this.context;function u(){t={liveDelay:NaN,liveCatchup:{maxDrift:NaN,playbackRate:NaN},minBitrate:{},maxBitrate:{},initialBitrate:{}},n=[]}function l(e,n,i){try{t[e][n]=i/1e3}catch(e){r.error(e)}}return e={getServiceDescriptionSettings:function(){return t},getProducerReferenceTimeOffsets:function(){return n},calculateProducerReferenceTimeOffsets:function(e){try{var t=[];if(e&&e.length>0){var s=[a.a.VIDEO,a.a.AUDIO,a.a.TEXT],u=i.getAvailabilityStartTime()/1e3;e.forEach((function(e){var n=s.reduce((function(t,n){return t=t.concat(i.getAllMediaInfoForType(e,n))}),[]).reduce((function(t,n){return i.getProducerReferenceTimes(e,n).forEach((function(r){var a=i.getVoRepresentations(n);if(a&&a.length>0&&a[0].adaptation&&a[0].segmentInfoType===o.a.SEGMENT_TEMPLATE){var s=a[0],l=new Date(r[o.a.WALL_CLOCK_TIME]).getTime()/1e3-(r[o.a.PRESENTATION_TIME]/s[o.a.TIMESCALE]-s[o.a.PRESENTATION_TIME_OFFSET]+e.start),c=u-l;t.push({id:r[o.a.ID],to:c})}})),t}),[]);t=t.concat(n)}))}n=t}catch(e){r.error(e),n=[]}},applyServiceDescription:function(e){if(e&&e.serviceDescriptions){var i=e.serviceDescriptions.filter((function(e){return Se.includes(e.schemeIdUri)})),o=e.serviceDescriptions.filter((function(e){return null==e.schemeIdUri})),s=i.length>0?i[i.length-1]:o[o.length-1];s&&(s.latency&&s.latency.target>0&&function(e){var i;i=e.schemeIdUri===a.a.SERVICE_DESCRIPTION_DVB_LL_SCHEME?function(e){var t=e.latency.target/1e3,n=!isNaN(e.latency.max)&&e.latency.max>e.latency.target?(e.latency.max-e.latency.target+500)/1e3:NaN,r=e.latency.referenceId||NaN;return{liveDelay:t,maxDrift:n,referenceId:r}}(e):function(e){var t=e.latency.target/1e3,n=!isNaN(e.latency.max)&&e.latency.max>e.latency.target?(e.latency.max-e.latency.target+500)/1e3:NaN,r=e.latency.referenceId||NaN;return{liveDelay:t,maxDrift:n,referenceId:r}}(e);if(n.length>0){var o=function(e){var t,r=0,i=n.filter((function(t){return t.id===e.referenceId}));0===i.length?(r=n.length>0?n[0].to:0,t=n[0].id||NaN):(r=i[0].to||0,t=i[0].id||NaN);return{to:r,id:t}}(i),s=o.to,u=o.id;t.liveDelay=i.liveDelay-s,t.liveCatchup.maxDrift=i.maxDrift,r.debug("\n Found latency properties coming from service description. Applied time offset of ".concat(s," from ProducerReferenceTime element with id ").concat(u,".\n Live Delay: ").concat(i.liveDelay-s,", Live catchup max drift: ").concat(i.maxDrift,"\n "))}else t.liveDelay=i.liveDelay,t.liveCatchup.maxDrift=i.maxDrift,r.debug("Found latency properties coming from service description: Live Delay: ".concat(i.liveDelay,", Live catchup max drift: ").concat(i.maxDrift))}(s),s.playbackRate&&s.playbackRate.max>1&&function(e){var n=Math.round(1e3*(e.playbackRate.max-1))/1e3;t.liveCatchup.playbackRate=n,r.debug("Found latency properties coming from service description: Live catchup playback rate: ".concat(n))}(s),s.operatingQuality,s.operatingBandwidth&&function(e){if(!e||!e.operatingBandwidth||!e.operatingBandwidth.mediaType||e.operatingBandwidth.mediaType===Re)return;var t={};t.minBandwidth=e.operatingBandwidth.min,t.maxBandwidth=e.operatingBandwidth.max,t.targetBandwidth=e.operatingBandwidth.target;var n=[];e.operatingBandwidth.mediaType===Ae||e.operatingBandwidth.mediaType===be?n.push(e.operatingBandwidth.mediaType):e.operatingBandwidth.mediaType===Ie&&(n.push(be),n.push(Ae));n.forEach((function(e){isNaN(t.minBandwidth)||l("minBitrate",e,t.minBandwidth),isNaN(t.maxBandwidth)||l("maxBitrate",e,t.maxBandwidth),isNaN(t.targetBandwidth)||l("initialBitrate",e,t.targetBandwidth)}))}(s))}},reset:function(){u()},setConfig:function(e){e&&e.adapter&&(i=e.adapter)}},r=Object(f.a)(s).getInstance().getLogger(e),u(),e}Ne.__dashjs_factory_name="ServiceDescriptionController";var Ce=c.a.getSingletonFactory(Ne);function De(){var e,t,n,r,i,o,s,c,d=this.context,h=Object(u.a)(d).getInstance();function p(e,t){return e&&n[t]&&n[t][e]?n[t][e].list:[]}function g(e,t){return e&&n[t]&&n[t][e]?n[t][e].current:null}function m(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(e&&e.streamInfo){var i=e.type,s=e.streamInfo,u=s.id,f=g(i,u);if(n[u]&&n[u][i]&&(n[u][i].current=e,n[u][i].current&&(i!==a.a.TEXT&&!_(e,f)||i===a.a.TEXT&&e.isFragmented)&&h.trigger(l.a.CURRENT_TRACK_CHANGED,{oldMediaInfo:f,newMediaInfo:e,switchMode:r.get().streaming.trackSwitchMode[i]},{streamId:u}),!t)){var d=v(e);if(!d||!n[u][i].storeLastSettings)return;d.roles&&(d.role=d.roles[0],delete d.roles),d.accessibility&&(d.accessibility=d.accessibility[0]),d.audioChannelConfiguration&&(d.audioChannelConfiguration=d.audioChannelConfiguration[0]),o[i]=d,c.setSavedMediaSettings(i,d)}}}function y(e,t){e&&t&&(i[e]=t)}function E(e){return e?i[e]:null}function _(e,t){if(!e&&!t)return!0;if(!e||!t)return!1;var n=e.id===t.id,r=e.viewpoint===t.viewpoint,i=e.lang===t.lang,a=e.codec===t.codec,o=e.roles.toString()===t.roles.toString(),s=e.accessibility.toString()===t.accessibility.toString(),u=e.audioChannelConfiguration.toString()===t.audioChannelConfiguration.toString();return n&&a&&r&&i&&o&&s&&u}function T(){n={},o={},i={audio:null,video:null,text:null}}function v(e){var t={lang:e.lang,viewpoint:e.viewpoint,roles:e.roles,accessibility:e.accessibility,audioChannelConfiguration:e.audioChannelConfiguration};return t.lang||t.viewpoint||t.role&&t.role.length>0||t.accessibility&&t.accessibility.length>0||t.audioChannelConfiguration&&t.audioChannelConfiguration.length>0?t:null}function S(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=!e.lang||t.lang.match(e.lang),i=void 0===e.index||null===e.index||t.index===e.index,o=!e.viewpoint||e.viewpoint===t.viewpoint,s=!e.role||!!t.roles.filter((function(t){return t===e.role}))[0],u=!e.accessibility||!!t.accessibility.filter((function(t){return t===e.accessibility}))[0],l=!e.audioChannelConfiguration||!!t.audioChannelConfiguration.filter((function(t){return t===e.audioChannelConfiguration}))[0];return r&&i&&o&&(s||t.type===a.a.AUDIO&&n)&&u&&l}function A(e){var t,n=0,r=[];return e.forEach((function(e){(t=Math.max.apply(Math,e.bitrateList.map((function(e){return e.bandwidth}))))>n?(n=t,r=[e]):t===n&&r.push(e)})),r}function b(e){var t,n=1/0,r=[];return e.forEach((function(e){var i=e.bitrateList.reduce((function(e,t){var n=Math.max(1,t.width*t.height);return e+t.bandwidth/n}),0);(t=i/e.bitrateList.length)n?(n=t,r=[e]):t===n&&r.push(e)})),r}function R(e,n){if(e===a.a.TEXT)return n[0];var i,o=r.get().streaming.selectionModeForInitialTrack,u=s.getCustomInitialTrackSelectionFunction();if(u&&"function"==typeof u)i=u(n);else switch(o){case a.a.TRACK_SELECTION_MODE_HIGHEST_SELECTION_PRIORITY:i=function(e){var t=(n=e,r=0,i=[],n.forEach((function(e){isNaN(e.selectionPriority)||(e.selectionPriority>r?(r=e.selectionPriority,i=[e]):e.selectionPriority===r&&i.push(e))})),i);var n,r,i;t.length>1&&(t=A(t));t.length>1&&(t=I(t));return t}(n);break;case a.a.TRACK_SELECTION_MODE_HIGHEST_BITRATE:i=function(e){var t=A(e);t.length>1&&(t=I(t));return t}(n);break;case a.a.TRACK_SELECTION_MODE_FIRST_TRACK:i=N(n);break;case a.a.TRACK_SELECTION_MODE_HIGHEST_EFFICIENCY:i=function(e){var t=b(e);t.length>1&&(t=A(t));return t}(n);break;case a.a.TRACK_SELECTION_MODE_WIDEST_RANGE:i=function(e){var t=I(e);t.length>1&&(t=A(e));return t}(n);break;default:t.warn("Track selection mode ".concat(o," is not supported. Falling back to TRACK_SELECTION_MODE_FIRST_TRACK")),i=N(n)}return i.length>0?i[0]:n[0]}function N(e){return e[0]}return e={setInitialMediaSettingsForType:function(e,t){var n=o[e]||E(e),r=p(e,t.id),i=[];n||(n=c.getSavedMediaSettings(e),y(e,n)),r&&0!==r.length&&(n&&r.forEach((function(t){S(n,t,!!o[e])&&i.push(t)})),0===i.length?m(R(e,r),!0):i.length>1?m(R(e,i,o[e])):m(i[0]))},addTrack:function(e){if(e){var t=e.type;if((r=t)===a.a.AUDIO||r===a.a.VIDEO||r===a.a.TEXT||r===a.a.IMAGE){var r,i=e.streamInfo.id;n[i]||(n[i]={audio:{list:[],storeLastSettings:!0,current:null},video:{list:[],storeLastSettings:!0,current:null},text:{list:[],storeLastSettings:!0,current:null},image:{list:[],storeLastSettings:!0,current:null}});for(var o=n[i][t].list,s=0,u=o.length;s1&&(n.forEach((function(e){r+=e.dvb_weight,i.push(r)})),t=Math.floor(Math.random()*(r-1)),i.every((function(e,n){return a=n,!(t")+2),r=t.resolvedContent.substr(0,i)+""+t.resolvedContent.substr(i)+"",t.resolvedContent=a.xml_str2json(r)}(function(e){var t;for(t=0;t=0;o--){if(t=e.elements[o],n=t.type+"_asArray",t.resolvedContent){if(t.resolvedContent)for(s=0;s0&&r.run(i)}(e),"onActuate"===e.resolveType&&f.trigger(l.a.XLINK_READY,{manifest:i}),"onLoad"===e.resolveType)switch(e.type){case o.a.PERIOD:for(t=0;t=0;a--)(i=e[a]).hasOwnProperty("xlink:href")&&"urn:mpeg:dash:resolve-to-zero:2013"===i["xlink:href"]&&e.splice(a,1);for(a=0;a-1?(g&&(t=g.createMssParser(),g.registerEvents()),t):e.indexOf("MPD")>-1||e.indexOf("Patch")>-1?Object(it.a)(c).create({debug:f}):t}(t)),null!==s){i.setMatchers(s.getMatchers()),i.setIron(s.getIron());try{_=s.parse(t)}catch(t){return void h.trigger(l.a.INTERNAL_MANIFEST_LOADED,{manifest:null,error:new m.a(y.a.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE,y.a.MANIFEST_LOADER_PARSING_FAILURE_ERROR_MESSAGE+"".concat(e))})}if(_){if(_.url=u||e,_.originalUrl||(_.originalUrl=_.url),_.hasOwnProperty(a.a.LOCATION)&&(E=p.parseBaseUrl(_.Location_asArray[0]),n.debug("BaseURI set by Location to: "+E)),d&&d.get().streaming.enableManifestDurationMismatchFix&&_.mediaPresentationDuration&&_.Period_asArray.length>1){var T=_.Period_asArray.reduce((function(e,t){return e+t.duration}),0);!isNaN(T)&&_.mediaPresentationDuration>T&&(n.warn("Media presentation duration greater than duration of all periods. Setting duration to total period duration"),_.mediaPresentationDuration=T)}_.baseUri=E,_.loadedTime=new Date,i.resolveManifestOnLoad(_),h.trigger(l.a.ORIGINAL_MANIFEST_LOADED,{originalManifest:t})}else h.trigger(l.a.INTERNAL_MANIFEST_LOADED,{manifest:null,error:new m.a(y.a.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE,y.a.MANIFEST_LOADER_PARSING_FAILURE_ERROR_MESSAGE+"".concat(e))})}else h.trigger(l.a.INTERNAL_MANIFEST_LOADED,{manifest:null,error:new m.a(y.a.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE,y.a.MANIFEST_LOADER_PARSING_FAILURE_ERROR_MESSAGE+"".concat(e))});else h.trigger(l.a.INTERNAL_MANIFEST_LOADED,{manifest:null})},error:function(t,n,r){h.trigger(l.a.INTERNAL_MANIFEST_LOADED,{manifest:null,error:new m.a(y.a.MANIFEST_LOADER_LOADING_FAILURE_ERROR_CODE,y.a.MANIFEST_LOADER_LOADING_FAILURE_ERROR_MESSAGE+"".concat(e,", ").concat(r))})}})},reset:function(){h.off(l.a.XLINK_READY,T,t),g&&g.reset(),i&&(i.reset(),i=null),r&&(r.abort(),r=null)}},n=f.getLogger(t),h.on(l.a.XLINK_READY,T,t),r=Object(Ke.a)(c).create({errHandler:e.errHandler,dashMetrics:e.dashMetrics,mediaPlayerModel:e.mediaPlayerModel,requestModifier:e.requestModifier,urlUtils:p,constants:a.a,dashConstants:o.a,errors:y.a}),i=rt(c).create({errHandler:E,dashMetrics:e.dashMetrics,mediaPlayerModel:e.mediaPlayerModel,requestModifier:e.requestModifier,settings:e.settings}),s=null,t}at.__dashjs_factory_name="ManifestLoader";var ot=c.a.getClassFactory(at);function st(){var e=this.context,t=Object(u.a)(e).getInstance();return{error:function(e){t.trigger(l.a.ERROR,{error:e})}}}st.__dashjs_factory_name="ErrorHandler";var ut=c.a.getSingletonFactory(st),lt=n(50);function ct(){var e,t,n,r,i,o,s=this.context,c=Object(u.a)(s).getInstance();function d(e,r){if(!r||!r.Period_asArray||0===r.Period_asArray.length)return Promise.resolve();var i=[];return r.Period_asArray.forEach((function(r){i.push(function(e,r){return new Promise((function(i){if(e&&e.AdaptationSet_asArray&&0!==e.AdaptationSet_asArray.length){var s=[];e.AdaptationSet_asArray.forEach((function(e){t.getIsTypeOf(e,r)&&s.push(function(e,r){return new Promise((function(i){if(e.Representation_asArray&&0!==e.Representation_asArray.length){var s=[],u=[];e.Representation_asArray.forEach((function(i,o){var l=t.getCodec(e,o,!1),c=function(e,t,n){switch(e){case a.a.VIDEO:return function(e,t){var n=e.width||null,r=e.height||null,i=e.frameRate||null,a=e.bandwidth||null;return{codec:t,width:n,height:r,framerate:i,bitrate:a}}(t,n);case a.a.AUDIO:return function(e,t){var n=e.audioSamplingRate||null,r=e.bandwidth||null;return{codec:t,bitrate:r,samplerate:n}}(t,n);default:return null}}(r,i,l);u.push(c),s.push(n.supportsCodec(c,r))})),Promise.all(s).then((function(t){e.Representation_asArray=e.Representation_asArray.filter((function(e,n){return t[n]||o.debug("[Stream] Codec ".concat(u[n].codec," not supported ")),t[n]})),i()})).catch((function(){i()}))}else i()}))}(e,r))})),Promise.all(s).then((function(){e.AdaptationSet_asArray=e.AdaptationSet_asArray.filter((function(e){var t=e.Representation_asArray&&e.Representation_asArray.length>0;return t||(c.trigger(l.a.ADAPTATION_SET_REMOVED_NO_CAPABILITIES,{adaptationSet:e}),o.warn("AdaptationSet has been removed because of no supported Representation")),t})),i()})).catch((function(){i()}))}else i()}))}(r,e))})),Promise.all(i)}return e={setConfig:function(e){e&&(e.adapter&&(t=e.adapter),e.capabilities&&(n=e.capabilities),e.settings&&(r=e.settings),e.customParametersModel&&(i=e.customParametersModel))},filterUnsupportedFeatures:function(e){return new Promise((function(s){var u=[];u.push(d(a.a.VIDEO,e)),u.push(d(a.a.AUDIO,e)),Promise.all(u).then((function(){r.get().streaming.capabilities.filterUnsupportedEssentialProperties&&function(e){if(!e||!e.Period_asArray||0===e.Period_asArray.length)return;e.Period_asArray.forEach((function(e){e.AdaptationSet_asArray=e.AdaptationSet_asArray.filter((function(e){return!e.Representation_asArray||0===e.Representation_asArray.length||(e.Representation_asArray=e.Representation_asArray.filter((function(e){var r=t.getEssentialPropertiesForRepresentation(e);if(r&&r.length>0)for(var i=0;i0)}))}))}(e),function(e){var t=i.getCustomCapabilitiesFilters();if(!t||0===t.length||!e||!e.Period_asArray||0===e.Period_asArray.length)return;e.Period_asArray.forEach((function(e){e.AdaptationSet_asArray=e.AdaptationSet_asArray.filter((function(e){return!e.Representation_asArray||0===e.Representation_asArray.length||(e.Representation_asArray=e.Representation_asArray.filter((function(e){return!t.some((function(t){return!t(e)}))})),e.Representation_asArray&&e.Representation_asArray.length>0)}))}))}(e),s()})).catch((function(){s()}))}))}},o=Object(f.a)(s).getInstance().getLogger(e),e}ct.__dashjs_factory_name="CapabilitiesFilter";var ft=c.a.getSingletonFactory(ct);var dt=function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.t=null,this.xywh=null,this.track=null,this.id=null,this.s=null,this.r=null};function ht(){var e;return{initialize:function(t){if(e=new dt,!t)return null;var n=t.indexOf("#");if(-1!==n)for(var r=t.substr(n+1).split("&"),i=0,a=r.length;i0?r.get().streaming.buffer.stableBufferTime:r.get().streaming.buffer.fastSwitchEnabled?20:12,n=e.getLiveDelay();return!isNaN(n)&&n>0?Math.min(t,n):t}return{getCatchupMaxDrift:function(){if(!isNaN(r.get().streaming.liveCatchup.maxDrift)&&r.get().streaming.liveCatchup.maxDrift>0)return r.get().streaming.liveCatchup.maxDrift;var e=t.getServiceDescriptionSettings();return e&&e.liveCatchup&&!isNaN(e.liveCatchup.maxDrift)&&e.liveCatchup.maxDrift>0?e.liveCatchup.maxDrift:12},getCatchupModeEnabled:function(){return null!==r.get().streaming.liveCatchup.enabled?r.get().streaming.liveCatchup.enabled:e.getInitialCatchupModeActivated()},getLiveCatchupLatencyThreshold:function(){try{var t=r.get().streaming.liveCatchup.latencyThreshold,n=e.getLiveDelay();return null===t||isNaN(t)?NaN:Math.max(t,n)}catch(e){return NaN}},getStableBufferTime:i,getInitialBufferLevel:function(){var e=r.get().streaming.buffer.initialBufferLevel;return isNaN(e)||e<0?0:Math.min(i(),e)},getRetryAttemptsForType:function(t){var n=isNaN(r.get().streaming.retryAttempts.lowLatencyMultiplyFactor)?5:r.get().streaming.retryAttempts.lowLatencyMultiplyFactor;return e.getLowLatencyModeEnabled()?r.get().streaming.retryAttempts[t]*n:r.get().streaming.retryAttempts[t]},getRetryIntervalsForType:function(t){var n=isNaN(r.get().streaming.retryIntervals.lowLatencyReductionFactor)?10:r.get().streaming.retryIntervals.lowLatencyReductionFactor;return e.getLowLatencyModeEnabled()?r.get().streaming.retryIntervals[t]/n:r.get().streaming.retryIntervals[t]},getCatchupPlaybackRate:function(){if(!isNaN(r.get().streaming.liveCatchup.playbackRate)&&r.get().streaming.liveCatchup.playbackRate>0)return r.get().streaming.liveCatchup.playbackRate;var e=t.getServiceDescriptionSettings();return e&&e.liveCatchup&&!isNaN(e.liveCatchup.playbackRate)&&e.liveCatchup.playbackRate>0?e.liveCatchup.playbackRate:.5},getAbrBitrateParameter:function(e,n){try{var i=r.get().streaming.abr[e][n];if(!isNaN(i)&&-1!==i)return i;var a=t.getServiceDescriptionSettings();return a&&a[e]&&!isNaN(a[e][n])?a[e][n]:-1}catch(e){return-1}},setConfig:function(n){n.playbackController&&(e=n.playbackController),n.serviceDescriptionController&&(t=n.serviceDescriptionController)},reset:function(){}}}yt.__dashjs_factory_name="MediaPlayerModel";var Et=c.a.getSingletonFactory(yt),_t=n(27);function Tt(e){var t=(e=e||{}).abrController,n=e.switchHistory,r=e.droppedFramesHistory,i=e.currentRequest,a=e.useBufferOccupancyABR,o=e.useL2AABR,s=e.useLoLPABR,u=e.streamProcessor?e.streamProcessor.getScheduleController():null,l=e.streamProcessor?e.streamProcessor.getRepresentationInfo():null,c=e.videoModel?e.videoModel:null;function f(){return l?l.mediaInfo:null}return{getMediaType:function(){var e=f();return e?e.type:null},getMediaInfo:f,getDroppedFramesHistory:function(){return r},getCurrentRequest:function(){return i},getSwitchHistory:function(){return n},getStreamInfo:function(){var e=f();return e?e.streamInfo:null},getScheduleController:function(){return u},getAbrController:function(){return t},getRepresentationInfo:function(){return l},useBufferOccupancyABR:function(){return a},useL2AABR:function(){return o},useLoLPABR:function(){return s},getVideoModel:function(){return c}}}Tt.__dashjs_factory_name="RulesContext";var vt=c.a.getClassFactory(Tt),St=n(8);function At(){var e=[],t=[];return{push:function(n){n.newValue===St.a.NO_CHANGE&&(n.newValue=n.oldValue),e[n.oldValue]||(e[n.oldValue]={noDrops:0,drops:0,dropSize:0});var r=n.newValue-n.oldValue,i=r<0?1:0,a=i?-r:0,o=i?0:1;if(e[n.oldValue].drops+=i,e[n.oldValue].dropSize+=a,e[n.oldValue].noDrops+=o,t.push({idx:n.oldValue,noDrop:o,drop:i,dropSize:a}),t.length>8){var s=t.shift();e[s.idx].drops-=s.drop,e[s.idx].dropSize-=s.dropSize,e[s.idx].noDrops-=s.noDrop}},getSwitchRequests:function(){return e},reset:function(){e=[],t=[]}}}At.__dashjs_factory_name="SwitchRequestHistory";var bt=c.a.getClassFactory(At);function It(){var e={},t={},n={};return{push:function(r,i,a){if(i){e[r]||(e[r]=[],t[r]=0,n[r]=0);var o=a&&a.droppedVideoFrames?a.droppedVideoFrames:0,s=a&&a.totalVideoFrames?a.totalVideoFrames:0,u=o-t;t[r]=o;var l=s-n;n[r]=s;var c=e[r];isNaN(i)||(c[i]?(c[i].droppedVideoFrames+=u,c[i].totalVideoFrames+=l):c[i]={droppedVideoFrames:u,totalVideoFrames:l})}},getFrameHistory:function(t){return e[t]},clearForStream:function(r){try{delete e[r],delete t[r],delete n[r]}catch(e){}},reset:function(){e={},t={},n={}}}}It.__dashjs_factory_name="DroppedFramesHistory";var Rt=c.a.getClassFactory(It);function Nt(e){var t,n,r,i,o,s=(e=e||{}).settings;function u(e,t,n,r){var i=Math.pow(.5,n/r.fast);e.fastEstimate=(1-i)*t+i*e.fastEstimate;var a=Math.pow(.5,n/r.slow);e.slowEstimate=(1-a)*t+a*e.slowEstimate,e.totalWeight+=n}function l(e,u,l){return s.get().streaming.abr.movingAverageMethod!==a.a.MOVING_AVERAGE_SLIDING_WINDOW?function(e,t){var n=e?o.throughputHalfLife:o.latencyHalfLife,a=e?r[t]:i[t];if(!a||a.totalWeight<=0)return NaN;var s=a.fastEstimate/(1-Math.pow(.5,a.totalWeight/n.fast)),u=a.slowEstimate/(1-Math.pow(.5,a.totalWeight/n.slow));return e?Math.min(s,u):Math.max(s,u)}(e,u):function(e,r,i){var a=function(e,r,i){var a,o;if(e?(a=t[r],o=i?3:4):(a=n[r],o=4),a){if(o>=a.length)o=a.length;else if(e)for(var s=1;s=1.3||u<=1/1.3)&&(o+=1)===a.length)break}}else o=0;return o}(e,r,i),o=(e?t:n)[r];if(0===a||!o||0===o.length)return NaN;return(o=o.slice(-a)).reduce((function(e,t){return e+t}))/o.length}(e,u,l)}function c(e,t){return l(!0,e,t)}function f(e){t[e]=t[e]||[],n[e]=n[e]||[],r[e]=r[e]||{fastEstimate:0,slowEstimate:0,totalWeight:0},i[e]=i[e]||{fastEstimate:0,slowEstimate:0,totalWeight:0}}function d(){t={},n={},r={},i={}}var h={push:function(e,l,c){if(l.trace&&l.trace.length){var d=l.tresponse.getTime()-l.trequest.getTime()||1,h=l._tfinish.getTime()-l.tresponse.getTime()||1,p=l.trace.reduce((function(e,t){return e+t.b[0]}),0),g=0,m=0;if(0!==(g=l._fileLoaderType&&l._fileLoaderType===a.a.FILE_LOADER_TYPES.FETCH?l.trace.reduce((function(e,t){return e+t.d}),0):c?h:d+h)&&(m=Math.round(8*p/g)),f(e),function(e,t,n){return e===a.a.VIDEO?n0&&!t[e].hasCachedEntries)return;t[e].hasCachedEntries=!0}else t[e]&&t[e].hasCachedEntries&&function(e){delete t[e],delete n[e],delete r[e],delete i[e],f(e)}(e);t[e].push(m),t[e].length>20&&t[e].shift(),n[e].push(d),n[e].length>20&&n[e].shift(),u(r[e],m,.001*h,o.throughputHalfLife),u(i[e],d,1,o.latencyHalfLife)}},getAverageThroughput:c,getSafeAverageThroughput:function(e,t){var n=c(e,t);return isNaN(n)||(n*=s.get().streaming.abr.bandwidthSafetyFactor),n},getAverageLatency:function(e){return l(!1,e)},reset:d};return o={throughputHalfLife:{fast:3,slow:8},latencyHalfLife:{fast:1,slow:2}},d(),h}Nt.__dashjs_factory_name="ThroughputHistory";var Ct=c.a.getClassFactory(Nt);function Dt(){var e,t,n,r,i,o,c,h,p,m,y,E,T,v,S,A,b,I,R,N,C,D,w,M,P,L,F=this.context,x=Object(f.a)(F).getInstance(),U=Object(u.a)(F).getInstance();function B(){i={},o={},h={},c={},R={},D={},w={},M={},void 0===m&&(m=!1),N&&N.reset(),I=void 0,N=void 0,C=void 0,clearTimeout(p),p=null}function k(t){var i=t.request.mediaType,a=t.streamId;if(i&&a&&c[a]&&L.get().streaming.abr.autoSwitchBitrate[i]){var o=c[a][i];if(o){var u=vt(F).create({abrController:e,streamProcessor:o,currentRequest:t.request,useBufferOccupancyABR:D[i],useL2AABR:w[i],useLoLPABR:M[i],videoModel:v}),l=n.shouldAbandonFragment(u,a);if(l.quality>St.a.NO_CHANGE)o.getFragmentModel().getRequests({state:g.a.FRAGMENT_MODEL_LOADING,index:t.request.index})[0]&&(h[a][i].state=s.a.ABANDON_LOAD,R[a][i].reset(),R[a][i].push({oldValue:V(i,a),newValue:l.quality,confidence:1,reason:l.reason}),K(i,r.getActiveStreamInfo(),l.quality,l.reason),clearTimeout(p),p=setTimeout((function(){h[a][i].state=s.a.ALLOW_LOAD,p=null}),L.get().streaming.abandonLoadTimeout))}}}function G(e){e.mediaType===a.a.VIDEO&&(void 0!==I&&N.push(e.streamId,I,v.getPlaybackQuality()),I=e.newQuality)}function j(e){var n,r;e.metric!==s.a.HTTP_REQUEST||!e.value||e.value.type!==_.a.MEDIA_SEGMENT_TYPE||e.mediaType!==a.a.AUDIO&&e.mediaType!==a.a.VIDEO||C.push(e.mediaType,e.value,L.get().streaming.abr.useDeadTimeLatency),e.metric!==s.a.BUFFER_LEVEL||e.mediaType!==a.a.AUDIO&&e.mediaType!==a.a.VIDEO||(n=e.mediaType,r=.001*e.value.level,L.get().streaming.abr.ABRStrategy===a.a.ABR_STRATEGY_DYNAMIC&&function(e,n){try{var r=S.getStableBufferTime(),i=r,a=.5*r,o=D[e],s=n>(o?a:i);D[e]=s,s!==o&&(s?t.info("["+e+"] switching from throughput to buffer occupancy ABR rule (buffer: "+n.toFixed(3)+")."):t.info("["+e+"] switching from buffer occupancy to throughput ABR rule (buffer: "+n.toFixed(3)+")."))}catch(e){t.error(e)}}(n,r))}function Y(e,t){try{return i[t]=i[t]||{},i[t].hasOwnProperty(e)||(i[t][e]=0),function(e,t,n){if(t!==a.a.VIDEO||!L.get().streaming.abr.limitBitrateByPortal||!c[n]||!c[n][t])return e;m||Q();var r=c[n][t].getStreamInfo(),i=T.getAdaptationForType(r.index,t,r).Representation_asArray,o=e;if(y>0&&E>0){for(;o>0&&i[o]&&y=1||a<0)return e;return Math.min(e,Math.round(r*a))}(function(e,t){var n=i[t][e],r=n;if(!c[t]||!c[t][e])return r;var a=H(e,t);void 0!==a&&(r=Math.max(n,a));var o=function(e,t){try{var n=S.getAbrBitrateParameter("maxBitrate",e);return n>-1?W(c[t][e].getMediaInfo(),n,t):void 0}catch(e){return}}(e,t);void 0!==o&&(r=Math.min(r,o));return r}(e,t),e,t),e,t)}catch(e){return}}function H(e,t){try{return function(e,t){try{var n=S.getAbrBitrateParameter("minBitrate",e);if(n>-1){var r=c[t][e].getMediaInfo(),i=X(r),a=W(r,n,t);return i[a]&&a1&&void 0!==arguments[1]?arguments[1]:null;try{if(t||(t=r.getActiveStreamInfo().id),e&&c[t]&&c[t][e])if(t)return o[t]=o[t]||{},o[t].hasOwnProperty(e)||(o[t][e]=0),o[t][e];return 0}catch(e){return 0}}function K(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(t&&t.id&&e){var i=t.id,a=V(e,i);Object(O.a)(n);var o=Y(e,i);n!==a&&n>=0&&n<=o&&q(e,a,n,o,r,i)}}function q(e,n,r,i,a,s){if(e&&c[s]&&c[s][e]){var u=c[s][e].getStreamInfo(),f=u&&u.manifestInfo&&u.manifestInfo.isDynamic,d=P.getCurrentBufferLevel(e);t.info("Stream ID: "+s+" ["+e+"] switch from "+n+" to "+r+"/"+i+" (buffer: "+d+") "+(a?JSON.stringify(a):".")),o[s]=o[s]||{},o[s][e]=r;var h=function(e,t,n){if(t&&c&&c[e]&&c[e][t]){var r=X(c[e][t].getMediaInfo());return r[n]?r[n]:null}return null}(s,e,r);U.trigger(l.a.QUALITY_CHANGE_REQUESTED,{oldQuality:n,newQuality:r,reason:a,streamInfo:u,bitrateInfo:h,maxIdx:i,mediaType:e},{streamId:u.id,mediaType:e});var p=C.getAverageThroughput(e,f);isNaN(p)||b.setSavedBitrateSettings(e,p)}}function W(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,i=e&&e.type?c[n][e.type].getRepresentationInfo():null;if(L.get().streaming.abr.useDeadTimeLatency&&r&&i&&i.fragmentDuration){r/=1e3;var a=i.fragmentDuration;if(r>a)return 0;var o=r/a;t*=1-o}for(var s=X(e),u=s.length-1;u>=0;u--){var l=s[u];if(1e3*t>=l.bitrate)return u}return 0}function X(e){var t=[];if(!e||!e.bitrateList)return t;for(var n,r=e.bitrateList,i=e.type,a=0,o=r.length;a1&&void 0!==arguments[1]?arguments[1]:null;if(t||(t=r.getActiveStreamInfo().id),e&&c&&c[t]&&c[t][e]){var n=Y(e,t),i=X(c[t][e].getMediaInfo());return i[n]?i[n]:null}return null},getMinAllowedIndexFor:H,getMaxAllowedIndexFor:Y,getInitialBitrateFor:function(e,t){if(function(){if(!b||!b.hasOwnProperty("getSavedBitrateSettings"))throw new Error(a.a.MISSING_CONFIG_ERROR)}(),e===a.a.TEXT)return NaN;var n=b.getSavedBitrateSettings(e),r=S.getAbrBitrateParameter("initialBitrate",e),i=L.get().streaming.abr.initialRepresentationRatio[e];if(-1===r)if(i>-1){var o=c[t][e].getStreamInfo(),s=T.getAdaptationForType(o.index,e,o).Representation_asArray;if(Array.isArray(s))r=s[Math.max(Math.round(s.length*i)-1,0)].bandwidth/1e3;else r=0}else r=isNaN(n)?e===a.a.VIDEO?1e3:100:n;return r},getQualityFor:V,getAbandonmentStateFor:function(e,t){return h[e]&&h[e][t]?h[e][t].state:null},setPlaybackQuality:K,checkPlaybackQuality:function(t,r){try{if(!(t&&c&&c[r]&&c[r][t]))return!1;if(N){var i=v.getPlaybackQuality();i&&N.push(r,I,i)}if(!L.get().streaming.abr.autoSwitchBitrate[t])return!1;var a=V(t,r),o=vt(F).create({abrController:e,switchHistory:R[r][t],droppedFramesHistory:N,streamProcessor:c[r][t],currentValue:a,useBufferOccupancyABR:D[t],useL2AABR:w[t],useLoLPABR:M[t],videoModel:v}),u=H(t,r),l=Y(t,r),f=n.getMaxQuality(o),d=f.quality;return void 0!==u&&(d>St.a.NO_CHANGE?d:a)l&&(d=l),R[r][t].push({oldValue:a,newValue:d}),d>St.a.NO_CHANGE&&d!==a&&(h[r][t].state===s.a.ALLOW_LOAD||d0}function p(){if(n&&h()&&0===n.playbackRate){var e=document.createEvent("Event");e.initEvent("waiting",!0,!1),n.dispatchEvent(e)}}function g(e,t){n&&n.addEventListener(e,t)}function m(e,t){n&&n.removeEventListener(e,t)}function y(){return n?n.readyState:NaN}function E(){return n?n.buffered:null}function _(e,t,r,i,a){if(n)for(var o=0;o=e?t():function(e,t){g(e,(function n(){m(e,n),t(e)}))}(Pt.get(e),t)}return e={initialize:function(){s.on(l.a.PLAYBACK_PLAYING,p,this)},setCurrentTime:function(e,t){r=e,T(a.a.VIDEO_ELEMENT_READY_STATES.HAVE_METADATA,(function(){if(n){if(n.currentTime===r)return void(r=NaN);try{r=t?function(e){var t=E(),n=e,r=9999999999;if(t)for(var i=0;i=a&&e<=o)return e;s1&&void 0!==arguments[1]&&arguments[1];n&&(!t&&n.readyState<=2&&e>0?n.addEventListener("canplay",d):n.playbackRate=e)},getPlayedRanges:function(){return n?n.played:null},getEnded:function(){return n?n.ended:null},setStallState:function(e,t){!function(e,t){t?function(e){if(null===e||!n||n.seeking||-1!==c.indexOf(e))return;c.push(e)}(e):function(e){var t=c.indexOf(e);if(null===e)return;-1!==t&&c.splice(t,1)}(e)}(e,t)},getElement:function(){return n},setElement:function(e){if(!(null==e||e&&/^(VIDEO|AUDIO)$/i.test(e.nodeName)))throw"element is not video or audio DOM type!";(n=e)&&(n.preload="auto")},setSource:function(e){n&&(e?n.src=e:(n.removeAttribute("src"),n.load()))},getSource:function(){return n?n.src:null},getTTMLRenderingDiv:function(){return i},setTTMLRenderingDiv:function(e){(i=e).style.position="absolute",i.style.display="flex",i.style.overflow="hidden",i.style.pointerEvents="none",i.style.top=0,i.style.left=0},getPlaybackQuality:function(){if(!n)return null;var e="webkitDroppedFrameCount"in n&&"webkitDecodedFrameCount"in n,t=null;return"getVideoPlaybackQuality"in n?t=n.getVideoPlaybackQuality():e&&(t={droppedVideoFrames:n.webkitDroppedFrameCount,totalVideoFrames:n.webkitDroppedFrameCount+n.webkitDecodedFrameCount,creationTime:new Date}),t},addEventListener:g,removeEventListener:m,getReadyState:y,getBufferRange:E,getClientWidth:function(){return n?n.clientWidth:NaN},getClientHeight:function(){return n?n.clientHeight:NaN},getTextTracks:function(){return n?n.textTracks:[]},getTextTrack:_,addTextTrack:function(e,t,r,i,a){if(!n)return null;var o=_(e,t,r,i,a);return o||((o=n.addTextTrack(e,t,r)).isEmbedded=a,o.isTTML=i),o},appendChild:function(e){n&&(n.appendChild(e),void 0!==e.isTTML&&(n.textTracks[n.textTracks.length-1].isTTML=e.isTTML,n.textTracks[n.textTracks.length-1].isEmbedded=e.isEmbedded))},removeChild:function(e){n&&n.removeChild(e)},getVideoWidth:function(){return n?n.videoWidth:NaN},getVideoHeight:function(){return n?n.videoHeight:NaN},getVideoRelativeOffsetTop:function(){var e=n.parentNode.host||n.parentNode;return e?n.getBoundingClientRect().top-e.getBoundingClientRect().top:NaN},getVideoRelativeOffsetLeft:function(){var e=n.parentNode.host||n.parentNode;return e?n.getBoundingClientRect().left-e.getBoundingClientRect().left:NaN},waitForReadyState:T,reset:function(){s.off(l.a.PLAYBACK_PLAYING,p,this)}},t=Object(f.a)(o).getInstance().getLogger(e),r=NaN,e}Lt.__dashjs_factory_name="VideoModel";var Ft=c.a.getSingletonFactory(Lt),xt=n(42),Ut=[{oldKey:"dashjs_vbitrate",newKey:"dashjs_video_bitrate"},{oldKey:"dashjs_abitrate",newKey:"dashjs_audio_bitrate"},{oldKey:"dashjs_vsettings",newKey:"dashjs_video_settings"},{oldKey:"dashjs_asettings",newKey:"dashjs_audio_settings"}];function Bt(e){e=e||{};var t,n,r,i=this.context,o=e.settings;function s(e){if(void 0!==r)return r;r=!1;var t;try{"undefined"!=typeof window&&(t=window[e])}catch(e){return n.warn("DOMStorage access denied: "+e.message),r}if(!t||"localStorage"!==e&&"sessionStorage"!==e)return r;try{t.setItem("1","1"),t.removeItem("1"),r=!0}catch(e){n.warn("DOMStorage is supported, but cannot be used: "+e.message)}return r}function u(){return 6e5*Math.round((new Date).getTime()/6e5)}function l(e,t){return s(e)&&o.get().streaming[t+"CachingInfo"].enabled}function c(){if(!o)throw new Error(a.a.MISSING_CONFIG_ERROR)}return t={getSavedBitrateSettings:function(e){if(c(),!o.get().streaming.lastBitrateCachingInfo.enabled)return NaN;var t=NaN;if(l("localStorage","lastBitrate")){var r="dashjs_?_bitrate".replace(/\?/,e);try{var i=JSON.parse(localStorage.getItem(r))||{},a=(new Date).getTime()-parseInt(i.timestamp,10)>=o.get().streaming.lastBitrateCachingInfo.ttl||!1,s=parseFloat(i.bitrate);isNaN(s)||a?a&&localStorage.removeItem(r):(t=s,n.debug("Last saved bitrate for "+e+" was "+s))}catch(e){return null}}return t},setSavedBitrateSettings:function(e,t){if(l("localStorage","lastBitrate")&&t){var r="dashjs_?_bitrate".replace(/\?/,e);try{localStorage.setItem(r,JSON.stringify({bitrate:t.toFixed(3),timestamp:u()}))}catch(e){n.error(e.message)}}},getSavedMediaSettings:function(e){if(c(),!o.get().streaming.lastMediaSettingsCachingInfo.enabled)return null;var t=null;if(l("localStorage","lastMediaSettings")){var n="dashjs_?_settings".replace(/\?/,e);try{var r=JSON.parse(localStorage.getItem(n))||{},i=(new Date).getTime()-parseInt(r.timestamp,10)>=o.get().streaming.lastMediaSettingsCachingInfo.ttl||!1;t=r.settings,i&&(localStorage.removeItem(n),t=null)}catch(e){return null}}return t},setSavedMediaSettings:function(e,t){if(l("localStorage","lastMediaSettings")){var r="dashjs_?_settings".replace(/\?/,e);try{localStorage.setItem(r,JSON.stringify({settings:t,timestamp:u()}))}catch(e){n.error(e.message)}}}},n=Object(f.a)(i).getInstance().getLogger(t),s("localStorage")&&Ut.forEach((function(e){var t=localStorage.getItem(e.oldKey);if(t){localStorage.removeItem(e.oldKey);try{localStorage.setItem(e.newKey,t)}catch(e){n.error(e.message)}}})),t}Bt.__dashjs_factory_name="DOMStorage";var kt=c.a.getSingletonFactory(Bt),Gt=n(55),jt=n(32);function Yt(){var e,t,n,r,i,a,o,s,u,l,c,f,d,h=this.context;function p(e,t,n){n({segments:e,representation:t,error:e?void 0:new m.a(u.SEGMENT_BASE_LOADER_ERROR_CODE,u.SEGMENT_BASE_LOADER_ERROR_MESSAGE)})}function g(e){if(e.url){var t=new qe.a;return t.setInfo(e),t}}return e={setConfig:function(s){s.baseURLController&&(d=s.baseURLController),s.dashMetrics&&(a=s.dashMetrics),s.mediaPlayerModel&&(o=s.mediaPlayerModel),s.errHandler&&(n=s.errHandler),s.boxParser&&(r=s.boxParser),s.debug&&(t=s.debug.getLogger(e)),s.requestModifier&&(i=s.requestModifier),s.errors&&(u=s.errors),s.urlUtils&&(f=s.urlUtils),s.constants&&(l=s.constants),s.dashConstants&&(c=s.dashConstants)},initialize:function(){s=Object(Ke.a)(h).create({errHandler:n,dashMetrics:a,mediaPlayerModel:o,requestModifier:i,boxParser:r,errors:u,urlUtils:f,constants:l,dashConstants:c})},loadInitialization:function(e,n){return new Promise((function(i){!function e(n,i,a,o){var u=null,l=n?d.resolve(n.path):null,c=o||{init:!0,url:l?l.url:void 0,range:{start:0,end:1500},searching:!1,bytesLoaded:0,bytesToLoad:1500,mediaType:i};t.debug("Start searching for initialization.");var f=g(c),h=function(t){if(c.bytesLoaded=c.range.end,!(u=r.findInitRange(t)))return c.range.end=c.bytesLoaded+c.bytesToLoad,e(n,i,a,c);n.range=u,a(n)};s.load({request:f,success:h,error:function(){a(n)}}),t.debug("Perform init search: "+c.url)}(e,n,i)}))},loadSegments:function(e,n,i){return new Promise((function(a){!function e(n,i,a,o,u,l){if(a&&(void 0===a.start||void 0===a.end)){var c=a?a.toString().split("-"):null;a=c?{start:parseFloat(c[0]),end:parseFloat(c[1])}:null}u=u||p;var f=null,h=null,m=!!a,y=n?d.resolve(n.path):null,E={init:!1,url:y?y.url:void 0,range:m?a:{start:0,end:1500},searching:!m,bytesLoaded:l?l.bytesLoaded:0,bytesToLoad:1500,mediaType:i},_=g(E),T=function(a){var s=E.bytesToLoad,l=a.byteLength;if(E.bytesLoaded=E.range.end-E.range.start,f=r.parse(a),(h=f.getBox("sidx"))&&h.isComplete){var c,d,p=h.references;if(null!=p&&p.length>0&&(c=1===p[0].reference_type),c){var g,m,y,_;t.debug("Initiate multiple SIDX load."),E.range.end=E.range.start+h.size;var T=[],v=0,S=(h.offset||E.range.start)+h.size,A=function(e){e?(T=T.concat(e),++v>=m&&(T.sort((function(e,t){return e.startTime-t.startTime<0?-1:0})),u(T,n,o))):u(null,n,o)};for(g=0,m=p.length;g16777215?(n.getUint32(r)!==e.tag&&(i=!1),a=4):e.tag>65535?(256*n.getUint16(r)+n.getUint8(r+2)!==e.tag&&(i=!1),a=3):e.tag>255?(n.getUint16(r)!==e.tag&&(i=!1),a=2):(n.getUint8(r)!==e.tag&&(i=!1),a=1),!i&&e.required&&!t)throw new Error("required tag not found");return i&&(r+=a),i}function a(e){var t=1,i=128,a=-1,o=0,s=n.getUint8(r),u=0;for(u=0;u<8;u+=1){if((s&i)===i){o=void 0===e?s&~i:s,a=u;break}i>>=1}for(u=0;u1&&a){var l=d(a,n);if(i[a.id]&&i[a.id][n])for(var f=0,h=u.length;f0))return u;s=r[0].mpd.manifest}var l=E(e,o),c=t.getAdaptationsForType(s,e?e.index:null,n);return u=f(s,l,e,c,n),n===a.TEXT&&(c=t.getAdaptationsForType(s,e?e.index:null,a.VIDEO),u=u.concat(f(s,l,e,c,n,!0))),u}function h(e){var n=p(e);return t.getRegularPeriods(n)}function p(e){var n=m(e);return t.getMpd(n)}function g(){r=[],i={}}function m(e){return e||(r.length>0?r[0].mpd.manifest:null)}function y(e){try{var n=E(e.streamInfo,r),i=t.getAdaptationsForPeriod(n);return e&&e.streamInfo&&void 0!==e.streamInfo.id&&i?i[e.index]:null}catch(e){return null}}function E(e,t){for(var n=t.length,r=0;r=0&&void 0!==s&&(n=t?"cea-608:"+t:"cea-608",r.embeddedCaptions=!0),n})),r.audioChannelConfiguration=t.getAudioChannelConfigurationForAdaptation(i).map((function(e){return e.value})),0===r.audioChannelConfiguration.length&&Array.isArray(i.Representation_asArray)&&i.Representation_asArray.length>0&&(r.audioChannelConfiguration=t.getAudioChannelConfigurationForRepresentation(i.Representation_asArray[0]).map((function(e){return e.value}))),r.roles=t.getRolesForAdaptation(i).map((function(e){return e.value})),r.codec=t.getCodec(i),r.mimeType=t.getMimeType(i),r.contentProtection=t.getContentProtectionData(i),r.bitrateList=t.getBitrateListForAdaptation(i),r.selectionPriority=t.getSelectionPriority(i),r.contentProtection){var a=r.contentProtection.map((function(e){return t.getKID(e)})).filter((function(e){return null!==e}));if(a.length){var o=a[0];r.contentProtection.forEach((function(e){e.keyId=o}))}}return r.isText=t.getIsText(i),r.supplementalProperties=t.getSupplementalProperties(i),r.isFragmented=t.getIsFragmented(i),r.isEmbedded=!1,r}function T(e,t,n){e.id=t,e.index=100+parseInt(t.substring(2,3)),e.type=a.TEXT,e.codec="cea-608-in-SEI",e.isEmbedded=!0,e.isFragmented=!1,e.lang=n,e.roles=["caption"]}function v(e){var n,r,i=new Zt;return i.id=e.id,i.index=e.index,i.start=e.start,i.duration=e.duration,i.manifestInfo=(n=e.mpd,(r=new Jt).dvrWindowSize=n.timeShiftBufferDepth,r.loadedTime=n.manifest.loadedTime,r.availableFrom=n.availabilityStartTime,r.minBufferTime=n.manifest.minBufferTime,r.maxFragmentDuration=n.maxSegmentDuration,r.duration=t.getDuration(n.manifest),r.isDynamic=t.getIsDynamic(n.manifest),r.serviceDescriptions=t.getServiceDescriptions(n.manifest),r.protocol=n.manifest.protocol,r),i.isLast=1===e.mpd.manifest.Period_asArray.length||Math.abs(i.start+i.duration-i.manifestInfo.duration)<1,i}function S(){if(!a)throw new Error("setConfig function has to be called previously")}function A(e){return r.length>0?r[0].mpd.manifest.Period_asArray[e]:null}function b(e,t,n){var r,i,a,o,s;if(e)for(r=e.AdaptationSet_asArray,o=0;o0?e.segments[0].duration:NaN),n.MSETimeOffset=e.MSETimeOffset,n.mediaInfo=_(e.adaptation),n}return null},getStreamsInfo:function(e,t){var n=[],i=r;if(e&&(S(),i=h(e)),i.length>0){(!t||t>i.length)&&(t=i.length);for(var a=0;a0&&o&&(a=i?t.getAdaptationForId(i,r[0].mpd.manifest,o.index):t.getAdaptationForIndex(n?n.index:null,r[0].mpd.manifest,o.index)),a},getProducerReferenceTimes:function(e,n){var i,a,o=E(e,r);return i=n?n.id:null,r.length>0&&o&&(a=i?t.getAdaptationForId(i,r[0].mpd.manifest,o.index):t.getAdaptationForIndex(n?n.index:null,r[0].mpd.manifest,o.index)),a?t.getProducerReferenceTimesForAdaptation(a):[]},getRealPeriodByIndex:function(e){return t.getRealPeriodForIndex(e,r[0].mpd.manifest)},getEssentialPropertiesForRepresentation:function(e){try{return t.getEssentialPropertiesForRepresentation(e)}catch(e){return[]}},getVoRepresentations:function(e){var n=y(e);return t.getRepresentationsForAdaptation(n)},getEventsFor:function(e,n,i){var a=[];if(r.length>0){var o=r[0].mpd.manifest;if(e instanceof Zt){var s=E(e,r);a=t.getEventsForPeriod(s)}else if(e instanceof $t){var u=E(i,r);a=t.getEventStreamForAdaptationSet(o,y(e),u)}else if(e instanceof Qt){var l=E(i,r);a=t.getEventStreamForRepresentation(o,n,l)}}return a},getEvent:function(e,t,n,r){try{if(!e||!t||isNaN(n)||!r)return null;var i=e.scheme_id_uri,a=e.value;if(!t[i+"/"+a])return null;var o,s=new en.a,u=e.timescale||1,l=r.adaptation.period.start,c=t[i+"/"+a],f=isNaN(r.presentationTimeOffset)?isNaN(c.presentationTimeOffset)?0:c.presentationTimeOffset:r.presentationTimeOffset,d=e.presentation_time_delta/u;o=0===e.version?l+n-f+d:l-f+d;var h=e.event_duration/u,p=e.id,g=e.message_data;return s.eventStream=c,s.eventStream.value=a,s.eventStream.timescale=u,s.duration=h,s.id=p,s.calculatedPresentationTime=o,s.messageData=g,s.presentationTimeDelta=d,s}catch(e){return null}},getMpd:p,setConfig:function(e){e&&(e.constants&&(a=e.constants),e.cea608parser&&(s=e.cea608parser),e.errHandler&&t.setConfig({errHandler:e.errHandler}),e.BASE64&&t.setConfig({BASE64:e.BASE64}))},updatePeriods:function(e){if(!e)return null;S(),r=h(e)},getIsTextTrack:function(e){return t.getIsText(e)},getUTCTimingSources:function(){var e=m();return t.getUTCTimingSources(e)},getSuggestedPresentationDelay:function(){var e=r.length>0?r[0].mpd:null;return t.getSuggestedPresentationDelay(e)},getAvailabilityStartTime:function(e){var n=p(e);return t.getAvailabilityStartTime(n)},getIsTypeOf:function(e,n){return t.getIsTypeOf(e,n)},getIsDynamic:function(e){var n=m(e);return t.getIsDynamic(n)},getDuration:function(e){var n=m(e);return t.getDuration(n)},getRegularPeriods:h,getLocation:function(e){return t.getLocation(e)},getPatchLocation:function(e){var n=t.getPatchLocation(e),r=t.getPublishTime(e);if(!n||!r)return null;if(n.hasOwnProperty("ttl")&&r){var i=1e3*parseFloat(n.ttl);if(r.getTime()+i<=(new Date).getTime())return null}return n.__text},getManifestUpdatePeriod:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return t.getManifestUpdatePeriod(e,n)},getPublishTime:function(e){return t.getPublishTime(e)},getIsDVB:function(e){return t.hasProfile(e,"urn:dvb:dash:profile:dvb-dash:2014")},getIsPatch:function(e){return n.getIsPatch(e)},getBaseURLsFromElement:function(e){return t.getBaseURLsFromElement(e)},getRepresentationSortFunction:function(){return t.getRepresentationSortFunction()},getCodec:function(e,n,r){return t.getCodec(e,n,r)},getPeriodById:function(e){if(!e||0===r.length)return null;var t=r.filter((function(t){return t.id===e}));return t&&t.length>0?t[0]:null},setCurrentMediaInfo:function(e,t,n){i[e]=i[e]||{},i[e][t]=i[e][t]||{},i[e][t]=n},isPatchValid:function(e,r){var i=t.getId(e),a=n.getMpdId(r),o=t.getPublishTime(e),s=n.getPublishTime(r),u=n.getOriginalPublishTime(r);return!!(i&&a&&i==a&&o&&u&&o.getTime()==u.getTime()&&s&&o.getTime()1?i[r]=u:1==u.length?i[r]=u[0]:delete i[r+"_asArray"]}"add"!==t.action&&"replace"!==t.action||Object.keys(t.value).forEach((function(e){var n=t.value[e],a=i[e+"_asArray"]||[];if(0===a.length&&i[e]&&a.push(i[e]),0===a.length)a=n;else{var u=a.length;u=e==r&&-1!=o?o+(s?0:1)+("replace"==t.action?-1:0):s?0:a.length,a.splice.apply(a,[u,0].concat(n))}i[e+"_asArray"]=a,i[e]=1==a.length?a[0]:a}))}}}))},areMediaInfosEqual:c,reset:g},t=Object(tn.a)(u).getInstance(),n=un(u).getInstance(),g(),e}ln.__dashjs_factory_name="DashAdapter";var cn=c.a.getSingletonFactory(ln);function fn(e,t){for(var n=0;nr.get().streaming.metrics.maxListDepth&&i[t].shift())}function m(e,t,n){g(e,t,n),h(e,t,n)}return t={clearCurrentMetricsForType:function(e){delete n[e],f(e)},clearAllCurrentMetrics:function(){n={},c()},getMetricsFor:p,addHttpRequest:function e(t,n,r,i,a,o,u,l,c,f,d,h,p,g,y,E){var T=new _.a;o&&o!==i&&(e(t,null,r,i,a,null,null,l,c,null,null,null,p,null,null,E),T.actualurl=o),T.tcpid=n,T.type=r,T.url=i,T.range=l,T.trequest=c,T.tresponse=f,T.responsecode=h,T._tfinish=d,T._stream=t,T._mediaduration=p,T._quality=a,T._responseHeaders=g,T._serviceLocation=u,T._fileLoaderType=E,y?y.forEach((function(e){!function(e,t,n,r){var i=new _.b;i.s=t,i.d=n,i.b=r,e.trace.push(i),e.interval||(e.interval=0),e.interval+=n}(T,e.s,e.d,e.b)})):(delete T.interval,delete T.trace),m(t,s.a.HTTP_REQUEST,T)},addRepresentationSwitch:function(e,t,n,r,i){var a=new pn;a.t=t,a.mt=n,a.to=r,i?a.lto=i:delete a.lto,m(e,s.a.TRACK_SWITCH,a)},addBufferLevel:function(e,t,n){var r=new gn;r.t=t,r.level=n,m(e,s.a.BUFFER_LEVEL,r)},addBufferState:function(e,t,n){var r=new mn;r.target=n,r.state=t,m(e,s.a.BUFFER_STATE,r)},addDVRInfo:function(e,t,n,r){var i=new yn;i.time=t,i.range=r,i.manifestInfo=n,m(e,s.a.DVR_INFO,i)},addDroppedFrames:function(e,t){var n=new En,r=p(e).DroppedFrames;t&&(n.time=t.creationTime,n.droppedFrames=t.droppedVideoFrames,r.length>0&&r[r.length-1]==n||m(e,s.a.DROPPED_FRAMES,n))},addSchedulingInfo:function(e,t,n,r,i,a,o,u,l){var c=new An;c.mediaType=e,c.t=t,c.type=n,c.startTime=r,c.availabilityStartTime=i,c.duration=a,c.quality=o,c.range=u,c.state=l,m(e,s.a.SCHEDULING_INFO,c)},addRequestsQueue:function(e,t,n){var r=new bn;r.loadingRequests=t,r.executedRequests=n,p(e).RequestsQueue=r,h(e,s.a.REQUESTS_QUEUE,r)},addManifestUpdate:function(e,t,n,r,i,o,u,l,c,f){var d=new Tn;d.mediaType=e,d.type=t,d.requestTime=n,d.fetchTime=r,d.availabilityStartTime=i,d.presentationStartTime=o,d.clientTimeOffset=u,d.currentTime=l,d.buffered=c,d.latency=f,g(a.a.STREAM,s.a.MANIFEST_UPDATE,d),h(e,s.a.MANIFEST_UPDATE,d)},updateManifestUpdateInfo:function(e,t){if(e){for(var n in t)e[n]=t[n];d(e.mediaType,s.a.MANIFEST_UPDATE,e)}},addManifestUpdateStreamInfo:function(e,t,n,r,i){if(e){var a=new vn;a.id=t,a.index=n,a.start=r,a.duration=i,e.streamInfo.push(a),d(e.mediaType,s.a.MANIFEST_UPDATE_STREAM_INFO,e)}},addManifestUpdateRepresentationInfo:function(e,t,n,r,i,a,o,u){if(e&&e.representationInfo){var l=new Sn;l.id=t,l.index=n,l.streamIndex=r,l.mediaType=i,l.startNumber=o,l.fragmentInfoType=u,l.presentationTimeOffset=a,e.representationInfo.push(l),d(e.mediaType,s.a.MANIFEST_UPDATE_TRACK_INFO,e)}},addPlayList:function(e){e.trace&&Array.isArray(e.trace)?e.trace.forEach((function(e){e.hasOwnProperty("subreplevel")&&!e.subreplevel&&delete e.subreplevel})):delete e.trace,m(a.a.STREAM,s.a.PLAY_LIST,e)},addDVBErrors:function(e){m(a.a.STREAM,s.a.DVB_ERRORS,e)}},n={},t}In.__dashjs_factory_name="MetricsModel";var Rn=c.a.getSingletonFactory(In),Nn=n(15);function Cn(e){e=e||{};var t,n,r,i,o=this.context,u=e.metricsModel;function l(e){var t=u.getMetricsFor(e,!0);if(!t)return null;var n,r=t.HttpList,i=null;if(!r||r.length<=0)return null;for(n=r.length-1;n>=0;){if(r[n].responsecode){i=r[n];break}n--}return i}function c(e){var t=u.getMetricsFor(e,!0);return t&&t.HttpList?t.HttpList:[]}function f(e,t){if(!e)return null;var n=e[t];return n&&0!==n.length?n[n.length-1]:null}return t={getCurrentRepresentationSwitch:function(e){return f(u.getMetricsFor(e,!0),s.a.TRACK_SWITCH)},getCurrentBufferState:function(e){return f(u.getMetricsFor(e,!0),s.a.BUFFER_STATE)},getCurrentBufferLevel:function(e){var t=f(u.getMetricsFor(e,!0),s.a.BUFFER_LEVEL);return t?dn.round10(t.level/1e3,-3):0},getCurrentHttpRequest:l,getHttpRequests:c,getCurrentDroppedFrames:function(){return f(u.getMetricsFor(a.a.VIDEO,!0),s.a.DROPPED_FRAMES)},getCurrentSchedulingInfo:function(e){return f(u.getMetricsFor(e,!0),s.a.SCHEDULING_INFO)},getCurrentDVRInfo:function(e){return f(e?u.getMetricsFor(e,!0):u.getMetricsFor(a.a.VIDEO,!0)||u.getMetricsFor(a.a.AUDIO,!0),s.a.DVR_INFO)},getCurrentManifestUpdate:function(){return f(u.getMetricsFor(a.a.STREAM),s.a.MANIFEST_UPDATE)},getLatestFragmentRequestHeaderValueByID:function(e,t){if(!t)return null;var n={},r=l(e);r&&(n=Nn.a.parseHttpHeaders(r._responseHeaders));var i=n[t.toLowerCase()];return void 0===i?null:i},getLatestMPDRequestHeaderValueByID:function(e){if(!e)return null;var t,n,r,i={};for(r=(t=c(a.a.STREAM)).length-1;r>=0;r--)if((n=t[r]).type===_.a.MPD_TYPE){i=Nn.a.parseHttpHeaders(n._responseHeaders);break}var o=i[e.toLowerCase()];return void 0===o?null:o},addRepresentationSwitch:function(e,t,n,r,i){u.addRepresentationSwitch(e,t,n,r,i)},addDVRInfo:function(e,t,n,r){u.addDVRInfo(e,t,n,r)},updateManifestUpdateInfo:function(e){var t=this.getCurrentManifestUpdate();u.updateManifestUpdateInfo(t,e)},addManifestUpdateStreamInfo:function(e){if(e){var t=this.getCurrentManifestUpdate();u.addManifestUpdateStreamInfo(t,e.id,e.index,e.start,e.duration)}},addManifestUpdateRepresentationInfo:function(e,t){if(e){var n=this.getCurrentManifestUpdate();u.addManifestUpdateRepresentationInfo(n,e.id,e.index,e.streamIndex,t,e.presentationTimeOffset,e.startNumber,e.fragmentInfoType)}},addManifestUpdate:function(e){u.addManifestUpdate(a.a.STREAM,e.type,e.requestStartDate,e.requestEndDate)},addHttpRequest:function(e,t,n,r,i){u.addHttpRequest(e.mediaType,null,e.type,e.url,e.quality,t,e.serviceLocation||null,e.range||null,e.requestStartDate,e.firstByteDate,e.requestEndDate,n,e.duration,r,i,e.fileLoaderType)},addSchedulingInfo:function(e,t){u.addSchedulingInfo(e.mediaType,new Date,e.type,e.startTime,e.availabilityStartTime,e.duration,e.quality,e.range,t)},addRequestsQueue:function(e,t,n){u.addRequestsQueue(e,t,n)},addBufferLevel:function(e,t,n){u.addBufferLevel(e,t,n)},addBufferState:function(e,t,n){u.addBufferState(e,t,n)},addDroppedFrames:function(e){u.addDroppedFrames(a.a.VIDEO,e)},addPlayList:function(){i&&(u.addPlayList(i),i=null)},addDVBErrors:function(e){u.addDVBErrors(e)},createPlaylistMetrics:function(e,t){(i=new U).start=new Date,i.mstart=e,i.starttype=t},createPlaylistTraceMetrics:function(e,t,i){!0===n&&(n=!1,(r=new B).representationid=e,r.start=new Date,r.mstart=t,r.playbackspeed=null!==i?i.toString():null)},updatePlayListTraceMetrics:function(e){if(r)for(var t in r)r[t]=e[t]},pushPlayListTraceMetrics:function(e,t){if(!1===n&&i&&r&&r.start){var a=r.start,o=e.getTime()-a.getTime();r.duration=o,r.stopreason=t,i.trace.push(r),n=!0}},clearAllCurrentMetrics:function(){u.clearAllCurrentMetrics()}},u=u||Rn(o).getInstance({settings:e.settings}),n=!0,r=null,i=null,t}Cn.__dashjs_factory_name="DashMetrics";var Dn=c.a.getSingletonFactory(Cn);function wn(){var e,t,n,r,i=this.context,s=Object(u.a)(i).getInstance(),c=Object(E.a)(i).getInstance();function f(e){r=e}function h(e,t,n,r){var i,a=t.adaptation.period.mpd,o=a.availabilityStartTime;if(r)i=n&&a.timeShiftBufferDepth!==Number.POSITIVE_INFINITY?new Date(o.getTime()+1e3*(e+a.timeShiftBufferDepth)):a.availabilityEndTime;else if(n){var s=t.availabilityTimeOffset;i=new Date(o.getTime()+1e3*(e-s))}else i=o;return i}function p(e,t){return(e.getTime()-t.mpd.availabilityStartTime.getTime()+1e3*r)/1e3}function g(e,t){return e+(t.adaptation.period.start-t.presentationTimeOffset)}function m(e){var n={start:NaN,end:NaN},r=e[0].getAdapter().getRegularPeriods()[0],i=p(new Date,r);if(!e||0===e.length)return{range:n,now:i};e.forEach((function(e){var r=e.getAdapter(),s=r.getMediaInfoForType(e.getStreamInfo(),a.a.VIDEO)||r.getMediaInfoForType(e.getStreamInfo(),a.a.AUDIO),u=r.getVoRepresentations(s)[0],l={start:NaN,end:NaN};if(u)if(u.segmentInfoType===o.a.SEGMENT_TIMELINE)l=function(e){var n,r,i,a,o=e.adaptation.period.mpd.manifest.Period_asArray[e.adaptation.period.index].AdaptationSet_asArray[e.adaptation.index],s=t.getRepresentationFor(e.index,o),u=s.SegmentTemplate.SegmentTimeline,l=s.SegmentTemplate.timescale,c=u.S_asArray,f={start:0,end:0},d=0;for(f.start=g(c[0].t/l,e),i=0,a=c.length;il.start)&&(n.start=l.start),!isNaN(l.end)&&(isNaN(n.end)||n.end2&&void 0!==arguments[2]&&arguments[2];try{for(var r=0,i=!1,a=NaN;!i&&r=t)?(a=t,i=!0):!n&&o.start>t&&(isNaN(a)||o.starta)&&(a=o.start+o.duration),r+=1}return a}catch(e){return t}}function T(e){void 0===e.offset||isNaN(e.offset)||f(e.offset/1e3)}function v(){r=0,n=0}function S(){s.off(l.a.UPDATE_TIME_SYNC_OFFSET,T,this),v()}return e={initialize:function(){v(),s.on(l.a.UPDATE_TIME_SYNC_OFFSET,T,this)},getClientTimeOffset:function(){return r},setClientTimeOffset:f,getClientReferenceTime:function(){return Date.now()-1e3*n+1e3*r},calcAvailabilityStartTimeFromPresentationTime:function(e,t,n){return h(e,t,n)},calcAvailabilityEndTimeFromPresentationTime:function(e,t,n){return h(e,t,n,!0)},calcPresentationTimeFromWallTime:p,calcPresentationTimeFromMediaTime:g,calcPeriodRelativeTimeFromMpdRelativeTime:function(e,t){return t-e.adaptation.period.start},calcMediaTimeFromPresentationTime:function(e,t){return e-t.adaptation.period.start+t.presentationTimeOffset},calcWallTimeForSegment:function(e,t){var n,r,i;return t&&(n=e.representation.adaptation.period.mpd.suggestedPresentationDelay,r=e.presentationStartTime+n,i=new Date(e.availabilityStartTime.getTime()+1e3*r)),i},calcTimeShiftBufferWindow:function(e,t){if(!t)return function(e){var t={start:NaN,end:NaN},n=0,r=NaN;return e.forEach((function(e){var t=e.getStreamInfo();n+=t.duration,(isNaN(r)||t.start0&&(g.spans.push({name:m,line:v,row:c}),v="");var N="style_cea608_"+R.foreground+"_"+R.background;R.underline&&(N+="_underline"),R.italics&&(N+="_italics"),E.hasOwnProperty(N)||(E[N]=JSON.parse(JSON.stringify(R))),S=R,m=N}v+=I.uchar}v.trim().length>0&&g.spans.push({name:m,line:v,row:c}),h=!0,p=A}else h=!1,p=-1,d&&(d.p.push(g),g={start:s,end:u,spans:[]},d.y2=c,d.name="region_"+d.x+"_"+d.y1+"_"+d.y2,!1===y.hasOwnProperty(d.name)?(_.push(d),y[d.name]=d):y[d.name].p.contat(d.p),d=null)}d&&(d.p.push(g),d.y2=c+1,d.name="region_"+d.x+"_"+d.y1+"_"+d.y2,!1===y.hasOwnProperty(d.name)?(_.push(d),y[d.name]=d):y[d.name].p.contat(d.p),d=null);var C=[];for(c=0;c<_.length;++c){var D=_[c],w="sub_cea608_"+e++,O=document.createElement("div");O.id=w;var M=n(D);O.style.cssText="position: absolute; margin: 0; display: flex; box-sizing: border-box; pointer-events: none;"+M;var P=document.createElement("div");P.className="paragraph bodyStyle",P.style.cssText=i(r);var L=document.createElement("div");L.className="cueUniWrapper",L.style.cssText="unicode-bidi: normal; direction: ltr;";for(var F=0;F0){if(0!==f&&U!=B.row){var k=document.createElement("br");k.className="lineBreak",L.appendChild(k)}var G=!1;U===B.row&&(G=!0),U=B.row;var j=E[B.name],Y=document.createElement("span");Y.className="spanPadding "+B.name+" customSpanColor",Y.style.cssText=i(r,j),0!==f&&G?f===x.spans.length-1?Y.textContent=o(B.line):Y.textContent=B.line:x.spans.length>1&&f1&&e.isEmbedded?t=e.id&&e.id===a.a.CC1:1===T.length?e.id&&"string"==typeof e.id&&"CC"===e.id.substring(0,2)&&(t=!0):0===T.length&&(t=e.index===s[0].index);return t}(e),t.isFragmented=e.isFragmented,t.isEmbedded=!!e.isEmbedded,t.isTTML=function(e){return e.codec&&e.codec.search(a.a.STPP)>=0||e.mimeType&&e.mimeType.search(a.a.TTML)>=0}(e),t.kind=function(e,t){var n=e.roles&&e.roles.length>0?t[e.roles[0]]:t.caption;return n=n===t.caption||n===t.subtitle?n:t.caption}(e,{subtitle:"subtitles",caption:"captions"}),D.addTextTrack(t)}function k(e){var t=e.chunk;t.mediaInfo.embeddedCaptions&&j(t.bytes,t)}function G(e){E=e}function j(e,s){var u=s.mediaInfo,l=u.type,f=u.mimeType,p=u.codec||f;p?-1!==u.codec.indexOf("application/mp4")?function(e,i,s){var u,l;if("InitializationSegment"===i.segmentType)d=!0,h=r.getMediaTimescaleFromMoov(e);else{if(!d)return;l=r.getSamplesInfo(e),(u=l.sampleList).length>0&&(g=u[0].cts-i.start*h),s.search(a.a.STPP)>=0?function(e,r,i){var s,u;for(o=null!==o?o:V(i),s=0;s0&&D.addCaptions(E,0,s)}(e,u)}}(e,s,p):l===a.a.VIDEO?function(e,t){var a,o;if(t.segmentType===_.a.INIT_SEGMENT_TYPE)0===v&&(v=r.getMediaTimescaleFromMoov(e));else if(t.segmentType===_.a.MEDIA_SEGMENT_TYPE){if(0===v)return void n.warn("CEA-608: No timescale for embeddedTextTrack yet");var s=(o=r.getSamplesInfo(e)).lastSequenceNumber;if(A[0]||A[1]||function(){for(var e,t=0;t0){o.cts!==u?l=0:l+=1;var h=H();n.fields[d].push([o.cts+h*v,f[d],l]),u=o.cts}return n.fields.forEach((function(e){e.sort((function(e,t){return e[0]===t[0]?e[2]-t[2]:e[0]-t[0]}))})),n}(e,o.sampleList),l=0;l=0?t=w:(e.search(a.a.TTML)>=0||e.search(a.a.STPP)>=0)&&(t=O),t}function K(e){T.forEach((function(t){var n=D.getTrackIdxForId(t.id);n>=0&&D.deleteCuesFromTrackIdx(n,e.from,e.to)}))}return t={initialize:function(){x||(T=[],E=null,v=0,A=[],S=null,x=!0,b=Vn(P).getInstance(),L.on(l.a.VIDEO_CHUNK_RECEIVED,k,t),L.on(l.a.BUFFER_CLEARED,K,t))},addMediaInfos:function(e,n,r){if(s=s.concat(n),e===a.a.TEXT&&n[0].isFragmented&&!n[0].isEmbedded){c=r,t.buffered=Object(Yn.a)(P).create(),p=N.getTracksFor(a.a.TEXT,M.id).filter((function(e){return e.isFragmented}));for(var i=N.getCurrentTrackFor(a.a.TEXT,M.id),o=0;on/r?o=(s=t)/r*n:s=(o=e)/n*r;var u,l,c=0,f=0;return o/s>i?(f=s,c=s*i):(c=o,f=o/i),u=(e-c)/2,l=(t-f)/2,a?{x:u+.1*c,y:l+.1*f,w:.8*c,h:.8*f}:{x:u,y:l,w:c,h:f}}function C(e,t){var n=I.getClientWidth(),r=I.getClientHeight(),i=I.getVideoWidth(),a=I.getVideoHeight(),o=I.getVideoRelativeOffsetTop(),s=I.getVideoRelativeOffsetLeft();if(0!==i&&0!==a){var u=i/a,l=!1;e.isFromCEA608&&(u=3.5/3,l=!0);var f=N.call(this,n,r,i,a,u,l),y=f.w,T=f.h,S=f.x,A=f.y;if(y!=p||T!=g||S!=c||A!=h||t){if(c=S+s,h=A+o,p=y,g=T,m){var R=m.style;R&&(R.left=c+"px",R.top=h+"px",R.width=p+"px",R.height=g+"px",R.zIndex=E&&document[E]||_?v:null,b.trigger(d.a.CAPTION_CONTAINER_RESIZE))}var C=e.activeCues;if(C)for(var D=C.length,w=0;w=0&&i[e]?I.getTextTrack(i[e].kind,i[e].id,i[e].lang,i[e].isTTML,i[e].isEmbedded):null}function P(e){var t=this;if(e!==s){var n=M(s=e);L.call(this,n),y&&(clearInterval(y),y=null),n&&"html"===n.renderingType&&(C.call(this,n,!0),window.ResizeObserver?(S=new window.ResizeObserver((function(){C.call(t,n,!0)}))).observe(I.getElement()):y=setInterval(C.bind(this,n),500))}}function L(e){G.call(this),e&&"html"===e.renderingType?B.call(this):k.call(this)}function F(e,t){if(!e.cues)return!1;for(var n=0;n3&&void 0!==arguments[3])||arguments[3];return(isNaN(t)||(r?e.startTime:e.endTime)>=t)&&(isNaN(n)||(r?e.endTime:e.startTime)<=n)}function U(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];if(e.cues)for(var i=e.cues,a=i.length-1,o=a;o>=0;o--)x(i[o],t,n,r)&&(i[o].onexit&&i[o].onexit(),e.removeCue(i[o]))}function B(){var e=document.getElementById("native-cue-style");if(!e){(e=document.createElement("style")).id="native-cue-style",document.head.appendChild(e);var t=e.sheet,r=I.getElement();try{r&&(r.id?t.insertRule("#"+r.id+"::cue {background: transparent}",0):0!==r.classList.length?t.insertRule("."+r.className+"::cue {background: transparent}",0):t.insertRule("video::cue {background: transparent}",0))}catch(e){n.info(""+e.message)}}}function k(){var e=document.getElementById("native-cue-style");e&&document.head.removeChild(e)}function G(){if(m)for(;m.firstChild;)m.removeChild(m.firstChild)}return t={initialize:function(){"undefined"!=typeof window&&"undefined"!=typeof navigator&&(r=window.VTTCue||window.TextTrackCue,i=[],o=[],s=-1,c=0,h=0,p=0,g=0,m=null,y=null,_=!1,v=2147483647,T=null,void 0!==document.fullscreenElement?E="fullscreenElement":void 0!==document.webkitIsFullScreen?E="webkitIsFullScreen":document.msFullscreenElement?E="msFullscreenElement":document.mozFullScreen&&(E="mozFullScreen"))},getStreamId:function(){return R.id},addTextTrack:function(e){i.push(e)},addCaptions:O,createTracks:function(){i.sort((function(e,t){return e.index-t.index})),m=I.getTTMLRenderingDiv();for(var e,t,n,r,u,c,f=-1,h=0;h=0){b.on(d.a.PLAYBACK_METADATA_LOADED,(function e(){var t=M(f);t&&"html"===t.renderingType&&C.call(this,t,!0),b.off(d.a.PLAYBACK_METADATA_LOADED,e,this)}),this);for(var y=0;y1){var n=e.split(/:/)[1];n&&-1!=n.search(/%/)&&(n=parseInt(n.replace(/%/,""),10)),(e.match(/align/)||e.match(/A/))&&(t.align=n),(e.match(/line/)||e.match(/L/))&&(t.line=n),(e.match(/position/)||e.match(/P/))&&(t.position=n),(e.match(/size/)||e.match(/S/))&&(t.size=n)}})),t}function c(e,t){for(var n,i=t,a="",o="";""!==e[i]&&i1)for(var s=0;s0&&"WEBVTT"!==d&&d.match(r)){var h=u(d),p=h.cuePoints,g=h.styles,m=c(e,f+1),y=s(p[0].replace(i,"")),E=s(p[1].replace(i,""));!isNaN(y)&&!isNaN(E)&&y>=o&&E>y?""!==m?(o=y,l.push({start:y,end:E,data:m,styles:g})):t.error("Skipping cue due to empty/malformed cue text"):t.error("Skipping cue due to incorrect cue timing")}}return l}},t=Object(f.a)(o).getInstance().getLogger(e),n=/(?:\r\n|\r|\n)/gm,r=/-->/,i=/(^[\s]+|[\s]+$)/g,a=/\s\b/g,e}Qn.__dashjs_factory_name="VTTParser";var $n=c.a.getSingletonFactory(Qn);function Zn(){var e,t,n=this.context,r=Object(u.a)(n).getInstance(),i=0;return e={parse:function(e,n,a,o,s){var u,c,f,h="",p=[],g={},m={},y="",E="",_={onOpenTag:function(e,n,i){if(i[" imagetype"]&&!i[" imageType"]&&(r.trigger(d.a.CONFORMANCE_VIOLATION,{level:he.LEVELS.ERROR,event:he.EVENTS.NON_COMPLIANT_SMPTE_IMAGE_ATTRIBUTE}),i[" imageType"]=i[" imagetype"]),"image"===n&&("http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"===e||"http://www.smpte-ra.org/schemas/2052-1/2013/smpte-tt"===e)){if(!i[" imageType"]||"PNG"!==i[" imageType"].value)return void t.warn("smpte-tt imageType != PNG. Discarded");y=i["http://www.w3.org/XML/1998/namespace id"].value}},onCloseTag:function(){y&&(m[y]=E.trim()),E="",y=""},onText:function(e){y&&(E+=e)}};if(!e)throw h="no ttml data to parse",new Error(h);g.data=e,r.trigger(l.a.TTML_TO_PARSE,g);var T=Object(Wn.fromXML)(g.data,(function(e){h=e}),_);r.trigger(l.a.TTML_PARSED,{ttmlString:g.data,ttmlDoc:T});var v,S=T.getMediaTimeEvents();for(f=0;fo?o:S[f+1]+n)&&p.push({start:u,end:c,type:"html",cueID:(v=void 0,v="cue_TTML_"+i,i++,v),isd:A,images:s,embeddedImages:m})}if(""!==h)throw t.error(h),new Error(h);return p}},t=Object(f.a)(n).getInstance().getLogger(e),e}Zn.__dashjs_factory_name="TTMLParser";var Jn=c.a.getSingletonFactory(Zn);function er(e){var t,n,r,i,o,s,c,f,h,p,g,m,y,E=this.context,_=e.adapter,T=e.errHandler,v=e.manifestModel,S=e.mediaController,A=e.videoModel,b=e.settings;function I(e){var t=e.tracks,r=e.index,i=e.streamId;!1===b.get().streaming.text.defaultEnabled&&!N()||y?C(i,-1):(f&&t.some((function(e,t){if(S.matchSettings(f,e))return C(i,t),r=t,!0})),p=!1),n[i].lastEnabledIndex=r,c.trigger(d.a.TEXT_TRACKS_ADDED,{enabled:N(),index:r,tracks:t,streamId:i}),m=!0}function R(e){if(!h&&e&&e.newMediaInfo){var t=e.newMediaInfo;t.type===a.a.TEXT&&(f={lang:t.lang,role:t.roles[0],index:t.index,codec:t.codec,accessibility:t.accessibility[0]})}}function N(){var e=!0;return p&&!g&&(e=!1),e}function C(e,t){(p=-1===t)&&S&&S.saveTextSettingsDisabled();var n=D(e);if(n!==t&&i[e]){i[e].setModeForTrackIdx(n,a.a.TEXT_HIDDEN),i[e].setCurrentTrackIdx(t),i[e].setModeForTrackIdx(t,a.a.TEXT_SHOWING);var o=i[e].getCurrentTrackInfo();o&&o.isFragmented&&!o.isEmbedded?function(e,t,n){if(!r[e])return;for(var o=r[e].getConfig().fragmentedTracks,s=0;s3&&void 0!==arguments[3]?arguments[3]:null,a=e.id;r[a]&&r[a].addMediaInfos(t,n,i)},reset:function(){w(),c.off(l.a.CURRENT_TRACK_CHANGED,R,t),c.off(l.a.TEXT_TRACKS_QUEUE_INITIALIZED,I,t),Object.keys(r).forEach((function(e){r[e].resetEmbedded(),r[e].reset()}))}},f=null,g=!1,m=!1,h=!1,y=!1,o=$n(E).getInstance(),s=Jn(E).getInstance(),c=Object(u.a)(E).getInstance(),w(),t}er.__dashjs_factory_name="TextController";var tr=c.a.getClassFactory(er),nr=n(31);function rr(){var e,t,n,r,h,g,T,v,S,A,b,I,R,N,C,D,w,M,x,U,B,k,G,j,Y,H,V,K,q,W,z,X,Q,$,Z,J,ee="You must first call initialize() and set a source before calling this method",te="You must first call initialize() and set a valid source and view before calling this method",ne="You must first call attachView() to set the video element before calling this method",re=this.context,ae=Object(u.a)(re).getInstance(),oe=Object(E.a)(re).getInstance(),se=Object(f.a)(re).getInstance({settings:oe});function ue(){be(null),Se(null),r=null,R&&(R.reset(),R=null),N&&(N.reset(),N=null),x&&x.reset(),oe.reset(),D&&(D.reset(),D=null)}function le(){return!!n&&!!Q.getElement()}function ce(){return Object(Gt.a)()}function fe(){if(!T)throw te;return V.isPaused()}function de(e){var t=j&&j.hasVideoTrack()?a.a.VIDEO:a.a.AUDIO,n=W.getCurrentDVRInfo(t);if(!n)return 0;var r=V.getLiveDelay(),i=n.range.start+e;return i>n.range.end-r&&(i=n.range.end-r),i}function he(e){if(!T)throw te;var t=Te().currentTime;if(void 0!==e)t=j.getTimeRelativeToStreamId(t,e);else if(V.getIsDynamic()){var n=j&&j.hasVideoTrack()?a.a.VIDEO:a.a.AUDIO,r=W.getCurrentDVRInfo(n);t=null===r||0===t?0:Math.max(0,t-r.range.start)}return t}function pe(){if(!T)throw te;var e=Te().duration;if(V.getIsDynamic()){var t=j&&j.hasVideoTrack()?a.a.VIDEO:a.a.AUDIO,n=W.getCurrentDVRInfo(t);e=n?n.range.end-n.range.start:0}return e}function ge(e){Object(O.b)(e,"boolean"),v=e}function me(){x.restoreDefaultUTCTimingSources()}function Ee(){return W}function Te(){if(!Q.getElement())throw ne;return Q.getElement()}function Se(e){if(!h)throw"MediaPlayer not initialized!";Q.setElement(e),e&&(we(),function(){if(N)return;var e=dashjs.MetricsReporting;if("function"==typeof e){var t=e(re).create();N=t.createMetricsReporting({debug:se,eventBus:ae,mediaElement:Te(),adapter:w,dashMetrics:W,mediaPlayerModel:M,events:l.a,constants:a.a,metricsConstants:s.a})}}(),function(){if(C)return;var e=dashjs.MssHandler;"function"==typeof e&&(y.a.extend(e.errors),C=e(re).create({eventBus:ae,mediaPlayerModel:M,dashMetrics:W,manifestModel:z,playbackController:V,streamController:j,protectionController:R,baseURLController:B,errHandler:U,events:l.a,constants:a.a,debug:se,initSegmentType:_.a.INIT_SEGMENT_TYPE,BASE64:Pn.a,ISOBoxer:Fn.a,settings:oe}))}(),j&&j.switchToVideoElement()),T&&Re(),Le()}function Ae(e){if(!g)throw ee;var t=j.getActiveStreamInfo();return t?I.getTracksFor(e,t.id):[]}function be(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:NaN;if(!h)throw"MediaPlayer not initialized!";"string"==typeof e&&$.initialize(e),n=e,(g||T)&&Re(),le()&&Le(t)}function Ie(){if(!g)throw ee;var e=j.getActiveStreamInfo();return e?j.getStreamById(e.id):null}function Re(){T=!1,g=!1,w.reset(),j.reset(),H.reset(),q.reset(),V.reset(),K.reset(),S.reset(),I.reset(),J.reset(),R&&(oe.get().streaming.protection.keepProtectionMediaKeys?R.stop():(R.reset(),R=null,we())),Y.reset(),X.reset()}function Ne(){var e=De();j||(j=ye(re).getInstance()),Y||(Y=tr(re).create({errHandler:U,manifestModel:z,adapter:w,mediaController:I,videoModel:Q,settings:oe})),G.setConfig({capabilities:k,customParametersModel:x,adapter:w,settings:oe,manifestModel:z,errHandler:U}),j.setConfig({capabilities:k,capabilitiesFilter:G,manifestLoader:e,manifestModel:z,mediaPlayerModel:M,customParametersModel:x,protectionController:R,textController:Y,adapter:w,dashMetrics:W,errHandler:U,timelineConverter:b,videoModel:Q,playbackController:V,serviceDescriptionController:K,abrController:S,mediaController:I,settings:oe,baseURLController:B,uriFragmentModel:$,segmentBaseController:J}),H.setConfig({settings:oe,playbackController:V,streamController:j,videoModel:Q,timelineConverter:b,adapter:w}),V.setConfig({streamController:j,serviceDescriptionController:K,dashMetrics:W,adapter:w,videoModel:Q,timelineConverter:b,settings:oe}),q.setConfig({streamController:j,playbackController:V,mediaPlayerModel:M,dashMetrics:W,videoModel:Q,settings:oe}),S.setConfig({streamController:j,domStorage:Z,mediaPlayerModel:M,customParametersModel:x,dashMetrics:W,adapter:w,videoModel:Q,settings:oe}),X.setConfig({abrController:S,dashMetrics:W,playbackController:V}),S.initialize(),j.initialize(v,r),Y.initialize(),H.initialize(),q.initialize(),X.initialize(),J.initialize()}function De(){return ot(re).create({debug:se,errHandler:U,dashMetrics:W,mediaPlayerModel:M,requestModifier:Object(P.a)(re).getInstance(),mssHandler:C,settings:oe})}function we(){if(R)return R;var e=dashjs.Protection;if("function"==typeof e){var t=e(re).create();return l.a.extend(e.events),d.a.extend(e.events,{publicOnly:!0}),y.a.extend(e.errors),k||(k=Object(lt.a)(re).getInstance()),R=t.createProtectionSystem({debug:se,errHandler:U,videoModel:Q,customParametersModel:x,capabilities:k,eventBus:ae,events:l.a,BASE64:Pn.a,constants:a.a,cmcdModel:X,settings:oe})}return null}function Me(){if(!h)throw"MediaPlayer not initialized!";if(D)return D;var e=dashjs.OfflineController;if("function"==typeof e){l.a.extend(e.events),d.a.extend(e.events,{publicOnly:!0}),y.a.extend(e.errors);var t=De(),n=ie(re).create();return n.setConfig({manifestModel:z,adapter:w,manifestLoader:t,errHandler:U}),D=e(re).create({debug:se,manifestUpdater:n,baseURLController:B,manifestLoader:t,manifestModel:z,mediaPlayerModel:M,abrController:S,playbackController:V,adapter:w,errHandler:U,dashMetrics:W,timelineConverter:b,segmentBaseController:J,schemeLoaderFactory:A,eventBus:ae,events:l.a,errors:y.a,constants:a.a,settings:oe,dashConstants:o.a,urlUtils:Object(L.a)(re).getInstance()})}return null}function Pe(e){var t=j&&j.hasVideoTrack()?a.a.VIDEO:a.a.AUDIO,n=W.getCurrentDVRInfo(t);return n?e+(n.manifestInfo.availableFrom.getTime()/1e3+n.range.start):0}function Le(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:NaN;D&&D.resetRecords(),!g&&n&&(g=!0,t.info("Streaming Initialized"),Ne(),"string"==typeof n?j.load(n,e):j.loadWithManifest(n,e)),!T&&le()&&(T=!0,t.info("Playback Initialized"))}return e={initialize:function(e,n,r){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:NaN;k||(k=Object(lt.a)(re).getInstance()).setConfig({settings:oe}),U||(U=ut(re).getInstance()),k.supportsMediaSource()?(h||(h=!0,b=On(re).getInstance(),S||(S=Ot(re).getInstance()).setConfig({settings:oe}),A||(A=Object(Mt.a)(re).getInstance()),V||(V=p(re).getInstance()),I||(I=Oe(re).getInstance()),j||(j=ye(re).getInstance()),H||(H=_e(re).getInstance()),q||(q=ve(re).getInstance()),K||(K=Ce(re).getInstance()),G||(G=ft(re).getInstance()),w=cn(re).getInstance(),z=mt(re).getInstance(),X=Object(xt.a)(re).getInstance(),W=Dn(re).getInstance({settings:oe}),Z=kt(re).getInstance({settings:oe}),w.setConfig({constants:a.a,cea608parser:i.a,errHandler:U,BASE64:Pn.a}),B||(B=Ve(re).create()),B.setConfig({adapter:w}),K.setConfig({adapter:w}),J||(J=Xt(re).getInstance({dashMetrics:W,mediaPlayerModel:M,errHandler:U,baseURLController:B,events:l.a,eventBus:ae,debug:se,boxParser:Object(F.a)(re).getInstance(),requestModifier:Object(P.a)(re).getInstance(),errors:y.a})),I.setConfig({domStorage:Z,settings:oe,customParametersModel:x}),M.setConfig({playbackController:V,serviceDescriptionController:K}),me(),ge(void 0===r||r),Me()),e&&Se(e),n&&be(n,o),t.info("[dash.js "+ce()+"] MediaPlayer has been initialized")):U.error(new m.a(y.a.CAPABILITY_MEDIASOURCE_ERROR_CODE,y.a.CAPABILITY_MEDIASOURCE_ERROR_MESSAGE))},setConfig:function(e){e&&(e.capabilities&&(k=e.capabilities),e.capabilitiesFilter&&(G=e.capabilitiesFilter),e.streamController&&(j=e.streamController),e.textController&&(Y=e.textController),e.gapController&&(H=e.gapController),e.playbackController&&(V=e.playbackController),e.serviceDescriptionController&&(K=e.serviceDescriptionController),e.catchupController&&(q=e.catchupController),e.mediaPlayerModel&&(M=e.mediaPlayerModel),e.customParametersModel&&(x=e.customParametersModel),e.abrController&&(S=e.abrController),e.schemeLoaderFactory&&(A=e.schemeLoaderFactory),e.mediaController&&(I=e.mediaController),e.settings&&(oe=e.settings))},on:function(e,t,n,r){ae.on(e,t,n,r)},off:function(e,t,n){ae.off(e,t,n)},extend:function(e,t,n){c.a.extend(e,t,n,re)},attachView:Se,attachSource:be,isReady:le,play:function(){if(!T)throw te;(!v||fe()&&T)&&V.play()},isPaused:fe,pause:function(){if(!T)throw te;V.pause()},isSeeking:function(){if(!T)throw te;return V.isSeeking()},isDynamic:function(){if(!T)throw te;return V.getIsDynamic()},getLowLatencyModeEnabled:function(){if(!T)throw te;return V.getLowLatencyModeEnabled()},seek:function(e){if(!T)throw te;if(Object(O.b)(e,"number"),isNaN(e))throw a.a.BAD_ARGUMENT_ERROR;var t=V.getIsDynamic()?de(e):e;V.seek(t)},setPlaybackRate:function(e){Te().playbackRate=e},getPlaybackRate:function(){return Te().playbackRate},setMute:function(e){Object(O.b)(e,"boolean"),Te().muted=e},isMuted:function(){return Te().muted},setVolume:function(e){if("number"!=typeof e||isNaN(e)||e<0||e>1)throw a.a.BAD_ARGUMENT_ERROR;Te().volume=e},getVolume:function(){return Te().volume},time:he,duration:pe,timeAsUTC:function(){if(!T)throw te;return he()<0?NaN:Pe(he())},durationAsUTC:function(){if(!T)throw te;return Pe(pe())},getActiveStream:Ie,getDVRWindowSize:function(){var e=j&&j.hasVideoTrack()?a.a.VIDEO:a.a.AUDIO,t=W.getCurrentDVRInfo(e);return t?t.manifestInfo.dvrWindowSize:0},getDVRSeekOffset:de,getTargetLiveDelay:function(){if(!T)throw te;return V.getLiveDelay()},convertToTimeCode:function(e){e=Math.max(e,0);var t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=Math.floor(e%3600%60);return(0===t?"":t<10?"0"+t.toString()+":":t.toString()+":")+(n<10?"0"+n.toString():n.toString())+":"+(r<10?"0"+r.toString():r.toString())},formatUTC:function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]&&arguments[3],i=new Date(1e3*e),a=i.toLocaleDateString(t),o=i.toLocaleTimeString(t,{hour12:n});return r?o+" "+a:o},getVersion:ce,getDebug:function(){return se},getBufferLength:function(e){var n=[a.a.VIDEO,a.a.AUDIO,a.a.TEXT];if(e){if(-1!==n.indexOf(e)){var r=Ee().getCurrentBufferLevel(e);return r||NaN}return t.warn("getBufferLength requested for invalid type"),NaN}var i=n.map((function(e){return Ae(e).length>0?Ee().getCurrentBufferLevel(e):Number.MAX_VALUE})).reduce((function(e,t){return Math.min(e,t)}));return i===Number.MAX_VALUE?NaN:i},getTTMLRenderingDiv:function(){return Q?Q.getTTMLRenderingDiv():null},getVideoElement:Te,getSource:function(){if(!n)throw"You must first call attachSource() with a valid source before calling this method";return n},updateSource:function(e){n=e,j.load(n)},getCurrentLiveLatency:function(){if(!h)throw"MediaPlayer not initialized!";return T?V.getCurrentLiveLatency():NaN},getTopBitrateInfoFor:function(e){if(!g)throw ee;return S.getTopBitrateInfoFor(e)},setAutoPlay:ge,getAutoPlay:function(){return v},getDashMetrics:Ee,getQualityFor:function(e){if(!g)throw ee;if(e===a.a.IMAGE){var t=Ie();if(!t)return-1;var n=t.getThumbnailController();return n?n.getCurrentTrackIndex():-1}return S.getQualityFor(e)},setQualityFor:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!g)throw ee;if(e===a.a.IMAGE){var r=Ie();if(!r)return;var i=r.getThumbnailController();i&&i.setTrackByIndex(t)}S.setPlaybackQuality(e,j.getActiveStreamInfo(),t,{forceReplace:n})},updatePortalSize:function(){S.setElementSize(),S.setWindowResizeEventCalled(!0)},enableText:function(e){var t=j.getActiveStreamInfo();return!(!t||!Y)&&Y.enableText(t.id,e)},enableForcedTextStreaming:function(e){return!(!j.getActiveStreamInfo()||!Y)&&Y.enableForcedTextStreaming(e)},isTextEnabled:function(){var e=j.getActiveStreamInfo();return!(!e||!Y)&&Y.isTextEnabled(e)},setTextTrack:function(e){if(!T)throw te;var t=j.getActiveStreamInfo();t&&Y&&Y.setTextTrack(t.id,e)},getBitrateInfoListFor:function(e){if(!g)throw ee;var t=Ie();return t?t.getBitrateListFor(e):[]},getStreamsFromManifest:function(e){if(!g)throw ee;return w.getStreamsInfo(e)},getTracksFor:Ae,getTracksForTypeFromManifest:function(e,t,n){if(!g)throw ee;return(n=n||w.getStreamsInfo(t,1)[0])?w.getAllMediaInfoForType(n,e,t):[]},getCurrentTrackFor:function(e){if(!g)throw ee;var t=j.getActiveStreamInfo();return I.getCurrentTrackFor(e,t.id)},setInitialMediaSettingsFor:function(e,t){if(!h)throw"MediaPlayer not initialized!";I.setInitialSettings(e,t)},getInitialMediaSettingsFor:function(e){if(!h)throw"MediaPlayer not initialized!";return I.getInitialSettings(e)},setCurrentTrack:function(e){if(!g)throw ee;I.setTrack(e)},addABRCustomRule:function(e,t,n){x.addAbrCustomRule(e,t,n)},removeABRCustomRule:function(e){x.removeAbrCustomRule(e)},removeAllABRCustomRule:function(){x.removeAllAbrCustomRule()},getABRCustomRules:function(){return x.getAbrCustomRules()},getAverageThroughput:function(e){var t=S.getThroughputHistory(),n=V.getIsDynamic();return t?t.getAverageThroughput(e,n):0},retrieveManifest:function(e,t){var n=De(),r=this;ae.on(l.a.INTERNAL_MANIFEST_LOADED,(function e(i){i.error?t(null,i.error):t(i.manifest),ae.off(l.a.INTERNAL_MANIFEST_LOADED,e,r),n.reset()}),r),$.initialize(e),n.load(e)},addUTCTimingSource:function(e,t){x.addUTCTimingSource(e,t)},removeUTCTimingSource:function(e,t){x.removeUTCTimingSource(e,t)},clearDefaultUTCTimingSources:function(){x.clearDefaultUTCTimingSources()},restoreDefaultUTCTimingSources:me,setXHRWithCredentialsForType:function(e,t){x.setXHRWithCredentialsForType(e,t)},getXHRWithCredentialsForType:function(e){return x.getXHRWithCredentialsForType(e)},getProtectionController:function(){return we()},attachProtectionController:function(e){R=e},setProtectionData:function(e){r=e,j&&j.setProtectionData(r)},registerLicenseRequestFilter:function(e){x.registerLicenseRequestFilter(e)},registerLicenseResponseFilter:function(e){x.registerLicenseResponseFilter(e)},unregisterLicenseRequestFilter:function(e){x.unregisterLicenseRequestFilter(e)},unregisterLicenseResponseFilter:function(e){x.unregisterLicenseResponseFilter(e)},registerCustomCapabilitiesFilter:function(e){x.registerCustomCapabilitiesFilter(e)},unregisterCustomCapabilitiesFilter:function(e){x.unregisterCustomCapabilitiesFilter(e)},setCustomInitialTrackSelectionFunction:function(e){x.setCustomInitialTrackSelectionFunction(e)},resetCustomInitialTrackSelectionFunction:function(){x.resetCustomInitialTrackSelectionFunction(null)},attachTTMLRenderingDiv:function(e){if(!Q.getElement())throw ne;Q.setTTMLRenderingDiv(e)},getCurrentTextTrackIndex:function(){var e=j.getActiveStreamInfo();if(e&&Y)return Y.getCurrentTrackIdx(e.id)},provideThumbnail:function(e,t){if("function"==typeof t)if(e<0)t(null);else{var n=V.getIsDynamic()?de(e):e,r=j.getStreamForTime(n);if(null!==r){var i=r.getThumbnailController();if(i)return i.provide(n,t);t(null)}else t(null)}},getDashAdapter:function(){return w},getOfflineController:function(){return Me()},getSettings:function(){return oe.get()},updateSettings:function(e){oe.update(e)},resetSettings:function(){oe.reset()},reset:ue,destroy:function(){ue(),c.a.deleteSingletonInstances(re)}},t=se.getLogger(e),h=!1,T=!1,g=!1,v=!0,R=null,D=null,r=null,w=null,J=null,l.a.extend(d.a),M=Et(re).getInstance(),x=Object(nr.a)(re).getInstance(),Q=Ft(re).getInstance(),$=pt(re).getInstance(),e}rr.__dashjs_factory_name="MediaPlayer";var ir=c.a.getClassFactory(rr);ir.events=d.a,ir.errors=y.a,c.a.updateClassFactory(rr.__dashjs_factory_name,ir);t.a=ir},function(e,t,n){"use strict";n.d(t,"a",(function(){return r}));function r(){return"4.4.1"}},function(e,t,n){var r,i,o,u,l,c={encode:function(e){for(var t=[],n=0;n>6),t.push(128|63&r)):r<65536?(t.push(224|r>>12),t.push(128|63&r>>6),t.push(128|63&r)):(t.push(240|r>>18),t.push(128|63&r>>12),t.push(128|63&r>>6),t.push(128|63&r))}return t},decode:function(e){for(var t=[],n=0;n>18)),n.push(r.charAt(63&a>>12)),n.push(r.charAt(63&a>>6)),n.push(r.charAt(63&a))}return 2==e.length-t?(a=(e[t]<<16)+(e[t+1]<<8),n.push(r.charAt(63&a>>18)),n.push(r.charAt(63&a>>12)),n.push(r.charAt(63&a>>6)),n.push("=")):1==e.length-t&&(a=e[t]<<16,n.push(r.charAt(63&a>>18)),n.push(r.charAt(63&a>>12)),n.push("==")),n.join("")},o=function(){for(var e=[],t=0;t0&&(e.segments=u);return e}(e,n[1])),(r=e).mediaFinishedInformation=E.getMediaFinishedInformation(r),function(e){if(!S())return;var t,n=d.getCurrentManifestUpdate(),r=!1;if(n){for(var i=0;i=s.length?null:s[e]}function C(e){i=!1,l.trigger(c.DATA_UPDATE_COMPLETED,{data:n,currentRepresentation:u,error:e},{streamId:m.id,mediaType:g})}function D(e){u=e}function w(e){if(e.newDuration){var t=A();if(t&&t.adaptation.period)t.adaptation.period.duration=e.newDuration}}return t={getStreamId:function(){return m.id},getType:T,getData:function(){return n},isUpdating:S,updateData:function(e,t,a,o,u){if(v(),i=!0,s=t,D(N(u)),n=e,a!==r.a.VIDEO&&a!==r.a.AUDIO&&(a!==r.a.TEXT||!o))return C(),Promise.resolve();for(var l=[],c=0,f=s.length;c=0}return!1}),(function(e){return String(e)}))}return n}(l),E=n(1);function _(e){return(_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function T(e,t){return(T=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function v(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=A(e);if(t){var i=A(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return S(this,n)}}function S(e,t){return!t||"object"!==_(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function A(e){return(A=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}var b=/^([-])?P(([\d.]*)Y)?(([\d.]*)M)?(([\d.]*)D)?T?(([\d.]*)H)?(([\d.]*)M)?(([\d.]*)S)?/,I=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&T(e,t)}(n,e);var t=v(n);function n(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),t.call(this,(function(e){for(var t=[c.a.MIN_BUFFER_TIME,c.a.MEDIA_PRESENTATION_DURATION,c.a.MINIMUM_UPDATE_PERIOD,c.a.TIMESHIFT_BUFFER_DEPTH,c.a.MAX_SEGMENT_DURATION,c.a.MAX_SUBSEGMENT_DURATION,c.a.SUGGESTED_PRESENTATION_DELAY,c.a.START,E.a.START_TIME,c.a.DURATION],n=t.length,r=0;r4)return null;var r=[];for(var i in t){var a=n.parseLength(t[i]);if(!a)return null;r.push(a)}return r}),(function(t,n,r,i,a){var o;if(1===i.length)o=[i[0],i[0],i[0],i[0]];else if(2===i.length)o=[i[0],i[1],i[0],i[1]];else if(3===i.length)o=[i[0],i[1],i[2],i[1]];else{if(4!==i.length)return null;o=[i[0],i[1],i[2],i[3]]}var s=r.styleAttrs[e.byName.writingMode.qname];if("lrtb"===s||"lr"===s)o=[o[0],o[3],o[2],o[1]];else if("rltb"===s||"rl"===s)o=[o[0],o[1],o[2],o[3]];else if("tblr"===s)o=[o[3],o[0],o[1],o[2]];else{if("tbrl"!==s&&"tb"!==s)return null;o=[o[3],o[2],o[1],o[0]]}var u=[];for(var l in o)if(0===o[l].value)u[l]=0;else if("%"===o[l].unit)u[l]="0"===l||"2"===l?r.styleAttrs[e.byName.extent.qname].h*o[l].value/100:r.styleAttrs[e.byName.extent.qname].w*o[l].value/100;else if("em"===o[l].unit)u[l]=r.styleAttrs[e.byName.fontSize.qname]*o[l].value;else if("c"===o[l].unit)u[l]=o[l].value/t.cellResolution.h;else{if("px"!==o[l].unit)return null;u[l]="0"===l||"2"===l?o[l].value/t.pxDimensions.h:o[l].value/t.pxDimensions.w}return u})),new r(t.ns_tts,"showBackground","always",["region"],!1,!0,(function(e){return e}),null),new r(t.ns_tts,"textAlign","start",["p"],!0,!0,(function(e){return e}),(function(e,t,n,r,i){return"left"===r?"start":"right"===r?"end":r})),new r(t.ns_tts,"textDecoration","none",["span"],!0,!0,(function(e){return e.split(" ")}),null),new r(t.ns_tts,"textOutline","none",["span"],!0,!0,(function(e){if("none"===e)return e;var t={},r=e.split(" ");if(0===r.length||r.length>2)return null;var i=n.parseColor(r[0]);if(t.color=i,null!==i&&r.shift(),1!==r.length)return null;var a=n.parseLength(r[0]);return a?(t.thickness=a,t):null}),(function(t,n,r,i,a){if("none"===i)return i;var o={};if(null===i.color?o.color=r.styleAttrs[e.byName.color.qname]:o.color=i.color,"%"===i.thickness.unit)o.thickness=r.styleAttrs[e.byName.fontSize.qname]*i.thickness.value/100;else if("em"===i.thickness.unit)o.thickness=r.styleAttrs[e.byName.fontSize.qname]*i.thickness.value;else if("c"===i.thickness.unit)o.thickness=i.thickness.value/t.cellResolution.h;else{if("px"!==i.thickness.unit)return null;o.thickness=i.thickness.value/t.pxDimensions.h}return o})),new r(t.ns_tts,"unicodeBidi","normal",["span","p"],!1,!0,(function(e){return e}),null),new r(t.ns_tts,"visibility","visible",["body","div","p","region","span"],!0,!0,(function(e){return e}),null),new r(t.ns_tts,"wrapOption","wrap",["span"],!0,!0,(function(e){return e}),null),new r(t.ns_tts,"writingMode","lrtb",["region"],!1,!0,(function(e){return e}),null),new r(t.ns_tts,"zIndex","auto",["region"],!1,!0,(function(e){var t;return"auto"===e?t=e:(t=parseInt(e),isNaN(t)&&(t=null)),t}),null),new r(t.ns_ebutts,"linePadding","0c",["p"],!0,!1,n.parseLength,(function(e,t,n,r,i){return"c"===r.unit?r.value/e.cellResolution.h:null})),new r(t.ns_ebutts,"multiRowAlign","auto",["p"],!0,!1,(function(e){return e}),null),new r(t.ns_smpte,"backgroundImage",null,["div"],!1,!1,(function(e){return e}),null),new r(t.ns_itts,"forcedDisplay","false",["body","div","p","region","span"],!0,!0,(function(e){return"true"===e}),null),new r(t.ns_itts,"fillLineGap","false",["p"],!0,!0,(function(e){return"true"===e}),null)],e.byQName={},e.all)e.byQName[e.all[i].qname]=e.all[i];for(var a in e.byName={},e.all)e.byName[e.all[a].name]=e.all[a]}(t,"undefined"==typeof imscNames?n(51):imscNames,"undefined"==typeof imscUtils?n(69):imscUtils)},function(e,t,n){"use strict";(function(e){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +var r=n(81),i=n(82),a=n(70);function o(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(o()=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|e}function p(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return G(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return j(e).length;default:if(r)return G(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return D(this,t,n);case"utf8":case"utf-8":return R(this,t,n);case"ascii":return N(this,t,n);case"latin1":case"binary":return C(this,t,n);case"base64":return I(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return w(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function m(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:E(e,t,n,r,i);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):E(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function E(e,t,n,r,i){var a,o=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;o=2,s/=2,u/=2,n/=2}function l(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(i){var c=-1;for(a=n;as&&(n=s-u),a=n;a>=0;a--){for(var f=!0,d=0;di&&(r=i):r=i;var a=t.length;if(a%2!=0)throw new TypeError("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o>8,i=n%256,a.push(i),a.push(r);return a}(t,e.length-n),e,n,r)}function I(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function R(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i239?4:l>223?3:l>191?2:1;if(i+f<=n)switch(f){case 1:l<128&&(c=l);break;case 2:128==(192&(a=e[i+1]))&&(u=(31&l)<<6|63&a)>127&&(c=u);break;case 3:a=e[i+1],o=e[i+2],128==(192&a)&&128==(192&o)&&(u=(15&l)<<12|(63&a)<<6|63&o)>2047&&(u<55296||u>57343)&&(c=u);break;case 4:a=e[i+1],o=e[i+2],s=e[i+3],128==(192&a)&&128==(192&o)&&128==(192&s)&&(u=(15&l)<<18|(63&a)<<12|(63&o)<<6|63&s)>65535&&u<1114112&&(c=u)}null===c?(c=65533,f=1):c>65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c),i+=f}return function(e){var t=e.length;if(t<=4096)return String.fromCharCode.apply(String,e);var n="",r=0;for(;r0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,i){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(this===e)return 0;for(var a=(i>>>=0)-(r>>>=0),o=(n>>>=0)-(t>>>=0),s=Math.min(a,o),l=this.slice(r,i),c=e.slice(t,n),f=0;fi)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return _(this,e,t,n);case"utf8":case"utf-8":return T(this,e,t,n);case"ascii":return v(this,e,t,n);case"latin1":case"binary":return S(this,e,t,n);case"base64":return A(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return b(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function N(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;ir)&&(n=r);for(var i="",a=t;an)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,i,a){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function P(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function L(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function F(e,t,n,r,i,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function x(e,t,n,r,a){return a||F(e,0,n,4),i.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,a){return a||F(e,0,n,8),i.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(i*=256);)r+=this[e+--t]*i;return r},u.prototype.readUInt8=function(e,t){return t||O(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||O(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||O(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||O(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||O(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||O(e,t,this.length);for(var r=this[e],i=1,a=0;++a=(i*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||O(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return a>=(i*=128)&&(a-=Math.pow(2,8*t)),a},u.prototype.readInt8=function(e,t){return t||O(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||O(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||O(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||O(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||O(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||O(e,4,this.length),i.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||O(e,4,this.length),i.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||O(e,8,this.length),i.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||O(e,8,this.length),i.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var i=1,a=0;for(this[t]=255&e;++a=0&&(a*=256);)this[t+i]=e/a&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):L(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):L(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);M(this,e,t,n,i-1,-i)}var a=0,o=1,s=0;for(this[t]=255&e;++a>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);M(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=0;for(this[t+a]=255&e;--a>=0&&(o*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):L(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):L(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return x(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return x(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--i)e[i+t]=this[i+n];else if(a<1e3||!u.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(a=t;a55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function j(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(B,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function Y(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}}).call(this,n(23))},function(e,t,n){"use strict";var r,i="object"==typeof Reflect?Reflect:null,a=i&&"function"==typeof i.apply?i.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};r=i&&"function"==typeof i.ownKeys?i.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var o=Number.isNaN||function(e){return e!=e};function s(){s.init.call(this)}e.exports=s,e.exports.once=function(e,t){return new Promise((function(n,r){function i(n){e.removeListener(t,a),r(n)}function a(){"function"==typeof e.removeListener&&e.removeListener("error",i),n([].slice.call(arguments))}y(e,t,a,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&y(e,"error",t,n)}(e,i,{once:!0})}))},s.EventEmitter=s,s.prototype._events=void 0,s.prototype._eventsCount=0,s.prototype._maxListeners=void 0;var u=10;function l(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function c(e){return void 0===e._maxListeners?s.defaultMaxListeners:e._maxListeners}function f(e,t,n,r){var i,a,o,s;if(l(n),void 0===(a=e._events)?(a=e._events=Object.create(null),e._eventsCount=0):(void 0!==a.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),a=e._events),o=a[t]),void 0===o)o=a[t]=n,++e._eventsCount;else if("function"==typeof o?o=a[t]=r?[n,o]:[o,n]:r?o.unshift(n):o.push(n),(i=c(e))>0&&o.length>i&&!o.warned){o.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=o.length,s=u,console&&console.warn&&console.warn(s)}return e}function d(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function h(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},i=d.bind(r);return i.listener=n,r.wrapFn=i,i}function p(e,t,n){var r=e._events;if(void 0===r)return[];var i=r[t];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(e){for(var t=new Array(e.length),n=0;n0&&(o=t[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=i[e];if(void 0===u)return!1;if("function"==typeof u)a(u,this,t);else{var l=u.length,c=m(u,l);for(n=0;n=0;a--)if(n[a]===t||n[a].listener===t){o=n[a].listener,i=a;break}if(i<0)return this;0===i?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return p(this,e,!0)},s.prototype.rawListeners=function(e){return p(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):g.call(e,t)},s.prototype.listenerCount=g,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){(t=e.exports=n(71)).Stream=t,t.Readable=t,t.Writable=n(67),t.Duplex=n(35),t.Transform=n(74),t.PassThrough=n(90)},function(e,t,n){"use strict";(function(t,r,i){var a=n(52);function o(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var i=r.callback;t.pendingcb--,i(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=E;var s,u=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:a.nextTick;E.WritableState=y;var l=n(47);l.inherits=n(40);var c={deprecate:n(89)},f=n(72),d=n(53).Buffer,h=i.Uint8Array||function(){};var p,g=n(73);function m(){}function y(e,t){s=s||n(35),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var i=e.highWaterMark,l=e.writableHighWaterMark,c=this.objectMode?16:16384;this.highWaterMark=i||0===i?i:r&&(l||0===l)?l:c,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,i){--t.pendingcb,n?(a.nextTick(i,r),a.nextTick(b,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(i(r),e._writableState.errorEmitted=!0,e.emit("error",r),b(e,t))}(e,n,r,t,i);else{var o=S(n);o||n.corked||n.bufferProcessing||!n.bufferedRequest||v(e,n),r?u(T,e,n,o,i):T(e,n,o,i)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new o(this)}function E(e){if(s=s||n(35),!(p.call(E,this)||this instanceof s))return new E(e);this._writableState=new y(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function _(e,t,n,r,i,a,o){t.writelen=r,t.writecb=o,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,a,t.onwrite),t.sync=!1}function T(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),b(e,t)}function v(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var s=0,u=!0;n;)i[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;i.allBuffers=u,_(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new o(t),t.bufferedRequestCount=0}else{for(;n;){var l=n.chunk,c=n.encoding,f=n.callback;if(_(e,t,!1,t.objectMode?1:l.length,l,c,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function A(e,t){e._final((function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),b(e,t)}))}function b(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,a.nextTick(A,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}l.inherits(E,f),y.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(y.prototype,"buffer",{get:c.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(p=Function.prototype[Symbol.hasInstance],Object.defineProperty(E,Symbol.hasInstance,{value:function(e){return!!p.call(this,e)||this===E&&(e&&e._writableState instanceof y)}})):p=function(e){return e instanceof this},E.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},E.prototype.write=function(e,t,n){var r,i=this._writableState,o=!1,s=!i.objectMode&&(r=e,d.isBuffer(r)||r instanceof h);return s&&!d.isBuffer(e)&&(e=function(e){return d.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=m),i.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),a.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var i=!0,o=!1;return null===n?o=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(o=new TypeError("Invalid non-string/buffer chunk")),o&&(e.emit("error",o),a.nextTick(r,o),i=!1),i}(this,i,e,n))&&(i.pendingcb++,o=function(e,t,n,r,i,a){if(!n){var o=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=d.from(t,n));return t}(t,r,i);r!==o&&(n=!0,i="buffer",r=o)}var s=t.objectMode?1:r.length;t.length+=s;var u=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(E.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),E.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},E.prototype._writev=null,E.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,b(e,t),n&&(t.finished?a.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(E.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),E.prototype.destroy=g.destroy,E.prototype._undestroy=g.undestroy,E.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(25),n(87).setImmediate,n(23))},function(e,t,n){"use strict";var r=n(53).Buffer,i=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function a(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=l,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=c,this.end=f,t=3;break;default:return this.write=d,void(this.end=h)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function o(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function u(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function l(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function c(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function d(e){return e.toString(this.encoding)}function h(e){return e&&e.length?this.write(e):""}t.StringDecoder=a,a.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return i>0&&(e.lastNeed=i-1),i;if(--r=0)return i>0&&(e.lastNeed=i-2),i;if(--r=0)return i>0&&(2===i?i=0:e.lastNeed=i-3),i;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},a.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){!function(e){var t=/#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})?/,n=/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/,r=/rgba\(\s*(\d+),\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/,i={transparent:[0,0,0,0],black:[0,0,0,255],silver:[192,192,192,255],gray:[128,128,128,255],white:[255,255,255,255],maroon:[128,0,0,255],red:[255,0,0,255],purple:[128,0,128,255],fuchsia:[255,0,255,255],magenta:[255,0,255,255],green:[0,128,0,255],lime:[0,255,0,255],olive:[128,128,0,255],yellow:[255,255,0,255],navy:[0,0,128,255],blue:[0,0,255,255],teal:[0,128,128,255],aqua:[0,255,255,255],cyan:[0,255,255,255]};e.parseColor=function(e){var a,o=null,s=i[e.toLowerCase()];return void 0!==s?o=s:null!==(a=t.exec(e))?o=[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16),void 0!==a[4]?parseInt(a[4],16):255]:null!==(a=n.exec(e))?o=[parseInt(a[1]),parseInt(a[2]),parseInt(a[3]),255]:null!==(a=r.exec(e))&&(o=[parseInt(a[1]),parseInt(a[2]),parseInt(a[3]),parseInt(a[4])]),o};var a=/^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%)$/;e.parseLength=function(e){var t,n=null;return null!==(t=a.exec(e))&&(n={value:parseFloat(t[1]),unit:t[2]}),n}}(t)},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t,n){"use strict";(function(t,r){var i=n(52);e.exports=_;var a,o=n(70);_.ReadableState=E;n(65).EventEmitter;var s=function(e,t){return e.listeners(t).length},u=n(72),l=n(53).Buffer,c=t.Uint8Array||function(){};var f=n(47);f.inherits=n(40);var d=n(84),h=void 0;h=d&&d.debuglog?d.debuglog("stream"):function(){};var p,g=n(85),m=n(73);f.inherits(_,u);var y=["error","close","destroy","pause","resume"];function E(e,t){e=e||{};var r=t instanceof(a=a||n(35));this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.readableObjectMode);var i=e.highWaterMark,o=e.readableHighWaterMark,s=this.objectMode?16:16384;this.highWaterMark=i||0===i?i:r&&(o||0===o)?o:s,this.highWaterMark=Math.floor(this.highWaterMark),this.buffer=new g,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(p||(p=n(68).StringDecoder),this.decoder=new p(e.encoding),this.encoding=e.encoding)}function _(e){if(a=a||n(35),!(this instanceof _))return new _(e);this._readableState=new E(e,this),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),u.call(this)}function T(e,t,n,r,i){var a,o=e._readableState;null===t?(o.reading=!1,function(e,t){if(t.ended)return;if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,A(e)}(e,o)):(i||(a=function(e,t){var n;r=t,l.isBuffer(r)||r instanceof c||"string"==typeof t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk"));var r;return n}(o,t)),a?e.emit("error",a):o.objectMode||t&&t.length>0?("string"==typeof t||o.objectMode||Object.getPrototypeOf(t)===l.prototype||(t=function(e){return l.from(e)}(t)),r?o.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):v(e,o,t,!0):o.ended?e.emit("error",new Error("stream.push() after EOF")):(o.reading=!1,o.decoder&&!n?(t=o.decoder.write(t),o.objectMode||0!==t.length?v(e,o,t,!1):I(e,o)):v(e,o,t,!1))):r||(o.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=8388608?e=8388608:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function A(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(h("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?i.nextTick(b,e):b(e))}function b(e){h("emit readable"),e.emit("readable"),D(e)}function I(e,t){t.readingMore||(t.readingMore=!0,i.nextTick(R,e,t))}function R(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ea.length?a.length:e;if(o===a.length?i+=a:i+=a.slice(0,e),0===(e-=o)){o===a.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=a.slice(o));break}++r}return t.length-=r,i}(e,t):function(e,t){var n=l.allocUnsafe(e),r=t.head,i=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var a=r.data,o=e>a.length?a.length:e;if(a.copy(n,n.length-e,0,o),0===(e-=o)){o===a.length?(++i,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=a.slice(o));break}++i}return t.length-=i,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function O(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,i.nextTick(M,t,e))}function M(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function P(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return h("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?O(this):A(this),null;if(0===(e=S(e,t))&&t.ended)return 0===t.length&&O(this),null;var r,i=t.needReadable;return h("need readable",i),(0===t.length||t.length-e0?w(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&O(this)),null!==r&&this.emit("data",r),r},_.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},_.prototype.pipe=function(e,t){var n=this,a=this._readableState;switch(a.pipesCount){case 0:a.pipes=e;break;case 1:a.pipes=[a.pipes,e];break;default:a.pipes.push(e)}a.pipesCount+=1,h("pipe count=%d opts=%j",a.pipesCount,t);var u=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?c:_;function l(t,r){h("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,h("cleanup"),e.removeListener("close",y),e.removeListener("finish",E),e.removeListener("drain",f),e.removeListener("error",m),e.removeListener("unpipe",l),n.removeListener("end",c),n.removeListener("end",_),n.removeListener("data",g),d=!0,!a.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function c(){h("onend"),e.end()}a.endEmitted?i.nextTick(u):n.once("end",u),e.on("unpipe",l);var f=function(e){return function(){var t=e._readableState;h("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,D(e))}}(n);e.on("drain",f);var d=!1;var p=!1;function g(t){h("ondata"),p=!1,!1!==e.write(t)||p||((1===a.pipesCount&&a.pipes===e||a.pipesCount>1&&-1!==P(a.pipes,e))&&!d&&(h("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,p=!0),n.pause())}function m(t){h("onerror",t),_(),e.removeListener("error",m),0===s(e,"error")&&e.emit("error",t)}function y(){e.removeListener("finish",E),_()}function E(){h("onfinish"),e.removeListener("close",y),_()}function _(){h("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?o(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",m),e.once("close",y),e.once("finish",E),e.emit("pipe",n),a.flowing||(h("pipe resume"),n.resume()),e},_.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n)),this;if(!e){var r=t.pipes,i=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var a=0;a0&&(t+=4+16*n.getUint32(t)),t+=4,e.slice(t)}},{key:"getPSSHForKeySystem",value:function(t,n){var r=e.parsePSSHList(n);return t&&r.hasOwnProperty(t.uuid.toLowerCase())?r[t.uuid.toLowerCase()]:null}},{key:"parseInitDataFromContentProtection",value:function(e,t){return"pssh"in e?(e.pssh.__text=e.pssh.__text.replace(/\r?\n|\r/g,"").replace(/\s+/g,""),t.decodeArray(e.pssh.__text).buffer):null}},{key:"parsePSSHList",value:function(e){if(null==e)return[];for(var t=new DataView(e.buffer||e),n={},r=0;;){var i,a,o=void 0,s=r;if(r>=t.buffer.byteLength)break;if(i=r+t.getUint32(r),r+=4,1886614376===t.getUint32(r))if(r+=4,0===(a=t.getUint8(r))||1===a){r++,r+=3,o="";var u=void 0,l=void 0;for(u=0;u<4;u++)o+=1===(l=t.getUint8(r+u).toString(16)).length?"0"+l:l;for(r+=4,o+="-",u=0;u<2;u++)o+=1===(l=t.getUint8(r+u).toString(16)).length?"0"+l:l;for(r+=2,o+="-",u=0;u<2;u++)o+=1===(l=t.getUint8(r+u).toString(16)).length?"0"+l:l;for(r+=2,o+="-",u=0;u<2;u++)o+=1===(l=t.getUint8(r+u).toString(16)).length?"0"+l:l;for(r+=2,o+="-",u=0;u<6;u++)o+=1===(l=t.getUint8(r+u).toString(16)).length?"0"+l:l;r+=6,r+=4,n[o=o.toLowerCase()]=t.buffer.slice(s,i),r=i}else r=i;else r=i}return n}},{key:"getLicenseServerUrlFromMediaInfo",value:function(e,t){try{if(!e||0===e.length)return null;for(var n=0,r=null;n0){var o=a.contentProtection.filter((function(e){return e.schemeIdUri&&e.schemeIdUri===t}));if(o&&o.length>0)for(var s=0;s=0?u[t.ks.systemString].priority:e.length)-(u&&u[n.ks.systemString]&&u[n.ks.systemString].priority>=0?u[n.ks.systemString].priority:e.length)})),r.push(e);for(var o=0;o0&&b.setServerCertificate(C.decodeArray(n.serverCertificate).buffer);for(var a=0;a0?t.audioRobustness:c,u=t&&t.videoRobustness&&t.videoRobustness.length>0?t.videoRobustness:c,l=e.sessionType,f=t&&t.distinctiveIdentifier?t.distinctiveIdentifier:"optional",d=t&&t.persistentState?t.persistentState:"temporary"===l?"optional":"required";return i.forEach((function(e){e.type===D.AUDIO?n.push(new o(e.codec,a)):e.type===D.VIDEO&&r.push(new o(e.codec,u))})),new s(n,r,f,d,[l])}function H(e){e.error?I.trigger(R.KEY_STATUSES_CHANGED,{data:null,error:e.error}):n.debug("DRM: key status = "+e.status)}function V(e){n.debug("DRM: onKeyMessage");var t=e.data;I.trigger(R.KEY_MESSAGE,{data:t});var r=t.messageType?t.messageType:"license-request",o=t.message,s=t.sessionToken,u=k(f),l=A.getLicenseServerModelInstance(f,u,r),c={sessionToken:s,messageType:r};if(o&&0!==o.byteLength){if(!l)return n.debug("DRM: License server request not required for this message (type = "+e.data.messageType+"). Session ID = "+s.getSessionId()),void K(c);if(A.isClearKey(f)){var d=A.processClearKeyLicenseRequest(f,u,o);if(d&&d.keyPairs&&d.keyPairs.length>0)return n.debug("DRM: ClearKey license request handled by application!"),K(c),void b.updateKeySession(s,d)}!function(e,t,r){var o=e.sessionToken,s=e.messageType?e.messageType:"license-request",u={sessionToken:o,messageType:s},l=f?f.systemString:null,c=function(e,t,n,r,o){var s=null,u=r.message;if(e&&e.serverURL){var l=e.serverURL;"string"==typeof l&&""!==l?s=l:"object"===v(l)&&l.hasOwnProperty(t)&&(s=l[t])}else if(e&&e.laURL&&""!==e.laURL)s=e.laURL;else if(!(s=a.getLicenseServerUrlFromMediaInfo(i,f.schemeIdURI))&&!A.isClearKey(f)){var c=a.getPSSHData(n.initData);(s=f.getLicenseServerURLFromInitData(c))||(s=r.laURL)}return s=o.getServerURLFromMessage(s,u,t)}(r,s,o,e,t);if(!c)return void K(u,new p.a(h.MEDIA_KEY_MESSAGE_NO_LICENSE_SERVER_URL_ERROR_CODE,h.MEDIA_KEY_MESSAGE_NO_LICENSE_SERVER_URL_ERROR_MESSAGE));var d={},N=!1;r&&W(d,r.httpRequestHeaders);var C=e.message,D=f.getRequestHeadersFromMessage(C);W(d,D),Object.keys(d).forEach((function(e){"authorization"===e.toLowerCase()&&(N=!0)})),r&&"boolean"==typeof r.withCredentials&&(N=r.withCredentials);var w=function(e){if(b)if(e.status>=200&&e.status<=299){var n=E.a.parseHttpHeaders(e.getAllResponseHeaders?e.getAllResponseHeaders():null),r=new m(e.responseURL,n,e.response);X(P.getLicenseResponseFilters(),r).then((function(){var n=t.getLicenseMessage(r.data,l,s);null!==n?(K(u),b.updateKeySession(o,n)):z(e,u,l,s,t)}))}else z(e,u,l,s,t)},L=function(e){K(u,new p.a(h.MEDIA_KEY_MESSAGE_LICENSER_ERROR_CODE,h.MEDIA_KEY_MESSAGE_LICENSER_ERROR_MESSAGE+l+' update, XHR aborted. status is "'+e.statusText+'" ('+e.status+"), readyState is "+e.readyState))},F=function(e){K(u,new p.a(h.MEDIA_KEY_MESSAGE_LICENSER_ERROR_CODE,h.MEDIA_KEY_MESSAGE_LICENSER_ERROR_MESSAGE+l+' update, XHR error. status is "'+e.statusText+'" ('+e.status+"), readyState is "+e.readyState))},x=f.getLicenseRequestFromMessage(C),U=t.getHTTPMethod(s),B=t.getResponseType(l,s),k=r&&!isNaN(r.httpTimeout)?r.httpTimeout:8e3,G=o.getSessionId()||null,j=new g(c,U,B,d,N,s,G,x),Y=isNaN(M.get().streaming.retryAttempts[y.a.LICENSE])?3:M.get().streaming.retryAttempts[y.a.LICENSE];X(P.getLicenseRequestFilters(),j).then((function(){!function e(t,r,i,a,o,s){var u=new XMLHttpRequest;if(M.get().streaming.cmcd&&M.get().streaming.cmcd.enabled){if(M.get().streaming.cmcd.mode===_.a.CMCD_MODE_QUERY){var l=O.getQueryParameter({url:t.url,type:y.a.LICENSE});l&&(t.url=E.a.addAditionalQueryParameterToUrl(t.url,[l]))}}u.open(t.method,t.url,!0),u.responseType=t.responseType,u.withCredentials=t.withCredentials,i>0&&(u.timeout=i);for(var c in t.headers)u.setRequestHeader(c,t.headers[c]);if(M.get().streaming.cmcd&&M.get().streaming.cmcd.enabled){if(M.get().streaming.cmcd.mode===_.a.CMCD_MODE_HEADER){var f=O.getHeaderParameters({url:t.url,type:y.a.LICENSE});if(f)for(var d in f){var h=f[d];h&&u.setRequestHeader(d,h)}}}var p=function(){r--;var n=isNaN(M.get().streaming.retryIntervals[y.a.LICENSE])?1e3:M.get().streaming.retryIntervals[y.a.LICENSE];S=setTimeout((function(){e(t,r,i,a,o,s)}),n)};u.onload=function(){T=null,this.status>=200&&this.status<=299||r<=0?a(this):(n.warn("License request failed ("+this.status+"). Retrying it... Pending retries: "+r),p())},u.ontimeout=u.onerror=function(){T=null,r<=0?s(this):(n.warn("License request network request failed . Retrying it... Pending retries: "+r),p())},u.onabort=function(){o(this)},I.trigger(R.LICENSE_REQUEST_SENDING,{url:t.url,headers:t.headers,payload:t.data,sessionId:t.sessionId}),T=u,u.send(t.data)}(j,Y,k,w,L,F)}))}(t,l,u)}else K(c,new p.a(h.MEDIA_KEY_MESSAGE_NO_CHALLENGE_ERROR_CODE,h.MEDIA_KEY_MESSAGE_NO_CHALLENGE_ERROR_MESSAGE))}function K(e,t){I.trigger(R.LICENSE_REQUEST_COMPLETE,{data:e,error:t})}function q(){T&&(T.onloadend=T.onerror=T.onprogress=void 0,T.abort(),T=null),S&&(clearTimeout(S),S=null)}function W(e,t){if(t)for(var n in t)e[n]=t[n]}function z(e,t,n,r,i){var a="NONE",o=null;e.response&&(a=i.getErrorResponse(e.response,n,r),o={serverResponse:e.response||null,responseCode:e.status||null,responseText:e.statusText||null}),K(t,new p.a(h.MEDIA_KEY_MESSAGE_LICENSER_ERROR_CODE,h.MEDIA_KEY_MESSAGE_LICENSER_ERROR_MESSAGE+n+' update, XHR complete. status is "'+e.statusText+'" ('+e.status+"), readyState is "+e.readyState+". Response is "+a,o))}function X(e,t){return e?e.reduce((function(e,n){return e.then((function(){return n(t)}))}),Promise.resolve()):Promise.resolve()}function Q(e,t){if(!M.get().streaming.protection.ignoreEmeEncryptedEvent){if(n.debug("DRM: onNeedKey"),"cenc"!==e.key.initDataType)return void n.warn("DRM: Only 'cenc' initData is supported! Ignoring initData of type: "+e.key.initDataType);if(0===i.length&&(n.warn("DRM: onNeedKey called before initializeForMedia, wait until initialized"),(t=void 0===t?1:t+1)<5))return void w.push(setTimeout((function(){Q(e,t)}),500));var r=e.key.initData;if(ArrayBuffer.isView(r)&&(r=r.buffer),f){var o=a.getPSSHForKeySystem(f,r);if(o&&G(o))return}n.debug("DRM: initData:",String.fromCharCode.apply(null,new Uint8Array(r)));var s=A.getSupportedKeySystemsFromSegmentPssh(r,u,l);if(0===s.length)return void n.debug("DRM: Received needkey event with initData, but we don't support any of the key systems!");F(s,!1)}}return t={initializeForMedia:function(e){if(!e)throw new Error("mediaInfo can not be null or undefined");L(),i.push(e);var t=A.getSupportedKeySystemsFromContentProtection(e.contentProtection,u,l);t&&t.length>0&&F(t,!0)},clearMediaInfoArray:function(){i=[]},createKeySession:B,loadKeySession:U,removeKeySession:function(e){L(),b.removeKeySession(e)},closeKeySession:function(e){L(),b.closeKeySession(e)},setServerCertificate:function(e){L(),b.setServerCertificate(e)},setMediaElement:j,setSessionType:function(e){l=e},setRobustnessLevel:function(e){c=e},setProtectionData:function(e){u=e,A.setProtectionData(e)},getSupportedKeySystemsFromContentProtection:function(e){return L(),A.getSupportedKeySystemsFromContentProtection(e,u,l)},getKeySystems:function(){return A?A.getKeySystems():[]},setKeySystems:function(e){A&&A.setKeySystems(e)},stop:function(){q(),b&&b.stop()},reset:function(){I.off(R.INTERNAL_KEY_MESSAGE,V,t),I.off(R.INTERNAL_KEY_STATUS_CHANGED,H,t),L(),q(),j(null),f=null,d=!1,b&&(b.reset(),b=null),w.forEach((function(e){return clearTimeout(e)})),w=[],i=[],r=[]}},n=N.getLogger(t),r=[],i=[],l="temporary",c="",T=null,S=null,I.on(R.INTERNAL_KEY_MESSAGE,V,t),I.on(R.INTERNAL_KEY_STATUS_CHANGED,H,t),t}S.__dashjs_factory_name="ProtectionController";var A=T.a.getClassFactory(S);var b=function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.keyID=t,this.key=n};function I(e,t){for(var n=0;n%CUSTOMDATA%'.replace("%CUSTOMDATA%",t),a=[],o=0;o0&&(e[0]&&("string"==typeof e[0]?t=e[0]:n=e[0]),e[1]&&("string"==typeof e[1]?t=e[1]:n=e[1])),{status:t,keyId:n}}function E(e,t){var r={session:e,keyId:t.keyId,initData:t.initData,sessionId:t.sessionId,sessionType:t.sessionType,handleEvent:function(e){switch(e.type){case"keystatuseschange":c.trigger(f.KEY_STATUSES_CHANGED,{data:this}),e.target.keyStatuses.forEach((function(){var e=y(arguments);switch(e.status){case"expired":c.trigger(f.INTERNAL_KEY_STATUS_CHANGED,{error:new p.a(h.KEY_STATUS_CHANGED_EXPIRED_ERROR_CODE,h.KEY_STATUS_CHANGED_EXPIRED_ERROR_MESSAGE)});break;default:c.trigger(f.INTERNAL_KEY_STATUS_CHANGED,e)}}));break;case"message":var t=ArrayBuffer.isView(e.message)?e.message.buffer:e.message;c.trigger(f.INTERNAL_KEY_MESSAGE,{data:new ae(this,t,void 0,e.messageType)})}},getKeyId:function(){return this.keyId},getSessionId:function(){return e.sessionId},getSessionType:function(){return this.sessionType},getExpirationTime:function(){return e.expiration},getKeyStatuses:function(){return e.keyStatuses},getUsable:function(){var t=!1;return e.keyStatuses.forEach((function(){var e=y(arguments);"usable"===e.status&&(t=!0)})),t}};return e.addEventListener("keystatuseschange",r),e.addEventListener("message",r),e.closed.then((function(){m(r),n.debug("DRM: Session closed. SessionID = "+r.getSessionId()),c.trigger(f.KEY_SESSION_CLOSED,{data:r.getSessionId()})})),o.push(r),r}return t={getAllInitData:function(){for(var e=[],t=0;t=1?t():(e=t.bind(this),r.addEventListener("loadedmetadata",e))}return t={getAllInitData:function(){for(var e=[],t=0;t0&&(t=o.ksConfiguration.videoCapabilities[0]),null===t&&o.ksConfiguration.audioCapabilities&&o.ksConfiguration.audioCapabilities.length>0&&(t=o.ksConfiguration.audioCapabilities[0]),null===t)throw new Error("Can not create sessions for unknown content types.");var r=t.contentType,s=a.createSession(r,new Uint8Array(e.initData),e.cdmData?new Uint8Array(e.cdmData):null),l=function(e,t){return{session:e,keyId:t.keyId,initData:t.initData,getKeyId:function(){return this.keyId},getSessionId:function(){return this.session.sessionId},getExpirationTime:function(){return NaN},getSessionType:function(){return"temporary"},handleEvent:function(e){switch(e.type){case y.error:d.trigger(g.KEY_ERROR,{error:new p.a(h.MEDIA_KEYERR_CODE,"KeyError",this)});break;case y.message:var t=ArrayBuffer.isView(e.message)?e.message.buffer:e.message;d.trigger(g.INTERNAL_KEY_MESSAGE,{data:new ae(this,t,e.destinationURL)});break;case y.ready:n.debug("DRM: Key added."),d.trigger(g.KEY_ADDED);break;case y.close:n.debug("DRM: Session closed. SessionID = "+this.getSessionId()),d.trigger(g.KEY_SESSION_CLOSED,{data:this.getSessionId()})}}}}(s,e);s.addEventListener(y.error,l),s.addEventListener(y.message,l),s.addEventListener(y.ready,l),s.addEventListener(y.close,l),u.push(l),n.debug("DRM: Session created. SessionID = "+l.getSessionId()),d.trigger(g.KEY_SESSION_CREATED,{data:l})},updateKeySession:function(e,t){var n=e.session;c.isClearKey(i)?n.update(new Uint8Array(t.toJWK())):n.update(new Uint8Array(t)),d.trigger(g.KEY_SESSION_UPDATED)},closeKeySession:_,setServerCertificate:function(){},loadKeySession:function(){},removeKeySession:function(){},stop:E,reset:E},n=m.getLogger(t),r=null,i=null,a=null,o=null,u=[],c=$(f).getInstance(),l={handleEvent:function(e){switch(e.type){case y.needkey:if(e.initData){var t=ArrayBuffer.isView(e.initData)?e.initData.buffer:e.initData;d.trigger(g.NEED_KEY,{key:new ie(t,"cenc")})}}}},t}ce.__dashjs_factory_name="ProtectionModel_3Feb2014";var fe=dashjs.FactoryMaker.getClassFactory(ce);function de(e){e=e||{};var t,n,r,i,a,o,u,l,c,f=this.context,d=e.eventBus,g=e.events,m=e.debug,y=e.api,E=e.errHandler;function _(){r&&S();for(var e=0;e0&&(t=o.shift(),u.push(t),t.sessionId=e.sessionId,d.trigger(g.KEY_SESSION_CREATED,{data:t})):o.length>0&&(t=o.shift(),u.push(t),0!==o.length&&E.error(new p.a(h.MEDIA_KEY_MESSAGE_ERROR_CODE,h.MEDIA_KEY_MESSAGE_ERROR_MESSAGE))),t){var s=ArrayBuffer.isView(e.message)?e.message.buffer:e.message;t.keyMessage=s,d.trigger(g.INTERNAL_KEY_MESSAGE,{data:new ae(t,s,e.defaultURL)})}else n.warn("No session token found for key message")}}},t}de.__dashjs_factory_name="ProtectionModel_01b";var he=dashjs.FactoryMaker.getClassFactory(de),pe=[{generateKeyRequest:"generateKeyRequest",addKey:"addKey",cancelKeyRequest:"cancelKeyRequest",needkey:"needkey",keyerror:"keyerror",keyadded:"keyadded",keymessage:"keymessage"},{generateKeyRequest:"webkitGenerateKeyRequest",addKey:"webkitAddKey",cancelKeyRequest:"webkitCancelKeyRequest",needkey:"webkitneedkey",keyerror:"webkitkeyerror",keyadded:"webkitkeyadded",keymessage:"webkitkeymessage"}],ge=[{setMediaKeys:"setMediaKeys",MediaKeys:"MediaKeys",release:"close",needkey:"needkey",error:"keyerror",message:"keymessage",ready:"keyadded",close:"keyclose"},{setMediaKeys:"msSetMediaKeys",MediaKeys:"MSMediaKeys",release:"close",needkey:"msneedkey",error:"mskeyerror",message:"mskeymessage",ready:"mskeyadded",close:"mskeyclose"}];function me(){var e,t=this.context;function n(e,t){for(var n=0;n=400||t.responsecode<100||t.responsecode>=600)&&l({errorcode:t.responsecode||i.CONNECTION_ERROR,url:t.url,terror:t.tresponse,servicelocation:t._serviceLocation})}var t}function p(e){var t;switch(e.error?e.error.code:0){case MediaError.MEDIA_ERR_NETWORK:t=i.CONNECTION_ERROR;break;case MediaError.MEDIA_ERR_DECODE:t=i.CORRUPT_MEDIA_OTHER;break;default:return}l({errorcode:t})}return t={initialise:function(){r.on(u.MANIFEST_UPDATED,c,t),r.on(u.SERVICE_LOCATION_BLACKLIST_CHANGED,f,t),r.on(u.METRIC_ADDED,h,t),r.on(u.METRIC_UPDATED,h,t),r.on(u.PLAYBACK_ERROR,p,t),r.on(a.a.BECAME_REPORTING_PLAYER,d,t)},reset:function(){r.off(u.MANIFEST_UPDATED,c,t),r.off(u.SERVICE_LOCATION_BLACKLIST_CHANGED,f,t),r.off(u.METRIC_ADDED,h,t),r.off(u.METRIC_UPDATED,h,t),r.off(u.PLAYBACK_ERROR,p,t),r.off(a.a.BECAME_REPORTING_PLAYER,d,t)}}}o.__dashjs_factory_name="DVBErrorsTranslator";var s=dashjs.FactoryMaker.getSingletonFactory(o),u=n(49);function l(e){e=e||{};var t,n,r=!1,i=this.context,a=e.mediaElement;return t={initialize:function(e){e&&e.length&&(e.forEach((function(e){var t=e.starttime,r=t+e.duration;n.add(t,r)})),r=!!e[0]._useWallClockTime)},reset:function(){n.clear()},isEnabled:function(){var e,t=n.length;if(!t)return!0;e=r?(new Date).getTime()/1e3:a.currentTime;for(var i=0;i=200&&i.status<300?t&&t():n&&n())};c.push(i);try{i.open("GET",e),i.onloadend=a,i.onerror=a,i.send()}catch(e){i.onerror()}}(i="".concat(s,"?").concat(i),null,(function(){o=!1}))}))},initialize:function(e,t){var n;if(u=t,!(s=e.dvb_reportingUrl))throw new Error("required parameter missing (dvb:reportingUrl)");a||((n=e.dvb_probability)&&(1e3===n||n/1e3>=i.random())&&(o=!0),a=!0)},reset:function(){h()}},n=d(l).getInstance(),i=p(l).getInstance(),r=Object(g.a)(l).getInstance(),h(),t}m.__dashjs_factory_name="DVBReporting";var y=dashjs.FactoryMaker.getClassFactory(m);function E(e){e=e||{};var t,n={"urn:dvb:dash:reporting:2014":y},r=this.context,i=e.debug?e.debug.getLogger(t):{},a=e.metricsConstants,o=e.mediaPlayerModel||{};return t={create:function(e,t){var s;try{(s=n[e.schemeIdUri](r).create({metricsConstants:a,mediaPlayerModel:o})).initialize(e,t)}catch(t){s=null,i.error("ReportingFactory: could not create Reporting with schemeIdUri ".concat(e.schemeIdUri," (").concat(t.message,")"))}return s},register:function(e,t){n[e]=t},unregister:function(e){delete n[e]}}}E.__dashjs_factory_name="ReportingFactory";var _=dashjs.FactoryMaker.getSingletonFactory(E);function T(e){var t=[],n=_(this.context).getInstance(e);return{initialize:function(e,r){e.some((function(e){var i=n.create(e,r);if(i)return t.push(i),!0}))},reset:function(){t.forEach((function(e){return e.reset()})),t=[]},report:function(e,n){t.forEach((function(t){return t.report(e,n)}))}}}T.__dashjs_factory_name="ReportingController";var v=dashjs.FactoryMaker.getClassFactory(T);function S(){return{reconstructFullMetricName:function(e,t,n){var r=e;return t&&(r+="("+t,n&&n.length&&(r+=","+n),r+=")"),r},validateN:function(e){if(!e)throw new Error("missing n");if(isNaN(e))throw new Error("n is NaN");if(e<0)throw new Error("n must be positive");return e}}}S.__dashjs_factory_name="HandlerHelpers";var A=dashjs.FactoryMaker.getSingletonFactory(S);function b(e){var t,n,r,i,a;e=e||{};var o=this.context,s=A(o).getInstance(),u=[],l=e.metricsConstants;function c(){var e=function(){try{return Object.keys(u).map((function(e){return u[e]})).reduce((function(e,t){return e.level=c.end)return null;var h="regionID"in c&&""!==c.regionID?c.regionID:l;if(null!==u&&h!==i.id&&(!("contents"in c)||"contents"in c&&0===c.contents.length||""!==h))return null;var p=new a(c);for(var g in c.sets)t=c.sets[g].end||(p.styleAttrs[c.sets[g].qname]=c.sets[g].value);var m,y={};for(var E in p.styleAttrs)if(y[E]=!0,E===n.byName.writingMode.qname&&!(n.byName.direction.qname in p.styleAttrs)){var _=p.styleAttrs[E];"lrtb"===_||"lr"===_?p.styleAttrs[n.byName.direction.qname]="ltr":"rltb"!==_&&"rl"!==_||(p.styleAttrs[n.byName.direction.qname]="rtl")}if(null!==u)for(var T in n.all){var v=n.all[T];if(v.qname===n.byName.textDecoration.qname){var S=u.styleAttrs[v.qname],A=p.styleAttrs[v.qname],b=[];void 0===A?b=S:-1===A.indexOf("none")?((-1===A.indexOf("noUnderline")&&-1!==S.indexOf("underline")||-1!==A.indexOf("underline"))&&b.push("underline"),(-1===A.indexOf("noLineThrough")&&-1!==S.indexOf("lineThrough")||-1!==A.indexOf("lineThrough"))&&b.push("lineThrough"),(-1===A.indexOf("noOverline")&&-1!==S.indexOf("overline")||-1!==A.indexOf("overline"))&&b.push("overline")):b.push("none"),p.styleAttrs[v.qname]=b}else v.inherit&&v.qname in u.styleAttrs&&!(v.qname in p.styleAttrs)&&(p.styleAttrs[v.qname]=u.styleAttrs[v.qname])}for(var I in n.all){var R=n.all[I];R.qname in p.styleAttrs||("region"===p.kind||!1===R.inherit&&null!==R.initial)&&(p.styleAttrs[R.qname]=R.parse(R.initial),y[R.qname]=!0)}for(var N in n.all){var C=n.all[N];if(C.qname in y&&null!==C.compute){var D=C.compute(e,u,p,p.styleAttrs[C.qname],d);null!==D?p.styleAttrs[C.qname]=D:o(f,"Style '"+C.qname+"' on element '"+p.kind+"' cannot be computed")}}if("none"===p.styleAttrs[n.byName.display.qname])return null;for(var w in null===u?m=null===s?[]:[s]:"contents"in c&&(m=c.contents),m){var O=r(e,t,i,s,p,h,m[w],f,d);null!==O&&p.contents.push(O.element)}for(var M in p.styleAttrs){-1===n.byQName[M].applies.indexOf(p.kind)&&delete p.styleAttrs[M]}if("span"===p.kind&&p.text&&"default"===p.space){var P=p.text.replace(/\s+/g," ");p.text=P}if("p"===p.kind){var L=[];!function e(t,n){if("contents"in t)for(var r in t.contents)e(t.contents[r],n);else n.push(t)}(p,L);for(var F=0,x="after_br",U=0;;)if("after_br"===x)F>=L.length||"br"===L[F].kind?(x="before_br",U=F,F--):("preserve"!==L[F].space&&(L[F].text=L[F].text.replace(/^\s+/g,"")),L[F].text.length>0?(x="looking_br",F++):L.splice(F,1));else if("before_br"===x)if(F<0||"br"===L[F].kind){if(x="after_br",(F=U+1)>=L.length)break}else if("preserve"!==L[F].space&&(L[F].text=L[F].text.replace(/\s+$/g,"")),L[F].text.length>0){if(x="after_br",(F=U+1)>=L.length)break}else L.splice(F,1),F--;else F>=L.length||"br"===L[F].kind?(x="before_br",U=F,F--):F++;!function e(t){if("br"===t.kind)return!1;if("text"in t)return 0===t.text.length;if("contents"in t){for(var n=t.contents.length;n--;)e(t.contents[n])&&t.contents.splice(n,1);return 0===t.contents.length}}(p)}return"div"===p.kind&&n.byName.backgroundImage.qname in p.styleAttrs||"br"===p.kind||"contents"in p&&p.contents.length>0||"span"===p.kind&&null!==p.text||"region"===p.kind&&"always"===p.styleAttrs[n.byName.showBackground.qname]?{region_id:h,element:p}:null}function i(e){this.contents=[],this.aspectRatio=e.aspectRatio}function a(e){for(var t in this.kind=e.kind||"region",e.id&&(this.id=e.id),this.styleAttrs={},e.styleAttrs)this.styleAttrs[t]=e.styleAttrs[t];"text"in e?this.text=e.text:"br"!==e.kind&&(this.contents=[]),"space"in e&&(this.space=e.space)}function o(e,t){if(e&&e.error&&e.error(t))throw t}e.generateISD=function(e,t,n){var a=new i(e),o={};for(var s in e.head.layout.regions){var u=r(e,t,e.head.layout.regions[s],e.body,null,"",e.head.layout.regions[s],n,o);null!==u&&a.contents.push(u.element)}return a}}(t,"undefined"==typeof imscNames?n(51):imscNames,"undefined"==typeof imscStyles?n(63):imscStyles)},function(e,t,n){!function(e,t,n,r,i){function a(e,t,n,r){var i=r&&"seq"===r.timeContainer,o=0;r&&(o=i&&n?n.end:r.begin),t.begin=t.explicit_begin?t.explicit_begin+o:o;var s=t.begin,u=null;for(var l in t.sets)a(e,t.sets[l],u,t),s="seq"===t.timeContainer?t.sets[l].end:Math.max(s,t.sets[l].end),u=t.sets[l];if("contents"in t)for(var c in t.contents)a(e,t.contents[c],u,t),s="seq"===t.timeContainer?t.contents[c].end:Math.max(s,t.contents[c].end),u=t.contents[c];else s=i?t.begin:Number.POSITIVE_INFINITY;null!==t.explicit_end&&null!==t.explicit_dur?t.end=Math.min(t.begin+t.explicit_dur,o+t.explicit_end):null===t.explicit_end&&null!==t.explicit_dur?t.end=t.begin+t.explicit_dur:null!==t.explicit_end&&null===t.explicit_dur?t.end=o+t.explicit_end:t.end=s,delete t.explicit_begin,delete t.explicit_dur,delete t.explicit_end,e._registerEvent(t)}function o(e){this.node=e}function s(){this.events=[],this.head=null,this.body=null}function u(){this.styling=null,this.layout=null}function l(){this.styles={}}function c(){this.id=null,this.styleAttrs=null,this.styleRefs=null}function f(){this.regions={}}function d(e){this.kind=e}function h(e){this.id=e}function p(e){this.regionID=e}function g(e){this.styleAttrs=e}function m(e){this.sets=e}function y(e){this.contents=e}function E(e,t,n){this.explicit_begin=e,this.explicit_end=t,this.explicit_dur=n}function _(){d.call(this,"body")}function T(){d.call(this,"div")}function v(){d.call(this,"p")}function S(){d.call(this,"span")}function A(){d.call(this,"span")}function b(){d.call(this,"br")}function I(){}function R(){}function N(e){return e&&"xml:id"in e.attributes&&e.attributes["xml:id"].value||null}function C(e){return e&&"style"in e.attributes?e.attributes.style.value.split(" "):[]}function D(e,t){var n={};if(null!==e)for(var i in e.attributes){var a=e.attributes[i].uri+" "+e.attributes[i].local,o=r.byQName[a];if(void 0!==o){var s=o.parse(e.attributes[i].value);null!==s?(n[a]=s,o===r.byName.zIndex&&F(t,"zIndex attribute present but not used by IMSC1 since regions do not overlap")):x(t,"Cannot parse styling attribute "+a+" --\x3e "+e.attributes[i].value)}}return n}function w(e,t,n){for(var r in e.attributes)if(e.attributes[r].uri===t&&e.attributes[r].local===n)return e.attributes[r].value;return null}function O(e,t,n){var r,i=null;return null!==(r=/^(\d+(?:\.\d+)?)f$/.exec(n))?null!==t&&(i=parseFloat(r[1])/t):null!==(r=/^(\d+(?:\.\d+)?)t$/.exec(n))?null!==e&&(i=parseFloat(r[1])/e):null!==(r=/^(\d+(?:\.\d+)?)ms$/.exec(n))?i=parseFloat(r[1])/1e3:null!==(r=/^(\d+(?:\.\d+)?)s$/.exec(n))?i=parseFloat(r[1]):null!==(r=/^(\d+(?:\.\d+)?)h$/.exec(n))?i=3600*parseFloat(r[1]):null!==(r=/^(\d+(?:\.\d+)?)m$/.exec(n))?i=60*parseFloat(r[1]):null!==(r=/^(\d{2,}):(\d\d):(\d\d(?:\.\d+)?)$/.exec(n))?i=3600*parseInt(r[1])+60*parseInt(r[2])+parseFloat(r[3]):null!==(r=/^(\d{2,}):(\d\d):(\d\d)\:(\d{2,})$/.exec(n))&&null!==t&&(i=3600*parseInt(r[1])+60*parseInt(r[2])+parseInt(r[3])+(null===r[4]?0:parseInt(r[4])/t)),i}function M(e,t,n){for(;t.styleRefs.length>0;){var r=t.styleRefs.pop();r in e.styles?(M(e,e.styles[r],n),L(e.styles[r].styleAttrs,t.styleAttrs)):x(n,"Non-existant style id referenced")}}function P(e,t,n,r){for(var i=t.length-1;i>=0;i--){var a=t[i];a in e.styles?L(e.styles[a].styleAttrs,n):x(r,"Non-existant style id referenced")}}function L(e,t){for(var n in e)n in t||(t[n]=e[n])}function F(e,t){if(e&&e.warn&&e.warn(t))throw t}function x(e,t){if(e&&e.error&&e.error(t))throw t}function U(e,t){throw e&&e.fatal&&e.fatal(t),t}function B(e,t){for(var n,r=0,i=e.length-1;r<=i;){var a=e[n=Math.floor((r+i)/2)];if(at))return{found:!0,index:n};i=n-1}}return{found:!1,index:r}}e.fromXML=function(e,r,i){var d=t.parser(!0,{xmlns:!0}),h=[],p=[],g=[],m=0,y=null;d.onclosetag=function(e){if(h[0]instanceof l)for(var t in h[0].styles)M(h[0],h[0].styles[t],r);else if(h[0]instanceof v||h[0]instanceof S){if(h[0].contents.length>1){var a,s=[h[0].contents[0]];for(a=1;a0&&i&&"onCloseTag"in i&&i.onCloseTag());g.shift(),p.shift(),h.shift()},d.ontext=function(e){if(void 0===h[0]);else if(h[0]instanceof S||h[0]instanceof v){var t=new A;t.initFromText(y,h[0],e,g[0],r),h[0].contents.push(t)}else h[0]instanceof o&&m>0&&i&&"onText"in i&&i.onText(e)},d.onopentag=function(e){var t=e.attributes["xml:space"];t?g.unshift(t.value):0===g.length?g.unshift("default"):g.unshift(g[0]);var a=e.attributes["xml:lang"];if(a?p.unshift(a.value):0===p.length?p.unshift(""):p.unshift(p[0]),e.uri===n.ns_tt)if("tt"===e.local)null!==y&&U(r,"Two elements at ("+this.line+","+this.column+")"),(y=new s).initFromNode(e,r),h.unshift(y);else if("head"===e.local)h[0]instanceof s||U(r,"Parent of element is not at ("+this.line+","+this.column+")"),null!==y.head&&U("Second element at ("+this.line+","+this.column+")"),y.head=new u,h.unshift(y.head);else if("styling"===e.local)h[0]instanceof u||U(r,"Parent of element is not at ("+this.line+","+this.column+")"),null!==y.head.styling&&U("Second element at ("+this.line+","+this.column+")"),y.head.styling=new l,h.unshift(y.head.styling);else if("style"===e.local){var d;h[0]instanceof l?((d=new c).initFromNode(e,r),d.id?y.head.styling.styles[d.id]=d:x(r," + + +
    + + + + +