From 467360dc9c8cb388c9a77e2314932c82e6cf7f61 Mon Sep 17 00:00:00 2001 From: FireMasterK <20838718+FireMasterK@users.noreply.github.com> Date: Thu, 14 Jan 2021 14:48:02 +0530 Subject: [PATCH 01/32] Use ThinLTO --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index ce4cc7658..4ccab2dc1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -10,7 +10,7 @@ COPY ./src/ ./src/ # See definition of CURRENT_BRANCH, CURRENT_COMMIT and CURRENT_VERSION. COPY ./.git/ ./.git/ RUN crystal build ./src/invidious.cr \ - --static --warnings all \ + --static --lto=thin --warnings all \ --link-flags "-lxml2 -llzma" FROM alpine:latest From 2472fd57946485e70de1c0cf83409ac1fefbb4ec Mon Sep 17 00:00:00 2001 From: Perflyst Date: Sat, 16 Jan 2021 22:18:22 +0100 Subject: [PATCH 02/32] Add container CI release --- .github/workflows/release.yml | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..77877080d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,37 @@ +name: Build and release container + +on: + push: + branches: + - "master" + +jobs: + release: + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to registry + uses: docker/login-action@v1 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_PASSWORD }} + + - name: Build and push + uses: docker/build-push-action@v2 + with: + push: true + tags: quay.io/invidious/invidious:latest + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} From 50a65c6f76afed688550b6a6ade66c19dbe09767 Mon Sep 17 00:00:00 2001 From: Andre Borie Date: Sun, 17 Jan 2021 01:43:36 +0000 Subject: [PATCH 03/32] Fix DASH playback bug. --- assets/js/player.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assets/js/player.js b/assets/js/player.js index 5d0453916..043266318 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -19,6 +19,11 @@ var options = { 'playbackRateMenuButton', 'fullscreenToggle' ] + }, + html5: { + hls: { + overrideNative: true + } } } From 8b4d490a7b424218cbd24b56511c09a1fcd95bc4 Mon Sep 17 00:00:00 2001 From: Andrew Zhao Date: Sat, 2 Jan 2021 19:35:31 -0500 Subject: [PATCH 04/32] add ui for searching --- assets/css/default.css | 3 + assets/js/search.js | 13 +++++ locales/en-US.json | 27 +++++++++ src/invidious/routes/playlists.cr | 2 +- src/invidious/routes/search.cr | 8 ++- src/invidious/search.cr | 2 +- src/invidious/views/search.ecr | 97 +++++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 assets/js/search.js diff --git a/assets/css/default.css b/assets/css/default.css index e403e6061..793295d9d 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -628,3 +628,6 @@ body.dark-theme { } } +#filters { + display: none; +} \ No newline at end of file diff --git a/assets/js/search.js b/assets/js/search.js new file mode 100644 index 000000000..36edd053b --- /dev/null +++ b/assets/js/search.js @@ -0,0 +1,13 @@ +function toggle_comments(event) { + var target = event.target; + var body = document.getElementById('filters'); + if (body.style.display === 'flex') { + target.innerHTML = '[ + ]'; + body.style.display = 'none'; + } else { + target.innerHTML = '[ - ]'; + body.style.display = 'flex'; + } +} + +document.getElementById('togglefilters').onclick = toggle_comments; \ No newline at end of file diff --git a/locales/en-US.json b/locales/en-US.json index acd2b6670..66e71bb62 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -383,5 +383,32 @@ "Videos": "Videos", "Playlists": "Playlists", "Community": "Community", + "relevance": "Relevance", + "rating": "Rating", + "date": "Upload date", + "views": "View count", + "content_type": "Type", + "duration": "Duration", + "features": "Features", + "sort": "Sort By", + "hour": "Last Hour", + "today": "Today", + "week": "This week", + "month": "This month", + "year": "This year", + "video": "Video", + "channel": "Channel", + "playlist": "Playlist", + "movie": "Movie", + "show": "Show", + "hd": "HD", + "subtitles": "Subtitles/CC", + "creative_commons": "Creative Commons", + "3d": "3D", + "live": "Live", + "4k": "4K", + "location": "Location", + "hdr": "HDR", + "filter": "Filter", "Current version: ": "Current version: " } \ No newline at end of file diff --git a/src/invidious/routes/playlists.cr b/src/invidious/routes/playlists.cr index 6c899054e..c5023c086 100644 --- a/src/invidious/routes/playlists.cr +++ b/src/invidious/routes/playlists.cr @@ -267,7 +267,7 @@ class Invidious::Routes::Playlists < Invidious::Routes::BaseRoute query = env.params.query["q"]? if query begin - search_query, count, items = process_search_query(query, page, user, region: nil) + search_query, count, items, operators = process_search_query(query, page, user, region: nil) videos = items.select { |item| item.is_a? SearchVideo }.map { |item| item.as(SearchVideo) } rescue ex videos = [] of SearchVideo diff --git a/src/invidious/routes/search.cr b/src/invidious/routes/search.cr index 48446161e..a993a17a0 100644 --- a/src/invidious/routes/search.cr +++ b/src/invidious/routes/search.cr @@ -48,11 +48,17 @@ class Invidious::Routes::Search < Invidious::Routes::BaseRoute user = env.get? "user" begin - search_query, count, videos = process_search_query(query, page, user, region: nil) + search_query, count, videos, operators = process_search_query(query, page, user, region: nil) rescue ex return error_template(500, ex) end + operator_hash = {} of String => String + operators.each do |operator| + key, value = operator.downcase.split(":") + operator_hash[key] = value + end + env.set "search", query templated "search" end diff --git a/src/invidious/search.cr b/src/invidious/search.cr index 85fd024a4..1c4bc74e8 100644 --- a/src/invidious/search.cr +++ b/src/invidious/search.cr @@ -445,5 +445,5 @@ def process_search_query(query, page, user, region) count, items = search(search_query, page, search_params, region).as(Tuple) end - {search_query, count, items} + {search_query, count, items, operators} end diff --git a/src/invidious/views/search.ecr b/src/invidious/views/search.ecr index bc13b7ea1..3fa9242bb 100644 --- a/src/invidious/views/search.ecr +++ b/src/invidious/views/search.ecr @@ -2,6 +2,102 @@ <%= search_query.not_nil!.size > 30 ? HTML.escape(query.not_nil![0,30].rstrip(".") + "...") : HTML.escape(query.not_nil!) %> - Invidious <% end %> +

+ [ + ] + <%= translate(locale, "filter") %> +

+ + +
+
+ <%= translate(locale, "date") %> +
+ <% ["hour", "today", "week", "month", "year"].each do |date| %> +
+ <% if operator_hash.fetch("date", "all") == date %> + <%= translate(locale, date) %> + <% else %> + &page=<%= page %>"> + <%= translate(locale, date) %> + + <% end %> +
+ <% end %> +
+
+ <%= translate(locale, "content_type") %> +
+ <% ["video", "channel", "playlist", "movie", "show"].each do |content_type| %> +
+ <% if operator_hash.fetch("content_type", "all") == content_type %> + <%= translate(locale, content_type) %> + <% else %> + &page=<%= page %>"> + <%= translate(locale, content_type) %> + + <% end %> +
+ <% end %> +
+
+ <%= translate(locale, "duration") %> +
+ <% ["short", "long"].each do |duration| %> +
+ <% if operator_hash.fetch("duration", "all") == duration %> + <%= translate(locale, duration) %> + <% else %> + &page=<%= page %>"> + <%= translate(locale, duration) %> + + <% end %> +
+ <% end %> +
+
+ <%= translate(locale, "features") %> +
+ <% ["hd", "subtitles", "creative_commons", "3d", "live", "purchased", "4k", "360", "location", "hdr"].each do |feature| %> +
+ <% if operator_hash.fetch("features", "all").includes?(feature) %> + <%= translate(locale, feature) %> + <% elsif operator_hash.has_key?("features") %> + &page=<%= page %>"> + <%= translate(locale, feature) %> + + <% else %> + &page=<%= page %>"> + <%= translate(locale, feature) %> + + <% end %> +
+ <% end %> +
+
+ <%= translate(locale, "sort") %> +
+ <% ["relevance", "rating", "date", "views"].each do |sort| %> +
+ <% if operator_hash.fetch("sort", "relevance") == sort %> + <%= translate(locale, sort) %> + <% else %> + &page=<%= page %>"> + <%= translate(locale, sort) %> + + <% end %> +
+ <% end %> +
+
+ +
+
<% if page > 1 %> @@ -45,3 +141,4 @@ <% end %>
+ \ No newline at end of file From b1d45fd2c4cbe9366088808147422a3e034d62e9 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Wed, 20 Jan 2021 12:44:01 +0100 Subject: [PATCH 05/32] Rename release.yml to container-release.yml --- .github/workflows/{release.yml => container-release.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{release.yml => container-release.yml} (100%) diff --git a/.github/workflows/release.yml b/.github/workflows/container-release.yml similarity index 100% rename from .github/workflows/release.yml rename to .github/workflows/container-release.yml From ca82a691fb6ab018aa411e084f7fb7393d7117ee Mon Sep 17 00:00:00 2001 From: Perflyst Date: Thu, 21 Jan 2021 07:45:43 +0100 Subject: [PATCH 06/32] Fix container build --- .github/workflows/container-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/container-release.yml b/.github/workflows/container-release.yml index 77877080d..b21123d23 100644 --- a/.github/workflows/container-release.yml +++ b/.github/workflows/container-release.yml @@ -30,6 +30,8 @@ jobs: - name: Build and push uses: docker/build-push-action@v2 with: + context: . + file: docker/Dockerfile push: true tags: quay.io/invidious/invidious:latest From 0e58c7f46a0ed8ef22a4b4ea8ab743bc014f6717 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Thu, 21 Jan 2021 23:51:54 +0100 Subject: [PATCH 07/32] Build latest only on master, add commit sha tag Close #1688 --- .github/workflows/container-release.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/container-release.yml b/.github/workflows/container-release.yml index b21123d23..3d61928f3 100644 --- a/.github/workflows/container-release.yml +++ b/.github/workflows/container-release.yml @@ -4,6 +4,8 @@ on: push: branches: - "master" + pull_request: + branches: "*" jobs: release: @@ -27,7 +29,8 @@ jobs: username: ${{ secrets.QUAY_USERNAME }} password: ${{ secrets.QUAY_PASSWORD }} - - name: Build and push + - name: Build and push latest tag + if: github.ref == 'refs/heads/master' uses: docker/build-push-action@v2 with: context: . @@ -35,5 +38,13 @@ jobs: push: true tags: quay.io/invidious/invidious:latest + - name: Build and push commit sha tag + uses: docker/build-push-action@v2 + with: + context: . + file: docker/Dockerfile + push: true + tags: quay.io/invidious/invidious:${{ github.sha }} + - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} From cb2f328392a36891a3890575b7b24aa16e5db3c4 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Thu, 21 Jan 2021 23:54:31 +0100 Subject: [PATCH 08/32] Remove image digest output Does not work with two images at the same time --- .github/workflows/container-release.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/container-release.yml b/.github/workflows/container-release.yml index 3d61928f3..c8b2e56a7 100644 --- a/.github/workflows/container-release.yml +++ b/.github/workflows/container-release.yml @@ -45,6 +45,3 @@ jobs: file: docker/Dockerfile push: true tags: quay.io/invidious/invidious:${{ github.sha }} - - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} From 5eaad2af4893577808b2391664de0406326a3d78 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Fri, 22 Jan 2021 00:03:09 +0100 Subject: [PATCH 09/32] Expire sha images after 6 weeks --- .github/workflows/container-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/container-release.yml b/.github/workflows/container-release.yml index c8b2e56a7..b1a04f269 100644 --- a/.github/workflows/container-release.yml +++ b/.github/workflows/container-release.yml @@ -43,5 +43,6 @@ jobs: with: context: . file: docker/Dockerfile + labels: quay.expires-after=6w push: true tags: quay.io/invidious/invidious:${{ github.sha }} From ca5a110363ce45df5c581dc8e7d8c30709a414b8 Mon Sep 17 00:00:00 2001 From: FireMasterK <20838718+FireMasterK@users.noreply.github.com> Date: Fri, 22 Jan 2021 09:20:17 +0530 Subject: [PATCH 10/32] different steps depending on event. --- .github/workflows/container-release.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/container-release.yml b/.github/workflows/container-release.yml index b1a04f269..1859f082a 100644 --- a/.github/workflows/container-release.yml +++ b/.github/workflows/container-release.yml @@ -9,7 +9,6 @@ on: jobs: release: - runs-on: ubuntu-latest steps: @@ -29,16 +28,18 @@ jobs: username: ${{ secrets.QUAY_USERNAME }} password: ${{ secrets.QUAY_PASSWORD }} - - name: Build and push latest tag + - name: Build and push for Push Event if: github.ref == 'refs/heads/master' uses: docker/build-push-action@v2 with: context: . file: docker/Dockerfile + labels: quay.expires-after=12w push: true - tags: quay.io/invidious/invidious:latest + tags: quay.io/invidious/invidious:${{ github.sha }},quay.io/invidious/invidious:latest - - name: Build and push commit sha tag + - name: Build and push for Pull Request + if: github.ref != 'refs/heads/master' uses: docker/build-push-action@v2 with: context: . From fd6ed734279a0d01f13e274f6d2dcaa144398a8c Mon Sep 17 00:00:00 2001 From: FireMasterK <20838718+FireMasterK@users.noreply.github.com> Date: Fri, 22 Jan 2021 16:54:49 +0530 Subject: [PATCH 11/32] build image daily at 0:00 GMT --- .github/workflows/container-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/container-release.yml b/.github/workflows/container-release.yml index 1859f082a..137308d09 100644 --- a/.github/workflows/container-release.yml +++ b/.github/workflows/container-release.yml @@ -6,6 +6,8 @@ on: - "master" pull_request: branches: "*" + schedule: + - cron: 0 0 * * * jobs: release: From 0e5cd14df012512ac3aaa61cd7f339887189303c Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty Date: Sat, 23 Jan 2021 18:07:55 +0100 Subject: [PATCH 12/32] Make invidious use all the translation files --- src/invidious.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious.cr b/src/invidious.cr index deb24ac33..10c23dac3 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -84,9 +84,9 @@ LOCALES = { "en-US" => load_locale("en-US"), "eo" => load_locale("eo"), "es" => load_locale("es"), - "eu" => load_locale("eu"), + "fa" => load_locale("fa"), "fr" => load_locale("fr"), - "hu" => load_locale("hu-HU"), + "hr" => load_locale("hr"), "is" => load_locale("is"), "it" => load_locale("it"), "ja" => load_locale("ja"), From 6e8f7959f278e621a89291acd4e0b4d54d279e5a Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 23 Jan 2021 18:10:51 +0100 Subject: [PATCH 13/32] Translations update from Weblate (#1696) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update German translation * Add Bengali (Bangladesh) translation * Update Bengali (Bangladesh) translation * Update Portuguese (Portugal) translation * Update Icelandic translation * Update Bengali (Bangladesh) translation * Update Bengali (Bangladesh) translation * Add Catalan translation * Update Norwegian Bokmål translation * Add French (Canada) translation * Update German translation * Update Polish translation * Update Dutch translation * Update French translation * Update Italian translation * Update Greek translation * Update French (Canada) translation * Update Turkish translation * Update Norwegian Bokmål translation * Update Esperanto translation * Update Esperanto translation * Add Slovak translation * Update Slovak translation * Update Serbian (cyrillic) translation * Update Slovak translation * Update Esperanto translation * Add Persian translation * Update Persian translation * Add Kannada translation * Update Kannada translation * Update Bengali (Bangladesh) translation * Update Spanish translation * Update Portuguese (Brazil) translation * Update Chinese (Traditional) translation * Update Swedish translation * Update Portuguese (Portugal) translation * Add Finnish translation * Update Dutch translation * Update Finnish translation * Add Indonesian translation * Add Portuguese translation * Update Portuguese (Portugal) translation * Update Indonesian translation * Update Portuguese translation * Update Polish translation * Update Polish translation * Update Portuguese (Brazil) translation * Update Chinese (Simplified) translation * Add Croatian translation * Update Croatian translation * Update Norwegian Bokmål translation * Update Swedish translation * Update Croatian translation * Update Japanese translation * Update Indonesian translation * Add Danish translation * Update Bengali (Bangladesh) translation * Update Danish translation * Update Chinese (Simplified) translation * Update French (Canada) translation * Add Malayalam translation * Update Swedish translation * Update Greek translation * Update Greek translation * Update Portuguese (Brazil) translation * Delete Catalan translation * Delete Malayalam translation * Delete Kannada translation * Delete French (Canada) translation * Delete Portuguese translation Co-authored-by: Jeannette L Co-authored-by: Oymate Co-authored-by: Paulo Marinho Co-authored-by: recette-lemon <854qskawygnrtcdo@protonmail.com> Co-authored-by: Adolfo Jayme Barrientos Co-authored-by: Allan Nordhøy Co-authored-by: Oğuz Ersen Co-authored-by: Attila Farkas Co-authored-by: bongo bongo Co-authored-by: nathgit Co-authored-by: Kevin Scruff Co-authored-by: Yogesh Co-authored-by: The Cats Co-authored-by: FeiYang Co-authored-by: Luna Jernberg Co-authored-by: ssantos Co-authored-by: Unihuppio Co-authored-by: Joachim Opdenakker Co-authored-by: ziasukmana Co-authored-by: Atrate Co-authored-by: Karol Kosek Co-authored-by: André Marcelo Alvarenga Co-authored-by: Eric Co-authored-by: Milo Ivir Co-authored-by: Petter Reinholdtsen Co-authored-by: Y. Sakamoto Co-authored-by: Nimityx Co-authored-by: HackerNCoder Co-authored-by: vachan-maker Co-authored-by: fresh Co-authored-by: TheFrenchGhosty --- locales/bn_BD.json | 353 +++++++++++++++++++++++++++++++++++++++ locales/da.json | 387 +++++++++++++++++++++++++++++++++++++++++++ locales/de.json | 24 +-- locales/el.json | 148 +++++++---------- locales/eo.json | 14 +- locales/es.json | 6 +- locales/fa.json | 353 +++++++++++++++++++++++++++++++++++++++ locales/fi.json | 353 +++++++++++++++++++++++++++++++++++++++ locales/fr.json | 44 ++--- locales/hr.json | 387 +++++++++++++++++++++++++++++++++++++++++++ locales/id.json | 387 +++++++++++++++++++++++++++++++++++++++++++ locales/is.json | 66 ++++---- locales/it.json | 102 ++++-------- locales/ja.json | 6 +- locales/nb-NO.json | 144 ++++++++-------- locales/nl.json | 20 +-- locales/pl.json | 6 +- locales/pt-BR.json | 136 +++++++-------- locales/pt-PT.json | 124 +++++--------- locales/sk.json | 353 +++++++++++++++++++++++++++++++++++++++ locales/sr_Cyrl.json | 206 +++++++++++------------ locales/sv-SE.json | 216 ++++++++++++------------ locales/tr.json | 4 +- locales/zh-CN.json | 92 +++++----- locales/zh-TW.json | 92 ++++------ 25 files changed, 3236 insertions(+), 787 deletions(-) create mode 100644 locales/bn_BD.json create mode 100644 locales/da.json create mode 100644 locales/fa.json create mode 100644 locales/fi.json create mode 100644 locales/hr.json create mode 100644 locales/id.json create mode 100644 locales/sk.json diff --git a/locales/bn_BD.json b/locales/bn_BD.json new file mode 100644 index 000000000..8356424f7 --- /dev/null +++ b/locales/bn_BD.json @@ -0,0 +1,353 @@ +{ + "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` সাবস্ক্রাইবার।([^.,0-9]|^)1([^.,0-9]|$)", + "`x` subscribers.": "`x` সাবস্ক্রাইবার।", + "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` ভিডিও।([^.,0-9]|^)1([^.,0-9]|$)", + "`x` videos.": "`x` ভিডিও।", + "`x` playlists.([^.,0-9]|^)1([^.,0-9]|$)": "`x` প্লেলিস্ট।[^.,0-9]|^)1([^.,0-9]|$)", + "`x` playlists.": "`x` প্লেলিস্ট।", + "LIVE": "লাইভ", + "Shared `x` ago": "`x` আগে শেয়ার করা হয়েছে", + "Unsubscribe": "আনসাবস্ক্রাইব", + "Subscribe": "সাবস্ক্রাইব", + "View channel on YouTube": "ইউটিউবে চ্যানেল দেখুন", + "View playlist on YouTube": "ইউটিউবে প্লেলিস্ট দেখুন", + "newest": "সর্ব-নতুন", + "oldest": "পুরানতম", + "popular": "জনপ্রিয়", + "last": "শেষটা", + "Next page": "পরের পৃষ্ঠা", + "Previous page": "আগের পৃষ্ঠা", + "Clear watch history?": "দেখার ইতিহাস সাফ করবেন?", + "New password": "নতুন পাসওয়ার্ড", + "New passwords must match": "নতুন পাসওয়ার্ড অবশ্যই মিলতে হবে", + "Cannot change password for Google accounts": "গুগল অ্যাকাউন্টগুলোর জন্য পাসওয়ার্ড পরিবর্তন করা যায় না", + "Authorize token?": "টোকেন অনুমোদন করবেন?", + "Authorize token for `x`?": "`x` -এর জন্য টোকেন অনুমোদন?", + "Yes": "হ্যাঁ", + "No": "না", + "Import and Export Data": "তথ্য আমদানি ও রপ্তানি", + "Import": "আমদানি", + "Import Invidious data": "ইনভিডিয়াস তথ্য আমদানি", + "Import YouTube subscriptions": "ইউটিউব সাবস্ক্রিপশন আনুন", + "Import FreeTube subscriptions (.db)": "ফ্রিটিউব সাবস্ক্রিপশন (.db) আনুন", + "Import NewPipe subscriptions (.json)": "নতুন পাইপ সাবস্ক্রিপশন আনুন (.json)", + "Import NewPipe data (.zip)": "নিউপাইপ তথ্য আনুন (.zip)", + "Export": "তথ্য বের করুন", + "Export subscriptions as OPML": "সাবস্ক্রিপশন OPML হিসাবে আনুন", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "OPML-এ সাবস্ক্রিপশন বের করুন(নিউ পাইপ এবং ফ্রিউটিউব এর জন্য)", + "Export data as JSON": "JSON হিসাবে তথ্য বের করুন", + "Delete account?": "অ্যাকাউন্ট মুছে ফেলবেন?", + "History": "ইতিহাস", + "An alternative front-end to YouTube": "ইউটিউবের একটি বিকল্পস্বরূপ সম্মুখ-প্রান্ত", + "JavaScript license information": "জাভাস্ক্রিপ্ট লাইসেন্সের তথ্য", + "source": "সূত্র", + "Log in": "লগ ইন", + "Log in/register": "লগ ইন/রেজিস্টার", + "Log in with Google": "গুগল দিয়ে লগ ইন করুন", + "User ID": "ইউজার আইডি", + "Password": "পাসওয়ার্ড", + "Time (h:mm:ss):": "সময় (ঘণ্টা:মিনিট:সেকেন্ড):", + "Text CAPTCHA": "টেক্সট ক্যাপচা", + "Image CAPTCHA": "চিত্র ক্যাপচা", + "Sign In": "সাইন ইন", + "Register": "নিবন্ধন", + "E-mail": "ই-মেইল", + "Google verification code": "গুগল যাচাইকরণ কোড", + "Preferences": "পছন্দসমূহ", + "Player preferences": "প্লেয়ারের পছন্দসমূহ", + "Always loop: ": "সর্বদা লুপ: ", + "Autoplay: ": "স্বয়ংক্রিয় চালু: ", + "Play next by default: ": "ডিফল্টভাবে পরবর্তী চালাও: ", + "Autoplay next video: ": "পরবর্তী ভিডিও স্বয়ংক্রিয়ভাবে চালাও: ", + "Listen by default: ": "", + "Proxy videos: ": "", + "Default speed: ": "", + "Preferred video quality: ": "", + "Player volume: ": "", + "Default comments: ": "", + "youtube": "", + "reddit": "", + "Default captions: ": "", + "Fallback captions: ": "", + "Show related videos: ": "", + "Show annotations by default: ": "", + "Visual preferences": "", + "Player style: ": "", + "Dark mode: ": "", + "Theme: ": "", + "dark": "", + "light": "", + "Thin mode: ": "", + "Subscription preferences": "", + "Show annotations by default for subscribed channels: ": "", + "Redirect homepage to feed: ": "", + "Number of videos shown in feed: ": "", + "Sort videos by: ": "", + "published": "", + "published - reverse": "", + "alphabetically": "", + "alphabetically - reverse": "", + "channel name": "", + "channel name - reverse": "", + "Only show latest video from channel: ": "", + "Only show latest unwatched video from channel: ": "", + "Only show unwatched: ": "", + "Only show notifications (if there are any): ": "", + "Enable web notifications": "", + "`x` uploaded a video": "", + "`x` is live": "", + "Data preferences": "", + "Clear watch history": "", + "Import/export data": "", + "Change password": "", + "Manage subscriptions": "", + "Manage tokens": "", + "Watch history": "", + "Delete account": "", + "Administrator preferences": "", + "Default homepage: ": "", + "Feed menu: ": "", + "Top enabled: ": "", + "CAPTCHA enabled: ": "", + "Login enabled: ": "", + "Registration enabled: ": "", + "Report statistics: ": "", + "Save preferences": "", + "Subscription manager": "", + "Token manager": "", + "Token": "", + "`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` subscriptions.": "", + "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` tokens.": "", + "Import/export": "", + "unsubscribe": "", + "revoke": "", + "Subscriptions": "", + "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` unseen notifications.": "", + "search": "", + "Log out": "", + "Released under the AGPLv3 by Omar Roth.": "", + "Source available here.": "", + "View JavaScript license information.": "", + "View privacy policy.": "", + "Trending": "", + "Public": "", + "Unlisted": "", + "Private": "", + "View all playlists": "", + "Updated `x` ago": "", + "Delete playlist `x`?": "", + "Delete playlist": "", + "Create playlist": "", + "Title": "", + "Playlist privacy": "", + "Editing playlist `x`": "", + "Watch on YouTube": "", + "Hide annotations": "", + "Show annotations": "", + "Genre: ": "", + "License: ": "", + "Family friendly? ": "", + "Wilson score: ": "", + "Engagement: ": "", + "Whitelisted regions: ": "", + "Blacklisted regions: ": "", + "Shared `x`": "", + "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` views.": "", + "Premieres in `x`": "", + "Premieres `x`": "", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "", + "View YouTube comments": "", + "View more comments on Reddit": "", + "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "", + "View `x` comments.": "", + "View Reddit comments": "", + "Hide replies": "", + "Show replies": "", + "Incorrect password": "", + "Quota exceeded, try again in a few hours": "", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", + "Invalid TFA code": "", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "", + "Wrong answer": "", + "Erroneous CAPTCHA": "", + "CAPTCHA is a required field": "", + "User ID is a required field": "", + "Password is a required field": "", + "Wrong username or password": "", + "Please sign in using 'Log in with Google'": "", + "Password cannot be empty": "", + "Password cannot be longer than 55 characters": "", + "Please log in": "", + "Invidious Private Feed for `x`": "", + "channel:`x`": "", + "Deleted or invalid channel": "", + "This channel does not exist.": "", + "Could not get channel info.": "", + "Could not fetch comments": "", + "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "", + "View `x` replies.": "", + "`x` ago": "", + "Load more": "", + "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` points.": "", + "Could not create mix.": "", + "Empty playlist": "", + "Not a playlist.": "", + "Playlist does not exist.": "", + "Could not pull trending pages.": "", + "Hidden field \"challenge\" is a required field": "", + "Hidden field \"token\" is a required field": "", + "Erroneous challenge": "", + "Erroneous token": "", + "No such user": "", + "Token is expired, please try again": "", + "English": "", + "English (auto-generated)": "", + "Afrikaans": "", + "Albanian": "", + "Amharic": "", + "Arabic": "", + "Armenian": "", + "Azerbaijani": "", + "Bangla": "", + "Basque": "", + "Belarusian": "", + "Bosnian": "", + "Bulgarian": "", + "Burmese": "", + "Catalan": "", + "Cebuano": "", + "Chinese (Simplified)": "", + "Chinese (Traditional)": "", + "Corsican": "", + "Croatian": "", + "Czech": "", + "Danish": "", + "Dutch": "", + "Esperanto": "", + "Estonian": "", + "Filipino": "", + "Finnish": "", + "French": "", + "Galician": "", + "Georgian": "", + "German": "", + "Greek": "", + "Gujarati": "", + "Haitian Creole": "", + "Hausa": "", + "Hawaiian": "", + "Hebrew": "", + "Hindi": "", + "Hmong": "", + "Hungarian": "", + "Icelandic": "", + "Igbo": "", + "Indonesian": "", + "Irish": "", + "Italian": "", + "Japanese": "", + "Javanese": "", + "Kannada": "", + "Kazakh": "", + "Khmer": "", + "Korean": "", + "Kurdish": "", + "Kyrgyz": "", + "Lao": "", + "Latin": "", + "Latvian": "", + "Lithuanian": "", + "Luxembourgish": "", + "Macedonian": "", + "Malagasy": "", + "Malay": "", + "Malayalam": "", + "Maltese": "", + "Maori": "", + "Marathi": "", + "Mongolian": "", + "Nepali": "", + "Norwegian Bokmål": "", + "Nyanja": "", + "Pashto": "", + "Persian": "", + "Polish": "", + "Portuguese": "", + "Punjabi": "", + "Romanian": "", + "Russian": "", + "Samoan": "", + "Scottish Gaelic": "", + "Serbian": "", + "Shona": "", + "Sindhi": "", + "Sinhala": "", + "Slovak": "", + "Slovenian": "", + "Somali": "", + "Southern Sotho": "", + "Spanish": "", + "Spanish (Latin America)": "", + "Sundanese": "", + "Swahili": "", + "Swedish": "", + "Tajik": "", + "Tamil": "", + "Telugu": "", + "Thai": "", + "Turkish": "", + "Ukrainian": "", + "Urdu": "", + "Uzbek": "", + "Vietnamese": "", + "Welsh": "", + "Western Frisian": "", + "Xhosa": "", + "Yiddish": "", + "Yoruba": "", + "Zulu": "", + "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` years.": "", + "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` months.": "", + "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` weeks.": "", + "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` days.": "", + "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` hours.": "", + "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` minutes.": "", + "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` seconds.": "", + "Fallback comments: ": "", + "Popular": "", + "Top": "", + "About": "", + "Rating: ": "", + "Language: ": "", + "View as playlist": "", + "Default": "", + "Music": "", + "Gaming": "", + "News": "", + "Movies": "", + "Download": "", + "Download as: ": "", + "%A %B %-d, %Y": "", + "(edited)": "", + "YouTube comment permalink": "", + "permalink": "", + "`x` marked it with a ❤": "", + "Audio mode": "", + "Video mode": "", + "Videos": "", + "Playlists": "", + "Community": "", + "Current version: ": "" +} diff --git a/locales/da.json b/locales/da.json new file mode 100644 index 000000000..1944e47b8 --- /dev/null +++ b/locales/da.json @@ -0,0 +1,387 @@ +{ + "`x` subscribers": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` abonnenter.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` abonnenter." + }, + "`x` videos": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` videoer.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` videoer." + }, + "`x` playlists": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` afspilningslister.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` afspilningslister." + }, + "LIVE": "DIREKTE", + "Shared `x` ago": "Delt for `x` siden", + "Unsubscribe": "", + "Subscribe": "Abonner", + "View channel on YouTube": "Vis kanal på YouTube", + "View playlist on YouTube": "Vis afspilningsliste på YouTube", + "newest": "nyeste", + "oldest": "ældste", + "popular": "populært", + "last": "sidste", + "Next page": "Næste side", + "Previous page": "Forrige side", + "Clear watch history?": "Ryd afspilningshistorik?", + "New password": "Nyt kodeord", + "New passwords must match": "Nye kodeord skal matche", + "Cannot change password for Google accounts": "Kan ikke skifte kodeord til Google-konti", + "Authorize token?": "Godkend token?", + "Authorize token for `x`?": "Godkende token til `x`?", + "Yes": "Ja", + "No": "Nej", + "Import and Export Data": "Importer og Eksporter Data", + "Import": "Importer", + "Import Invidious data": "Importer Invidious data", + "Import YouTube subscriptions": "Importer Youtube abonnementer", + "Import FreeTube subscriptions (.db)": "Importer FreeTube abonnementer (.db)", + "Import NewPipe subscriptions (.json)": "Importer NewPipe abonnementer (.json)", + "Import NewPipe data (.zip)": "Importer NewPipe data (.zip)", + "Export": "Exporter", + "Export subscriptions as OPML": "Exporter abonnementer som OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exporter abonnementer som OPML (til NewPipe & FreeTube)", + "Export data as JSON": "Exporter data som JSON", + "Delete account?": "Slet konto?", + "History": "Historik", + "An alternative front-end to YouTube": "", + "JavaScript license information": "JavaScript licens information", + "source": "kilde", + "Log in": "Log på", + "Log in/register": "Log på/registrer", + "Log in with Google": "Log på med Google", + "User ID": "Bruger ID", + "Password": "Kodeord", + "Time (h:mm:ss):": "Tid (t:mm:ss):", + "Text CAPTCHA": "Tekst CAPTCHA", + "Image CAPTCHA": "Billede CAPTCHA", + "Sign In": "Log ind", + "Register": "Registrer", + "E-mail": "E-mail", + "Google verification code": "Google verifications kode", + "Preferences": "Præferencer", + "Player preferences": "", + "Always loop: ": "Altid gentag: ", + "Autoplay: ": "Auto afspil: ", + "Play next by default: ": "Afspil næste som standard: ", + "Autoplay next video: ": "Auto afspil næste video: ", + "Listen by default: ": "Lyt som standard: ", + "Proxy videos: ": "Proxy videoer: ", + "Default speed: ": "Standard hastighed: ", + "Preferred video quality: ": "Foretrukken video kvalitet: ", + "Player volume: ": "Lydstyrke: ", + "Default comments: ": "Standard kommentarer: ", + "youtube": "youtube", + "reddit": "reddit", + "Default captions: ": "", + "Fallback captions: ": "", + "Show related videos: ": "", + "Show annotations by default: ": "", + "Visual preferences": "", + "Player style: ": "", + "Dark mode: ": "", + "Theme: ": "", + "dark": "", + "light": "", + "Thin mode: ": "", + "Subscription preferences": "", + "Show annotations by default for subscribed channels: ": "", + "Redirect homepage to feed: ": "", + "Number of videos shown in feed: ": "", + "Sort videos by: ": "", + "published": "", + "published - reverse": "", + "alphabetically": "", + "alphabetically - reverse": "", + "channel name": "", + "channel name - reverse": "", + "Only show latest video from channel: ": "", + "Only show latest unwatched video from channel: ": "", + "Only show unwatched: ": "", + "Only show notifications (if there are any): ": "", + "Enable web notifications": "", + "`x` uploaded a video": "", + "`x` is live": "", + "Data preferences": "", + "Clear watch history": "", + "Import/export data": "", + "Change password": "", + "Manage subscriptions": "", + "Manage tokens": "", + "Watch history": "", + "Delete account": "", + "Administrator preferences": "", + "Default homepage: ": "", + "Feed menu: ": "", + "Top enabled: ": "", + "CAPTCHA enabled: ": "", + "Login enabled: ": "", + "Registration enabled: ": "", + "Report statistics: ": "", + "Save preferences": "", + "Subscription manager": "", + "Token manager": "", + "Token": "", + "`x` subscriptions": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` tokens": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Import/export": "", + "unsubscribe": "", + "revoke": "", + "Subscriptions": "", + "`x` unseen notifications": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "search": "", + "Log out": "", + "Released under the AGPLv3 by Omar Roth.": "", + "Source available here.": "", + "View JavaScript license information.": "", + "View privacy policy.": "", + "Trending": "", + "Public": "", + "Unlisted": "", + "Private": "", + "View all playlists": "", + "Updated `x` ago": "", + "Delete playlist `x`?": "", + "Delete playlist": "", + "Create playlist": "", + "Title": "", + "Playlist privacy": "", + "Editing playlist `x`": "", + "Watch on YouTube": "", + "Hide annotations": "", + "Show annotations": "", + "Genre: ": "", + "License: ": "", + "Family friendly? ": "", + "Wilson score: ": "", + "Engagement: ": "", + "Whitelisted regions: ": "", + "Blacklisted regions: ": "", + "Shared `x`": "", + "`x` views": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Premieres in `x`": "", + "Premieres `x`": "", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "", + "View YouTube comments": "", + "View more comments on Reddit": "", + "View `x` comments": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "View Reddit comments": "", + "Hide replies": "", + "Show replies": "", + "Incorrect password": "", + "Quota exceeded, try again in a few hours": "", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", + "Invalid TFA code": "", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "", + "Wrong answer": "", + "Erroneous CAPTCHA": "", + "CAPTCHA is a required field": "", + "User ID is a required field": "", + "Password is a required field": "", + "Wrong username or password": "", + "Please sign in using 'Log in with Google'": "", + "Password cannot be empty": "", + "Password cannot be longer than 55 characters": "", + "Please log in": "", + "Invidious Private Feed for `x`": "", + "channel:`x`": "", + "Deleted or invalid channel": "", + "This channel does not exist.": "", + "Could not get channel info.": "", + "Could not fetch comments": "", + "View `x` replies": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` ago": "", + "Load more": "", + "`x` points": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Could not create mix.": "", + "Empty playlist": "", + "Not a playlist.": "", + "Playlist does not exist.": "", + "Could not pull trending pages.": "", + "Hidden field \"challenge\" is a required field": "", + "Hidden field \"token\" is a required field": "", + "Erroneous challenge": "", + "Erroneous token": "", + "No such user": "", + "Token is expired, please try again": "", + "English": "", + "English (auto-generated)": "", + "Afrikaans": "", + "Albanian": "", + "Amharic": "", + "Arabic": "", + "Armenian": "", + "Azerbaijani": "", + "Bangla": "", + "Basque": "", + "Belarusian": "", + "Bosnian": "", + "Bulgarian": "", + "Burmese": "", + "Catalan": "", + "Cebuano": "", + "Chinese (Simplified)": "", + "Chinese (Traditional)": "", + "Corsican": "", + "Croatian": "", + "Czech": "", + "Danish": "", + "Dutch": "", + "Esperanto": "", + "Estonian": "", + "Filipino": "", + "Finnish": "", + "French": "", + "Galician": "", + "Georgian": "", + "German": "", + "Greek": "", + "Gujarati": "", + "Haitian Creole": "", + "Hausa": "", + "Hawaiian": "", + "Hebrew": "", + "Hindi": "", + "Hmong": "", + "Hungarian": "", + "Icelandic": "", + "Igbo": "", + "Indonesian": "", + "Irish": "", + "Italian": "", + "Japanese": "", + "Javanese": "", + "Kannada": "", + "Kazakh": "", + "Khmer": "", + "Korean": "", + "Kurdish": "", + "Kyrgyz": "", + "Lao": "", + "Latin": "", + "Latvian": "", + "Lithuanian": "", + "Luxembourgish": "", + "Macedonian": "", + "Malagasy": "", + "Malay": "", + "Malayalam": "", + "Maltese": "", + "Maori": "", + "Marathi": "", + "Mongolian": "", + "Nepali": "", + "Norwegian Bokmål": "", + "Nyanja": "", + "Pashto": "", + "Persian": "", + "Polish": "", + "Portuguese": "", + "Punjabi": "", + "Romanian": "", + "Russian": "", + "Samoan": "", + "Scottish Gaelic": "", + "Serbian": "", + "Shona": "", + "Sindhi": "", + "Sinhala": "", + "Slovak": "", + "Slovenian": "", + "Somali": "", + "Southern Sotho": "", + "Spanish": "", + "Spanish (Latin America)": "", + "Sundanese": "", + "Swahili": "", + "Swedish": "", + "Tajik": "", + "Tamil": "", + "Telugu": "", + "Thai": "", + "Turkish": "", + "Ukrainian": "", + "Urdu": "", + "Uzbek": "", + "Vietnamese": "", + "Welsh": "", + "Western Frisian": "", + "Xhosa": "", + "Yiddish": "", + "Yoruba": "", + "Zulu": "", + "`x` years": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` months": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` weeks": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` days": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` hours": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` minutes": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` seconds": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Fallback comments: ": "", + "Popular": "", + "Top": "", + "About": "", + "Rating: ": "", + "Language: ": "", + "View as playlist": "", + "Default": "", + "Music": "", + "Gaming": "", + "News": "", + "Movies": "", + "Download": "", + "Download as: ": "", + "%A %B %-d, %Y": "", + "(edited)": "", + "YouTube comment permalink": "", + "permalink": "", + "`x` marked it with a ❤": "", + "Audio mode": "", + "Video mode": "", + "Videos": "", + "Playlists": "", + "Community": "", + "Current version: ": "" +} diff --git a/locales/de.json b/locales/de.json index b685a8421..b995baac1 100644 --- a/locales/de.json +++ b/locales/de.json @@ -33,14 +33,14 @@ "Export subscriptions as OPML": "Abonnements als OPML exportieren", "Export subscriptions as OPML (for NewPipe & FreeTube)": "Abonnements als OPML exportieren (für NewPipe & FreeTube)", "Export data as JSON": "Daten als JSON exportieren", - "Delete account?": "Account löschen?", + "Delete account?": "Konto löschen?", "History": "Verlauf", "An alternative front-end to YouTube": "Eine alternative Oberfläche für YouTube", "JavaScript license information": "JavaScript Lizenzinformationen", "source": "Quelle", - "Log in": "Einloggen", - "Log in/register": "Einloggen/Registrieren", - "Log in with Google": "Mit Google einloggen", + "Log in": "Anmelden", + "Log in/register": "Anmelden/registrieren", + "Log in with Google": "Mit Google anmelden", "User ID": "Benutzer ID", "Password": "Passwort", "Time (h:mm:ss):": "Zeit (h:mm:ss):", @@ -106,7 +106,7 @@ "Feed menu: ": "Feed-Menü: ", "Top enabled: ": "Top aktiviert? ", "CAPTCHA enabled: ": "CAPTCHA aktiviert? ", - "Login enabled: ": "Login aktiviert? ", + "Login enabled: ": "Anmeldung aktiviert: ", "Registration enabled: ": "Registrierung aktiviert? ", "Report statistics: ": "Statistiken berichten? ", "Save preferences": "Einstellungen speichern", @@ -161,16 +161,16 @@ "Show replies": "Antworten anzeigen", "Incorrect password": "Falsches Passwort", "Quota exceeded, try again in a few hours": "Kontingent überschritten, versuche es in ein paar Stunden erneut", - "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Login nicht möglich, stellen Sie sicher dass two-factor Authentifikation (Authentifizierung oder SMS) aktiviert ist.", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Anmeldung nicht möglich, stellen Sie sicher, dass die Zwei-Faktor-Authentisierung (Authenticator oder SMS) aktiviert ist.", "Invalid TFA code": "Ungültiger TFA Code", - "Login failed. This may be because two-factor authentication is not turned on for your account.": "Login fehlgeschlagen. Das kann daran liegen dass two-factor Authentifizierung in ihrem Account nicht aktiviert ist.", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "Die Anmeldung ist fehlgeschlagen. Dies kann daran liegen, dass die Zwei-Faktor-Authentisierung für Ihr Konto nicht aktiviert ist.", "Wrong answer": "Ungültige Antwort", "Erroneous CAPTCHA": "Ungültiges CAPTCHA", "CAPTCHA is a required field": "CAPTCHA ist eine erforderliche Eingabe", "User ID is a required field": "Benutzer ID ist eine erforderliche Eingabe", "Password is a required field": "Passwort ist eine erforderliche Eingabe", "Wrong username or password": "Ungültiger Benutzername oder Passwort", - "Please sign in using 'Log in with Google'": "Bitte melden sie sich mit 'Mit Google anmelden' an", + "Please sign in using 'Log in with Google'": "Bitte melden Sie sich mit „Mit Google anmelden“ an", "Password cannot be empty": "Passwort darf nicht leer sein", "Password cannot be longer than 55 characters": "Passwort darf nicht länger als 55 Zeichen sein", "Please log in": "Bitte anmelden", @@ -189,8 +189,8 @@ "Not a playlist.": "Ungültige Playlist.", "Playlist does not exist.": "Playlist existiert nicht.", "Could not pull trending pages.": "Trending Seiten konnten nicht geladen werden.", - "Hidden field \"challenge\" is a required field": "Verstecktes Feld \"challenge\" ist eine erforderliche Eingabe", - "Hidden field \"token\" is a required field": "Verstecktes Feld \"token\" ist eine erforderliche Eingabe", + "Hidden field \"challenge\" is a required field": "Verstecktes Feld „challenge“ ist eine erforderliche Eingabe", + "Hidden field \"token\" is a required field": "Verstecktes Feld „token“ ist eine erforderliche Eingabe", "Erroneous challenge": "Ungültiger Test", "Erroneous token": "Ungültiger Token", "No such user": "Ungültiger Benutzer", @@ -322,7 +322,7 @@ "Movies": "Filme", "Download": "Herunterladen", "Download as: ": "Herunterladen als: ", - "%A %B %-d, %Y": "%A %B %-d, %Y", + "%A %B %-d, %Y": "%A %-d %B %Y", "(edited)": "(editiert)", "YouTube comment permalink": "YouTube-Kommentar Permalink", "permalink": "Permalink", @@ -333,4 +333,4 @@ "Playlists": "Wiedergabelisten", "Community": "Gemeinschaft", "Current version: ": "Aktuelle Version: " -} \ No newline at end of file +} diff --git a/locales/el.json b/locales/el.json index f4249ebcc..23b3cdf94 100644 --- a/locales/el.json +++ b/locales/el.json @@ -1,19 +1,15 @@ { - "`x` subscribers": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομητής", - "": "`x` συνδρομητές" - }, - "`x` videos": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` βίντεο", - "": "`x` βίντεο" - }, - "`x` playlists": "", + "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομητής", + "`x` subscribers.": "`x` συνδρομητές.", + "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` βίντεο", + "`x` videos.": "`x` βίντεο.", + "`x` playlists": "`x` κατάλογοι αναπαραγωγής", "LIVE": "ΖΩΝΤΑΝΑ", "Shared `x` ago": "Μοιράστηκε πριν `x`", "Unsubscribe": "Απεγγραφή", "Subscribe": "Εγγραφή", "View channel on YouTube": "Προβολή καναλιού στο YouTube", - "View playlist on YouTube": "", + "View playlist on YouTube": "Προβολή καταλόγου αναπαραγωγής στο YouTube", "newest": "νεότερα", "oldest": "παλιότερα", "popular": "δημοφιλή", @@ -54,7 +50,7 @@ "Image CAPTCHA": "Εικόνα CAPTCHA", "Sign In": "Σύνδεση", "Register": "Εγγραφή", - "E-mail": "E-mail", + "E-mail": "Ηλεκτρονικό ταχυδρομείο", "Google verification code": "Κωδικός επαλήθευσης Google", "Preferences": "Προτιμήσεις", "Player preferences": "Προτιμήσεις αναπαραγωγής", @@ -68,18 +64,18 @@ "Preferred video quality: ": "Προτιμώμενη ανάλυση: ", "Player volume: ": "Ένταση αναπαραγωγής: ", "Default comments: ": "Προεπιλεγμένα σχόλια: ", - "youtube": "youtube", + "youtube": "YouTube", "reddit": "reddit", "Default captions: ": "Προεπιλεγμένοι υπότιτλοι: ", "Fallback captions: ": "Εναλλακτικοί υπότιτλοι: ", "Show related videos: ": "Προβολή σχετικών βίντεο; ", - "Show annotations by default: ": "Αυτόματη προβολή σημειώσεων; :", + "Show annotations by default: ": "Αυτόματη προβολή σημειώσεων: ", "Visual preferences": "Προτιμήσεις εμφάνισης", - "Player style: ": "", + "Player style: ": "Τεχνοτροπία της συσκευής αναπαραγωγης: ", "Dark mode: ": "Σκοτεινή λειτουργία: ", - "Theme: ": "", - "dark": "", - "light": "", + "Theme: ": "Θέμα: ", + "dark": "σκοτεινό", + "light": "φωτεινό", "Thin mode: ": "Ελαφριά λειτουργία: ", "Subscription preferences": "Προτιμήσεις συνδρομών", "Show annotations by default for subscribed channels: ": "Προβολή σημειώσεων μόνο για κανάλια στα οποία είστε συνδρομητής; ", @@ -96,9 +92,9 @@ "Only show latest unwatched video from channel: ": "Προβολή μόνο του τελευταίου μη-προβεβλημένου βίντεο του καναλιού: ", "Only show unwatched: ": "Προβολή μόνο μη-προβεβλημένων: ", "Only show notifications (if there are any): ": "Προβολή μόνο ειδοποιήσεων (αν υπάρχουν): ", - "Enable web notifications": "", - "`x` uploaded a video": "", - "`x` is live": "", + "Enable web notifications": "Ενεργοποίηση ειδοποιήσεων δικτύου", + "`x` uploaded a video": "`x` κοινοποίησε ένα βίντεο", + "`x` is live": "`x` κάνει live", "Data preferences": "Προτιμήσεις δεδομένων", "Clear watch history": "Εκκαθάριση ιστορικού προβολής", "Import/export data": "Εισαγωγή/εξαγωγή δεδομένων", @@ -119,22 +115,16 @@ "Subscription manager": "Διαχειριστής συνδρομών", "Token manager": "Διαχειριστής διασυνδέσεων", "Token": "Διασύνδεση", - "`x` subscriptions": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομή", - "": "`x` συνδρομές" - }, - "`x` tokens": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` διασύνδεση", - "": "`x` διασυνδέσεις" - }, + "`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομή", + "`x` subscriptions.": "`x` συνδρομές.", + "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "`x` διασύνδεση", + "`x` tokens.": "`x` διασυνδέσεις.", "Import/export": "Εισαγωγή/εξαγωγή", "unsubscribe": "κατάργηση συνδρομής", "revoke": "ανάκληση", "Subscriptions": "Συνδρομές", - "`x` unseen notifications": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` καινούρια ειδοποίηση", - "": "`x` καινούριες ειδοποιήσεις" - }, + "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "`x` καινούρια ειδοποίηση", + "`x` unseen notifications.": "`x` καινούριες ειδοποιήσεις.", "search": "αναζήτηση", "Log out": "Αποσύνδεση", "Released under the AGPLv3 by Omar Roth.": "Κυκλοφορεί υπό την άδεια AGPLv3 από τον Omar Roth.", @@ -142,35 +132,33 @@ "View JavaScript license information.": "Προβολή πληροφοριών άδειας JavaScript.", "View privacy policy.": "Προβολή πολιτικής απορρήτου.", "Trending": "Τάσεις", - "Public": "", + "Public": "Δημόσιο", "Unlisted": "Κρυφό", - "Private": "", - "View all playlists": "", - "Updated `x` ago": "", - "Delete playlist `x`?": "", - "Delete playlist": "", - "Create playlist": "", - "Title": "", - "Playlist privacy": "", - "Editing playlist `x`": "", + "Private": "Ιδιωτικό", + "View all playlists": "Προβολή όλων των καταλόγων αναπαραγωγής", + "Updated `x` ago": "Ενημερώθηκε πριν από `x`", + "Delete playlist `x`?": "Διαγραφή `x` καταλόγου αναπαραγωγής;", + "Delete playlist": "Διαγραφή καταλόγου αναπαραγωγής", + "Create playlist": "Δημιουργία καταλόγου αναπαραγωγής", + "Title": "Τίτλος", + "Playlist privacy": "Ιδιωτικότητα καταλόγων αναπαραγωγής", + "Editing playlist `x`": "Επεξεργασία `x` καταλόγου αναπαραγωγής", "Watch on YouTube": "Προβολή στο YouTube", "Hide annotations": "Απόκρυψη σημειώσεων", "Show annotations": "Προβολή σημειώσεων", "Genre: ": "Είδος: ", "License: ": "Άδεια: ", "Family friendly? ": "Φιλικό προς την οικογένεια; ", - "Wilson score: ": "Wilson score: ", + "Wilson score: ": "Αποτελέσματα Wilson: ", "Engagement: ": "Ενδιαφέρον: ", "Whitelisted regions: ": "Επιτρεπτές περιοχές: ", "Blacklisted regions: ": "Μη-επιτρεπτές περιοχές: ", "Shared `x`": "Μοιράστηκε το `x`", - "`x` views": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` προβολή", - "": "`x` προβολές" - }, + "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "`x` προβολή", + "`x` views.": "`x` προβολές.", "Premieres in `x`": "Πρώτη προβολή σε `x`", - "Premieres `x`": "", - "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Γεια! Φαίνεται πως έχετε απενεργοποιήσει το JavaScript. Πατήστε εδώ για προβολή σχολίων, αλλά έχετε υπ'όψιν σας πως ίσως φορτώσουν πιο αργά. ", + "Premieres `x`": "Επίσημη πρώτη παράσταση του `x`", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Γεια! Φαίνεται πως έχετε απενεργοποιήσει το JavaScript. Πατήστε εδώ για προβολή σχολίων, αλλά έχετε υπ'όψιν σας πως ίσως φορτώσουν πιο αργά.", "View YouTube comments": "Προβολή σχολίων από το YouTube", "View more comments on Reddit": "Προβολή περισσότερων σχολίων στο Reddit", "View `x` comments": "Προβολή `x` σχολίων", @@ -198,19 +186,15 @@ "This channel does not exist.": "Αυτό το κανάλι δεν υπάρχει.", "Could not get channel info.": "Αδύναμια εύρεσης πληροφοριών καναλιού.", "Could not fetch comments": "Αδυναμία λήψης σχολίων", - "View `x` replies": { - "([^.,0-9]|^)1([^.,0-9]|$)": "Προβολή `x` απάντησης", - "": "Προβολή `x` απαντήσεων" - }, + "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "Προβολή `x` απάντησης", + "View `x` replies.": "Προβολή `x` απαντήσεων.", "`x` ago": "Πριν `x`", "Load more": "Φόρτωση περισσότερων", - "`x` points": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` βαθμός", - "": "`x` βαθμοί" - }, + "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "`x` βαθμός", + "`x` points.": "`x` βαθμοί.", "Could not create mix.": "Αδυναμία δημιουργίας μίξης.", "Empty playlist": "Κενή λίστα αναπαραγωγής", - "Not a playlist.": "Μη έγκυρη λίστα αναπαραγωγής", + "Not a playlist.": "Μη έγκυρη λίστα αναπαραγωγής.", "Playlist does not exist.": "Μη υπαρκτή λίστα αναπαραγωγής.", "Could not pull trending pages.": "Αδυναμία λήψης σελίδας τάσεων.", "Hidden field \"challenge\" is a required field": "Το Κρυφό πεδίο \"δοκιμασία\" είναι απαραίτητο", @@ -325,34 +309,20 @@ "Yiddish": "Γίντις", "Yoruba": "Γιορούμπα", "Zulu": "Ζουλού", - "`x` years": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` χρόνο", - "": "`x` χρόνια" - }, - "`x` months": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` μήνα", - "": "`x` μήνες" - }, - "`x` weeks": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` εβδομάδα", - "": "`x` εβδομάδες" - }, - "`x` days": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` ημέρα", - "": "`x` ημέρες" - }, - "`x` hours": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` ώρα", - "": "`x` ώρες" - }, - "`x` minutes": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` λεπτό", - "": "`x` λεπτά" - }, - "`x` seconds": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` δευτερόλεπτο", - "": "`x` δευτερόλεπτα" - }, + "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "`x` χρόνο", + "`x` years.": "`x` χρόνια.", + "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "`x` μήνα", + "`x` months.": "`x` μήνες.", + "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "`x` εβδομάδα", + "`x` weeks.": "`x` εβδομάδες.", + "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "`x` ημέρα", + "`x` days.": "`x` ημέρες.", + "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "`x` ώρα", + "`x` hours.": "`x` ώρες.", + "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "`x` λεπτό", + "`x` minutes.": "`x` λεπτά.", + "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "`x` δευτερόλεπτο", + "`x` seconds.": "`x` δευτερόλεπτα.", "Fallback comments: ": "Εναλλακτικά σχόλια: ", "Popular": "Δημοφιλή", "Top": "Κορυφαία", @@ -370,12 +340,12 @@ "%A %B %-d, %Y": "%A %B %-d, %Y", "(edited)": "(τροποποιημένο)", "YouTube comment permalink": "Σύνδεσμος YouTube σχολίου", - "permalink": "", + "permalink": "μόνιμος σύνδεσμος", "`x` marked it with a ❤": "Ο χρηστης `x` έβαλε ❤", "Audio mode": "Λειτουργία ήχου", "Video mode": "Λειτουργία βίντεο", "Videos": "Βίντεο", "Playlists": "Λίστες Αναπαραγωγής", - "Community": "", + "Community": "Κοινότητα", "Current version: ": "Τρέχουσα έκδοση: " -} \ No newline at end of file +} diff --git a/locales/eo.json b/locales/eo.json index ae640e37e..3052ac359 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -4,10 +4,10 @@ "`x` playlists": "`x` ludlistoj", "LIVE": "NUNA", "Shared `x` ago": "Konigita antaŭ `x`", - "Unsubscribe": "Malaboni", - "Subscribe": "Aboni", - "View channel on YouTube": "Vidi kanalon en JuTubo", - "View playlist on YouTube": "Vidi ludliston en JuTubo", + "Unsubscribe": "Malabonu", + "Subscribe": "Abonu", + "View channel on YouTube": "Vidu kanalon en JuTubo", + "View playlist on YouTube": "Vidu ludliston en JuTubo", "newest": "pli novaj", "oldest": "pli malnovaj", "popular": "popularaj", @@ -116,7 +116,7 @@ "`x` subscriptions": "`x` abonoj", "`x` tokens": "`x` ĵetonoj", "Import/export": "Importi/Eksporti", - "unsubscribe": "malaboni", + "unsubscribe": "malabonu", "revoke": "senvalidigi", "Subscriptions": "Abonoj", "`x` unseen notifications": "`x` neviditaj sciigoj", @@ -316,7 +316,7 @@ "Language: ": "Lingvo: ", "View as playlist": "Vidi kiel ludlisto", "Default": "Defaŭlte", - "Music": "Musiko", + "Music": "Muziko", "Gaming": "Komputiloludoj", "News": "Novaĵoj", "Movies": "Filmoj", @@ -333,4 +333,4 @@ "Playlists": "Ludlistoj", "Community": "Komunumo", "Current version: ": "Nuna versio: " -} \ No newline at end of file +} diff --git a/locales/es.json b/locales/es.json index 7fc750039..91faef1b9 100644 --- a/locales/es.json +++ b/locales/es.json @@ -132,8 +132,8 @@ "Private": "Privado", "View all playlists": "Ver todas las listas de reproducción", "Updated `x` ago": "Actualizado hace `x`", - "Delete playlist `x`?": "¿Eliminar la lista de reproducción `x`?", - "Delete playlist": "Eliminar lista de reproducción", + "Delete playlist `x`?": "¿Borrar la lista de reproducción `x`?", + "Delete playlist": "Borrar lista de reproducción", "Create playlist": "Crear lista de reproducción", "Title": "Título", "Playlist privacy": "Privacidad de la lista de reproducción", @@ -333,4 +333,4 @@ "Playlists": "Listas de reproducción", "Community": "Comunidad", "Current version: ": "Versión actual: " -} \ No newline at end of file +} diff --git a/locales/fa.json b/locales/fa.json new file mode 100644 index 000000000..0f0900a97 --- /dev/null +++ b/locales/fa.json @@ -0,0 +1,353 @@ +{ + "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` مشترکان.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` subscribers.": "`x` مشترکان.", + "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` ویدیو ها.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` videos.": "`x` ویدیو ها.", + "`x` playlists.([^.,0-9]|^)1([^.,0-9]|$)": "`x` لیست های پخش.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` playlists.": "`x` لیست های پخش.", + "LIVE": "زنده", + "Shared `x` ago": "به اشتراک گذاشته شده `x` پیش", + "Unsubscribe": "لغو اشتراک", + "Subscribe": "مشترک شدن", + "View channel on YouTube": "نمایش کانال در یوتیوب", + "View playlist on YouTube": "نمایش لیست پخش در یوتیوب", + "newest": "جدید تر", + "oldest": "قدیمی تر", + "popular": "محبوب", + "last": "آخرین", + "Next page": "صفحه بعد", + "Previous page": "صفحه قبل", + "Clear watch history?": "پاک کردن تاریخچه نمایش؟", + "New password": "گذرواژه جدید", + "New passwords must match": "گذارواژه های جدید باید باهم همخوانی داشته باشند", + "Cannot change password for Google accounts": "نمیتوان گذرواژه را برای حساب های کاربری گوگل تغییر داد", + "Authorize token?": "توکن دسترسی؟", + "Authorize token for `x`?": "توکن دسترسی برای `x`؟", + "Yes": "بله", + "No": "خیر", + "Import and Export Data": "وارد کردن و خارج کردن داده ها", + "Import": "وارد کردن", + "Import Invidious data": "وارد کردن داده Invidious", + "Import YouTube subscriptions": "وارد کردن اشتراک های یوتیوب", + "Import FreeTube subscriptions (.db)": "وارد کردن اشتراک های فری توب (.db)", + "Import NewPipe subscriptions (.json)": "وارد کردن اشتراک های نیو پایپ (.json)", + "Import NewPipe data (.zip)": "وارد کردن داده نیو پایپ (.zip)", + "Export": "خارج کردن", + "Export subscriptions as OPML": "خارج کردن اشتراک ها به عنوان OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "خارج کردن اشتراک ها به عنوان OPML (برای فری توب و نیو پایپ)", + "Export data as JSON": "خارج کردن داده ها به عنوان JSON", + "Delete account?": "حذف حساب کاربری؟", + "History": "تاریخچه", + "An alternative front-end to YouTube": "یک فرانت-اند جایگذین برای یوتیوب", + "JavaScript license information": "اطلاعات مجوز جاوا اسکریپت", + "source": "منبع", + "Log in": "ورود", + "Log in/register": "ورود/ثبت نام", + "Log in with Google": "ورود با گوگل", + "User ID": "شناسه کاربری", + "Password": "گذرواژه", + "Time (h:mm:ss):": "زمان (h:mm:ss):", + "Text CAPTCHA": "متن CAPTCHA", + "Image CAPTCHA": "تصویر CAPTCHA", + "Sign In": "ورود", + "Register": "ثبت نام", + "E-mail": "ایمیل", + "Google verification code": "کد تایید گوگل", + "Preferences": "ترجیحات", + "Player preferences": "ترجیحات نمایش‌دهنده", + "Always loop: ": "همیشه تکرار شنوده: ", + "Autoplay: ": "نمایش خودکار: ", + "Play next by default: ": "پخش بعدی به طور پیشفرض: ", + "Autoplay next video: ": "پخش خودکار ویدیو بعدی: ", + "Listen by default: ": "گوش کردن به طور پیشفرض: ", + "Proxy videos: ": "پروکسی ویدیو ها: ", + "Default speed: ": "سرعت پیشفرض: ", + "Preferred video quality: ": "کیفیت ویدیوی ترجیحی: ", + "Player volume: ": "صدای پخش کننده: ", + "Default comments: ": "نظرات پیشفرض: ", + "youtube": "یوتیوب", + "reddit": "ردیت", + "Default captions: ": "زیرنویس های پیشفرض: ", + "Fallback captions: ": "عقب گرد زیرنویس ها: ", + "Show related videos: ": "نمایش ویدیو های مرتبط: ", + "Show annotations by default: ": "نمایش حاشیه نویسی ها به طور پیشفرض: ", + "Visual preferences": "ترجیحات بصری", + "Player style: ": "حالت پخش کننده: ", + "Dark mode: ": "حالت تاریک: ", + "Theme: ": "تم: ", + "dark": "تاریک", + "light": "روشن", + "Thin mode: ": "حالت نازک: ", + "Subscription preferences": "ترجیحات اشتراک", + "Show annotations by default for subscribed channels: ": "نمایش حاشیه نویسی ها به طور پیشفرض برای کانال های مشترک شده: ", + "Redirect homepage to feed: ": "تغییر مسیر صفحه خانه به خوراک: ", + "Number of videos shown in feed: ": "تعداد ویدیو های نمایش داده شده در خوراک: ", + "Sort videos by: ": "مرتب سازی ویدیو ها بر اساس: ", + "published": "منتشر شده", + "published - reverse": "منتشر شده - معکوس", + "alphabetically": "بر اساس حروف الفبا", + "alphabetically - reverse": "بر اساس حروف الفبا - معکوس", + "channel name": "نام کانال", + "channel name - reverse": "نام کانال - معکوس", + "Only show latest video from channel: ": "تنها نمایش آخرین ویدیو های کانال: ", + "Only show latest unwatched video from channel: ": "تنها نمایش آخرین ویدیو های تماشا نشده از کانال: ", + "Only show unwatched: ": "تنها نمایش ویدیو های تماشا نشده: ", + "Only show notifications (if there are any): ": "تنها نمایش اعلان ها (اگر وجود داشته باشد) ", + "Enable web notifications": "فعال کردن اعلان های وب", + "`x` uploaded a video": "`x` یک ویدیو بارگذاری کرد", + "`x` is live": "`x` زنده است", + "Data preferences": "ترجیحات داده", + "Clear watch history": "پاک‌کردن تاریخچه تماشا", + "Import/export data": "وارد کردن/خارج کردن داده", + "Change password": "تغییر گذرواژه", + "Manage subscriptions": "مدیریت اشتراک ها", + "Manage tokens": "مدیریت توکن ها", + "Watch history": "تاریخچه تماشا", + "Delete account": "حذف حساب کاربری", + "Administrator preferences": "ترجیحات مدیریت", + "Default homepage: ": "صفحه خانه پیشفرض ", + "Feed menu: ": "منو خوراک: ", + "Top enabled: ": "بالا فعال شده: ", + "CAPTCHA enabled: ": "CAPTCHA فعال شده: ", + "Login enabled: ": "ورود فعال شده: ", + "Registration enabled: ": "ثبت نام فعال شده: ", + "Report statistics: ": "گذارش آمار: ", + "Save preferences": "ذخیره ترجیحات", + "Subscription manager": "مدیریت اشتراک", + "Token manager": "مدیر توکن", + "Token": "توکن", + "`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "`x` اشتراک ها.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` subscriptions.": "`x` اشتراک ها.", + "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "`x` توکن ها.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` tokens.": "`x` توکن ها.", + "Import/export": "وارد کردن/خارج کردن", + "unsubscribe": "لغو اشتراک", + "revoke": "ابطال", + "Subscriptions": "اشتراک ها", + "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "`x` اعلان نادیده.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` unseen notifications.": "`x` اعلان نادیده.", + "search": "جستجو", + "Log out": "خروج", + "Released under the AGPLv3 by Omar Roth.": "منتشر شده تحت مجوز AGPLv3 توسط Omar Roth.", + "Source available here.": "منبع اینجا دردسترس است.", + "View JavaScript license information.": "نمایش اطلاعات مجوز جاوا اسکریپت.", + "View privacy policy.": "نمایش سیاست حفظ حریم خصوصی.", + "Trending": "روند", + "Public": "عمومی", + "Unlisted": "لیست نشده", + "Private": "خصوصی", + "View all playlists": "نمایش همه لیست پخش", + "Updated `x` ago": "بروز شده `x` پیش", + "Delete playlist `x`?": "حذف لیست پخش `x`؟", + "Delete playlist": "حذف لیست پخش", + "Create playlist": "ایجاد لیست پخش", + "Title": "عنوان", + "Playlist privacy": "حریم خصوصی لیست پخش", + "Editing playlist `x`": "تغییر لیست پخش `x`", + "Watch on YouTube": "تماشا در یوتیوب", + "Hide annotations": "مخفی کردن حاشیه نویسی ها", + "Show annotations": "نمایش حاشیه نویسی ها", + "Genre: ": "ژانر: ", + "License: ": "مجوز: ", + "Family friendly? ": "خانواده دوستانه؟ ", + "Wilson score: ": "امتیاز ویلسون: ", + "Engagement: ": "نامزدی: ", + "Whitelisted regions: ": "مناطق لیست سفید: ", + "Blacklisted regions: ": "مناطق لیست سیاه: ", + "Shared `x`": "به اشتراک گذاشته شده `x`", + "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "`x` بازدید.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` views.": "`x` بازدید.", + "Premieres in `x`": "برای اولین بار در `x`", + "Premieres `x`": "برای اولین بار `x`", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "سلام! مثل اینکه تو جاوا اسکریپت رو خاموش کرده ای. اینجا کلیک کن تا نظرات را ببینی، این رو یادت باشه که ممکنه بارگذاری اونها کمی طول بکشه.", + "View YouTube comments": "نمایش نظرات یوتیوب", + "View more comments on Reddit": "نمایش نظرات بیشتر در ردیت", + "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "نمایش `x` نظرات.([^.,0-9]|^)1([^.,0-9]|$)", + "View `x` comments.": "نمایش `x` نظرات.", + "View Reddit comments": "نمایش نظرات ردیت", + "Hide replies": "مخفی کردن پاسخ ها", + "Show replies": "نمایش پاسخ ها", + "Incorrect password": "گذرواژه نا درست", + "Quota exceeded, try again in a few hours": "سهمیه بیشتر شده است، چند ساعت بعد دوباره تلاش کنید", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "قادر به ورود نیستید، مطمئن شوید احراز تایید-دو‌مرحله (Authenticator یا پیام‌کوتاه) خاموش باشد.", + "Invalid TFA code": "کد TFA نادرست است", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "ورود با خطا مواجه شد. این ممکن است به خاطر احراز تایید-دو‌مرحله باشد که برای حساب کاربری شما فعال نشده است.", + "Wrong answer": "پاسخ غلط", + "Erroneous CAPTCHA": "CAPTCHA نا درست", + "CAPTCHA is a required field": "CAPTCHA یک فیلد ضروری است", + "User ID is a required field": "شناسه کاربری یک فیلد ضروری است", + "Password is a required field": "گذرواژه یک فیلد ضروری است", + "Wrong username or password": "نام کاربری یا گذرواژه غلط است", + "Please sign in using 'Log in with Google'": "لطفا با استفاده از 'ورود توسط گوگل' وارد شوید", + "Password cannot be empty": "گذرواژه نمیتواند خالی باشد", + "Password cannot be longer than 55 characters": "گذر واژه نمیتواند از ۵۵ کاراکتر بیشتر باشد", + "Please log in": "لطفا وارد شوید", + "Invidious Private Feed for `x`": "خوراک خصوصی زشت برای `x`", + "channel:`x`": "کانال: `x`", + "Deleted or invalid channel": "کانال نا معتبر یا پاک شده است", + "This channel does not exist.": "این کانال وجود ندارد.", + "Could not get channel info.": "نمیتوان اطلاعات کانال را دریافت کرد.", + "Could not fetch comments": "نمیتوان نظرات را دریافت کرد", + "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "نمایش `x` پاسخ ها.([^.,0-9]|^)1([^.,0-9]|$)", + "View `x` replies.": "نمایش `x` پاسخ ها.", + "`x` ago": "`x` پیش", + "Load more": "بارگذاری بیشتر", + "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "`x` نقطه ها.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` points.": "`x` نقطه ها.", + "Could not create mix.": "نمیتوان میکس ساخت.", + "Empty playlist": "لیست پخش خالی", + "Not a playlist.": "یک لیست پخش نیست.", + "Playlist does not exist.": "لیست پخش وجود ندارد.", + "Could not pull trending pages.": "نمیتوان صفحه های پر طرفدار را بکشد.", + "Hidden field \"challenge\" is a required field": "فیلد مخفی \"چالش\" یک فیلد ضروری است", + "Hidden field \"token\" is a required field": "فیلد مخفی \"توکن\" یک فیلد ضروری است", + "Erroneous challenge": "چالش غلط", + "Erroneous token": "توکن غلط", + "No such user": "چنین کاربری وجود ندارد", + "Token is expired, please try again": "توکن ضروری است، لطفا دوباره تلاش کنید", + "English": "انگلیسی", + "English (auto-generated)": "انگلیسی (خودکار-تولید‌شده)", + "Afrikaans": "آفریکانس", + "Albanian": "آلبانیایی", + "Amharic": "امهری", + "Arabic": "عربی", + "Armenian": "ارمنی", + "Azerbaijani": "آذربایجانی", + "Bangla": "بنگالی", + "Basque": "باسکی", + "Belarusian": "بلاروسی", + "Bosnian": "بوسنیایی", + "Bulgarian": "بلغاری", + "Burmese": "برمه‌ای", + "Catalan": "کاتالان", + "Cebuano": "سبوانو", + "Chinese (Simplified)": "چینی (ساده شده)", + "Chinese (Traditional)": "چینی (سنتی)", + "Corsican": "کرس", + "Croatian": "کرواسی", + "Czech": "چکی", + "Danish": "دانمارکی", + "Dutch": "هلندی", + "Esperanto": "اسپرانتو", + "Estonian": "استونیایی", + "Filipino": "فلیپینی", + "Finnish": "فنلاندی", + "French": "فرانسوی", + "Galician": "گالیسی", + "Georgian": "گرجی", + "German": "آلمانی", + "Greek": "یونانی", + "Gujarati": "گجراتی", + "Haitian Creole": "کریول آییسینی", + "Hausa": "هوسه", + "Hawaiian": "هاوائی", + "Hebrew": "عبری", + "Hindi": "هندی", + "Hmong": "همونگ", + "Hungarian": "مجاری", + "Icelandic": "ایسلندی", + "Igbo": "ایگبو", + "Indonesian": "اندونزیایی", + "Irish": "شلتا", + "Italian": "ایتالیایی", + "Japanese": "ژاپنی", + "Javanese": "جاوه‌ای", + "Kannada": "کانارا", + "Kazakh": "قزاقی", + "Khmer": "خمر", + "Korean": "کره‌ای", + "Kurdish": "کردی", + "Kyrgyz": "قرقیزی", + "Lao": "لائو", + "Latin": "لاتین", + "Latvian": "لتونیایی", + "Lithuanian": "لیتوانیایی", + "Luxembourgish": "لوکزامبورگی", + "Macedonian": "مقدونی", + "Malagasy": "مالاگاسی", + "Malay": "مالایی", + "Malayalam": "مالایالم", + "Maltese": "مالتی", + "Maori": "مائوری", + "Marathi": "مراتی", + "Mongolian": "مغولی", + "Nepali": "نپالی", + "Norwegian Bokmål": "بوکمل", + "Nyanja": "چوایی", + "Pashto": "پشتو", + "Persian": "فارسی", + "Polish": "لهستانی", + "Portuguese": "پرتغالی", + "Punjabi": "پنجابی", + "Romanian": "رومانیایی", + "Russian": "روسی", + "Samoan": "ساموآیی", + "Scottish Gaelic": "گیلیک اسکاتلندی", + "Serbian": "صربی", + "Shona": "شونا", + "Sindhi": "سندی", + "Sinhala": "سینهالی", + "Slovak": "اسلواکی", + "Slovenian": "اسلونیایی", + "Somali": "سومالیایی", + "Southern Sotho": "سوتو", + "Spanish": "اسپانیایی", + "Spanish (Latin America)": "اسپانیایی (آمریکای لاتین)", + "Sundanese": "سوندایی", + "Swahili": "سواحلی", + "Swedish": "سوئدی", + "Tajik": "تاجیک", + "Tamil": "تامیلی", + "Telugu": "تلوگو", + "Thai": "تای", + "Turkish": "ترکی", + "Ukrainian": "اوکراینی", + "Urdu": "اردو", + "Uzbek": "ازبکی", + "Vietnamese": "ویتنامی", + "Welsh": "ولزی", + "Western Frisian": "فریسی غربی", + "Xhosa": "خوسایی", + "Yiddish": "ییدیش", + "Yoruba": "یوروبایی", + "Zulu": "زولو", + "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "`x` سال.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` years.": "`x` سال.", + "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "`x` ماه.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` months.": "`x` ماه.", + "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "`x` هفته.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` weeks.": "`x` هفته.", + "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "`x` روز.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` days.": "`x` روز.", + "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "`x` ساعت.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` hours.": "`x` ساعت.", + "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "`x` دقیقه.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` minutes.": "`x` دقیقه.", + "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "`x` ثانیه.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` seconds.": "`x` ثانیه.", + "Fallback comments: ": "نظرات عقب گرد: ", + "Popular": "محبوب", + "Top": "بالا", + "About": "درباره", + "Rating: ": "رتبه دهی: ", + "Language: ": "زبان: ", + "View as playlist": "نمایش به عنوان لیست پخش", + "Default": "پیشفرض", + "Music": "موسیقی", + "Gaming": "بازی", + "News": "اخبار", + "Movies": "فیلم‌ها", + "Download": "بارگیری", + "Download as: ": "بارگیری به عنوان: ", + "%A %B %-d, %Y": "%A %B %-d، %Y", + "(edited)": "(ویرایش شده)", + "YouTube comment permalink": "پیوست ثابت نظرات یوتیوب", + "permalink": "پیوست ثابت", + "`x` marked it with a ❤": "`x` نشان گذاری شده با یک ❤", + "Audio mode": "حالت صدا", + "Video mode": "حالت ویدیو", + "Videos": "ویدیو ها", + "Playlists": "لیست های پخش", + "Community": "اجتماع", + "Current version: ": "نسخه فعلی: " +} diff --git a/locales/fi.json b/locales/fi.json new file mode 100644 index 000000000..7de46bf42 --- /dev/null +++ b/locales/fi.json @@ -0,0 +1,353 @@ +{ + "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tilaaja", + "`x` subscribers.": "`x` tilaajaa", + "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` video", + "`x` videos.": "`x` videota", + "`x` playlists.([^.,0-9]|^)1([^.,0-9]|$)": "`x` soittolista.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` playlists.": "`x` soittolistaa", + "LIVE": "SUORA", + "Shared `x` ago": "Jaettu `x` sitten", + "Unsubscribe": "Peruuta tilaus", + "Subscribe": "Tilaa", + "View channel on YouTube": "Näytä kanava YouTubessa", + "View playlist on YouTube": "Näytä soittolista YouTubessa", + "newest": "uusin", + "oldest": "vanhin", + "popular": "suosittu", + "last": "viimeisin", + "Next page": "Seuraava sivu", + "Previous page": "Edellinen sivu", + "Clear watch history?": "Tyhjennä katseluhistoria?", + "New password": "Uusi salasana", + "New passwords must match": "Uusien salasanojen täytyy täsmätä", + "Cannot change password for Google accounts": "Google-tilien salasanaa ei voi vaihtaa", + "Authorize token?": "Valuutetaanko tunnus?", + "Authorize token for `x`?": "Valtuutetaanko tunnus `x`:lle?", + "Yes": "Kyllä", + "No": "Ei", + "Import and Export Data": "Tuo ja vie tietoja", + "Import": "Tuo", + "Import Invidious data": "Vie Invidious-tietoja", + "Import YouTube subscriptions": "Tuo YouTube-tilaukset", + "Import FreeTube subscriptions (.db)": "Tuo FreeTube-tilaukset (.db)", + "Import NewPipe subscriptions (.json)": "Tuo NewPipe-tilaukset (.json)", + "Import NewPipe data (.zip)": "Tuo NewPipe data (.zip)", + "Export": "Vie", + "Export subscriptions as OPML": "Vie tilaukset muodossa OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "Vie tilaukset muodossa OPML (NewPipe ja FreeTube)", + "Export data as JSON": "Vie data muodossa JSON", + "Delete account?": "Poista tili?", + "History": "Historia", + "An alternative front-end to YouTube": "Vaihtoehtoinen käyttöliittymä YouTubelle", + "JavaScript license information": "JavaScript-käyttöoikeustiedot", + "source": "lähde", + "Log in": "Kirjaudu sisään", + "Log in/register": "Kirjaudu sisään / Rekisteröidy", + "Log in with Google": "Kirjaudu sisään Googlella", + "User ID": "Käyttäjätunnus", + "Password": "Salasana", + "Time (h:mm:ss):": "Aika (h:mm:ss):", + "Text CAPTCHA": "Teksti CAPTCHA", + "Image CAPTCHA": "Kuva CAPTCHA", + "Sign In": "Kirjaudu sisään", + "Register": "Rekisteröidy", + "E-mail": "Sähköposti", + "Google verification code": "Google-vahvistuskoodi", + "Preferences": "Asetukset", + "Player preferences": "Soittimen asetukset", + "Always loop: ": "Aina silmukka: ", + "Autoplay: ": "Automaattinen toisto: ", + "Play next by default: ": "Toista seuraava oletuksena: ", + "Autoplay next video: ": "Toista seuraava video automaattisesti: ", + "Listen by default: ": "Kuuntele oletuksena: ", + "Proxy videos: ": "Proxy videot: ", + "Default speed: ": "Oletusnopeus: ", + "Preferred video quality: ": "Ensisijainen videon laatu: ", + "Player volume: ": "Soittimen äänenvoimakkuus: ", + "Default comments: ": "Oletuskommentit: ", + "youtube": "YouTube", + "reddit": "Reddit", + "Default captions: ": "Tekstitykset: ", + "Fallback captions: ": "Toissijaiset tekstitykset: ", + "Show related videos: ": "Näytä aiheeseen liittyviä videoita: ", + "Show annotations by default: ": "Näytä huomautukset oletuksena: ", + "Visual preferences": "Visuaaliset asetukset", + "Player style: ": "Soittimen tyyli: ", + "Dark mode: ": "Tumma tila: ", + "Theme: ": "Teema: ", + "dark": "tumma", + "light": "vaalea", + "Thin mode: ": "Kapea tila ", + "Subscription preferences": "Tilausten asetukset", + "Show annotations by default for subscribed channels: ": "Näytä oletuksena tilattujen kanavien huomautukset: ", + "Redirect homepage to feed: ": "Uudelleenohjaa kotisivu syötteeseen: ", + "Number of videos shown in feed: ": "Syötteessä näytettävien videoiden määrä: ", + "Sort videos by: ": "Videoiden lajitteluperuste: ", + "published": "julkaistu", + "published - reverse": "julkaistu - käänteinen", + "alphabetically": "aakkosjärjestys", + "alphabetically - reverse": "aakkosjärjestys - käänteinen", + "channel name": "kanavan nimi", + "channel name - reverse": "kanavan nimi - käänteinen", + "Only show latest video from channel: ": "Näytä vain uusin video kanavalta: ", + "Only show latest unwatched video from channel: ": "Näytä vain uusin katsomaton video kanavalta: ", + "Only show unwatched: ": "Näytä vain katsomattomat: ", + "Only show notifications (if there are any): ": "Näytä vain ilmoitukset (jos niitä on): ", + "Enable web notifications": "Näytä verkkoilmoitukset", + "`x` uploaded a video": "`x` latasi videon", + "`x` is live": "`x` lähettää suorana", + "Data preferences": "Tietojen asetukset", + "Clear watch history": "Tyhjennä katseluhistoria", + "Import/export data": "Tuo/vie tiedot", + "Change password": "Vaihda salasana", + "Manage subscriptions": "Hallinnoi tilauksia", + "Manage tokens": "Hallinnoi tunnuksia", + "Watch history": "Katseluhistoria", + "Delete account": "Poista tili", + "Administrator preferences": "Järjestelmänvalvojan asetukset", + "Default homepage: ": "Oletuskotisivu: ", + "Feed menu: ": "Syötevalikko: ", + "Top enabled: ": "Yläosa käytössä: ", + "CAPTCHA enabled: ": "CAPTCHA käytössä: ", + "Login enabled: ": "Kirjautuminen käytössä: ", + "Registration enabled: ": "Rekisteröityminen käytössä: ", + "Report statistics: ": "Raportoi tilastot: ", + "Save preferences": "Tallenna asetukset", + "Subscription manager": "Tilausten hallinnoija", + "Token manager": "Tunnusten hallinnoija", + "Token": "Tunnus", + "`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tilausta.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` subscriptions.": "`x` tilausta.", + "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` tokens.": "", + "Import/export": "Tuo/vie", + "unsubscribe": "peru tilaus", + "revoke": "kumoa", + "Subscriptions": "Tilaukset", + "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` unseen notifications.": "", + "search": "", + "Log out": "", + "Released under the AGPLv3 by Omar Roth.": "", + "Source available here.": "", + "View JavaScript license information.": "", + "View privacy policy.": "", + "Trending": "", + "Public": "", + "Unlisted": "", + "Private": "", + "View all playlists": "", + "Updated `x` ago": "", + "Delete playlist `x`?": "", + "Delete playlist": "", + "Create playlist": "", + "Title": "", + "Playlist privacy": "", + "Editing playlist `x`": "", + "Watch on YouTube": "", + "Hide annotations": "", + "Show annotations": "", + "Genre: ": "", + "License: ": "", + "Family friendly? ": "", + "Wilson score: ": "", + "Engagement: ": "", + "Whitelisted regions: ": "", + "Blacklisted regions: ": "", + "Shared `x`": "", + "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` views.": "", + "Premieres in `x`": "", + "Premieres `x`": "", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "", + "View YouTube comments": "", + "View more comments on Reddit": "", + "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "", + "View `x` comments.": "", + "View Reddit comments": "", + "Hide replies": "", + "Show replies": "", + "Incorrect password": "", + "Quota exceeded, try again in a few hours": "", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", + "Invalid TFA code": "", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "", + "Wrong answer": "", + "Erroneous CAPTCHA": "", + "CAPTCHA is a required field": "", + "User ID is a required field": "", + "Password is a required field": "", + "Wrong username or password": "", + "Please sign in using 'Log in with Google'": "", + "Password cannot be empty": "", + "Password cannot be longer than 55 characters": "", + "Please log in": "", + "Invidious Private Feed for `x`": "", + "channel:`x`": "", + "Deleted or invalid channel": "", + "This channel does not exist.": "", + "Could not get channel info.": "", + "Could not fetch comments": "", + "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "", + "View `x` replies.": "", + "`x` ago": "", + "Load more": "", + "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` points.": "", + "Could not create mix.": "", + "Empty playlist": "", + "Not a playlist.": "", + "Playlist does not exist.": "", + "Could not pull trending pages.": "", + "Hidden field \"challenge\" is a required field": "", + "Hidden field \"token\" is a required field": "", + "Erroneous challenge": "", + "Erroneous token": "", + "No such user": "", + "Token is expired, please try again": "", + "English": "", + "English (auto-generated)": "", + "Afrikaans": "", + "Albanian": "", + "Amharic": "", + "Arabic": "", + "Armenian": "", + "Azerbaijani": "", + "Bangla": "", + "Basque": "", + "Belarusian": "", + "Bosnian": "", + "Bulgarian": "", + "Burmese": "", + "Catalan": "", + "Cebuano": "", + "Chinese (Simplified)": "", + "Chinese (Traditional)": "", + "Corsican": "", + "Croatian": "", + "Czech": "", + "Danish": "", + "Dutch": "", + "Esperanto": "", + "Estonian": "", + "Filipino": "", + "Finnish": "", + "French": "", + "Galician": "", + "Georgian": "", + "German": "", + "Greek": "", + "Gujarati": "", + "Haitian Creole": "", + "Hausa": "", + "Hawaiian": "", + "Hebrew": "", + "Hindi": "", + "Hmong": "", + "Hungarian": "", + "Icelandic": "", + "Igbo": "", + "Indonesian": "", + "Irish": "", + "Italian": "", + "Japanese": "", + "Javanese": "", + "Kannada": "", + "Kazakh": "", + "Khmer": "", + "Korean": "", + "Kurdish": "", + "Kyrgyz": "", + "Lao": "", + "Latin": "", + "Latvian": "", + "Lithuanian": "", + "Luxembourgish": "", + "Macedonian": "", + "Malagasy": "", + "Malay": "", + "Malayalam": "", + "Maltese": "", + "Maori": "", + "Marathi": "", + "Mongolian": "", + "Nepali": "", + "Norwegian Bokmål": "", + "Nyanja": "", + "Pashto": "", + "Persian": "", + "Polish": "", + "Portuguese": "", + "Punjabi": "", + "Romanian": "", + "Russian": "", + "Samoan": "", + "Scottish Gaelic": "", + "Serbian": "", + "Shona": "", + "Sindhi": "", + "Sinhala": "", + "Slovak": "", + "Slovenian": "", + "Somali": "", + "Southern Sotho": "", + "Spanish": "", + "Spanish (Latin America)": "", + "Sundanese": "", + "Swahili": "", + "Swedish": "", + "Tajik": "", + "Tamil": "", + "Telugu": "", + "Thai": "", + "Turkish": "", + "Ukrainian": "", + "Urdu": "", + "Uzbek": "", + "Vietnamese": "", + "Welsh": "", + "Western Frisian": "", + "Xhosa": "", + "Yiddish": "", + "Yoruba": "", + "Zulu": "", + "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` years.": "", + "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` months.": "", + "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` weeks.": "", + "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` days.": "", + "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` hours.": "", + "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` minutes.": "", + "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` seconds.": "", + "Fallback comments: ": "", + "Popular": "", + "Top": "", + "About": "", + "Rating: ": "", + "Language: ": "", + "View as playlist": "", + "Default": "", + "Music": "", + "Gaming": "", + "News": "", + "Movies": "", + "Download": "", + "Download as: ": "", + "%A %B %-d, %Y": "", + "(edited)": "", + "YouTube comment permalink": "", + "permalink": "", + "`x` marked it with a ❤": "", + "Audio mode": "", + "Video mode": "", + "Videos": "", + "Playlists": "", + "Community": "", + "Current version: ": "" +} diff --git a/locales/fr.json b/locales/fr.json index 24cabdea5..664e25f55 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -16,7 +16,7 @@ "Previous page": "Page précédente", "Clear watch history?": "Êtes-vous sûr de vouloir supprimer l'historique des vidéos regardées ?", "New password": "Nouveau mot de passe", - "New passwords must match": "Les champs \"Nouveau mot de passe\" doivent être identiques", + "New passwords must match": "Les nouveaux mots de passe doivent correspondre", "Cannot change password for Google accounts": "Le mot de passe d'un compte Google ne peut pas être changé depuis Invidious", "Authorize token?": "Autoriser le token ?", "Authorize token for `x`?": "Autoriser le token pour `x` ?", @@ -48,7 +48,7 @@ "Image CAPTCHA": "CAPTCHA Image", "Sign In": "Se connecter", "Register": "S'inscrire", - "E-mail": "E-mail", + "E-mail": "Courriel", "Google verification code": "Code de vérification Google", "Preferences": "Préférences", "Player preferences": "Préférences du lecteur", @@ -106,7 +106,7 @@ "Feed menu: ": "Préferences des abonnements : ", "Top enabled: ": "Top activé : ", "CAPTCHA enabled: ": "CAPTCHA activé : ", - "Login enabled: ": "Connexion activé : ", + "Login enabled: ": "Connexion activée : ", "Registration enabled: ": "Inscription activée : ", "Report statistics: ": "Télémétrie activé : ", "Save preferences": "Enregistrer les préférences", @@ -145,7 +145,7 @@ "License: ": "Licence : ", "Family friendly? ": "Vidéo tout public ? ", "Wilson score: ": "Score de Wilson : ", - "Engagement: ": "Pourcentage de spectateur aillant appuyé sur \"J'aime\" ou \"J'aime Pas\" : ", + "Engagement: ": "Taux d'implication : ", "Whitelisted regions: ": "Régions sur liste blanche : ", "Blacklisted regions: ": "Régions sur liste noire : ", "Shared `x`": "Ajoutée le `x`", @@ -170,12 +170,12 @@ "User ID is a required field": "Veuillez entrer un Identifiant Utilisateur", "Password is a required field": "Veuillez entrer un Mot de passe", "Wrong username or password": "Nom d'utilisateur ou mot de passe invalide", - "Please sign in using 'Log in with Google'": "Veuillez vous connecter en utilisant \"Se connecter avec Google\"", + "Please sign in using 'Log in with Google'": "Veuillez vous connecter en utilisant « Se connecter avec Google »", "Password cannot be empty": "Le mot de passe ne peut pas être vide", "Password cannot be longer than 55 characters": "Le mot de passe ne doit pas comporter plus de 55 caractères", "Please log in": "Veuillez vous connecter", "Invidious Private Feed for `x`": "Flux RSS privé pour `x`", - "channel:`x`": "chaîne:`x`", + "channel:`x`": "chaîne :`x`", "Deleted or invalid channel": "Chaîne supprimée ou invalide", "This channel does not exist.": "Cette chaine n'existe pas.", "Could not get channel info.": "Impossible de charger les informations de cette chaîne.", @@ -189,8 +189,8 @@ "Not a playlist.": "La liste de lecture est invalide.", "Playlist does not exist.": "La liste de lecture n'existe pas.", "Could not pull trending pages.": "Impossible de charger les pages de tendances.", - "Hidden field \"challenge\" is a required field": "Le champ masqué \"challenge\" est un champ obligatoire", - "Hidden field \"token\" is a required field": "Le champ caché \"token\" est requis", + "Hidden field \"challenge\" is a required field": "Le champ masqué « challenge » est un champ obligatoire", + "Hidden field \"token\" is a required field": "Le champ caché « token » est requis", "Erroneous challenge": "Challenge invalide", "Erroneous token": "Token invalide", "No such user": "Cet utilisateur n'existe pas", @@ -217,21 +217,21 @@ "Croatian": "Croate", "Czech": "Tchèque", "Danish": "Danois", - "Dutch": "Hollandais", + "Dutch": "Néerlandais", "Esperanto": "Espéranto", "Estonian": "Estonien", "Filipino": "Philippin", - "Finnish": "Finlandais", + "Finnish": "Finnois", "French": "Français", "Galician": "Galicien", "Georgian": "Géorgien", "German": "Allemand", "Greek": "Grec", "Gujarati": "Gujarati", - "Haitian Creole": "Créole Haïtien", + "Haitian Creole": "Créole haïtien", "Hausa": "Haoussa", "Hawaiian": "Hawaïen", - "Hebrew": "Hébraïque", + "Hebrew": "Hébreu", "Hindi": "Hindi", "Hmong": "Hmong", "Hungarian": "Hongrois", @@ -262,21 +262,21 @@ "Marathi": "Marathi", "Mongolian": "Mongol", "Nepali": "Népalais", - "Norwegian Bokmål": "Norvégien", + "Norwegian Bokmål": "Norvégien bokmål", "Nyanja": "Nyanja", - "Pashto": "Pachtou", + "Pashto": "Pachto", "Persian": "Persan", "Polish": "Polonais", "Portuguese": "Portugais", - "Punjabi": "Punjabi", + "Punjabi": "Pendjabi", "Romanian": "Roumain", "Russian": "Russe", "Samoan": "Samoan", - "Scottish Gaelic": "Eaélique Ècossais", + "Scottish Gaelic": "Gaélique écossais", "Serbian": "Serbe", "Shona": "Shona", "Sindhi": "Sindhi", - "Sinhala": "Cinghalais", + "Sinhala": "Singhalais", "Slovak": "Slovaque", "Slovenian": "Slovène", "Somali": "Somalien", @@ -286,9 +286,9 @@ "Sundanese": "Sundanais", "Swahili": "Swahili", "Swedish": "Suédois", - "Tajik": "Tajik", + "Tajik": "Tadjik", "Tamil": "Tamil", - "Telugu": "Telugu", + "Telugu": "Télougou", "Thai": "Thaï", "Turkish": "Turc", "Ukrainian": "Ukrainien", @@ -317,7 +317,7 @@ "View as playlist": "Voir en tant que liste de lecture", "Default": "Défaut", "Music": "Musique", - "Gaming": "Jeux Vidéo", + "Gaming": "Jeux vidéo", "News": "Actualités", "Movies": "Films", "Download": "Télécharger", @@ -325,7 +325,7 @@ "%A %B %-d, %Y": "%A %-d %B %Y", "(edited)": "(modifié)", "YouTube comment permalink": "Lien permanent vers le commentaire sur YouTube", - "permalink": "Lien permanent", + "permalink": "permalien", "`x` marked it with a ❤": "`x` l'a marqué d'un ❤", "Audio mode": "Mode audio", "Video mode": "Mode vidéo", @@ -333,4 +333,4 @@ "Playlists": "Listes de lecture", "Community": "Communauté", "Current version: ": "Version actuelle : " -} \ No newline at end of file +} diff --git a/locales/hr.json b/locales/hr.json new file mode 100644 index 000000000..a9a179f3e --- /dev/null +++ b/locales/hr.json @@ -0,0 +1,387 @@ +{ + "`x` subscribers": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` pretplatnika.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` pretplatnika." + }, + "`x` videos": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` videa.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` videa." + }, + "`x` playlists": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` playliste.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` playliste." + }, + "LIVE": "UŽIVO", + "Shared `x` ago": "Dijeljeno prije `x`", + "Unsubscribe": "Odjavi pretplatu", + "Subscribe": "Pretplati se", + "View channel on YouTube": "Prikaži kanal na YouTubeu", + "View playlist on YouTube": "Prikaži playlistu na YouTubeu", + "newest": "najnovije", + "oldest": "najstarije", + "popular": "popularni", + "last": "zadnji", + "Next page": "Sljedeća stranica", + "Previous page": "Prethodna stranica", + "Clear watch history?": "Izbrisati povijest gledanja?", + "New password": "Nova lozinka", + "New passwords must match": "Nove lozinke se moraju poklapati", + "Cannot change password for Google accounts": "Nije moguće promijeniti lozinku za Google račune", + "Authorize token?": "Autorizirati token?", + "Authorize token for `x`?": "Autorizirati token za `x`?", + "Yes": "Da", + "No": "Ne", + "Import and Export Data": "Uvezi i izvezi podatke", + "Import": "Uvezi", + "Import Invidious data": "Uvezi Invidious podatke", + "Import YouTube subscriptions": "Uvezi YouTube pretplate", + "Import FreeTube subscriptions (.db)": "Uvezi FreeTube pretplate (.db)", + "Import NewPipe subscriptions (.json)": "Uvezi NewPipe pretplate (.json)", + "Import NewPipe data (.zip)": "Uvezi NewPipe podatke (.zip)", + "Export": "Izvezi", + "Export subscriptions as OPML": "Izvezi pretplate kao OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "Izvezi pretplate kao OPML (za NewPipe i FreeTube)", + "Export data as JSON": "Izvezi podatke kao JSON", + "Delete account?": "Izbrisati račun?", + "History": "Povijest", + "An alternative front-end to YouTube": "Alternativa za YouTube", + "JavaScript license information": "Informacije o JavaScript licenci", + "source": "izvor", + "Log in": "Prijavi se", + "Log in/register": "Prijavi se/registriraj se", + "Log in with Google": "Prijavi se pomoću Googlea", + "User ID": "Korisnički ID", + "Password": "Lozinka", + "Time (h:mm:ss):": "Vrijeme (h:mm:ss):", + "Text CAPTCHA": "Tekstualni CAPTCHA", + "Image CAPTCHA": "Slikovni CAPTCHA", + "Sign In": "Prijava", + "Register": "Registriraj se", + "E-mail": "E-mail", + "Google verification code": "Googleov potvrdni kod", + "Preferences": "Postavke", + "Player preferences": "Postavke playera", + "Always loop: ": "Uvijek ponavljaj: ", + "Autoplay: ": "Automatski reproduciraj: ", + "Play next by default: ": "Standardno reproduciraj sljedeći: ", + "Autoplay next video: ": "Automatski reproduciraj sljedeći video: ", + "Listen by default: ": "Standardno slušaj: ", + "Proxy videos: ": "Koristi posrednika videa: ", + "Default speed: ": "Standardna brzina: ", + "Preferred video quality: ": "Primarna kvaliteta videa: ", + "Player volume: ": "Glasnoća playera: ", + "Default comments: ": "Standardni komentari: ", + "youtube": "youtube", + "reddit": "reddit", + "Default captions: ": "Standardni titlovi: ", + "Fallback captions: ": "Alternativni titlovi: ", + "Show related videos: ": "Prikaži povezana videa: ", + "Show annotations by default: ": "Standardno prikaži napomene: ", + "Visual preferences": "Postavke prikaza", + "Player style: ": "Stil playera: ", + "Dark mode: ": "Tamni modus: ", + "Theme: ": "Tema: ", + "dark": "tamno", + "light": "svijetlo", + "Thin mode: ": "Pojednostavljen prikaz: ", + "Subscription preferences": "Postavke pretplata", + "Show annotations by default for subscribed channels: ": "Standardno prikaži napomene za pretplaćene kanale: ", + "Redirect homepage to feed: ": "Preusmjeri početnu stranicu na feed: ", + "Number of videos shown in feed: ": "Broj prikazanih videa u feedu: ", + "Sort videos by: ": "Razvrstaj videa prema: ", + "published": "objavljeno", + "published - reverse": "objavljeno – obrnuto", + "alphabetically": "abecednim redom", + "alphabetically - reverse": "abecednim redom – obrnuto", + "channel name": "ime kanala", + "channel name - reverse": "ime kanala – obrnuto", + "Only show latest video from channel: ": "Prikaži samo najnovija videa kanala: ", + "Only show latest unwatched video from channel: ": "Prikaži samo najnovija nepogledana videa kanala: ", + "Only show unwatched: ": "Prikaži samo nepogledane: ", + "Only show notifications (if there are any): ": "Prikaži samo obavijesti (ako ih ima): ", + "Enable web notifications": "Aktiviraj web-obavijesti", + "`x` uploaded a video": "`x` je poslao/la video", + "`x` is live": "`x` je uživo", + "Data preferences": "Postavke podataka", + "Clear watch history": "Izbriši povijest gledanja", + "Import/export data": "Uvezi/izvezi podatke", + "Change password": "Promijeni lozinku", + "Manage subscriptions": "Upravljaj pretplatama", + "Manage tokens": "Upravljaj tokenima", + "Watch history": "Povijest gledanja", + "Delete account": "Izbriši račun", + "Administrator preferences": "Postavke administratora", + "Default homepage: ": "Standardna početna stranica: ", + "Feed menu: ": "Izbornik za feedove: ", + "Top enabled: ": "Najbolji aktivirani: ", + "CAPTCHA enabled: ": "Aktivirani CAPTCHA: ", + "Login enabled: ": "Prijava aktivirana: ", + "Registration enabled: ": "Registracija aktivirana: ", + "Report statistics: ": "Izvještaj o statistici: ", + "Save preferences": "Spremi postavke", + "Subscription manager": "Upravljanje pretplatama", + "Token manager": "Upravljanje tokenima", + "Token": "Token", + "`x` subscriptions": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` pretplate.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` pretplate." + }, + "`x` tokens": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` tokena.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` tokena." + }, + "Import/export": "Uvezi/izvezi", + "unsubscribe": "odjavi pretplatu", + "revoke": "opozovi", + "Subscriptions": "Pretplate", + "`x` unseen notifications": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` neviđene obavijesti.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` neviđene obavijesti." + }, + "search": "traži", + "Log out": "Odjavi se", + "Released under the AGPLv3 by Omar Roth.": "Izdano pod licencom AGPLv3, Omar Roth.", + "Source available here.": "Izvor je ovdje dostupan.", + "View JavaScript license information.": "Prikaži informacije o JavaScript licenci.", + "View privacy policy.": "Prikaži politiku privatnosti.", + "Trending": "U trendu", + "Public": "Javno", + "Unlisted": "Nenavedeno", + "Private": "Privatno", + "View all playlists": "Prikaži sve playliste", + "Updated `x` ago": "Aktualizirano prije `x`", + "Delete playlist `x`?": "Izbrisati playlistu `x`?", + "Delete playlist": "Izbriši playlistu", + "Create playlist": "Stvori playlistu", + "Title": "Naslov", + "Playlist privacy": "Privatnost playliste", + "Editing playlist `x`": "Uređivanje playliste `x`", + "Watch on YouTube": "Gledaj na YouTubeu", + "Hide annotations": "Sakrij napomene", + "Show annotations": "Prikaži napomene", + "Genre: ": "Žanr: ", + "License: ": "Licenca: ", + "Family friendly? ": "Pogodan za cijelu obitelj? ", + "Wilson score: ": "Wilson rezultat: ", + "Engagement: ": "Sudjelovanje: ", + "Whitelisted regions: ": "Odobrene regije: ", + "Blacklisted regions: ": "Blokirane regije: ", + "Shared `x`": "Dijeljeno `x`", + "`x` views": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` gledanja.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` gledanja." + }, + "Premieres in `x`": "Premijera za `x`", + "Premieres `x`": "Premijera `x`", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Bok! Izgleda da je JavaScript isključen. Pritisni ovdje za prikaz komentara. Učitavanje će možda trajati malo duže.", + "View YouTube comments": "Prikaži YouTube komentare", + "View more comments on Reddit": "Prikaži još komentara na Redditu", + "View `x` comments": { + "([^.,0-9]|^)1([^.,0-9]|$)": "Prikaži `x` komentara.([^.,0-9]|^)1([^.,0-9]|$)", + "": "Prikaži `x` komentara." + }, + "View Reddit comments": "Prikaži Reddit komentare", + "Hide replies": "Sakrij odgovore", + "Show replies": "Prikaži odgovore", + "Incorrect password": "Neispravna lozinka", + "Quota exceeded, try again in a few hours": "Kvota je prekoračena. Pokušaj ponovo za par sati", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Prijava neuspjela. Provjeri da je dvofaktorska autentifikacija uključena (Authenticator ili SMS).", + "Invalid TFA code": "Neispravan TFA kod", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "Prijava neuspjela. Možda zato što za tvoj račun nije uključena dvofaktorska autentifikacija.", + "Wrong answer": "Krivi odgovor", + "Erroneous CAPTCHA": "Neispravan CAPTCHA", + "CAPTCHA is a required field": "CAPTCHA je obavezno polje", + "User ID is a required field": "Korisnički ID je obavezno polje", + "Password is a required field": "Polje lozinke je obavezno polje", + "Wrong username or password": "Krivo korisničko ime ili lozinka", + "Please sign in using 'Log in with Google'": "Za prijavu koristi „Prijavi se pomoću Googlea”", + "Password cannot be empty": "Polje lozinke ne smije ostati prazno", + "Password cannot be longer than 55 characters": "Lozinka ne može biti duža od 55 znakova", + "Please log in": "Prijavi se", + "Invidious Private Feed for `x`": "Invidious privatni feed za `x`", + "channel:`x`": "kanal:`x`", + "Deleted or invalid channel": "Izbrisan ili neispravan kanal", + "This channel does not exist.": "Ovaj kanal ne postoji.", + "Could not get channel info.": "Neuspjelo dobivanje podataka kanala.", + "Could not fetch comments": "Neuspjelo dohvaćanje komentara", + "View `x` replies": { + "([^.,0-9]|^)1([^.,0-9]|$)": "Prikaži `x` odgovora.([^.,0-9]|^)1([^.,0-9]|$)", + "": "Prikaži `x` odgovora." + }, + "`x` ago": "prije `x`", + "Load more": "Učitaj više", + "`x` points": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` bodova.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` bodova." + }, + "Could not create mix.": "Neuspjelo stvaranje miksa.", + "Empty playlist": "Prazna playlista", + "Not a playlist.": "Nije playlista.", + "Playlist does not exist.": "Playlista ne postoji.", + "Could not pull trending pages.": "Neuspjelo preuzimanje stranica u trendu.", + "Hidden field \"challenge\" is a required field": "Skriveno polje „izazov” je obavezno polje", + "Hidden field \"token\" is a required field": "Skriveno polje „token” je obavezno polje", + "Erroneous challenge": "Neispravan izazov", + "Erroneous token": "Neispravan token", + "No such user": "Takav korisnik ne postoji", + "Token is expired, please try again": "Token je istekao, pokušaj ponovo", + "English": "Engleski", + "English (auto-generated)": "Engleski (automatki generirano)", + "Afrikaans": "Afrikaanski", + "Albanian": "Albanski", + "Amharic": "Amharski", + "Arabic": "Arapski", + "Armenian": "Armenski", + "Azerbaijani": "Azerbajdžanski", + "Bangla": "Bengalski", + "Basque": "Baskijski", + "Belarusian": "Bjeloruski", + "Bosnian": "Bošnjački", + "Bulgarian": "Bugarski", + "Burmese": "Burmanski", + "Catalan": "Katalonski", + "Cebuano": "Cebuano", + "Chinese (Simplified)": "Kineski (pojednostavljeni)", + "Chinese (Traditional)": "Kineski (tradicionalni)", + "Corsican": "Korzikanski", + "Croatian": "Hrvatski", + "Czech": "Češki", + "Danish": "Danski", + "Dutch": "Nizozemski", + "Esperanto": "Esperanto", + "Estonian": "Estonski", + "Filipino": "Filipinski", + "Finnish": "Finski", + "French": "Francuski", + "Galician": "Galicijski", + "Georgian": "Gruzijski", + "German": "Njemački", + "Greek": "Grčki", + "Gujarati": "Gudžaratski", + "Haitian Creole": "Haitjanski kreolski", + "Hausa": "Hauski", + "Hawaiian": "Havajski", + "Hebrew": "Hebrejski", + "Hindi": "Hindski", + "Hmong": "Hmong", + "Hungarian": "Mađarski", + "Icelandic": "Islandski", + "Igbo": "Igboški", + "Indonesian": "Indonezijski", + "Irish": "Irski", + "Italian": "Talijanski", + "Japanese": "Japanski", + "Javanese": "Javanski", + "Kannada": "Kannada", + "Kazakh": "Kazaški", + "Khmer": "Kmerski", + "Korean": "Korejski", + "Kurdish": "Kurdski", + "Kyrgyz": "Kirgiški", + "Lao": "Laoški", + "Latin": "Latinski", + "Latvian": "Latvijski", + "Lithuanian": "Litvanski", + "Luxembourgish": "Luksemburgški", + "Macedonian": "Makedonski", + "Malagasy": "Malagaški", + "Malay": "Malajski", + "Malayalam": "Malajalamski", + "Maltese": "Malteški", + "Maori": "Maorski", + "Marathi": "Marathi", + "Mongolian": "Mongolski", + "Nepali": "Nepalski", + "Norwegian Bokmål": "Norveški Bokmål", + "Nyanja": "Nijanja", + "Pashto": "Paštunski", + "Persian": "Perzijski", + "Polish": "Poljski", + "Portuguese": "Portugalski", + "Punjabi": "Pandžapski", + "Romanian": "Rumunjski", + "Russian": "Ruski", + "Samoan": "Samoanski", + "Scottish Gaelic": "Škotski galski", + "Serbian": "Srpski", + "Shona": "Šona", + "Sindhi": "Sindhi", + "Sinhala": "Singaleški", + "Slovak": "Slovački", + "Slovenian": "Slovenski", + "Somali": "Somalijski", + "Southern Sotho": "Sjeverno samski", + "Spanish": "Španjolski", + "Spanish (Latin America)": "Španjolski (Latinska Amerika)", + "Sundanese": "Sundski", + "Swahili": "Svahili", + "Swedish": "Švedski", + "Tajik": "Tadžički", + "Tamil": "Tamilski", + "Telugu": "Teluški", + "Thai": "Tajlandski", + "Turkish": "Turski", + "Ukrainian": "Ukrajinski", + "Urdu": "Urdski", + "Uzbek": "Uzbečki", + "Vietnamese": "Vijetnamski", + "Welsh": "Velški", + "Western Frisian": "Zapadni frizijski", + "Xhosa": "Xhosa", + "Yiddish": "Jidiš", + "Yoruba": "Jorubški", + "Zulu": "Zulu", + "`x` years": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` g.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` g." + }, + "`x` months": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` mj.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` mj." + }, + "`x` weeks": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` tj.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` tj." + }, + "`x` days": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` dana.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` dana." + }, + "`x` hours": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` h.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` h." + }, + "`x` minutes": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` min.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` min." + }, + "`x` seconds": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` s.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` s." + }, + "Fallback comments: ": "Alternativni komentari: ", + "Popular": "Popularni", + "Top": "Najbolji", + "About": "Informacije", + "Rating: ": "Ocjena: ", + "Language: ": "Jezik: ", + "View as playlist": "Prikaži kao playlistu", + "Default": "Standardno", + "Music": "Glazba", + "Gaming": "Videoigre", + "News": "Vijesti", + "Movies": "Filmovi", + "Download": "Preuzmi", + "Download as: ": "Preuzmi kao: ", + "%A %B %-d, %Y": "%A, %-d. %B %Y.", + "(edited)": "(uređeno)", + "YouTube comment permalink": "Permalink YouTube komentara", + "permalink": "permalink", + "`x` marked it with a ❤": "Označeno sa ❤ od `x`", + "Audio mode": "Audio modus", + "Video mode": "Videomodus", + "Videos": "Videa", + "Playlists": "Playliste", + "Community": "Zajednica", + "Current version: ": "Trenutačna verzija: " +} diff --git a/locales/id.json b/locales/id.json new file mode 100644 index 000000000..217ea1c7a --- /dev/null +++ b/locales/id.json @@ -0,0 +1,387 @@ +{ + "`x` subscribers": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` pelanggan.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` pelanggan." + }, + "`x` videos": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` video.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` video." + }, + "`x` playlists": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` daftar putar.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` daftar putar." + }, + "LIVE": "SIARAN LANGSUNG", + "Shared `x` ago": "Dibagikan`x` lalu", + "Unsubscribe": "Batal Langganan", + "Subscribe": "Langganan", + "View channel on YouTube": "Lihat kanal di YouTube", + "View playlist on YouTube": "Lihat daftar putar di YouTube", + "newest": "terbaru", + "oldest": "terlawas", + "popular": "populer", + "last": "terakhir", + "Next page": "Halaman berikutnya", + "Previous page": "Halaman sebelumnya", + "Clear watch history?": "Bersihkan riwayat tontonan?", + "New password": "Kata sandi baru", + "New passwords must match": "Kata sandi baru harus cocok", + "Cannot change password for Google accounts": "Tidak dapat mengganti kata sandi untuk akun Google", + "Authorize token?": "Otorisasi token?", + "Authorize token for `x`?": "Otorisasi token untuk `x`?", + "Yes": "Ya", + "No": "Tidak", + "Import and Export Data": "Impor dan Ekspor Data", + "Import": "Impor", + "Import Invidious data": "Impor data Invidious", + "Import YouTube subscriptions": "Impor langganan YouTube", + "Import FreeTube subscriptions (.db)": "Impor langganan FreeTube (.db)", + "Import NewPipe subscriptions (.json)": "Impor langganan NewPipe (.json)", + "Import NewPipe data (.zip)": "Impor data NewPipe (.zip)", + "Export": "Ekspor", + "Export subscriptions as OPML": "Ekspor langganan sebagai OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "Ekspor langganan sebagai OPML (untuk NewPipe & FreeTube)", + "Export data as JSON": "Ekspor data sebagai JSON", + "Delete account?": "Hapus akun?", + "History": "Riwayat", + "An alternative front-end to YouTube": "Sebuah alternatif front-end untuk YouTube", + "JavaScript license information": "Informasi lisensi JavaScript", + "source": "sumber", + "Log in": "Masuk", + "Log in/register": "Daftar", + "Log in with Google": "Masuk dengan Google", + "User ID": "ID Pengguna", + "Password": "Kata Sandi", + "Time (h:mm:ss):": "Waktu (j:mm:dd):", + "Text CAPTCHA": "Teks CAPTCHA", + "Image CAPTCHA": "Gambar CAPTCHA", + "Sign In": "Masuk", + "Register": "Daftar", + "E-mail": "Surel", + "Google verification code": "Kode verifikasi Google", + "Preferences": "Preferensi", + "Player preferences": "Preferensi pemutar", + "Always loop: ": "Selalu ulangi: ", + "Autoplay: ": "Putar-Otomatis: ", + "Play next by default: ": "Putar selanjutnya secara default: ", + "Autoplay next video: ": "Otomatis-Putar video berikutnya: ", + "Listen by default: ": "Dengarkan secara default: ", + "Proxy videos: ": "Video Proksi: ", + "Default speed: ": "Kecepatan default: ", + "Preferred video quality: ": "Kualitas video yang disukai: ", + "Player volume: ": "Volume pemutar: ", + "Default comments: ": "Komentar default: ", + "youtube": "youtube", + "reddit": "reddit", + "Default captions: ": "Subtitel default: ", + "Fallback captions: ": "", + "Show related videos: ": "Tampilkan video terkait: ", + "Show annotations by default: ": "Tampilkan anotasi secara default: ", + "Visual preferences": "Preferensi visual", + "Player style: ": "Gaya pemutar: ", + "Dark mode: ": "Mode gelap: ", + "Theme: ": "Tema: ", + "dark": "gelap", + "light": "terang", + "Thin mode: ": "Mode tipis: ", + "Subscription preferences": "Preferensi langganan", + "Show annotations by default for subscribed channels: ": "Tampilkan anotasi secara default untuk kanal langganan: ", + "Redirect homepage to feed: ": "Arahkan kembali laman beranda ke umpan: ", + "Number of videos shown in feed: ": "Jumlah video ditampilkan di umpan: ", + "Sort videos by: ": "Urutkan video berdasarkan: ", + "published": "dipublikasi", + "published - reverse": "dipublikasi - sebaliknya", + "alphabetically": "menurut abjad", + "alphabetically - reverse": "menurut abjad - sebaliknya", + "channel name": "nama kanal", + "channel name - reverse": "nama kanal - sebaliknya", + "Only show latest video from channel: ": "Hanya tampilkan video terbaru dari kanal: ", + "Only show latest unwatched video from channel: ": "Hanya tampilkan video belum ditonton terbaru dari kanal: ", + "Only show unwatched: ": "Hanya tampilkan belum ditonton: ", + "Only show notifications (if there are any): ": "Hanya tampilkan pemberitahuan (jika ada): ", + "Enable web notifications": "Aktifkan pemberitahuan web", + "`x` uploaded a video": "`x` mengunggah video", + "`x` is live": "`x` sedang siaran langsung", + "Data preferences": "Preferensi Data", + "Clear watch history": "Bersihkan riwayat tontonan", + "Import/export data": "Impor/Ekspor data", + "Change password": "Ganti kata sandi", + "Manage subscriptions": "Atur langganan", + "Manage tokens": "Atur token", + "Watch history": "Riwayat tontonan", + "Delete account": "Hapus akun", + "Administrator preferences": "Preferensi administrator", + "Default homepage: ": "Laman beranda default: ", + "Feed menu: ": "Menu umpan: ", + "Top enabled: ": "", + "CAPTCHA enabled: ": "CAPTCHA diaktifkan: ", + "Login enabled: ": "Masuk diaktifkan: ", + "Registration enabled: ": "Registrasi diaktifkan: ", + "Report statistics: ": "Laporan statistik: ", + "Save preferences": "Simpan preferensi", + "Subscription manager": "Pengatur langganan", + "Token manager": "Pengatur token", + "Token": "Token", + "`x` subscriptions": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` langganan.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` langganan." + }, + "`x` tokens": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` token.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` token." + }, + "Import/export": "Impor/ekspor", + "unsubscribe": "batal langganan", + "revoke": "cabut", + "Subscriptions": "Langganan", + "`x` unseen notifications": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` pemberitahuan belum dilihat.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` pemberitahuan belum dilihat." + }, + "search": "cari", + "Log out": "Keluar", + "Released under the AGPLv3 by Omar Roth.": "Dirilis dibawah AGPLv3 oleh Omar Roth.", + "Source available here.": "Sumber tersedia di sini.", + "View JavaScript license information.": "Tampilkan informasi lisensi JavaScript.", + "View privacy policy.": "Lihat kebijakan privasi.", + "Trending": "Sedang tren", + "Public": "Publik", + "Unlisted": "Tidak terdaftar", + "Private": "Pribadi", + "View all playlists": "Lihat semua daftar putar", + "Updated `x` ago": "Diperbarui`x` lalu", + "Delete playlist `x`?": "Hapus daftar putar `x`?", + "Delete playlist": "Hapus daftar putar", + "Create playlist": "Buat daftar putar", + "Title": "Judul", + "Playlist privacy": "Privasi daftar putar", + "Editing playlist `x`": "Menyunting daftar putar `x`", + "Watch on YouTube": "Tonton di YouTube", + "Hide annotations": "Sembunyikan anotasi", + "Show annotations": "Tampilkan anotasi", + "Genre: ": "Genre: ", + "License: ": "Lisensi: ", + "Family friendly? ": "Ramah keluarga? ", + "Wilson score: ": "Skor Wilson: ", + "Engagement: ": "Keterikatan: ", + "Whitelisted regions: ": "Wilayah daftar-putih: ", + "Blacklisted regions: ": "Wilayah daftar-hitam: ", + "Shared `x`": "Berbagi`x`", + "`x` views": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` tampilan.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` tampilan." + }, + "Premieres in `x`": "Tayang dalam `x`", + "Premieres `x`": "Tayang `x`", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hai! Kelihatannya JavaScript kamu dimatikan. Klik di sini untuk melihat komentar, perlu diingat hal ini mungkin membutuhkan waktu sedikit lebih lama untuk dimuat.", + "View YouTube comments": "Lihat komentar YouTube", + "View more comments on Reddit": "Lihat lebih banyak komentar di Reddit", + "View `x` comments": { + "([^.,0-9]|^)1([^.,0-9]|$)": "Lihat`x` komentar.([^.,0-9]|^)1([^.,0-9]|$)", + "": "Lihat`x` komentar." + }, + "View Reddit comments": "Lihat komentar Reddit", + "Hide replies": "Sembunyikan balasan", + "Show replies": "Lihat balasan", + "Incorrect password": "Kata sandi salah", + "Quota exceeded, try again in a few hours": "Kuota penuh, coba lagi dalam beberapa jam", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Tidak dapat masuk, pastikan autentikasi dua-faktor (autentikator atau SMS) sudah nyala.", + "Invalid TFA code": "Kode TFA tidak valid", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "Gagal masuk. Ini mungkin disebabkan autentikasi dua-faktor tidak dinyalakan untuk akun Anda.", + "Wrong answer": "Jawaban salah", + "Erroneous CAPTCHA": "CAPTCHA salah", + "CAPTCHA is a required field": "CAPTCHA perlu diisi", + "User ID is a required field": "ID pengguna perlu diisi", + "Password is a required field": "Kata sandi perlu diisi", + "Wrong username or password": "Nama pengguna atau kata sandi salah", + "Please sign in using 'Log in with Google'": "Harap masuk menggunakan 'Masuk dengan Google'", + "Password cannot be empty": "Kata sandi tidak boleh kosong", + "Password cannot be longer than 55 characters": "Kata sandi tidak boleh lebih dari 55 karakter", + "Please log in": "Harap masuk", + "Invidious Private Feed for `x`": "Umpan pribadi Invidious untuk`x`", + "channel:`x`": "kanal:`x`", + "Deleted or invalid channel": "Kanal terhapus atau invalid", + "This channel does not exist.": "Kanal ini tidak ada.", + "Could not get channel info.": "Tidak bisa mendapatkan info kanal.", + "Could not fetch comments": "Tidak dapat memuat komentar", + "View `x` replies": { + "([^.,0-9]|^)1([^.,0-9]|$)": "Lihat`x` balasan.([^.,0-9]|^)1([^.,0-9]|$)", + "": "Lihat `x` balasan." + }, + "`x` ago": "`x` lalu", + "Load more": "Muat lebih banyak", + "`x` points": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Could not create mix.": "", + "Empty playlist": "Daftar putar kosong", + "Not a playlist.": "Bukan daftar putar.", + "Playlist does not exist.": "Daftar putar tidak ada.", + "Could not pull trending pages.": "Tidak bisa mendapatkan laman tren.", + "Hidden field \"challenge\" is a required field": "", + "Hidden field \"token\" is a required field": "", + "Erroneous challenge": "", + "Erroneous token": "", + "No such user": "Tidak ada pengguna demikian", + "Token is expired, please try again": "Token kadaluwarsa, harap coba lagi", + "English": "Bahasa Inggris", + "English (auto-generated)": "Bahasa Inggris (dibuat-otomatis)", + "Afrikaans": "Bahasa Afrika", + "Albanian": "Bahasa Albania", + "Amharic": "Bahasa Amharik", + "Arabic": "Bahasa arab", + "Armenian": "Bahasa Armenia", + "Azerbaijani": "", + "Bangla": "", + "Basque": "", + "Belarusian": "", + "Bosnian": "Bahasa Bosnia", + "Bulgarian": "Bahasa Bulgaria", + "Burmese": "Bahasa Birma", + "Catalan": "", + "Cebuano": "", + "Chinese (Simplified)": "", + "Chinese (Traditional)": "", + "Corsican": "", + "Croatian": "Bahasa Kroasia", + "Czech": "Bahasa Ceko", + "Danish": "", + "Dutch": "Bahasa Belanda", + "Esperanto": "", + "Estonian": "", + "Filipino": "", + "Finnish": "", + "French": "", + "Galician": "", + "Georgian": "", + "German": "", + "Greek": "Bahasa Yunani", + "Gujarati": "", + "Haitian Creole": "", + "Hausa": "", + "Hawaiian": "", + "Hebrew": "", + "Hindi": "", + "Hmong": "", + "Hungarian": "", + "Icelandic": "", + "Igbo": "", + "Indonesian": "Bahasa Indonesia", + "Irish": "", + "Italian": "", + "Japanese": "Bahasa Jepang", + "Javanese": "Bahasa Jawa", + "Kannada": "", + "Kazakh": "", + "Khmer": "", + "Korean": "Bahasa Korea", + "Kurdish": "", + "Kyrgyz": "", + "Lao": "", + "Latin": "", + "Latvian": "", + "Lithuanian": "", + "Luxembourgish": "", + "Macedonian": "", + "Malagasy": "", + "Malay": "Bahasa Melayu", + "Malayalam": "", + "Maltese": "", + "Maori": "", + "Marathi": "", + "Mongolian": "", + "Nepali": "", + "Norwegian Bokmål": "", + "Nyanja": "", + "Pashto": "", + "Persian": "", + "Polish": "", + "Portuguese": "", + "Punjabi": "", + "Romanian": "", + "Russian": "", + "Samoan": "", + "Scottish Gaelic": "", + "Serbian": "", + "Shona": "", + "Sindhi": "", + "Sinhala": "", + "Slovak": "", + "Slovenian": "", + "Somali": "", + "Southern Sotho": "", + "Spanish": "", + "Spanish (Latin America)": "", + "Sundanese": "Bahasa Sunda", + "Swahili": "", + "Swedish": "", + "Tajik": "", + "Tamil": "", + "Telugu": "", + "Thai": "Bahasa Thailand", + "Turkish": "", + "Ukrainian": "", + "Urdu": "", + "Uzbek": "", + "Vietnamese": "Bahasa Vietnam", + "Welsh": "", + "Western Frisian": "", + "Xhosa": "", + "Yiddish": "", + "Yoruba": "", + "Zulu": "", + "`x` years": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` tahun.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` tahun." + }, + "`x` months": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` bulan.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` bulan." + }, + "`x` weeks": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` pekan.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` pekan." + }, + "`x` days": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` hari.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` hari." + }, + "`x` hours": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` jam.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` jam." + }, + "`x` minutes": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` menit.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` menit." + }, + "`x` seconds": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` detik.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` detik." + }, + "Fallback comments: ": "", + "Popular": "Populer", + "Top": "", + "About": "Ihwal", + "Rating: ": "Peringkat: ", + "Language: ": "Bahasa: ", + "View as playlist": "Tampilkan sebagai daftar putar", + "Default": "Asali", + "Music": "Musik", + "Gaming": "Gaming", + "News": "Berita", + "Movies": "Film", + "Download": "Unduh", + "Download as: ": "Unduh sebagai: ", + "%A %B %-d, %Y": "", + "(edited)": "(disunting)", + "YouTube comment permalink": "", + "permalink": "", + "`x` marked it with a ❤": "`x` telah ditandai dengan ❤", + "Audio mode": "Mode audio", + "Video mode": "Mode video", + "Videos": "Video", + "Playlists": "Daftar putar", + "Community": "Komunitas", + "Current version: ": "Versi saat ini: " +} diff --git a/locales/is.json b/locales/is.json index 4cd150760..a2943b88f 100644 --- a/locales/is.json +++ b/locales/is.json @@ -1,7 +1,7 @@ { - "`x` subscribers": "", - "`x` videos": "", - "`x` playlists": "", + "`x` subscribers": "`x`áskrifendur", + "`x` videos": "`x` myndbönd", + "`x` playlists": "`x` spilunarlistar", "`x` subscribers.": "`x` áskrifandar.", "`x` videos.": "`x` myndbönd.", "LIVE": "BEINT", @@ -71,11 +71,11 @@ "Show related videos: ": "Sýna tengd myndbönd? ", "Show annotations by default: ": "Á að sýna glósur sjálfgefið? ", "Visual preferences": "Sjónrænar stillingar", - "Player style: ": "", + "Player style: ": "Spilara stíl: ", "Dark mode: ": "Myrkur ham: ", - "Theme: ": "", - "dark": "", - "light": "", + "Theme: ": "Þema: ", + "dark": "dimmt", + "light": "ljóst", "Thin mode: ": "Þunnt ham: ", "Subscription preferences": "Áskriftarstillingar", "Show annotations by default for subscribed channels: ": "Á að sýna glósur sjálfgefið fyrir áskriftarrásir? ", @@ -113,13 +113,13 @@ "Report statistics: ": "Skrá talnagögn? ", "Save preferences": "Vista stillingar", "Subscription manager": "Áskriftarstjóri", - "`x` subscriptions": "", - "`x` tokens": "", + "`x` subscriptions": "`x` áskrifendur", + "`x` tokens": "`x` tákn", "Token manager": "Táknstjóri", "Token": "Tákn", "`x` subscriptions.": "`x` áskriftir.", "`x` tokens.": "`x` tákn.", - "`x` unseen notifications": "", + "`x` unseen notifications": "`x` óséðar tilkynningar", "Import/export": "Flytja inn/út", "unsubscribe": "afskrá", "revoke": "afturkalla", @@ -132,24 +132,24 @@ "View JavaScript license information.": "Skoða JavaScript leyfisupplýsingar.", "View privacy policy.": "Skoða meðferð persónuupplýsinga.", "Trending": "Vinsælt", - "Public": "", + "Public": "Opinbert", "Unlisted": "Óskráð", - "Private": "", - "View all playlists": "", - "Updated `x` ago": "", - "Delete playlist `x`?": "", - "Delete playlist": "", - "Create playlist": "", - "Title": "", - "Playlist privacy": "", - "Editing playlist `x`": "", + "Private": "Einka", + "View all playlists": "Skoða alla spilunarlista", + "Updated `x` ago": "Uppfært `x` síðann", + "Delete playlist `x`?": "Eiða spilunarlista `x`?", + "Delete playlist": "Eiða spilunarlista", + "Create playlist": "Búa til spilunarlista", + "Title": "Titill", + "Playlist privacy": "Spilunarlista opinberri", + "Editing playlist `x`": "Að breyta spilunarlista `x`", "Watch on YouTube": "Horfa á YouTube", "Hide annotations": "Fela glósur", "Show annotations": "Sýna glósur", "Genre: ": "Tegund: ", "License: ": "Notkunarleyfi: ", "Family friendly? ": "Fjölskylduvænt? ", - "`x` views": "", + "`x` views": "`x` áhorf", "Wilson score: ": "Wilson stig: ", "Engagement: ": "Þátttöku: ", "Whitelisted regions: ": "Svæði á hvítum lista: ", @@ -180,10 +180,10 @@ "Password cannot be empty": "Lykilorð má ekki vera autt", "Password cannot be longer than 55 characters": "Lykilorð má ekki vera lengra en 55 stafir", "Please log in": "Vinsamlegast skráðu þig inn", - "View `x` replies": "", + "View `x` replies": "Skoða `x` svör", "Invidious Private Feed for `x`": "Invidious Persónulegur Straumur fyrir `x`", "channel:`x`": "rás:`x`", - "`x` points": "", + "`x` points": "`x` stig", "Deleted or invalid channel": "Eytt eða ógild rás", "This channel does not exist.": "Þessi rás er ekki til.", "Could not get channel info.": "Ekki tókst að fá rásarupplýsingar.", @@ -301,13 +301,13 @@ "Turkish": "Tyrkneska", "Ukrainian": "Úkraníska", "Urdu": "Úrdú", - "`x` years": "", - "`x` months": "", - "`x` weeks": "", - "`x` days": "", - "`x` hours": "", - "`x` minutes": "", - "`x` seconds": "", + "`x` years": "`x` ár", + "`x` months": "`x` mánuði", + "`x` weeks": "`x` vikur", + "`x` days": "`x` daga", + "`x` hours": "`x` klukkustundir", + "`x` minutes": "`x` mínútur", + "`x` seconds": "`x` sekúndur", "Uzbek": "Úsbekíska", "Vietnamese": "Víetnamska", "Welsh": "Velska", @@ -325,13 +325,13 @@ "`x` seconds.": "`x` sekúndur.", "Fallback comments: ": "Vara ummæli: ", "Popular": "Vinsælt", - "permalink": "", + "permalink": "Varanlegur tengill", "Top": "Topp", "About": "Um", "Rating: ": "Einkunn: ", "Language: ": "Tungumál: ", "View as playlist": "Skoða sem spilunarlista", - "Community": "", + "Community": "Samfélag", "Default": "Sjálfgefið", "Music": "Tónlist", "Gaming": "Tólvuleikja", @@ -348,4 +348,4 @@ "Videos": "Myndbönd", "Playlists": "Spilunarlistar", "Current version: ": "Núverandi útgáfa: " -} \ No newline at end of file +} diff --git a/locales/it.json b/locales/it.json index 2e993c812..789bdd1ab 100644 --- a/locales/it.json +++ b/locales/it.json @@ -1,12 +1,8 @@ { - "`x` subscribers.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` iscritto", - "": "`x` iscritti." - }, - "`x` videos.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` video", - "": "`x` video." - }, + "`x` subscribers..([^.,0-9]|^)1([^.,0-9]|$)": "`x` iscritto", + "`x` subscribers..": "`x` iscritti.", + "`x` videos..([^.,0-9]|^)1([^.,0-9]|$)": "`x` video", + "`x` videos..": "`x` video.", "`x` playlists": "`x` playlist", "LIVE": "IN DIRETTA", "Shared `x` ago": "Condiviso `x` fa", @@ -54,7 +50,7 @@ "Image CAPTCHA": "Immagine CAPTCHA", "Sign In": "Accedi", "Register": "Registrati", - "E-mail": "Email", + "E-mail": "E-mail", "Google verification code": "Codice di verifica Google", "Preferences": "Preferenze", "Player preferences": "Preferenze del riproduttore", @@ -119,22 +115,16 @@ "Subscription manager": "Gestione delle iscrizioni", "Token manager": "Gestione dei gettoni", "Token": "Gettone", - "`x` subscriptions.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` iscrizione", - "": "`x` iscrizioni." - }, - "`x` tokens.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` gettone", - "": "`x` gettoni." - }, + "`x` subscriptions..([^.,0-9]|^)1([^.,0-9]|$)": "`x` iscrizione", + "`x` subscriptions..": "`x` iscrizioni.", + "`x` tokens..([^.,0-9]|^)1([^.,0-9]|$)": "`x` gettone", + "`x` tokens..": "`x` gettoni.", "Import/export": "Importa/esporta", "unsubscribe": "disiscriviti", "revoke": "revoca", "Subscriptions": "Iscrizioni", - "`x` unseen notifications.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` notifica non visualizzata", - "": "`x` notifiche non visualizzate." - }, + "`x` unseen notifications..([^.,0-9]|^)1([^.,0-9]|$)": "`x` notifica non visualizzata", + "`x` unseen notifications..": "`x` notifiche non visualizzate.", "search": "Cerca", "Log out": "Esci", "Released under the AGPLv3 by Omar Roth.": "Pubblicato con licenza AGPLv3 da Omar Roth.", @@ -164,10 +154,8 @@ "Whitelisted regions: ": "Regioni in lista bianca: ", "Blacklisted regions: ": "Regioni in lista nera: ", "Shared `x`": "Condiviso `x`", - "`x` views.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` visualizzazione", - "": "`x` visualizzazioni." - }, + "`x` views..([^.,0-9]|^)1([^.,0-9]|$)": "`x` visualizzazione", + "`x` views..": "`x` visualizzazioni.", "Premieres in `x`": "In anteprima in `x`", "Premieres `x`": "In anteprima `x`", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Ciao! Sembra che tu abbia disattivato JavaScript. Clicca qui per visualizzare i commenti. Considera che potrebbe volerci più tempo.", @@ -188,7 +176,7 @@ "User ID is a required field": "L'ID utente è obbligatorio", "Password is a required field": "La password è un campo obbligatorio", "Wrong username or password": "Nome utente o password errati", - "Please sign in using 'Log in with Google'": "Per favore accedi con \"Entra con Google\"", + "Please sign in using 'Log in with Google'": "Per favore accedi con «Entra con Google»", "Password cannot be empty": "La password non può essere vuota", "Password cannot be longer than 55 characters": "La password non può contenere più di 55 caratteri", "Please log in": "Per favore, accedi", @@ -198,24 +186,20 @@ "This channel does not exist.": "Questo canale non esiste.", "Could not get channel info.": "Impossibile ottenere le informazioni del canale.", "Could not fetch comments": "Impossibile recuperare i commenti", - "View `x` replies.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "Visualizza `x` risposta", - "": "Visualizza `x` risposte." - }, + "View `x` replies..([^.,0-9]|^)1([^.,0-9]|$)": "Visualizza `x` risposta", + "View `x` replies..": "Visualizza `x` risposte.", "`x` ago": "`x` fa", "Load more": "Carica altro", - "`x` points.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` punto", - "": "`x` punti." - }, + "`x` points..([^.,0-9]|^)1([^.,0-9]|$)": "`x` punto", + "`x` points..": "`x` punti.", "Could not create mix.": "Impossibile creare il mix.", "Empty playlist": "Playlist vuota", "Not a playlist.": "Non è una playlist.", "Playlist does not exist.": "La playlist non esiste.", "Could not pull trending pages.": "Impossibile recuperare le tendenze.", "Hidden field \"challenge\" is a required field": "Il campo nascosto \"challenge\" è obbligatorio", - "Hidden field \"token\" is a required field": "Il campo nascosto \"token\" è obbligatorio", - "Erroneous challenge": "Campo \"challenge\" non valido", + "Hidden field \"token\" is a required field": "Il campo nascosto «token» è obbligatorio", + "Erroneous challenge": "Campo «challenge» non valido", "Erroneous token": "Campo \"token\" non valido", "No such user": "Utente non valido", "Token is expired, please try again": "Gettone scaduto, riprova", @@ -288,7 +272,7 @@ "Nepali": "Nepalese", "Norwegian Bokmål": "Norvegese", "Nyanja": "Nyanja", - "Pashto": "Lingua pashtu", + "Pashto": "Pashtu", "Persian": "Persiano", "Polish": "Polacco", "Portuguese": "Portoghese", @@ -325,34 +309,20 @@ "Yiddish": "Yiddish", "Yoruba": "Yoruba", "Zulu": "Zulu", - "`x` years.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` anno", - "": "`x` anni." - }, - "`x` months.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` mese", - "": "`x` mesi." - }, - "`x` weeks.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` settimana", - "": "`x` settimane." - }, - "`x` days.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` giorno", - "": "`x` giorni." - }, - "`x` hours.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` ora", - "": "`x` ore." - }, - "`x` minutes.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` minuto", - "": "`x` minuti." - }, - "`x` seconds.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` secondo", - "": "`x` secondi." - }, + "`x` years..([^.,0-9]|^)1([^.,0-9]|$)": "`x` anno", + "`x` years..": "`x` anni.", + "`x` months..([^.,0-9]|^)1([^.,0-9]|$)": "`x` mese", + "`x` months..": "`x` mesi.", + "`x` weeks..([^.,0-9]|^)1([^.,0-9]|$)": "`x` settimana", + "`x` weeks..": "`x` settimane.", + "`x` days..([^.,0-9]|^)1([^.,0-9]|$)": "`x` giorno", + "`x` days..": "`x` giorni.", + "`x` hours..([^.,0-9]|^)1([^.,0-9]|$)": "`x` ora", + "`x` hours..": "`x` ore.", + "`x` minutes..([^.,0-9]|^)1([^.,0-9]|$)": "`x` minuto", + "`x` minutes..": "`x` minuti.", + "`x` seconds..([^.,0-9]|^)1([^.,0-9]|$)": "`x` secondo", + "`x` seconds..": "`x` secondi.", "Fallback comments: ": "Commenti alternativi: ", "Popular": "Popolare", "Top": "Top", @@ -378,4 +348,4 @@ "Playlists": "Playlist", "Community": "Comunità", "Current version: ": "Versione attuale: " -} \ No newline at end of file +} diff --git a/locales/ja.json b/locales/ja.json index e9ca0e624..0c429d6bd 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -201,7 +201,7 @@ "Invidious Private Feed for `x`": "`x` の Invidious プライベートフィード", "channel:`x`": "チャンネル:`x`", "Deleted or invalid channel": "削除済みまたは無効なチャンネルです", - "This channel does not exist.": "このチャンネルは存在していません", + "This channel does not exist.": "このチャンネルは存在しません。", "Could not get channel info.": "チャンネル情報を取得できませんでした。", "Could not fetch comments": "コメントを取得できませんでした", "View `x` replies": { @@ -217,7 +217,7 @@ "Could not create mix.": "ミックスを作成できませんでした。", "Empty playlist": "空の再生リスト", "Not a playlist.": "再生リストではありません。", - "Playlist does not exist.": "再生リストが存在していません・", + "Playlist does not exist.": "再生リストが存在しません。", "Could not pull trending pages.": "急上昇ページを取得できませんでした。", "Hidden field \"challenge\" is a required field": "非表示項目 \"challenge\" は必須項目です", "Hidden field \"token\" is a required field": "非表示項目 \"token\" は必須項目です", @@ -384,4 +384,4 @@ "Playlists": "プレイリスト", "Community": "コミュニティ", "Current version: ": "現在のバージョン: " -} \ No newline at end of file +} diff --git a/locales/nb-NO.json b/locales/nb-NO.json index ff40e27b7..6bf5107bc 100644 --- a/locales/nb-NO.json +++ b/locales/nb-NO.json @@ -132,12 +132,12 @@ "Private": "Privat", "View all playlists": "Vis alle spillelister", "Updated `x` ago": "Oppdatert `x` siden", - "Delete playlist `x`?": "Slett spillelisten `x`?", + "Delete playlist `x`?": "Slett spilleliste «x»?", "Delete playlist": "Slett spilleliste", "Create playlist": "Opprett spilleliste", "Title": "Tittel", "Playlist privacy": "Vern av spilleliste", - "Editing playlist `x`": "Redigerer spillelisten `x`", + "Editing playlist `x`": "Endre spilleliste «x»", "Watch on YouTube": "Vis video på YouTube", "Hide annotations": "Skjul merknader", "Show annotations": "Vis merknader", @@ -174,7 +174,7 @@ "Password cannot be empty": "Passordet kan ikke være tomt", "Password cannot be longer than 55 characters": "Passordet kan ikke være lengre enn 55 tegn", "Please log in": "Logg inn", - "Invidious Private Feed for `x`": "Ugyldig privat flyt for `x`", + "Invidious Private Feed for `x`": "Invidious personlige flyt for `x`", "channel:`x`": "kanal `x`", "Deleted or invalid channel": "Slettet eller ugyldig kanal", "This channel does not exist.": "Denne kanalen finnes ikke.", @@ -203,18 +203,18 @@ "Arabic": "Arabisk", "Armenian": "Armensk", "Azerbaijani": "Aserbajdsjansk", - "Bangla": "", - "Basque": "", + "Bangla": "Bengali", + "Basque": "Baskisk", "Belarusian": "Hviterussisk", "Bosnian": "Bosnisk", "Bulgarian": "Bulgarsk", "Burmese": "Burmesisk", "Catalan": "Katalansk", - "Cebuano": "", - "Chinese (Simplified)": "", - "Chinese (Traditional)": "", - "Corsican": "", - "Croatian": "", + "Cebuano": "Sugboanon", + "Chinese (Simplified)": "Forenklet kinesisk", + "Chinese (Traditional)": "Tradisjonell kinesisk", + "Corsican": "Korsikansk", + "Croatian": "Kroatisk", "Czech": "Tsjekkisk", "Danish": "Dansk", "Dutch": "Nederlandsk", @@ -223,84 +223,84 @@ "Filipino": "Filippinsk", "Finnish": "Finsk", "French": "Fransk", - "Galician": "", - "Georgian": "", + "Galician": "Galisisk", + "Georgian": "Georgisk", "German": "Tysk", "Greek": "Gresk", - "Gujarati": "", - "Haitian Creole": "", - "Hausa": "", - "Hawaiian": "", - "Hebrew": "", - "Hindi": "", - "Hmong": "", + "Gujarati": "Gujarati", + "Haitian Creole": "Haitisk kreol", + "Hausa": "Hausa", + "Hawaiian": "Hawaiisk", + "Hebrew": "Hebraisk", + "Hindi": "Hindi", + "Hmong": "Hmong", "Hungarian": "Ungarsk", "Icelandic": "Islandsk", - "Igbo": "", + "Igbo": "Ibo", "Indonesian": "Indonesisk", "Irish": "Irsk", "Italian": "Italiensk", "Japanese": "Japansk", - "Javanese": "", - "Kannada": "", - "Kazakh": "", - "Khmer": "", - "Korean": "", - "Kurdish": "", - "Kyrgyz": "", - "Lao": "", - "Latin": "", - "Latvian": "", - "Lithuanian": "", - "Luxembourgish": "", - "Macedonian": "", - "Malagasy": "", - "Malay": "", - "Malayalam": "", - "Maltese": "", - "Maori": "", - "Marathi": "", - "Mongolian": "", - "Nepali": "", + "Javanese": "Javanesisk", + "Kannada": "Kanaresisk", + "Kazakh": "Kasakhisk", + "Khmer": "Khmer", + "Korean": "Koreansk", + "Kurdish": "Kurdisk", + "Kyrgyz": "Kirgisisk", + "Lao": "Laotisk", + "Latin": "Latin", + "Latvian": "Latvisk", + "Lithuanian": "Litauisk", + "Luxembourgish": "Luxemburgsk", + "Macedonian": "Makedonsk", + "Malagasy": "Madagassisk", + "Malay": "Malayisk", + "Malayalam": "Malayalam", + "Maltese": "Maltesisk", + "Maori": "Maorisk", + "Marathi": "Marathi", + "Mongolian": "Mongolsk", + "Nepali": "Gurkhali", "Norwegian Bokmål": "Norsk bokmål", - "Nyanja": "", - "Pashto": "", - "Persian": "", - "Polish": "", - "Portuguese": "", - "Punjabi": "", - "Romanian": "", + "Nyanja": "Nyanja", + "Pashto": "Pukhto", + "Persian": "Persisk", + "Polish": "Polsk", + "Portuguese": "Portugisisk", + "Punjabi": "Panjabi", + "Romanian": "Rumensk", "Russian": "Russisk", - "Samoan": "", - "Scottish Gaelic": "", + "Samoan": "Samoansk", + "Scottish Gaelic": "Skotsk-gælisk", "Serbian": "Serbisk", - "Shona": "", - "Sindhi": "", - "Sinhala": "", + "Shona": "Shona", + "Sindhi": "Sindhī", + "Sinhala": "Singalesisk", "Slovak": "Slovakisk", "Slovenian": "Slovensk", "Somali": "Somali", - "Southern Sotho": "", + "Southern Sotho": "Sørsotho", "Spanish": "Spansk", - "Spanish (Latin America)": "", - "Sundanese": "", - "Swahili": "", + "Spanish (Latin America)": "Spansk (Latin-Amerika)", + "Sundanese": "Sundanesisk", + "Swahili": "Kiswahili", "Swedish": "Svensk", - "Tajik": "", - "Tamil": "", - "Telugu": "", - "Thai": "", + "Tajik": "Tadsjikisk", + "Tamil": "Tamil", + "Telugu": "Telugu", + "Thai": "Thai", "Turkish": "Tyrkisk", "Ukrainian": "Ukrainsk", - "Urdu": "", - "Uzbek": "", + "Urdu": "Lashkari", + "Uzbek": "Usbekisk", "Vietnamese": "Vietnamesisk", - "Welsh": "", - "Western Frisian": "", - "Xhosa": "", - "Yiddish": "", - "Yoruba": "", - "Zulu": "", + "Welsh": "Velsk", + "Western Frisian": "Vestfrisisk", + "Xhosa": "Xhosa", + "Yiddish": "Jiddisk", + "Yoruba": "Joruba", + "Zulu": "Zulu", "`x` years": "`x` år", "`x` months": "`x` måneder", "`x` weeks": "`x` uker", @@ -322,7 +322,7 @@ "Movies": "Filmer", "Download": "Last ned", "Download as: ": "Last ned som: ", - "%A %B %-d, %Y": "", + "%A %B %-d, %Y": "%A %B %-d, %Y", "(edited)": "(redigert)", "YouTube comment permalink": "Permanent YouTube-lenke til innholdet", "permalink": "permanent lenke", @@ -332,5 +332,5 @@ "Videos": "Videoer", "Playlists": "Spillelister", "Community": "Gemenskap", - "Current version: ": "Nåværende versjon: " -} \ No newline at end of file + "Current version: ": "Gjeldende versjon: " +} diff --git a/locales/nl.json b/locales/nl.json index 29af954a9..de2a2bb7e 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -69,7 +69,7 @@ "Show related videos: ": "Gerelateerde video's tonen? ", "Show annotations by default: ": "Standaard annotaties tonen? ", "Visual preferences": "Visuele instellingen", - "Player style: ": "Speler vormgeving", + "Player style: ": "Speler vormgeving ", "Dark mode: ": "Donkere modus: ", "Theme: ": "Thema: ", "dark": "donker", @@ -103,7 +103,7 @@ "Delete account": "Account verwijderen", "Administrator preferences": "Beheerdersinstellingen", "Default homepage: ": "Standaard startpagina: ", - "Feed menu: ": "Feedmenu:", + "Feed menu: ": "Feedmenu: ", "Top enabled: ": "Bovenkant inschakelen? ", "CAPTCHA enabled: ": "CAPTCHA gebruiken? ", "Login enabled: ": "Inloggen toestaan? ", @@ -125,7 +125,7 @@ "Released under the AGPLv3 by Omar Roth.": "Uitgebracht onder de AGPLv3-licentie, door Omar Roth.", "Source available here.": "De broncode is hier beschikbaar.", "View JavaScript license information.": "JavaScript-licentieinformatie tonen.", - "View privacy policy.": "Privacybeleid tonen", + "View privacy policy.": "Privacybeleid tonen.", "Trending": "Uitgelicht", "Public": "Publiek", "Unlisted": "Verborgen", @@ -151,7 +151,7 @@ "Shared `x`": "`x` gedeeld", "`x` views": "`x` weergaven", "Premieres in `x`": "Verschijnt over `x`", - "Premieres `x`": "", + "Premieres `x`": "Verschijnt op `x`", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hoi! Het lijkt erop dat je JavaScript hebt uitgeschakeld. Klik hier om de reacties te bekijken. Let op: het laden duurt wat langer.", "View YouTube comments": "YouTube-reacties tonen", "View more comments on Reddit": "Meer reacties bekijken op Reddit", @@ -308,16 +308,16 @@ "`x` hours": "`x` uur", "`x` minutes": "`x` minuten", "`x` seconds": "`x` seconden", - "Fallback comments: ": "Terugvallen op", + "Fallback comments: ": "Terugvallen op ", "Popular": "Populair", "Top": "Top", "About": "Over", - "Rating: ": "Waardering", - "Language: ": "Taal", + "Rating: ": "Waardering: ", + "Language: ": "Taal: ", "View as playlist": "Tonen als afspeellijst", "Default": "Standaard", "Music": "Muziek", - "Gaming": "Gaming", + "Gaming": "Gamen", "News": "Nieuws", "Movies": "Films", "Download": "Downloaden", @@ -325,7 +325,7 @@ "%A %B %-d, %Y": "%A %B %-d, %Y", "(edited)": "(bewerkt)", "YouTube comment permalink": "Link naar YouTube-reactie", - "permalink": "", + "permalink": "permalink", "`x` marked it with a ❤": "`x` heeft dit gemarkeerd met ❤", "Audio mode": "Audiomodus", "Video mode": "Videomodus", @@ -334,4 +334,4 @@ "Community": "Gemeenschap", "Current version: ": "Huidige versie: ", "Download is disabled.": "Downloaden is uitgeschakeld." -} \ No newline at end of file +} diff --git a/locales/pl.json b/locales/pl.json index 32ff05301..66b8f4b0c 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -48,7 +48,7 @@ "Image CAPTCHA": "Obraz CAPTCHA", "Sign In": "Zaloguj się", "Register": "Zarejestruj się", - "E-mail": "Email", + "E-mail": "E-mail", "Google verification code": "Kod weryfikacyjny Google", "Preferences": "Preferencje", "Player preferences": "Ustawienia odtwarzacza", @@ -322,7 +322,7 @@ "Movies": "Filmy", "Download": "Pobierz", "Download as: ": "Pobierz jako: ", - "%A %B %-d, %Y": "", + "%A %B %-d, %Y": "%A, %-d %B %Y", "(edited)": "(edytowany)", "YouTube comment permalink": "Odnośnik bezpośredni do komentarza na YouTube", "permalink": "bezpośredni odnośnik", @@ -333,4 +333,4 @@ "Playlists": "Playlisty", "Community": "Społeczność", "Current version: ": "Aktualna wersja: " -} \ No newline at end of file +} diff --git a/locales/pt-BR.json b/locales/pt-BR.json index 9dd237c64..cf73abd86 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -1,10 +1,10 @@ { "`x` subscribers": "`x` inscritos", - "`x` videos": "`x` videos", - "`x` playlists": "`x` lista de reprodução", + "`x` videos": "`x` vídeos", + "`x` playlists": "`x` listas de reprodução", "LIVE": "AO VIVO", "Shared `x` ago": "Compartilhado `x` atrás", - "Unsubscribe": "Desinscrever-se", + "Unsubscribe": "Cancelar inscrição", "Subscribe": "Inscrever-se", "View channel on YouTube": "Ver canal no YouTube", "View playlist on YouTube": "Ver lista de reprodução no YouTube", @@ -17,14 +17,14 @@ "Clear watch history?": "Limpar histórico de reprodução?", "New password": "Nova senha", "New passwords must match": "Nova senha deve ser igual", - "Cannot change password for Google accounts": "Não é possível alterar sua senha da conta Google", + "Cannot change password for Google accounts": "Não é possível alterar sua senha de contas do Google", "Authorize token?": "Autorizar o token?", "Authorize token for `x`?": "Autorizar o token para `x`?", "Yes": "Sim", "No": "Não", "Import and Export Data": "Importar e Exportar Dados", "Import": "Importar", - "Import Invidious data": "Importar datos do Invidious", + "Import Invidious data": "Importar dados do Invidious", "Import YouTube subscriptions": "Importar inscrições do YouTube", "Import FreeTube subscriptions (.db)": "Importar inscrições do FreeTube (.db)", "Import NewPipe subscriptions (.json)": "Importar inscrições do NewPipe (.json)", @@ -33,11 +33,11 @@ "Export subscriptions as OPML": "Exportar inscrições como OPML", "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar inscrições como OPML (para NewPipe e FreeTube)", "Export data as JSON": "Exportar dados como JSON", - "Delete account?": "Deletar conta?", + "Delete account?": "Excluir conta?", "History": "Histórico", "An alternative front-end to YouTube": "Uma interface alternativa para o YouTube", "JavaScript license information": "Informação de licença do JavaScript", - "source": "código fonte", + "source": "código-fonte", "Log in": "Entrar", "Log in/register": "Entrar/Registrar", "Log in with Google": "Entrar com conta Google", @@ -45,7 +45,7 @@ "Password": "Senha", "Time (h:mm:ss):": "Hora (h:mm:ss):", "Text CAPTCHA": "CAPTCHA em texto", - "Image CAPTCHA": "CAPTCHA em imagen", + "Image CAPTCHA": "CAPTCHA em imagem", "Sign In": "Entrar", "Register": "Registrar", "E-mail": "E-mail", @@ -55,43 +55,43 @@ "Always loop: ": "Repetir sempre: ", "Autoplay: ": "Reprodução automática: ", "Play next by default: ": "Sempre reproduzir próximo: ", - "Autoplay next video: ": "Reproduzir próximo video automaticamente: ", - "Listen by default: ": "Sempre ativar som: ", - "Proxy videos: ": "Usar proxy nos videos: ", - "Default speed: ": "Velocidade preferida: ", - "Preferred video quality: ": "Qualidade de video preferida: ", + "Autoplay next video: ": "Reproduzir próximo vídeo automaticamente: ", + "Listen by default: ": "Apenas áudio por padrão: ", + "Proxy videos: ": "Usar proxy nos vídeos: ", + "Default speed: ": "Velocidade padrão: ", + "Preferred video quality: ": "Qualidade de vídeo preferida: ", "Player volume: ": "Volume de reprodução: ", "Default comments: ": "Preferência de comentários: ", "youtube": "youtube", "reddit": "reddit", "Default captions: ": "Preferência de legendas: ", "Fallback captions: ": "Legendas alternativas: ", - "Show related videos: ": "Ver videos relacionados: ", + "Show related videos: ": "Mostrar vídeos relacionados: ", "Show annotations by default: ": "Sempre mostrar anotações: ", "Visual preferences": "Preferências visuais", - "Player style: ": "Estilo do reprodutor", + "Player style: ": "Estilo do tocador: ", "Dark mode: ": "Modo escuro: ", - "Theme: ": "Tema", + "Theme: ": "Tema: ", "dark": "escuro", "light": "claro", "Thin mode: ": "Modo compacto: ", "Subscription preferences": "Preferências de inscrições", - "Show annotations by default for subscribed channels: ": "Sempre mostrar anotações nos videos de canais inscritos ", + "Show annotations by default for subscribed channels: ": "Sempre mostrar anotações dos vídeos de canais inscritos: ", "Redirect homepage to feed: ": "Redirecionar página inicial para o feed: ", - "Number of videos shown in feed: ": "Número de videos no feed: ", - "Sort videos by: ": "Ordenar videos por: ", + "Number of videos shown in feed: ": "Número de vídeos no feed: ", + "Sort videos by: ": "Ordenar vídeos por: ", "published": "publicado", "published - reverse": "publicado - ordem inversa", "alphabetically": "alfabética", "alphabetically - reverse": "alfabética - ordem inversa", "channel name": "nome do canal", "channel name - reverse": "nome do canal - ordem inversa", - "Only show latest video from channel: ": "Mostrar apenas o video mais recente do canal: ", - "Only show latest unwatched video from channel: ": "Mostrar apenas o video mais recente não visualizados do canal: ", - "Only show unwatched: ": "Mostrar apenas videos não visualizados: ", + "Only show latest video from channel: ": "Mostrar apenas o vídeo mais recente do canal: ", + "Only show latest unwatched video from channel: ": "Mostrar apenas o vídeo mais recente não visualizado do canal: ", + "Only show unwatched: ": "Mostrar apenas vídeos não visualizados: ", "Only show notifications (if there are any): ": "Mostrar apenas notificações (se existentes): ", "Enable web notifications": "Ativar notificações pela web", - "`x` uploaded a video": "`x` publicou um novo video", + "`x` uploaded a video": "`x` publicou um novo vídeo", "`x` is live": "`x` está ao vivo", "Data preferences": "Preferências de dados", "Clear watch history": "Limpar histórico de reprodução", @@ -102,8 +102,8 @@ "Watch history": "Histórico de reprodução", "Delete account": "Apagar sua conta", "Administrator preferences": "Preferências de administrador", - "Default homepage: ": "Página de inicio padrão: ", - "Feed menu: ": "Menú do feed: ", + "Default homepage: ": "Página de início padrão: ", + "Feed menu: ": "Menu do feed: ", "Top enabled: ": "Habilitar destaques: ", "CAPTCHA enabled: ": "Habilitar CAPTCHA: ", "Login enabled: ": "Habilitar login: ", @@ -116,64 +116,64 @@ "`x` subscriptions": "`x` inscrições", "`x` tokens": "`x` tokens", "Import/export": "Importar/Exportar", - "unsubscribe": "desinscrever-se", + "unsubscribe": "cancelar inscrição", "revoke": "revogar", "Subscriptions": "Inscrições", "`x` unseen notifications": "`x` notificações não visualizadas", - "search": "procurar", + "search": "Pesquisar", "Log out": "Sair", "Released under the AGPLv3 by Omar Roth.": "Publicado sob a licença AGPLv3, por Omar Roth.", - "Source available here.": "Código fonte disponível aqui.", + "Source available here.": "Código-fonte disponível aqui.", "View JavaScript license information.": "Ver informações da licença do JavaScript.", - "View privacy policy.": "Ver a política de privacidade", - "Trending": "Trending", + "View privacy policy.": "Ver a política de privacidade.", + "Trending": "Tendências", "Public": "Público", - "Unlisted": "No listado", + "Unlisted": "Não listado", "Private": "Privado", "View all playlists": "Mostrar todas listas de reprodução", - "Updated `x` ago": "Enviado `x` atrás", + "Updated `x` ago": "Atualizado `x` atrás", "Delete playlist `x`?": "Apagar a playlist `x`?", "Delete playlist": "Apagar playlist", "Create playlist": "Criar playlist", "Title": "Título", "Playlist privacy": "Privacidade da playlist", - "Editing playlist `x`": "Editando playlist", - "Watch on YouTube": "Assistir vídeo no YouTube", + "Editing playlist `x`": "Editando playlist `x`", + "Watch on YouTube": "Assistir no YouTube", "Hide annotations": "Ocultar anotações", "Show annotations": "Mostrar anotações", "Genre: ": "Gênero: ", "License: ": "Licença: ", - "Family friendly? ": "Fistrar conteúdo impróprio: ", + "Family friendly? ": "Filtrar conteúdo impróprio: ", "Wilson score: ": "Pontuação de Wilson: ", - "Engagement: ": "Engagement: ", + "Engagement: ": "Empenho: ", "Whitelisted regions: ": "Regiões permitidas: ", "Blacklisted regions: ": "Regiões bloqueadas: ", "Shared `x`": "Compartilhado `x`", "`x` views": "`x` visualizações", - "Premieres in `x`": "Estreias em `x`", + "Premieres in `x`": "Estreia em `x`", "Premieres `x`": "Estreia `x`", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Oi! Parece que seu JavaScript está desativado. Clique aqui para ver os comentários, entretanto eles podem levar um pouco mais de tempo para carregar.", - "View YouTube comments": "Ver comentários do YouTube", - "View more comments on Reddit": "Ver mais comentários do Reddit", + "View YouTube comments": "Ver comentários no YouTube", + "View more comments on Reddit": "Ver mais comentários no Reddit", "View `x` comments": "Ver `x` comentários", - "View Reddit comments": "Ver comentários do Reddit", + "View Reddit comments": "Ver comentários no Reddit", "Hide replies": "Ocultar respostas", "Show replies": "Mostrar respostas", "Incorrect password": "Senha incorreta", "Quota exceeded, try again in a few hours": "Cota excedida, tente novamente em algumas horas", - "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Não foi possível fazer login, sua autenticação por dois passos (app autenticador ou sms) deve estar ativada.", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Não foi possível fazer login, sua autenticação em dois passos (app autenticador ou sms) deve estar ativada.", "Invalid TFA code": "Código TFA inválido", - "Login failed. This may be because two-factor authentication is not turned on for your account.": "Falha no login. Isso pode acontecer pois a autenticação por dois passos está desativada para sua conta.", - "Wrong answer": "Respuesta inválida", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "Falha no login. Isso pode acontecer porque a autenticação em dois passos está desativada para sua conta.", + "Wrong answer": "Resposta incorreta", "Erroneous CAPTCHA": "CAPTCHA inválido", "CAPTCHA is a required field": "O CAPTCHA é um campo obrigatório", "User ID is a required field": "O nome de usuário é um campo obrigatório", "Password is a required field": "A senha é um campo obrigatório", "Wrong username or password": "Nome de usuário ou senha inválidos", "Please sign in using 'Log in with Google'": "Por favor, entre usando 'Entrar com conta Google'", - "Password cannot be empty": "A senha não pode estar vazia", + "Password cannot be empty": "A senha não pode ficar em branco", "Password cannot be longer than 55 characters": "A senha não pode ter mais que 55 caracteres", - "Please log in": "Por favor, inicie sua seção", + "Please log in": "Por favor, inicie sua sessão", "Invidious Private Feed for `x`": "Feed Privado do Invidious para `x`", "channel:`x`": "canal: `x`", "Deleted or invalid channel": "Este canal foi apagado ou é inválido", @@ -185,15 +185,15 @@ "Load more": "Carregar mais", "`x` points": "`x` pontos", "Could not create mix.": "Não foi possível criar o mix.", - "Empty playlist": "A lista de reprodução está vazia", - "Not a playlist.": "Lista de reprodução inválida.", + "Empty playlist": "Lista de reprodução vazia", + "Not a playlist.": "Não é uma lista de reprodução.", "Playlist does not exist.": "A lista de reprodução não existe.", - "Could not pull trending pages.": "Não foi possível oberter as páginas dos videos em alta.", + "Could not pull trending pages.": "Não foi possível obter as páginas dos vídeos em alta.", "Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório", "Hidden field \"token\" is a required field": "O campo oculto \"token\" é obrigatório", - "Erroneous challenge": "Desafío inválido", - "Erroneous token": "Símbolo inválido", - "No such user": "Usuario inválido", + "Erroneous challenge": "Desafio inválido", + "Erroneous token": "Token inválido", + "No such user": "Usuário inválido", "Token is expired, please try again": "Token expirou, tente novamente", "English": "Inglês", "English (auto-generated)": "Inglês (gerado automaticamente)", @@ -206,7 +206,7 @@ "Bangla": "Bengalês", "Basque": "Basco", "Belarusian": "Bielorrusso", - "Bosnian": "Língua Bósnia", + "Bosnian": "Bósnio", "Bulgarian": "Búlgaro", "Burmese": "Birmanês", "Catalan": "Catalão", @@ -242,7 +242,7 @@ "Italian": "Italiano", "Japanese": "Japonês", "Javanese": "Javanês", - "Kannada": "Canarẽs", + "Kannada": "Canarês", "Kazakh": "Cazaque", "Khmer": "Khmer", "Korean": "Coreano", @@ -266,26 +266,26 @@ "Nyanja": "Nianja", "Pashto": "Pachto", "Persian": "Persa", - "Polish": "Polaco", + "Polish": "Polonês", "Portuguese": "Português", "Punjabi": "Panjábi", - "Romanian": "Língua Romena", + "Romanian": "Romeno", "Russian": "Russo", "Samoan": "Samoano", "Scottish Gaelic": "Ânglico Escocês", - "Serbian": "Língua Sérvia", + "Serbian": "Sérvio", "Shona": "Xona", "Sindhi": "Sindi", "Sinhala": "Cingalês", "Slovak": "Eslovaco", "Slovenian": "Esloveno", - "Somali": "Língua Somalí", + "Somali": "Somali", "Southern Sotho": "Sesoto", "Spanish": "Espanhol", - "Spanish (Latin America)": "Espanhol (América)", - "Sundanese": "Sondanese", + "Spanish (Latin America)": "Espanhol (América Latina)", + "Sundanese": "Sundanês", "Swahili": "Suaíli", - "Swedish": "Suéco", + "Swedish": "Sueco", "Tajik": "Tajiques", "Tamil": "Tâmil", "Telugu": "Telugo", @@ -300,7 +300,7 @@ "Xhosa": "Xhosa", "Yiddish": "Iídiche", "Yoruba": "Iorubá", - "Zulu": "Língua Zulú", + "Zulu": "Zulu", "`x` years": "`x` anos", "`x` months": "`x` meses", "`x` weeks": "`x` semanas", @@ -315,22 +315,22 @@ "Rating: ": "Avaliação: ", "Language: ": "Idioma: ", "View as playlist": "Ver como lista de reprodução", - "Default": "Configuração padrão", - "Music": "Música", - "Gaming": "Video Games", + "Default": "Padrão", + "Music": "Músicas", + "Gaming": "Jogos", "News": "Notícias", "Movies": "Filmes", "Download": "Baixar", "Download as: ": "Baixar como: ", "%A %B %-d, %Y": "%A %-d %B %Y", "(edited)": "(editado)", - "YouTube comment permalink": "Link permanente do comentário do YouTube", + "YouTube comment permalink": "Link permanente do comentário no YouTube", "permalink": "Link permanente", "`x` marked it with a ❤": "`x` foi marcado como ❤", - "Audio mode": "Modo de audio", - "Video mode": "Modo de video", + "Audio mode": "Modo de áudio", + "Video mode": "Modo de vídeo", "Videos": "Vídeos", "Playlists": "Listas de reprodução", "Community": "Comunidade", "Current version: ": "Versão atual: " -} \ No newline at end of file +} diff --git a/locales/pt-PT.json b/locales/pt-PT.json index ab7d3468b..1082c023e 100644 --- a/locales/pt-PT.json +++ b/locales/pt-PT.json @@ -1,16 +1,10 @@ { - "`x` subscribers.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` subscritores.", - "": "`x` subscritores." - }, - "`x` videos.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` vídeos.", - "": "`x` vídeos." - }, - "`x` playlists.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` listas de reprodução.", - "": "`x` listas de reprodução." - }, + "`x` subscribers..([^.,0-9]|^)1([^.,0-9]|$)": "`x` subscritores..([^.,0-9]|^)1([^.,0-9]|$)", + "`x` subscribers..": "`x` subscritores.", + "`x` videos..([^.,0-9]|^)1([^.,0-9]|$)": "`x` videos..([^.,0-9]|^)1([^.,0-9]|$)", + "`x` videos..": "`x` vídeos.", + "`x` playlists..([^.,0-9]|^)1([^.,0-9]|$)": "`x` listas de reprodução.", + "`x` playlists..": "`x` listas de reprodução.", "LIVE": "Em direto", "Shared `x` ago": "Partilhado `x` atrás", "Unsubscribe": "Anular subscrição", @@ -26,7 +20,7 @@ "Clear watch history?": "Limpar histórico de reprodução?", "New password": "Nova palavra-chave", "New passwords must match": "As novas palavra-chaves devem corresponder", - "Cannot change password for Google accounts": "Não é possível alterar palavra-chave para contas do Google", + "Cannot change password for Google accounts": "Não é possível alterar a palavra-passe para contas do Google", "Authorize token?": "Autorizar token?", "Authorize token for `x`?": "Autorizar token para `x`?", "Yes": "Sim", @@ -42,9 +36,9 @@ "Export subscriptions as OPML": "Exportar subscrições como OPML", "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar subscrições como OPML (para NewPipe e FreeTube)", "Export data as JSON": "Exportar dados como JSON", - "Delete account?": "Eliminar conta?", + "Delete account?": "Apagar conta?", "History": "Histórico", - "An alternative front-end to YouTube": "Uma interface alternativa para o YouTube", + "An alternative front-end to YouTube": "Uma interface alternativa ao YouTube", "JavaScript license information": "Informação de licença do JavaScript", "source": "código-fonte", "Log in": "Iniciar sessão", @@ -85,9 +79,9 @@ "light": "claro", "Thin mode: ": "Modo compacto: ", "Subscription preferences": "Preferências de subscrições", - "Show annotations by default for subscribed channels: ": "Mostrar sempre anotações para os canais subscritos: ", + "Show annotations by default for subscribed channels: ": "Mostrar sempre anotações aos canais subscritos: ", "Redirect homepage to feed: ": "Redirecionar página inicial para subscrições: ", - "Number of videos shown in feed: ": "Número de vídeos nas subscrições: ", + "Number of videos shown in feed: ": "Quantidade de vídeos nas subscrições: ", "Sort videos by: ": "Ordenar vídeos por: ", "published": "publicado", "published - reverse": "publicado - inverso", @@ -109,9 +103,9 @@ "Manage subscriptions": "Gerir as subscrições", "Manage tokens": "Gerir tokens", "Watch history": "Histórico de reprodução", - "Delete account": "Eliminar conta", + "Delete account": "Apagar conta", "Administrator preferences": "Preferências de administrador", - "Default homepage: ": "Página inicial padrão: ", + "Default homepage: ": "Página inicial predefinida: ", "Feed menu: ": "Menu de subscrições: ", "Top enabled: ": "Top ativado: ", "CAPTCHA enabled: ": "CAPTCHA ativado: ", @@ -122,22 +116,16 @@ "Subscription manager": "Gerir subscrições", "Token manager": "Gerir tokens", "Token": "Token", - "`x` subscriptions.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` subscrições.", - "": "`x` subscrições." - }, - "`x` tokens.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` tokens.", - "": "`x` tokens." - }, + "`x` subscriptions..([^.,0-9]|^)1([^.,0-9]|$)": "`x` subscrições.", + "`x` subscriptions..": "`x` subscrições.", + "`x` tokens..([^.,0-9]|^)1([^.,0-9]|$)": "`x` tokens.", + "`x` tokens..": "`x` tokens.", "Import/export": "Importar/Exportar", "unsubscribe": "Anular subscrição", "revoke": "revogar", "Subscriptions": "Subscrições", - "`x` unseen notifications.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` notificações não vistas.", - "": "`x` notificações não vistas." - }, + "`x` unseen notifications..([^.,0-9]|^)1([^.,0-9]|$)": "`x` notificações não vistas.", + "`x` unseen notifications..": "`x` notificações não vistas.", "search": "Pesquisar", "Log out": "Terminar sessão", "Released under the AGPLv3 by Omar Roth.": "Publicado sob a licença AGPLv3, por Omar Roth.", @@ -150,8 +138,8 @@ "Private": "Privado", "View all playlists": "Ver todas as listas de reprodução", "Updated `x` ago": "Atualizado `x` atrás", - "Delete playlist `x`?": "Eliminar a lista de reprodução 'x'?", - "Delete playlist": "Eliminar lista de reprodução", + "Delete playlist `x`?": "Apagar a lista de reprodução 'x'?", + "Delete playlist": "Apagar lista de reprodução", "Create playlist": "Criar lista de reprodução", "Title": "Título", "Playlist privacy": "Privacidade da lista de reprodução", @@ -167,19 +155,15 @@ "Whitelisted regions: ": "Regiões permitidas: ", "Blacklisted regions: ": "Regiões bloqueadas: ", "Shared `x`": "Partilhado `x`", - "`x` views.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` visualizações.", - "": "`x` visualizações." - }, + "`x` views..([^.,0-9]|^)1([^.,0-9]|$)": "`x` visualizações.", + "`x` views..": "`x` visualizações.", "Premieres in `x`": "Estreias em 'x'", "Premieres `x`": "Estreias 'x'", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Oi! Parece que JavaScript está desativado. Clique aqui para ver os comentários, entretanto eles podem levar mais tempo para carregar.", "View YouTube comments": "Ver comentários do YouTube", "View more comments on Reddit": "Ver mais comentários no Reddit", - "View `x` comments.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` comentários.", - "": "Ver `x` comentários." - }, + "View `x` comments..([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` comentários.", + "View `x` comments..": "Ver `x` comentários.", "View Reddit comments": "Ver comentários do Reddit", "Hide replies": "Ocultar respostas", "Show replies": "Mostrar respostas", @@ -204,16 +188,12 @@ "This channel does not exist.": "Este canal não existe.", "Could not get channel info.": "Não foi possível obter as informações do canal.", "Could not fetch comments": "Não foi possível obter os comentários", - "View `x` replies.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` respostas.", - "": "Ver `x` respostas." - }, + "View `x` replies..([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` respostas.", + "View `x` replies..": "Ver `x` respostas.", "`x` ago": "`x` atrás", "Load more": "Carregar mais", - "`x` points.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "'x' pontos.", - "": "'x' pontos." - }, + "`x` points..([^.,0-9]|^)1([^.,0-9]|$)": "'x' pontos.", + "`x` points..": "'x' pontos.", "Could not create mix.": "Não foi possível criar mistura.", "Empty playlist": "Lista de reprodução vazia", "Not a playlist.": "Não é uma lista de reprodução.", @@ -331,34 +311,20 @@ "Yiddish": "Iídiche", "Yoruba": "Ioruba", "Zulu": "Zulu", - "`x` years.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` anos.", - "": "`x` anos." - }, - "`x` months.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` meses.", - "": "`x` meses." - }, - "`x` weeks.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` semanas.", - "": "`x` semanas." - }, - "`x` days.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` dias.", - "": "`x` dias." - }, - "`x` hours.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` horas.", - "": "`x` horas." - }, - "`x` minutes.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` minutos.", - "": "`x` minutos." - }, - "`x` seconds.": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` segundos.", - "": "`x` segundos." - }, + "`x` years..([^.,0-9]|^)1([^.,0-9]|$)": "`x` anos.", + "`x` years..": "`x` anos.", + "`x` months..([^.,0-9]|^)1([^.,0-9]|$)": "`x` meses.", + "`x` months..": "`x` meses.", + "`x` weeks..([^.,0-9]|^)1([^.,0-9]|$)": "`x` semanas.", + "`x` weeks..": "`x` semanas.", + "`x` days..([^.,0-9]|^)1([^.,0-9]|$)": "`x` dias.", + "`x` days..": "`x` dias.", + "`x` hours..([^.,0-9]|^)1([^.,0-9]|$)": "`x` horas.", + "`x` hours..": "`x` horas.", + "`x` minutes..([^.,0-9]|^)1([^.,0-9]|$)": "`x` minutos.", + "`x` minutes..": "`x` minutos.", + "`x` seconds..([^.,0-9]|^)1([^.,0-9]|$)": "`x` segundos.", + "`x` seconds..": "`x` segundos.", "Fallback comments: ": "Comentários alternativos: ", "Popular": "Popular", "Top": "Top", @@ -375,7 +341,7 @@ "Download as: ": "Transferir como: ", "%A %B %-d, %Y": "%A %B %-d, %Y", "(edited)": "(editado)", - "YouTube comment permalink": "Link permanente do comentário do YouTube", + "YouTube comment permalink": "Hiperligação permanente ao comentário do YouTube", "permalink": "ligação permanente", "`x` marked it with a ❤": "`x` foi marcado como ❤", "Audio mode": "Modo de áudio", @@ -384,4 +350,4 @@ "Playlists": "Listas de reprodução", "Community": "Comunidade", "Current version: ": "Versão atual: " -} \ No newline at end of file +} diff --git a/locales/sk.json b/locales/sk.json new file mode 100644 index 000000000..0957cb877 --- /dev/null +++ b/locales/sk.json @@ -0,0 +1,353 @@ +{ + "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` subscribers.": "`x` odberateľov.", + "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` videos.": "", + "`x` playlists.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` playlists.": "", + "LIVE": "NAŽIVO", + "Shared `x` ago": "", + "Unsubscribe": "Zrušiť odber", + "Subscribe": "Odoberať", + "View channel on YouTube": "Zobraziť kanál na YouTube", + "View playlist on YouTube": "", + "newest": "najnovšie", + "oldest": "najstaršie", + "popular": "populárne", + "last": "posledné", + "Next page": "Ďalšia strana", + "Previous page": "Predchádzajúca strana", + "Clear watch history?": "Vymazať históriu sledovania?", + "New password": "Nové heslo", + "New passwords must match": "Nové heslá sa musia zhodovať", + "Cannot change password for Google accounts": "Heslo pre účty Google sa nedá zmeniť", + "Authorize token?": "Autorizovať token?", + "Authorize token for `x`?": "", + "Yes": "Áno", + "No": "Nie", + "Import and Export Data": "Import a Export údajov", + "Import": "Import", + "Import Invidious data": "Importovať údaje Invidious", + "Import YouTube subscriptions": "Importovať odbery YouTube", + "Import FreeTube subscriptions (.db)": "Importovať odbery FreeTube (.db)", + "Import NewPipe subscriptions (.json)": "Importovať odbery NewPipe (.json)", + "Import NewPipe data (.zip)": "Importovať údaje NewPipe (.zip)", + "Export": "Export", + "Export subscriptions as OPML": "Exportovať odbery ako OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportovať odbery ako OPML (pre NewPipe a FreeTube)", + "Export data as JSON": "Export údajov ako JSON", + "Delete account?": "Zrušiť účet?", + "History": "História", + "An alternative front-end to YouTube": "Alternatívny front-end pre YouTube", + "JavaScript license information": "Informácie o licencii JavaScript", + "source": "zdroj", + "Log in": "Prihlásiť sa", + "Log in/register": "Prihlásiť sa/Registrovať", + "Log in with Google": "Prihlásiť sa pomocou účtu Google", + "User ID": "ID používateľa", + "Password": "Heslo", + "Time (h:mm:ss):": "Čas (h:mm:ss):", + "Text CAPTCHA": "Textové CAPTCHA", + "Image CAPTCHA": "Obrázkové CAPTCHA", + "Sign In": "Prihlásiť sa", + "Register": "Registrovať", + "E-mail": "E-mail", + "Google verification code": "Overovací kód Google", + "Preferences": "Nastavenia", + "Player preferences": "Nastavenia prehrávača", + "Always loop: ": "Vždy opakovať: ", + "Autoplay: ": "Automatické prehrávanie: ", + "Play next by default: ": "", + "Autoplay next video: ": "Automatické prehrávanie nasledujúceho videa: ", + "Listen by default: ": "Predvolene počúvať: ", + "Proxy videos: ": "Proxy videá: ", + "Default speed: ": "Predvolená rýchlosť: ", + "Preferred video quality: ": "Preferovaná kvalita videa: ", + "Player volume: ": "Hlasitosť prehrávača: ", + "Default comments: ": "Predvolené komentáre: ", + "youtube": "YouTube", + "reddit": "Reddit", + "Default captions: ": "Predvolené titulky: ", + "Fallback captions: ": "Náhradné titulky: ", + "Show related videos: ": "Zobraziť súvisiace videá: ", + "Show annotations by default: ": "Predvolene zobraziť anotácie: ", + "Visual preferences": "Vizuálne nastavenia", + "Player style: ": "Štýl prehrávača: ", + "Dark mode: ": "Tmavý režim: ", + "Theme: ": "Téma: ", + "dark": "tmavá", + "light": "svetlá", + "Thin mode: ": "Tenký režim: ", + "Subscription preferences": "Nastavenia predplatného", + "Show annotations by default for subscribed channels: ": "Predvolene zobraziť anotácie odoberaných kanálov: ", + "Redirect homepage to feed: ": "Presmerovanie domovskej stránky na informačný kanál: ", + "Number of videos shown in feed: ": "Počet videí zobrazených v informačnom kanáli: ", + "Sort videos by: ": "Zoradiť videá podľa: ", + "published": "zverejnené (od najnovších)", + "published - reverse": "zverejnené (od najstarších)", + "alphabetically": "abecedne (A-Z)", + "alphabetically - reverse": "abecedne (Z-A)", + "channel name": "názov kanála (A-Z)", + "channel name - reverse": "názov kanála (Z-A)", + "Only show latest video from channel: ": "Zobraziť iba najnovšie video z kanála: ", + "Only show latest unwatched video from channel: ": "Zobraziť iba najnovšie neprehrané video z kanála: ", + "Only show unwatched: ": "Zobraziť iba neprehrané: ", + "Only show notifications (if there are any): ": "Zobraziť iba upozornenia (ak existujú): ", + "Enable web notifications": "Povoliť webové upozornenia", + "`x` uploaded a video": "`x` nahral(a) video", + "`x` is live": "", + "Data preferences": "", + "Clear watch history": "", + "Import/export data": "", + "Change password": "", + "Manage subscriptions": "", + "Manage tokens": "", + "Watch history": "", + "Delete account": "", + "Administrator preferences": "", + "Default homepage: ": "", + "Feed menu: ": "", + "Top enabled: ": "", + "CAPTCHA enabled: ": "", + "Login enabled: ": "", + "Registration enabled: ": "", + "Report statistics: ": "", + "Save preferences": "", + "Subscription manager": "", + "Token manager": "", + "Token": "", + "`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` subscriptions.": "", + "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` tokens.": "", + "Import/export": "", + "unsubscribe": "", + "revoke": "", + "Subscriptions": "", + "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` unseen notifications.": "", + "search": "", + "Log out": "", + "Released under the AGPLv3 by Omar Roth.": "", + "Source available here.": "", + "View JavaScript license information.": "", + "View privacy policy.": "", + "Trending": "", + "Public": "", + "Unlisted": "", + "Private": "", + "View all playlists": "", + "Updated `x` ago": "", + "Delete playlist `x`?": "", + "Delete playlist": "", + "Create playlist": "", + "Title": "", + "Playlist privacy": "", + "Editing playlist `x`": "", + "Watch on YouTube": "", + "Hide annotations": "", + "Show annotations": "", + "Genre: ": "", + "License: ": "", + "Family friendly? ": "", + "Wilson score: ": "", + "Engagement: ": "", + "Whitelisted regions: ": "", + "Blacklisted regions: ": "", + "Shared `x`": "", + "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` views.": "", + "Premieres in `x`": "", + "Premieres `x`": "", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "", + "View YouTube comments": "", + "View more comments on Reddit": "", + "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "", + "View `x` comments.": "", + "View Reddit comments": "", + "Hide replies": "", + "Show replies": "", + "Incorrect password": "", + "Quota exceeded, try again in a few hours": "", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", + "Invalid TFA code": "", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "", + "Wrong answer": "", + "Erroneous CAPTCHA": "", + "CAPTCHA is a required field": "", + "User ID is a required field": "", + "Password is a required field": "", + "Wrong username or password": "", + "Please sign in using 'Log in with Google'": "", + "Password cannot be empty": "", + "Password cannot be longer than 55 characters": "", + "Please log in": "", + "Invidious Private Feed for `x`": "", + "channel:`x`": "", + "Deleted or invalid channel": "", + "This channel does not exist.": "", + "Could not get channel info.": "", + "Could not fetch comments": "", + "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "", + "View `x` replies.": "", + "`x` ago": "", + "Load more": "", + "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` points.": "", + "Could not create mix.": "", + "Empty playlist": "", + "Not a playlist.": "", + "Playlist does not exist.": "", + "Could not pull trending pages.": "", + "Hidden field \"challenge\" is a required field": "", + "Hidden field \"token\" is a required field": "", + "Erroneous challenge": "", + "Erroneous token": "", + "No such user": "", + "Token is expired, please try again": "", + "English": "", + "English (auto-generated)": "", + "Afrikaans": "", + "Albanian": "", + "Amharic": "", + "Arabic": "", + "Armenian": "", + "Azerbaijani": "", + "Bangla": "", + "Basque": "", + "Belarusian": "", + "Bosnian": "", + "Bulgarian": "", + "Burmese": "", + "Catalan": "", + "Cebuano": "", + "Chinese (Simplified)": "", + "Chinese (Traditional)": "", + "Corsican": "", + "Croatian": "", + "Czech": "", + "Danish": "", + "Dutch": "", + "Esperanto": "", + "Estonian": "", + "Filipino": "", + "Finnish": "", + "French": "", + "Galician": "", + "Georgian": "", + "German": "", + "Greek": "", + "Gujarati": "", + "Haitian Creole": "", + "Hausa": "", + "Hawaiian": "", + "Hebrew": "", + "Hindi": "", + "Hmong": "", + "Hungarian": "", + "Icelandic": "", + "Igbo": "", + "Indonesian": "", + "Irish": "", + "Italian": "", + "Japanese": "", + "Javanese": "", + "Kannada": "", + "Kazakh": "", + "Khmer": "", + "Korean": "", + "Kurdish": "", + "Kyrgyz": "", + "Lao": "", + "Latin": "", + "Latvian": "", + "Lithuanian": "", + "Luxembourgish": "", + "Macedonian": "", + "Malagasy": "", + "Malay": "", + "Malayalam": "", + "Maltese": "", + "Maori": "", + "Marathi": "", + "Mongolian": "", + "Nepali": "", + "Norwegian Bokmål": "", + "Nyanja": "", + "Pashto": "", + "Persian": "", + "Polish": "", + "Portuguese": "", + "Punjabi": "", + "Romanian": "", + "Russian": "", + "Samoan": "", + "Scottish Gaelic": "", + "Serbian": "", + "Shona": "", + "Sindhi": "", + "Sinhala": "", + "Slovak": "", + "Slovenian": "", + "Somali": "", + "Southern Sotho": "", + "Spanish": "", + "Spanish (Latin America)": "", + "Sundanese": "", + "Swahili": "", + "Swedish": "", + "Tajik": "", + "Tamil": "", + "Telugu": "", + "Thai": "", + "Turkish": "", + "Ukrainian": "", + "Urdu": "", + "Uzbek": "", + "Vietnamese": "", + "Welsh": "", + "Western Frisian": "", + "Xhosa": "", + "Yiddish": "", + "Yoruba": "", + "Zulu": "", + "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` years.": "", + "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` months.": "", + "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` weeks.": "", + "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` days.": "", + "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` hours.": "", + "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` minutes.": "", + "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "", + "`x` seconds.": "", + "Fallback comments: ": "", + "Popular": "", + "Top": "", + "About": "", + "Rating: ": "", + "Language: ": "", + "View as playlist": "", + "Default": "", + "Music": "", + "Gaming": "", + "News": "", + "Movies": "", + "Download": "", + "Download as: ": "", + "%A %B %-d, %Y": "", + "(edited)": "", + "YouTube comment permalink": "", + "permalink": "", + "`x` marked it with a ❤": "", + "Audio mode": "", + "Video mode": "", + "Videos": "", + "Playlists": "", + "Community": "", + "Current version: ": "" +} diff --git a/locales/sr_Cyrl.json b/locales/sr_Cyrl.json index 786532dff..0ca9a8a00 100644 --- a/locales/sr_Cyrl.json +++ b/locales/sr_Cyrl.json @@ -1,109 +1,109 @@ { - "`x` subscribers.": "", - "`x` videos.": "", - "`x` playlists.": "", - "LIVE": "", - "Shared `x` ago": "", - "Unsubscribe": "", + "`x` subscribers.": "%(count)s пратилац.", + "`x` videos.": "`x` видеа.", + "`x` playlists.": "`x` плејлиста/е.", + "LIVE": "УЖИВО", + "Shared `x` ago": "Објављено пре `x`", + "Unsubscribe": "Прекините праћење", "Subscribe": "Пратите", "View channel on YouTube": "Погледајте канал на YouTube-у", "View playlist on YouTube": "Погледајте плејлисту на YouTube-у", - "newest": "", - "oldest": "", - "popular": "", - "last": "", - "Next page": "", - "Previous page": "", - "Clear watch history?": "", - "New password": "", - "New passwords must match": "", - "Cannot change password for Google accounts": "", - "Authorize token?": "", - "Authorize token for `x`?": "", - "Yes": "", - "No": "", - "Import and Export Data": "", - "Import": "", - "Import Invidious data": "", - "Import YouTube subscriptions": "", - "Import FreeTube subscriptions (.db)": "", - "Import NewPipe subscriptions (.json)": "", - "Import NewPipe data (.zip)": "", - "Export": "", - "Export subscriptions as OPML": "", - "Export subscriptions as OPML (for NewPipe & FreeTube)": "", - "Export data as JSON": "", - "Delete account?": "", - "History": "", - "An alternative front-end to YouTube": "", - "JavaScript license information": "", - "source": "", - "Log in": "", - "Log in/register": "", - "Log in with Google": "", - "User ID": "", - "Password": "", - "Time (h:mm:ss):": "", - "Text CAPTCHA": "", - "Image CAPTCHA": "", - "Sign In": "", - "Register": "", - "E-mail": "", - "Google verification code": "", - "Preferences": "", - "Player preferences": "", - "Always loop: ": "", - "Autoplay: ": "", - "Play next by default: ": "", - "Autoplay next video: ": "", - "Listen by default: ": "", - "Proxy videos: ": "", - "Default speed: ": "", - "Preferred video quality: ": "", - "Player volume: ": "", - "Default comments: ": "", - "youtube": "", - "reddit": "", - "Default captions: ": "", - "Fallback captions: ": "", - "Show related videos: ": "", - "Show annotations by default: ": "", - "Visual preferences": "", - "Player style: ": "", - "Dark mode: ": "", - "Theme: ": "", - "dark": "", - "light": "", - "Thin mode: ": "", - "Subscription preferences": "", - "Show annotations by default for subscribed channels: ": "", - "Redirect homepage to feed: ": "", - "Number of videos shown in feed: ": "", - "Sort videos by: ": "", - "published": "", - "published - reverse": "", - "alphabetically": "", - "alphabetically - reverse": "", - "channel name": "", - "channel name - reverse": "", - "Only show latest video from channel: ": "", - "Only show latest unwatched video from channel: ": "", - "Only show unwatched: ": "", - "Only show notifications (if there are any): ": "", - "Enable web notifications": "", - "`x` uploaded a video": "", - "`x` is live": "", - "Data preferences": "", - "Clear watch history": "", - "Import/export data": "", - "Change password": "", - "Manage subscriptions": "", - "Manage tokens": "", - "Watch history": "", - "Delete account": "", - "Administrator preferences": "", - "Default homepage: ": "", - "Feed menu: ": "", + "newest": "најновије", + "oldest": "најстарије", + "popular": "популарно", + "last": "последње", + "Next page": "Следећа страна", + "Previous page": "Претходна страна", + "Clear watch history?": "Обришите историју прегледања?", + "New password": "Нова лозинка", + "New passwords must match": "Нове лозинке се морају поклапати", + "Cannot change password for Google accounts": "Није могуће променити лозинку за Google налоге", + "Authorize token?": "Овластите токен?", + "Authorize token for `x`?": "Овластите токен за `x`?", + "Yes": "Да", + "No": "Не", + "Import and Export Data": "Увоз и извоз података", + "Import": "Увезите", + "Import Invidious data": "Увезите Invidious податке", + "Import YouTube subscriptions": "Увезите праћења са YouTube-а", + "Import FreeTube subscriptions (.db)": "Увезите праћења са FreeTube-а (.db)", + "Import NewPipe subscriptions (.json)": "Увезите праћења са NewPipe-а (.json)", + "Import NewPipe data (.zip)": "Увезите NewPipe податке (.zip)", + "Export": "Извезите", + "Export subscriptions as OPML": "Извезите праћења у OPML формату", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "Извезите праћења у OPML формату (за NewPipe и FreeTube )", + "Export data as JSON": "Изветизе податке у JSON формату", + "Delete account?": "Избришите налог?", + "History": "Историја", + "An alternative front-end to YouTube": "Алтернативни фронтенд за YouTube", + "JavaScript license information": "Извештај о JavaScript лиценци", + "source": "извор", + "Log in": "Пријавите се", + "Log in/register": "Пријавите се/направите налог", + "Log in with Google": "Пријавите се помоћу Google-а", + "User ID": "ИД корисника", + "Password": "Лозинка", + "Time (h:mm:ss):": "Колико је сати? (ч:мм:сс):", + "Text CAPTCHA": "Текстуална CAPTCHA", + "Image CAPTCHA": "Сликовна CAPTCHA", + "Sign In": "Пријавите се", + "Register": "Направите налог", + "E-mail": "Е-пошта", + "Google verification code": "Google верификациони кôд", + "Preferences": "Подешавања", + "Player preferences": "Подешавања видео плејера", + "Always loop: ": "Увек понављај: ", + "Autoplay: ": "Аутоматско пуштање: ", + "Play next by default: ": "Увек пуштај следеће: ", + "Autoplay next video: ": "Аутоматско пуштање следећег видеа: ", + "Listen by default: ": "Режим слушања као подразумевано: ", + "Proxy videos: ": "Пуштање видеа кроз прокси сервер: ", + "Default speed: ": "Подразумевана брзина репродукције: ", + "Preferred video quality: ": "Претпостављени квалитет видеа: ", + "Player volume: ": "Јачина звука: ", + "Default comments: ": "Подразумевани коментари: ", + "youtube": "са YouTube-а", + "reddit": "са редита", + "Default captions: ": "Подразумевани титлови: ", + "Fallback captions: ": "Алтернативни титлови: ", + "Show related videos: ": "Прикажи сличне видее: ", + "Show annotations by default: ": "Увек приказуј анотације: ", + "Visual preferences": "Подешавања изгледа", + "Player style: ": "Стил плејера: ", + "Dark mode: ": "Тамни режим: ", + "Theme: ": "Тема: ", + "dark": "тамна", + "light": "светла", + "Thin mode: ": "Узани режим: ", + "Subscription preferences": "Подешавања о праћењима", + "Show annotations by default for subscribed channels: ": "Увек приказуј анотације за канале које пратим: ", + "Redirect homepage to feed: ": "Прикажи праћења као почетну страницу: ", + "Number of videos shown in feed: ": "Количина приказаних видеа на доводу: ", + "Sort videos by: ": "Сортирај према: ", + "published": "датуму објављивања", + "published - reverse": "датуму објављивања - обрнуто", + "alphabetically": "алфабету", + "alphabetically - reverse": "алфабету - обрнуто", + "channel name": "називу канала", + "channel name - reverse": "називу канала - обрнуто", + "Only show latest video from channel: ": "Прикажи само најновији видео са канала: ", + "Only show latest unwatched video from channel: ": "Прикажи само најновији негледани видео са канала: ", + "Only show unwatched: ": "Прикажи само негледано: ", + "Only show notifications (if there are any): ": "Прикажи само обавештења (ако их има): ", + "Enable web notifications": "Укључи обавештења преко претраживача", + "`x` uploaded a video": "`x`је објавио/ла видео", + "`x` is live": "`x` емитује уживо", + "Data preferences": "Подешавања о подацима", + "Clear watch history": "Обришите историју прегледања", + "Import/export data": "Увезите или извезите податке", + "Change password": "Промените лозинку", + "Manage subscriptions": "Управљајте праћењима", + "Manage tokens": "Управљајте токенима", + "Watch history": "Историја прегледања", + "Delete account": "Избришите налог", + "Administrator preferences": "Подешавања администратора", + "Default homepage: ": "Подразумевана главна страница: ", + "Feed menu: ": "Мени довода: ", "Top enabled: ": "", "CAPTCHA enabled: ": "", "Login enabled: ": "", @@ -333,4 +333,4 @@ "Playlists": "", "Community": "", "Current version: ": "Тренутна верзија: " -} \ No newline at end of file +} diff --git a/locales/sv-SE.json b/locales/sv-SE.json index 14e7d53e3..fef5316f1 100644 --- a/locales/sv-SE.json +++ b/locales/sv-SE.json @@ -195,112 +195,112 @@ "Erroneous token": "Felaktig token", "No such user": "Ogiltig användare", "Token is expired, please try again": "Token föråldrad, försök igen", - "English": "", - "English (auto-generated)": "English (auto-genererat)", - "Afrikaans": "", - "Albanian": "", - "Amharic": "", - "Arabic": "", - "Armenian": "", - "Azerbaijani": "", - "Bangla": "", - "Basque": "", - "Belarusian": "", - "Bosnian": "", - "Bulgarian": "", - "Burmese": "", - "Catalan": "", - "Cebuano": "", - "Chinese (Simplified)": "", - "Chinese (Traditional)": "", - "Corsican": "", - "Croatian": "", - "Czech": "", - "Danish": "", - "Dutch": "", - "Esperanto": "", - "Estonian": "", - "Filipino": "", - "Finnish": "", - "French": "", - "Galician": "", - "Georgian": "", - "German": "", - "Greek": "", - "Gujarati": "", - "Haitian Creole": "", - "Hausa": "", - "Hawaiian": "", - "Hebrew": "", - "Hindi": "", - "Hmong": "", - "Hungarian": "", - "Icelandic": "", - "Igbo": "", - "Indonesian": "", - "Irish": "", - "Italian": "", - "Japanese": "", - "Javanese": "", - "Kannada": "", - "Kazakh": "", - "Khmer": "", - "Korean": "", - "Kurdish": "", - "Kyrgyz": "", - "Lao": "", - "Latin": "", - "Latvian": "", - "Lithuanian": "", - "Luxembourgish": "", - "Macedonian": "", - "Malagasy": "", - "Malay": "", - "Malayalam": "", - "Maltese": "", - "Maori": "", - "Marathi": "", - "Mongolian": "", - "Nepali": "", - "Norwegian Bokmål": "", - "Nyanja": "", - "Pashto": "", - "Persian": "", - "Polish": "", - "Portuguese": "", - "Punjabi": "", - "Romanian": "", - "Russian": "", - "Samoan": "", - "Scottish Gaelic": "", - "Serbian": "", - "Shona": "", - "Sindhi": "", - "Sinhala": "", - "Slovak": "", - "Slovenian": "", - "Somali": "", - "Southern Sotho": "", - "Spanish": "", - "Spanish (Latin America)": "", - "Sundanese": "", - "Swahili": "", - "Swedish": "", - "Tajik": "", - "Tamil": "", - "Telugu": "", - "Thai": "", - "Turkish": "", - "Ukrainian": "", - "Urdu": "", - "Uzbek": "", - "Vietnamese": "", - "Welsh": "", - "Western Frisian": "", - "Xhosa": "", - "Yiddish": "", - "Yoruba": "", - "Zulu": "", + "English": "Engelska", + "English (auto-generated)": "Engelska (auto-genererat)", + "Afrikaans": "Afrikanska", + "Albanian": "Albanska", + "Amharic": "Amhariska", + "Arabic": "Arabiska", + "Armenian": "Armeniska", + "Azerbaijani": "Azerbajdzjanska", + "Bangla": "Bengaliska", + "Basque": "Baskiska", + "Belarusian": "Vitryska", + "Bosnian": "Bosniska", + "Bulgarian": "Bulgariska", + "Burmese": "Burmesiska", + "Catalan": "Katalanska", + "Cebuano": "Cebuano", + "Chinese (Simplified)": "Kinesiska (Förenklad)", + "Chinese (Traditional)": "Kinesiska (Traditionell)", + "Corsican": "Korsikanska", + "Croatian": "Kroatiska", + "Czech": "Tjeckiska", + "Danish": "Danska", + "Dutch": "Nederländska", + "Esperanto": "Esperanto", + "Estonian": "Estniska", + "Filipino": "Filipino", + "Finnish": "Finska", + "French": "Franska", + "Galician": "Galiciska", + "Georgian": "Georgiska", + "German": "Tyska", + "Greek": "Grekiska", + "Gujarati": "Gujarati", + "Haitian Creole": "Haitisk Kreol", + "Hausa": "Hausa", + "Hawaiian": "Hawaiiska", + "Hebrew": "Hebreiska", + "Hindi": "Hindi", + "Hmong": "Hmong-mienspråk", + "Hungarian": "Ungerska", + "Icelandic": "Isländska", + "Igbo": "Igbo", + "Indonesian": "Indonesiska", + "Irish": "Irländska", + "Italian": "Italienska", + "Japanese": "Japanska", + "Javanese": "Javanesiska", + "Kannada": "Kanaresiska", + "Kazakh": "Kazakiska", + "Khmer": "Kambodjanska", + "Korean": "Koreanska", + "Kurdish": "Kurdiska", + "Kyrgyz": "Kirgiziska", + "Lao": "Laotiska", + "Latin": "Latin", + "Latvian": "Lettiska", + "Lithuanian": "Litauiska", + "Luxembourgish": "Luxemburgska", + "Macedonian": "Makedonska", + "Malagasy": "Malagassiska", + "Malay": "Malajiska", + "Malayalam": "Malayalam", + "Maltese": "Maltesiska", + "Maori": "Maori", + "Marathi": "Marathi", + "Mongolian": "Mongoliska", + "Nepali": "Nepali", + "Norwegian Bokmål": "Norska Bokmål", + "Nyanja": "Nyanja", + "Pashto": "Pashto", + "Persian": "Persiska", + "Polish": "Polska", + "Portuguese": "Portugisiska", + "Punjabi": "Punjabi", + "Romanian": "Rumänska", + "Russian": "Ryska", + "Samoan": "Samoanska", + "Scottish Gaelic": "Skotsk gäliska", + "Serbian": "Serbiska", + "Shona": "Shona", + "Sindhi": "Sindhi", + "Sinhala": "Singalesiska", + "Slovak": "Slovakiska", + "Slovenian": "Slovenska", + "Somali": "Somaliska", + "Southern Sotho": "Sydsotho", + "Spanish": "Spanska", + "Spanish (Latin America)": "Spanska (Latin Amerikansk)", + "Sundanese": "Sundanesiska", + "Swahili": "Swahili", + "Swedish": "Svenska", + "Tajik": "Tadzjikiska", + "Tamil": "Tamil", + "Telugu": "Telugu", + "Thai": "Thailändska", + "Turkish": "Turkiska", + "Ukrainian": "Ukrainska", + "Urdu": "Urdu", + "Uzbek": "Uzbekiska", + "Vietnamese": "Vietnamesiska", + "Welsh": "Walesiska", + "Western Frisian": "Västfrisiska", + "Xhosa": "Xhosa", + "Yiddish": "Jiddisch", + "Yoruba": "Yoruba", + "Zulu": "Zulu", "`x` years": "`x` år", "`x` months": "`x` månader", "`x` weeks": "`x` veckor", @@ -322,7 +322,7 @@ "Movies": "Filmer", "Download": "Ladda ned", "Download as: ": "Ladda ned som: ", - "%A %B %-d, %Y": "", + "%A %B %-d, %Y": "%A %B %-d, %Y", "(edited)": "(redigerad)", "YouTube comment permalink": "Permanent YouTube-länk till innehållet", "permalink": "permalänk", @@ -333,4 +333,4 @@ "Playlists": "Spellistor", "Community": "Gemenskap", "Current version: ": "Nuvarande version: " -} \ No newline at end of file +} diff --git a/locales/tr.json b/locales/tr.json index 652dff6dc..831ecc078 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -334,11 +334,11 @@ "(edited)": "(düzenlendi)", "YouTube comment permalink": "YouTube yorumu kalıcı linki", "permalink": "kalıcı link", - "`x` marked it with a ❤": "`x` ❤ ile işaretlendi", + "`x` marked it with a ❤": "`x` ❤ ile işaretledi", "Audio mode": "Ses modu", "Video mode": "Video modu", "Videos": "Videolar", "Playlists": "Oynatma listeleri", "Community": "Topluluk", "Current version: ": "Şu anki sürüm: " -} \ No newline at end of file +} diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 288f127d1..d7f12975e 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -11,7 +11,7 @@ "newest": "最新", "oldest": "最老", "popular": "时下流行", - "last": "last", + "last": "", "Next page": "下一页", "Previous page": "上一页", "Clear watch history?": "清除观看历史?", @@ -52,44 +52,44 @@ "Google verification code": "Google 验证代码", "Preferences": "偏好设置", "Player preferences": "播放器偏好设置", - "Always loop: ": "循环:", - "Autoplay: ": "自动播放:", - "Play next by default: ": "默认自动播放下一个视频:", - "Autoplay next video: ": "自动播放下一个视频:", - "Listen by default: ": "默认只聆听声音:", - "Proxy videos: ": "代理视频?", - "Default speed: ": "默认速度:", - "Preferred video quality: ": "视频质量偏好:", - "Player volume: ": "播放器音量:", - "Default comments: ": "默认评论源:", + "Always loop: ": "始终循环: ", + "Autoplay: ": "自动播放: ", + "Play next by default: ": "默认自动播放下一个视频: ", + "Autoplay next video: ": "自动播放下一个视频: ", + "Listen by default: ": "默认只听声音: ", + "Proxy videos: ": "是否代理视频: ", + "Default speed: ": "默认速度: ", + "Preferred video quality: ": "视频质量偏好: ", + "Player volume: ": "播放器音量: ", + "Default comments: ": "默认评论源: ", "youtube": "YouTube", "reddit": "Reddit", - "Default captions: ": "默认字幕语言:", - "Fallback captions: ": "后备字幕语言:", - "Show related videos: ": "显示相关视频?", - "Show annotations by default: ": "默认显示视频注释?", + "Default captions: ": "默认字幕语言: ", + "Fallback captions: ": "后备字幕语言: ", + "Show related videos: ": "是否显示相关视频: ", + "Show annotations by default: ": "是否默认显示视频注释: ", "Visual preferences": "视觉选项", - "Player style: ": "播放器样式:", - "Dark mode: ": "暗色模式:", - "Theme: ": "主题", + "Player style: ": "播放器样式: ", + "Dark mode: ": "深色模式: ", + "Theme: ": "主题: ", "dark": "暗色", "light": "亮色", - "Thin mode: ": "窄页模式:", + "Thin mode: ": "窄页模式: ", "Subscription preferences": "订阅设置", - "Show annotations by default for subscribed channels: ": "在订阅频道的视频默认显示注释?", + "Show annotations by default for subscribed channels: ": "默认情况下显示已订阅频道的注释: ", "Redirect homepage to feed: ": "跳转主页到 feed: ", - "Number of videos shown in feed: ": "Feed 中显示的视频数量:", - "Sort videos by: ": "视频排序方式:", + "Number of videos shown in feed: ": "Feed 中显示的视频数量: ", + "Sort videos by: ": "视频排序方式: ", "published": "发布时间", "published - reverse": "发布时间(反向)", "alphabetically": "字母序", "alphabetically - reverse": "字母序(反向)", "channel name": "频道名称", "channel name - reverse": "频道名称(反向)", - "Only show latest video from channel: ": "只显示订阅频道的最新一条视频:", - "Only show latest unwatched video from channel: ": "只显示订阅频道的最新未看过视频:", - "Only show unwatched: ": "只显示未看过的视频:", - "Only show notifications (if there are any): ": "只显示通知(如有):", + "Only show latest video from channel: ": "只显示频道的最新视频: ", + "Only show latest unwatched video from channel: ": "只显示频道的最新未看过视频: ", + "Only show unwatched: ": "只显示未看过的视频: ", + "Only show notifications (if there are any): ": "只显示通知 (如果有的话): ", "Enable web notifications": "启用浏览器通知", "`x` uploaded a video": "`x` 上传了视频", "`x` is live": "`x` 正在直播", @@ -102,13 +102,13 @@ "Watch history": "观看历史", "Delete account": "删除账户", "Administrator preferences": "管理员选项", - "Default homepage: ": "默认主页:", - "Feed menu: ": "Feed 菜单:", - "Top enabled: ": "启用“热门视频”页?", - "CAPTCHA enabled: ": "启用验证码?", - "Login enabled: ": "启用登录?", - "Registration enabled: ": "启用注册?", - "Report statistics: ": "报告统计信息?", + "Default homepage: ": "默认主页: ", + "Feed menu: ": "Feed 菜单: ", + "Top enabled: ": "是否启用“热门视频”页: ", + "CAPTCHA enabled: ": "是否启用验证码: ", + "Login enabled: ": "是否启用登录: ", + "Registration enabled: ": "是否启用注册: ", + "Report statistics: ": "是否报告统计信息: ", "Save preferences": "保存选项", "Subscription manager": "订阅管理器", "Token manager": "令牌管理器", @@ -141,13 +141,13 @@ "Watch on YouTube": "在 YouTube 观看", "Hide annotations": "隐藏注释", "Show annotations": "显示注释", - "Genre: ": "风格:", - "License: ": "协议:", - "Family friendly? ": "家庭友好?", - "Wilson score: ": "威尔逊得分:", - "Engagement: ": "参与度:", - "Whitelisted regions: ": "白名单区域:", - "Blacklisted regions: ": "黑名单区域:", + "Genre: ": "风格: ", + "License: ": "许可: ", + "Family friendly? ": "家庭友好? ", + "Wilson score: ": "威尔逊得分: ", + "Engagement: ": "参与度: ", + "Whitelisted regions: ": "白名单地区: ", + "Blacklisted regions: ": "黑名单地区: ", "Shared `x`": "`x`发布", "`x` views": "`x` 播放", "Premieres in `x`": "首映于 `x` 后", @@ -308,12 +308,12 @@ "`x` hours": "`x` 小时", "`x` minutes": "`x` 分钟", "`x` seconds": "`x` 秒", - "Fallback comments: ": "后备评论:", + "Fallback comments: ": "后备评论: ", "Popular": "热门频道", "Top": "热门视频", "About": "关于", - "Rating: ": "评分:", - "Language: ": "语言:", + "Rating: ": "评分: ", + "Language: ": "语言: ", "View as playlist": "作为播放列表查看", "Default": "默认", "Music": "音乐", @@ -321,7 +321,7 @@ "News": "新闻", "Movies": "电影", "Download": "下载", - "Download as: ": "下载为:", + "Download as: ": "下载为: ", "%A %B %-d, %Y": "%Y年%-m月%-d日 %a", "(edited)": "(已编辑)", "YouTube comment permalink": "YouTube 评论永久链接", @@ -332,5 +332,5 @@ "Videos": "视频", "Playlists": "播放列表", "Community": "社区", - "Current version: ": "当前版本:" -} \ No newline at end of file + "Current version: ": "当前版本: " +} diff --git a/locales/zh-TW.json b/locales/zh-TW.json index a81117506..6b40db55b 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -1,12 +1,8 @@ { - "`x` subscribers": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個訂閱者", - "": "`x` 個訂閱者。" - }, - "`x` videos": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 部影片", - "": "`x` 部影片。" - }, + "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個訂閱者", + "`x` subscribers.": "`x` 個訂閱者", + "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 部影片", + "`x` videos.": "`x` 部影片", "`x` playlists": "`x` 播放清單", "LIVE": "直播", "Shared `x` ago": "`x` 前分享", @@ -119,22 +115,16 @@ "Subscription manager": "訂閱管理員", "Token manager": "Token 管理員", "Token": "Token", - "`x` subscriptions": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個訂閱", - "": "`x` 個訂閱。" - }, - "`x` tokens": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` token", - "": "`x` tokens。" - }, + "`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個訂閱", + "`x` subscriptions.": "`x` 個訂閱", + "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "`x` token", + "`x` tokens.": "`x` 個存取金鑰", "Import/export": "匯入/匯出", "unsubscribe": "取消訂閱", "revoke": "撤銷", "Subscriptions": "訂閱", - "`x` unseen notifications": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個未讀的通知", - "": "`x` 個未讀的通知。" - }, + "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個未讀的通知", + "`x` unseen notifications.": "`x` 個未讀的通知", "search": "搜尋", "Log out": "登出", "Released under the AGPLv3 by Omar Roth.": "Omar Roth 以 AGPLv3 釋出。", @@ -164,10 +154,8 @@ "Whitelisted regions: ": "白名單區域: ", "Blacklisted regions: ": "黑名單區域: ", "Shared `x`": "`x` 發佈", - "`x` views": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 次檢視", - "": "`x` 次檢視。" - }, + "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 次檢視", + "`x` views.": "`x` 次檢視", "Premieres in `x`": "首映於 `x`", "Premieres `x`": "首映於 `x`", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "嗨!看來您將 JavaScript 關閉了。點擊這裡以檢視留言,請注意,它們可能需要比較長的時間載入。", @@ -198,16 +186,12 @@ "This channel does not exist.": "此頻道不存在。", "Could not get channel info.": "無法取得頻道資訊。", "Could not fetch comments": "無法擷取留言", - "View `x` replies": { - "([^.,0-9]|^)1([^.,0-9]|$)": "檢視 `x` 則回覆", - "": "檢視 `x` 則回覆。" - }, + "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "檢視 `x` 則回覆", + "View `x` replies.": "檢視 `x` 則回覆", "`x` ago": "`x` 以前", "Load more": "載入更多", - "`x` points": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 點", - "": "`x` 點。" - }, + "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 點", + "`x` points.": "`x` 點", "Could not create mix.": "無法建立混合。", "Empty playlist": "空的播放清單", "Not a playlist.": "不是播放清單。", @@ -325,34 +309,20 @@ "Yiddish": "意第緒語", "Yoruba": "約魯巴語", "Zulu": "祖魯語", - "`x` years": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 年", - "": "`x` 年。" - }, - "`x` months": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 月", - "": "`x` 月。" - }, - "`x` weeks": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 週", - "": "`x` 週。" - }, - "`x` days": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 天", - "": "`x` 天。" - }, - "`x` hours": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 小時", - "": "`x` 小時。" - }, - "`x` minutes": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 天", - "": "`x` 分鐘。" - }, - "`x` seconds": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 秒", - "": "`x` 秒。" - }, + "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 年", + "`x` years.": "`x` 年", + "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 月", + "`x` months.": "`x` 月", + "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 週", + "`x` weeks.": "`x` 週", + "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 天", + "`x` days.": "`x` 天", + "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 小時", + "`x` hours.": "`x` 小時", + "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 天", + "`x` minutes.": "`x` 分鐘", + "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "`x` 秒", + "`x` seconds.": "`x` 秒", "Fallback comments: ": "汰退留言: ", "Popular": "熱門頻道", "Top": "熱門影片", @@ -378,4 +348,4 @@ "Playlists": "播放清單", "Community": "社群", "Current version: ": "目前版本: " -} \ No newline at end of file +} From f8dbf9397911bd84d16e1fbae191c22de9b38afc Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty Date: Sat, 23 Jan 2021 18:22:05 +0100 Subject: [PATCH 14/32] Change some stuff done to the french translation in #1696 --- locales/fr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 664e25f55..d6bdc05a4 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -48,7 +48,7 @@ "Image CAPTCHA": "CAPTCHA Image", "Sign In": "Se connecter", "Register": "S'inscrire", - "E-mail": "Courriel", + "E-mail": "E-mail", "Google verification code": "Code de vérification Google", "Preferences": "Préférences", "Player preferences": "Préférences du lecteur", @@ -170,7 +170,7 @@ "User ID is a required field": "Veuillez entrer un Identifiant Utilisateur", "Password is a required field": "Veuillez entrer un Mot de passe", "Wrong username or password": "Nom d'utilisateur ou mot de passe invalide", - "Please sign in using 'Log in with Google'": "Veuillez vous connecter en utilisant « Se connecter avec Google »", + "Please sign in using 'Log in with Google'": "Veuillez vous connecter en utilisant \"Se connecter avec Google\"", "Password cannot be empty": "Le mot de passe ne peut pas être vide", "Password cannot be longer than 55 characters": "Le mot de passe ne doit pas comporter plus de 55 caractères", "Please log in": "Veuillez vous connecter", @@ -189,7 +189,7 @@ "Not a playlist.": "La liste de lecture est invalide.", "Playlist does not exist.": "La liste de lecture n'existe pas.", "Could not pull trending pages.": "Impossible de charger les pages de tendances.", - "Hidden field \"challenge\" is a required field": "Le champ masqué « challenge » est un champ obligatoire", + "Hidden field \"challenge\" is a required field": "Le champ masqué \"challenge\" est un champ obligatoire", "Hidden field \"token\" is a required field": "Le champ caché « token » est requis", "Erroneous challenge": "Challenge invalide", "Erroneous token": "Token invalide", From 10a3e742e380b2349166cee268f94f45a4b7be2d Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Sat, 23 Jan 2021 18:58:13 +0100 Subject: [PATCH 15/32] Add config environment variables The config file can now be specified with `INVIDIOUS_CONFIG_FILE`. A YAML formatted string can still be passed with `INVIDIOUS_CONFIG`, replacing the config file. Additionally all options can now be specified as environment variables. The syntax for variable names is `INVIDIOUS_` followed by the option name in upper case. The values are parsed as YAML. These new env vars only update the provided main configuration, but it is possible to point the config file at the example config and then use env vars for all config options: ``` INVIDIOUS_CONFIG_FILE=./config/config.example.yml \ INVIDIOUS_CHANNEL_THREADS=10 \ ./invidious ``` --- src/invidious.cr | 7 ++-- src/invidious/helpers/helpers.cr | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/invidious.cr b/src/invidious.cr index 10c23dac3..5415262a3 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -30,11 +30,8 @@ require "./invidious/*" require "./invidious/routes/**" require "./invidious/jobs/**" -ENV_CONFIG_NAME = "INVIDIOUS_CONFIG" - -CONFIG_STR = ENV.has_key?(ENV_CONFIG_NAME) ? ENV.fetch(ENV_CONFIG_NAME) : File.read("config/config.yml") -CONFIG = Config.from_yaml(CONFIG_STR) -HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32) +CONFIG = Config.load +HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32) PG_URL = URI.new( scheme: "postgres", diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index 1f56ec926..bcd786994 100644 --- a/src/invidious/helpers/helpers.cr +++ b/src/invidious/helpers/helpers.cr @@ -115,6 +115,63 @@ class Config return false end end + + def self.load + # Load config from file or YAML string env var + env_config_file = "INVIDIOUS_CONFIG_FILE" + env_config_yaml = "INVIDIOUS_CONFIG" + + config_file = ENV.has_key?(env_config_file) ? ENV.fetch(env_config_file) : "config/config.yml" + config_yaml = ENV.has_key?(env_config_yaml) ? ENV.fetch(env_config_yaml) : File.read(config_file) + + config = Config.from_yaml(config_yaml) + + # Update config from env vars (upcased and prefixed with "INVIDIOUS_") + {% for ivar in Config.instance_vars %} + {% env_id = "INVIDIOUS_#{ivar.id.upcase}" %} + + if ENV.has_key?({{env_id}}) + # puts %(Config.{{ivar.id}} : Loading from env var {{env_id}}) + env_value = ENV.fetch({{env_id}}) + success = false + + # Use YAML converter if specified + {% ann = ivar.annotation(::YAML::Field) %} + {% if ann && ann[:converter] %} + puts %(Config.{{ivar.id}} : Parsing "#{env_value}" as {{ivar.type}} with {{ann[:converter]}} converter) + config.{{ivar.id}} = {{ann[:converter]}}.from_yaml(YAML::ParseContext.new, YAML::Nodes.parse(ENV.fetch({{env_id}})).nodes[0]) + puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}}) + success = true + + # Use regular YAML parser otherwise + {% else %} + {% ivar_types = ivar.type.union? ? ivar.type.union_types : [ivar.type] %} + # Sort types to avoid parsing nulls and numbers as strings + {% ivar_types = ivar_types.sort_by { |ivar_type| ivar_type == Nil ? 0 : ivar_type == Int32 ? 1 : 2 } %} + {{ivar_types}}.each do |ivar_type| + if !success + begin + # puts %(Config.{{ivar.id}} : Trying to parse "#{env_value}" as #{ivar_type}) + config.{{ivar.id}} = ivar_type.from_yaml(env_value) + puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}} (#{ivar_type})) + success = true + rescue + # nop + end + end + end + {% end %} + + # Exit on fail + if !success + puts %(Config.{{ivar.id}} failed to parse #{env_value} as {{ivar.type}}) + exit(1) + end + end + {% end %} + + return config + end end struct DBConfig From 832bc04a0aca6518c9c5a0f37c474c3ed26e6050 Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Sat, 23 Jan 2021 19:39:04 +0100 Subject: [PATCH 16/32] Make config a constant Instead of passing around `config` there is now the global `CONFIG`. --- src/invidious.cr | 32 +++++++++----------- src/invidious/helpers/errors.cr | 32 ++++++++++---------- src/invidious/helpers/utils.cr | 12 ++++---- src/invidious/jobs/bypass_captcha_job.cr | 29 ++++++++---------- src/invidious/jobs/refresh_channels_job.cr | 7 ++--- src/invidious/jobs/refresh_feeds_job.cr | 5 ++- src/invidious/jobs/statistics_refresh_job.cr | 5 ++- src/invidious/jobs/subscribe_to_feeds_job.cr | 9 +++--- src/invidious/routes/base_route.cr | 4 --- src/invidious/routes/login.cr | 24 +++++++-------- src/invidious/routes/user_preferences.cr | 31 +++++++++---------- src/invidious/routing.cr | 4 +-- src/invidious/views/preferences.ecr | 14 ++++----- src/invidious/views/template.ecr | 2 +- 14 files changed, 97 insertions(+), 113 deletions(-) diff --git a/src/invidious.cr b/src/invidious.cr index 5415262a3..98d2ff89e 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -49,7 +49,7 @@ PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com") REDDIT_URL = URI.parse("https://www.reddit.com") TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com") YT_URL = URI.parse("https://www.youtube.com") -HOST_URL = make_host_url(CONFIG, Kemal.config) +HOST_URL = make_host_url(Kemal.config) CHARS_SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" TEST_IDS = {"AgbeGFYluEA", "BaW_jenozKc", "a9LDPn-MO4I", "ddFvjfvPnqk", "iqKdEhx-dD4"} @@ -142,8 +142,6 @@ end OUTPUT = CONFIG.output.upcase == "STDOUT" ? STDOUT : File.open(CONFIG.output, mode: "a") LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level) -config = CONFIG - # Check table integrity if CONFIG.check_tables check_enum(PG_DB, "privacy", PlaylistPrivacy) @@ -164,28 +162,28 @@ end # Start jobs -Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB, config) -Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB, config) +Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB) +Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB) DECRYPT_FUNCTION = DecryptFunction.new(CONFIG.decrypt_polling) -if config.decrypt_polling +if CONFIG.decrypt_polling Invidious::Jobs.register Invidious::Jobs::UpdateDecryptFunctionJob.new end -if config.statistics_enabled - Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, config, SOFTWARE) +if CONFIG.statistics_enabled + Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, SOFTWARE) end -if (config.use_pubsub_feeds.is_a?(Bool) && config.use_pubsub_feeds.as(Bool)) || (config.use_pubsub_feeds.is_a?(Int32) && config.use_pubsub_feeds.as(Int32) > 0) - Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, config, HMAC_KEY) +if (CONFIG.use_pubsub_feeds.is_a?(Bool) && CONFIG.use_pubsub_feeds.as(Bool)) || (CONFIG.use_pubsub_feeds.is_a?(Int32) && CONFIG.use_pubsub_feeds.as(Int32) > 0) + Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, HMAC_KEY) end -if config.popular_enabled +if CONFIG.popular_enabled Invidious::Jobs.register Invidious::Jobs::PullPopularVideosJob.new(PG_DB) end -if config.captcha_key - Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new(config) +if CONFIG.captcha_key + Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new end connection_channel = Channel({Bool, Channel(PQ::Notification)}).new(32) @@ -216,7 +214,7 @@ before_all do |env| env.response.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob:#{extra_media_csp}" env.response.headers["Referrer-Policy"] = "same-origin" - if (Kemal.config.ssl || config.https_only) && config.hsts + if (Kemal.config.ssl || CONFIG.https_only) && CONFIG.hsts env.response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload" end @@ -1161,7 +1159,7 @@ end get "/feed/popular" do |env| locale = LOCALES[env.get("preferences").as(Preferences).locale]? - if config.popular_enabled + if CONFIG.popular_enabled templated "popular" else message = translate(locale, "The Popular feed has been disabled by the administrator.") @@ -1819,7 +1817,7 @@ get "/api/v1/stats" do |env| locale = LOCALES[env.get("preferences").as(Preferences).locale]? env.response.content_type = "application/json" - if !config.statistics_enabled + if !CONFIG.statistics_enabled next error_json(400, "Statistics are not enabled.") end @@ -2229,7 +2227,7 @@ get "/api/v1/popular" do |env| env.response.content_type = "application/json" - if !config.popular_enabled + if !CONFIG.popular_enabled error_message = {"error" => "Administrator has disabled this endpoint."}.to_json env.response.status_code = 400 next error_message diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr index 2c62d44b5..68ced430b 100644 --- a/src/invidious/helpers/errors.cr +++ b/src/invidious/helpers/errors.cr @@ -7,7 +7,7 @@ class InfoException < Exception end macro error_template(*args) - error_template_helper(env, config, locale, {{*args}}) + error_template_helper(env, locale, {{*args}}) end def github_details(summary : String, content : String) @@ -22,9 +22,9 @@ def github_details(summary : String, content : String) return HTML.escape(details) end -def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) +def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) if exception.is_a?(InfoException) - return error_template_helper(env, config, locale, status_code, exception.message || "") + return error_template_helper(env, locale, status_code, exception.message || "") end env.response.content_type = "text/html" env.response.status_code = status_code @@ -43,7 +43,7 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale : return templated "error" end -def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) +def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) env.response.content_type = "text/html" env.response.status_code = status_code error_message = translate(locale, message) @@ -51,31 +51,31 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale : end macro error_atom(*args) - error_atom_helper(env, config, locale, {{*args}}) + error_atom_helper(env, locale, {{*args}}) end -def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) +def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) if exception.is_a?(InfoException) - return error_atom_helper(env, config, locale, status_code, exception.message || "") + return error_atom_helper(env, locale, status_code, exception.message || "") end env.response.content_type = "application/atom+xml" env.response.status_code = status_code return "#{exception.inspect_with_backtrace}" end -def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) +def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) env.response.content_type = "application/atom+xml" env.response.status_code = status_code return "#{message}" end macro error_json(*args) - error_json_helper(env, config, locale, {{*args}}) + error_json_helper(env, locale, {{*args}}) end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil) if exception.is_a?(InfoException) - return error_json_helper(env, config, locale, status_code, exception.message || "", additional_fields) + return error_json_helper(env, locale, status_code, exception.message || "", additional_fields) end env.response.content_type = "application/json" env.response.status_code = status_code @@ -86,11 +86,11 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has return error_message.to_json end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) - return error_json_helper(env, config, locale, status_code, exception, nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) + return error_json_helper(env, locale, status_code, exception, nil) end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil) env.response.content_type = "application/json" env.response.status_code = status_code error_message = {"error" => message} @@ -100,6 +100,6 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has return error_message.to_json end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) - error_json_helper(env, config, locale, status_code, message, nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) + error_json_helper(env, locale, status_code, message, nil) end diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index f068b5f2b..7d94a6e51 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -280,9 +280,9 @@ def arg_array(array, start = 1) return args end -def make_host_url(config, kemal_config) - ssl = config.https_only || kemal_config.ssl - port = config.external_port || kemal_config.port +def make_host_url(kemal_config) + ssl = CONFIG.https_only || kemal_config.ssl + port = CONFIG.external_port || kemal_config.port if ssl scheme = "https://" @@ -297,11 +297,11 @@ def make_host_url(config, kemal_config) port = "" end - if !config.domain + if !CONFIG.domain return "" end - host = config.domain.not_nil!.lchop(".") + host = CONFIG.domain.not_nil!.lchop(".") return "#{scheme}#{host}#{port}" end @@ -345,7 +345,7 @@ def sha256(text) return digest.final.hexstring end -def subscribe_pubsub(topic, key, config) +def subscribe_pubsub(topic, key) case topic when .match(/^UC[A-Za-z0-9_-]{22}$/) topic = "channel_id=#{topic}" diff --git a/src/invidious/jobs/bypass_captcha_job.cr b/src/invidious/jobs/bypass_captcha_job.cr index 22c540364..8b1aed5f0 100644 --- a/src/invidious/jobs/bypass_captcha_job.cr +++ b/src/invidious/jobs/bypass_captcha_job.cr @@ -1,9 +1,4 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob - private getter config : Config - - def initialize(@config) - end - def begin loop do begin @@ -22,9 +17,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob headers = response.cookies.add_request_headers(HTTP::Headers.new) - response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/createTask", + response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/createTask", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "task" => { "type" => "NoCaptchaTaskProxyless", "websiteURL" => "https://www.youtube.com#{path}", @@ -39,9 +34,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob loop do sleep 10.seconds - response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/getTaskResult", + response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/getTaskResult", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "taskId" => task_id, }.to_json).body) @@ -58,10 +53,10 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob response.cookies .select { |cookie| cookie.name != "PREF" } - .each { |cookie| config.cookies << cookie } + .each { |cookie| CONFIG.cookies << cookie } # Persist cookies between runs - File.write("config/config.yml", config.to_yaml) + File.write("config/config.yml", CONFIG.to_yaml) elsif response.headers["Location"]?.try &.includes?("/sorry/index") location = response.headers["Location"].try { |u| URI.parse(u) } headers = HTTP::Headers{":authority" => location.host.not_nil!} @@ -77,11 +72,11 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob inputs[node["name"]] = node["value"] end - captcha_client = HTTPClient.new(URI.parse(config.captcha_api_url)) - captcha_client.family = config.force_resolve || Socket::Family::INET + captcha_client = HTTPClient.new(URI.parse(CONFIG.captcha_api_url)) + captcha_client.family = CONFIG.force_resolve || Socket::Family::INET response = JSON.parse(captcha_client.post("/createTask", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "task" => { "type" => "NoCaptchaTaskProxyless", "websiteURL" => location.to_s, @@ -100,7 +95,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob response = JSON.parse(captcha_client.post("/getTaskResult", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "taskId" => task_id, }.to_json).body) @@ -119,10 +114,10 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob } cookies = HTTP::Cookies.from_headers(headers) - cookies.each { |cookie| config.cookies << cookie } + cookies.each { |cookie| CONFIG.cookies << cookie } # Persist cookies between runs - File.write("config/config.yml", config.to_yaml) + File.write("config/config.yml", CONFIG.to_yaml) end end rescue ex diff --git a/src/invidious/jobs/refresh_channels_job.cr b/src/invidious/jobs/refresh_channels_job.cr index 3e94a56e4..fbe6d381a 100644 --- a/src/invidious/jobs/refresh_channels_job.cr +++ b/src/invidious/jobs/refresh_channels_job.cr @@ -1,12 +1,11 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob private getter db : DB::Database - private getter config : Config - def initialize(@db, @config) + def initialize(@db) end def begin - max_fibers = config.channel_threads + max_fibers = CONFIG.channel_threads lim_fibers = max_fibers active_fibers = 0 active_channel = Channel(Bool).new @@ -31,7 +30,7 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob spawn do begin LOGGER.trace("RefreshChannelsJob: #{id} fiber : Fetching channel") - channel = fetch_channel(id, db, config.full_refresh) + channel = fetch_channel(id, db, CONFIG.full_refresh) lim_fibers = max_fibers diff --git a/src/invidious/jobs/refresh_feeds_job.cr b/src/invidious/jobs/refresh_feeds_job.cr index 7b4ccdeaf..926c27fa6 100644 --- a/src/invidious/jobs/refresh_feeds_job.cr +++ b/src/invidious/jobs/refresh_feeds_job.cr @@ -1,12 +1,11 @@ class Invidious::Jobs::RefreshFeedsJob < Invidious::Jobs::BaseJob private getter db : DB::Database - private getter config : Config - def initialize(@db, @config) + def initialize(@db) end def begin - max_fibers = config.feed_threads + max_fibers = CONFIG.feed_threads active_fibers = 0 active_channel = Channel(Bool).new diff --git a/src/invidious/jobs/statistics_refresh_job.cr b/src/invidious/jobs/statistics_refresh_job.cr index 021671bed..aa46fb0e7 100644 --- a/src/invidious/jobs/statistics_refresh_job.cr +++ b/src/invidious/jobs/statistics_refresh_job.cr @@ -21,9 +21,8 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob } private getter db : DB::Database - private getter config : Config - def initialize(@db, @config, @software_config : Hash(String, String)) + def initialize(@db, @software_config : Hash(String, String)) end def begin @@ -43,7 +42,7 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob "version" => @software_config["version"], "branch" => @software_config["branch"], } - STATISTICS["openRegistration"] = config.registration_enabled + STATISTICS["openRegistration"] = CONFIG.registration_enabled end private def refresh_stats diff --git a/src/invidious/jobs/subscribe_to_feeds_job.cr b/src/invidious/jobs/subscribe_to_feeds_job.cr index 750aceb8c..a431a48af 100644 --- a/src/invidious/jobs/subscribe_to_feeds_job.cr +++ b/src/invidious/jobs/subscribe_to_feeds_job.cr @@ -1,15 +1,14 @@ class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob private getter db : DB::Database private getter hmac_key : String - private getter config : Config - def initialize(@db, @config, @hmac_key) + def initialize(@db, @hmac_key) end def begin max_fibers = 1 - if config.use_pubsub_feeds.is_a?(Int32) - max_fibers = config.use_pubsub_feeds.as(Int32) + if CONFIG.use_pubsub_feeds.is_a?(Int32) + max_fibers = CONFIG.use_pubsub_feeds.as(Int32) end active_fibers = 0 @@ -30,7 +29,7 @@ class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob spawn do begin - response = subscribe_pubsub(ucid, hmac_key, config) + response = subscribe_pubsub(ucid, hmac_key) if response.status_code >= 400 LOGGER.error("SubscribeToFeedsJob: #{ucid} : #{response.body}") diff --git a/src/invidious/routes/base_route.cr b/src/invidious/routes/base_route.cr index 376242670..07c6f15b9 100644 --- a/src/invidious/routes/base_route.cr +++ b/src/invidious/routes/base_route.cr @@ -1,6 +1,2 @@ abstract class Invidious::Routes::BaseRoute - private getter config : Config - - def initialize(@config) - end end diff --git a/src/invidious/routes/login.cr b/src/invidious/routes/login.cr index 45a6d4d8c..662fdf13b 100644 --- a/src/invidious/routes/login.cr +++ b/src/invidious/routes/login.cr @@ -6,7 +6,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute return env.redirect "/feed/subscriptions" if user - if !config.login_enabled + if !CONFIG.login_enabled return error_template(400, "Login has been disabled by administrator.") end @@ -33,7 +33,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute referer = get_referer(env, "/feed/subscriptions") - if !config.login_enabled + if !CONFIG.login_enabled return error_template(403, "Login has been disabled by administrator.") end @@ -274,14 +274,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute host = URI.parse(env.request.headers["Host"]).host - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end cookies.each do |cookie| - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only cookie.secure = secure else cookie.secure = secure @@ -330,14 +330,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32)) PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", sid, email, Time.utc) - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years, @@ -354,7 +354,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute env.response.cookies << cookie end else - if !config.registration_enabled + if !CONFIG.registration_enabled return error_template(400, "Registration has been disabled by administrator.") end @@ -369,7 +369,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute password = password.byte_slice(0, 55) - if config.captcha_enabled + if CONFIG.captcha_enabled captcha_type = env.params.body["captcha_type"]? answer = env.params.body["answer"]? change_type = env.params.body["change_type"]? @@ -445,14 +445,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute view_name = "subscriptions_#{sha256(user.email)}" PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}") - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years, diff --git a/src/invidious/routes/user_preferences.cr b/src/invidious/routes/user_preferences.cr index 7f3341154..a689a2a2f 100644 --- a/src/invidious/routes/user_preferences.cr +++ b/src/invidious/routes/user_preferences.cr @@ -146,8 +146,8 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute user = user.as(User) PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email) - if config.admins.includes? user.email - config.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || config.default_user_preferences.default_home + if CONFIG.admins.includes? user.email + CONFIG.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || CONFIG.default_user_preferences.default_home admin_feed_menu = [] of String 4.times do |index| @@ -156,40 +156,39 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute admin_feed_menu << option end end - config.default_user_preferences.feed_menu = admin_feed_menu + CONFIG.default_user_preferences.feed_menu = admin_feed_menu popular_enabled = env.params.body["popular_enabled"]?.try &.as(String) popular_enabled ||= "off" - config.popular_enabled = popular_enabled == "on" + CONFIG.popular_enabled = popular_enabled == "on" captcha_enabled = env.params.body["captcha_enabled"]?.try &.as(String) captcha_enabled ||= "off" - config.captcha_enabled = captcha_enabled == "on" + CONFIG.captcha_enabled = captcha_enabled == "on" login_enabled = env.params.body["login_enabled"]?.try &.as(String) login_enabled ||= "off" - config.login_enabled = login_enabled == "on" + CONFIG.login_enabled = login_enabled == "on" registration_enabled = env.params.body["registration_enabled"]?.try &.as(String) registration_enabled ||= "off" - config.registration_enabled = registration_enabled == "on" + CONFIG.registration_enabled = registration_enabled == "on" statistics_enabled = env.params.body["statistics_enabled"]?.try &.as(String) statistics_enabled ||= "off" - config.statistics_enabled = statistics_enabled == "on" + CONFIG.statistics_enabled = statistics_enabled == "on" - CONFIG.default_user_preferences = config.default_user_preferences - File.write("config/config.yml", config.to_yaml) + File.write("config/config.yml", CONFIG.to_yaml) end else - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years, @@ -234,14 +233,14 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute preferences = preferences.to_json - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years, diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index 593c73727..82d0028ba 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -1,14 +1,14 @@ module Invidious::Routing macro get(path, controller, method = :handle) get {{ path }} do |env| - controller_instance = {{ controller }}.new(config) + controller_instance = {{ controller }}.new controller_instance.{{ method.id }}(env) end end macro post(path, controller, method = :handle) post {{ path }} do |env| - controller_instance = {{ controller }}.new(config) + controller_instance = {{ controller }}.new controller_instance.{{ method.id }}(env) end end diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr index 1ef080bed..14d63536f 100644 --- a/src/invidious/views/preferences.ecr +++ b/src/invidious/views/preferences.ecr @@ -208,14 +208,14 @@ <% # Web notifications are only supported over HTTPS %> - <% if Kemal.config.ssl || config.https_only %> + <% if Kemal.config.ssl || CONFIG.https_only %> <% end %> <% end %> - <% if env.get?("user") && config.admins.includes? env.get?("user").as(User).email %> + <% if env.get?("user") && CONFIG.admins.includes? env.get?("user").as(User).email %> <%= translate(locale, "Administrator preferences") %>
@@ -240,28 +240,28 @@
- checked<% end %>> + checked<% end %>>
- checked<% end %>> + checked<% end %>>
- checked<% end %>> + checked<% end %>>
- checked<% end %>> + checked<% end %>>
- checked<% end %>> + checked<% end %>>
<% end %> diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr index f6e5262dd..61b900e3d 100644 --- a/src/invidious/views/template.ecr +++ b/src/invidious/views/template.ecr @@ -87,7 +87,7 @@
- <% if config.login_enabled %> + <% if CONFIG.login_enabled %>
" class="pure-menu-heading"> <%= translate(locale, "Log in") %> From 1baea6a4366a75cbcb611412b0ca36ea3c592f0b Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Sat, 23 Jan 2021 19:41:50 +0100 Subject: [PATCH 17/32] Only start refresh jobs when necessary If `channel_threads` or `feed_threads` is set to zero the corresponding job is now not started. --- src/invidious.cr | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/invidious.cr b/src/invidious.cr index 98d2ff89e..12145d8bb 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -162,8 +162,13 @@ end # Start jobs -Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB) -Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB) +if CONFIG.channel_threads > 0 + Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB) +end + +if CONFIG.feed_threads > 0 + Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB) +end DECRYPT_FUNCTION = DecryptFunction.new(CONFIG.decrypt_polling) if CONFIG.decrypt_polling From a592031bbf1cf2df2f6885370ee23afe6403ecca Mon Sep 17 00:00:00 2001 From: Andrew Zhao Date: Wed, 27 Jan 2021 12:36:24 -0500 Subject: [PATCH 18/32] remove https from channel thumbnail in search --- src/invidious/helpers/helpers.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index bcd786994..000871436 100644 --- a/src/invidious/helpers/helpers.cr +++ b/src/invidious/helpers/helpers.cr @@ -282,7 +282,7 @@ def extract_item(item : JSON::Any, author_fallback : String? = nil, author_id_fa author = i["title"]["simpleText"]?.try &.as_s || author_fallback || "" author_id = i["channelId"]?.try &.as_s || author_id_fallback || "" - author_thumbnail = i["thumbnail"]["thumbnails"]?.try &.as_a[0]?.try { |u| "https:#{u["url"]}" } || "" + author_thumbnail = i["thumbnail"]["thumbnails"]?.try &.as_a[0]?.try &.["url"]?.try &.as_s || "" subscriber_count = i["subscriberCountText"]?.try &.["simpleText"]?.try &.as_s.try { |s| short_text_to_number(s.split(" ")[0]) } || 0 auto_generated = false From 870d4b0b19431a03052f83aea8b5aaf0b74759f4 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Thu, 28 Jan 2021 12:51:34 +0100 Subject: [PATCH 19/32] Remove container release on PR --- .github/workflows/container-release.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/container-release.yml b/.github/workflows/container-release.yml index 137308d09..1f811b7cb 100644 --- a/.github/workflows/container-release.yml +++ b/.github/workflows/container-release.yml @@ -4,8 +4,6 @@ on: push: branches: - "master" - pull_request: - branches: "*" schedule: - cron: 0 0 * * * @@ -39,13 +37,3 @@ jobs: labels: quay.expires-after=12w push: true tags: quay.io/invidious/invidious:${{ github.sha }},quay.io/invidious/invidious:latest - - - name: Build and push for Pull Request - if: github.ref != 'refs/heads/master' - uses: docker/build-push-action@v2 - with: - context: . - file: docker/Dockerfile - labels: quay.expires-after=6w - push: true - tags: quay.io/invidious/invidious:${{ github.sha }} From 30391c97f6a655d8d3731d869dba278563e9208c Mon Sep 17 00:00:00 2001 From: Andrew Zhao Date: Fri, 29 Jan 2021 12:36:19 -0500 Subject: [PATCH 20/32] install crystal 35.1 in ci --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fde6506ee..fc0e80965 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,8 @@ jobs: - name: Install Crystal uses: oprypin/install-crystal@v1.2.4 + with: + crystal: 0.35.1 - name: Cache Shards uses: actions/cache@v2 From b084192ce534d3c5ed954430efec1943f929a320 Mon Sep 17 00:00:00 2001 From: Andrew Zhao Date: Wed, 27 Jan 2021 10:45:03 -0500 Subject: [PATCH 21/32] Bump videojs and fix webworker --- assets/css/video-js.min.css | 2 +- assets/js/global.js | 3 --- assets/js/video.min.js | 25 +++++++++++-------- src/invidious.cr | 2 +- .../views/components/player_sources.ecr | 1 - 5 files changed, 17 insertions(+), 16 deletions(-) delete mode 100644 assets/js/global.js diff --git a/assets/css/video-js.min.css b/assets/css/video-js.min.css index b453b88cf..17702b1b6 100644 --- a/assets/css/video-js.min.css +++ b/assets/css/video-js.min.css @@ -1 +1 @@ -@charset "UTF-8";.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAABDkAAsAAAAAG6gAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPgAAAFZRiV3hY21hcAAAAYQAAADaAAADPv749/pnbHlmAAACYAAAC3AAABHQZg6OcWhlYWQAAA3QAAAAKwAAADYZw251aGhlYQAADfwAAAAdAAAAJA+RCLFobXR4AAAOHAAAABMAAACM744AAGxvY2EAAA4wAAAASAAAAEhF6kqubWF4cAAADngAAAAfAAAAIAE0AIFuYW1lAAAOmAAAASUAAAIK1cf1oHBvc3QAAA/AAAABJAAAAdPExYuNeJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGS7wTiBgZWBgaWQ5RkDA8MvCM0cwxDOeI6BgYmBlZkBKwhIc01hcPjI+FGJHcRdyA4RZgQRADK3CxEAAHic7dFZbsMgAEXRS0ycyZnnOeG7y+qC8pU1dHusIOXxuoxaOlwZYWQB0Aea4quIEN4E9LzKbKjzDeM6H/mua6Lmc/p8yhg0lvdYx15ZG8uOLQOGjMp3EzqmzJizYMmKNRu27Nhz4MiJMxeu3Ljz4Ekqm7T8P52G8PP3lnTOVk++Z6iN6QZzNN1F7ptuN7eGOjDUoaGODHVsuvU8MdTO9Hd5aqgzQ50b6sJQl4a6MtS1oW4MdWuoO0PdG+rBUI+GejLUs6FeDPVqqDdDvRvqw1CfhpqM9At0iFLaAAB4nJ1YDXBTVRZ+5/22TUlJ8we0pHlJm7RJf5O8F2j6EymlSPkpxaL8U2xpa3DKj0CBhc2IW4eWKSokIoLsuMqssM64f+jA4HSdWXXXscBq67IOs3FXZ1ZYWVyRFdo899yXtIBQZ90k7717zz3v3HPPOfd854YCCj9cL9dL0RQFOqCbGJnrHb5EayiKIWN8iA/hWBblo6hUWm8TtCDwE80WMJus/irwyxOdxeB0MDb14VNJHnXYoLLSl6FfCUYO9nYPTA8Epg9090LprfbBbZ2hY0UlJUXHQp3/vtWkS6EBv8+rPMq5u9692f/dNxJNiqwC1xPE9TCUgCsSdQWgE3XQD25lkG4CN2xmTcOXWBOyser6RN6KnGbKSbmQ3+d0OI1m2W8QzLLkI2sykrWAgJJEtA8vGGW/2Q+CmT3n8zS9wZwu2DCvtuZKZN3xkrLh36yCZuUomQSqGpY8t/25VfHVhw8z4ebGBtfLb0ya9PCaDc+8dGTvk2dsh6z7WzvowlXKUSWo9MJ15a3KrEP2loOr2Ojhw6iW6hf2BDdEccQvZGpaAy7YovSwq8kr7HGllxpd71rkS6G0Sf11sl9OvMK1+jwPPODxjUwkOim9CU3ix1wNjXDfmJSEn618Bs6lpWwUpU+8PCqLMY650zjq8VhCIP17NEKTx3eaLL+s5Pi6yJWaWjTHLR1jYzPSV9VF/6Ojdb/1kO3Mk3uhHC0x6gc1BjlKQ+nQFxTYdaJkZ7ySVxLBbhR1dsboNXp1tCYKW2LRaEzpYcIx2BKNxaL0ZaUnSqfFoiNhHKR/GkX6PWUSAaJelQaqZL1EpoHNsajSEyPSoJ9IjhIxTdjHLmwZvhRDOiFTY/YeQnvrVZmiTQtGncECXtFTBZLOVwwMRgoXHAkXzMzPn1nAJJ8jYSbMDaqN2waGLzNhih/bZynUBMpIWSg7VYi7DRx2m8ALkIdRCJwI6ArJx2EI8kaDWeTQKeAFk9fjl/1AvwktjQ1P7NjyMGQyfd4vjipX6M/i52D7Cq80kqlcxEcGXRr/FEcgs0u5uGgB4VWuMFfpdn2Re6Hi3PqzmxWKsz6+ae2Pn9hXXw/fqM859UiGC0oKYYILJBqJrsn1Z1E5qOs9rQCiUQRREjm8yJcbHF5cUJufX1vAHlefw0XgUoboS3ETfQlTxBC4SOtuE8VPRJTBSCQSjZCpk7Gqzu+masaZ2y7Zjehho4F3g82BNDkAHpORG4+OCS+f6JTPmtRn/PH1kch6d04sp7AQb25aQ/pqUyXeQ8vrebG8OYQdXOQ+585u0sdW9rqalzRURiJ+9F4MweRFrKUjl1GUYhH1A27WOHw5cTFSFPMo9EeUIGnQTZHIaJ7AHLaOKsOODaNF9jkBjYG2QEsQ2xjMUAx2bBEbeTBWMHwskBjngq56S/yfgkBnWBa4K9sqKtq2t1UI8S9He5XuBRbawAdatrQEAi30Aks2+LM8WeCbalVZkWNylvJ+dqJnzVb+OHlSoKW8nPCP7Rd+CcZ2DdWAGqJ2CBFOphgywFFCFBNtfAbGtNPBCwxvygHeYMZMY9ZboBqwq/pVrsbgN5tkv152ODlbMfiqwGMBgxa4Exz3QhovRIUp6acqZmQzRq0ypDXS2TPLT02YIkQETnOE445oOGxOmXAqUJNNG7XgupMjPq2ua9asrj5yY/yuKteO1Kx0YNJTufrirLe1mZnat7OL6rnUdCWenpW6I8mAnbsY8KWs1PuSovCW9A/Z25PQ24a7cNOqgmTkLmBMgh4THgc4b9k2IVv1/g/F5nGljwPLfOgHAzJzh45V/4+WenTzmMtR5Z7us2Tys909UHqrPY7KbckoxRvRHhmVc3cJGE97uml0R1S0jdULVl7EvZtDFVBF35N9cEdjpgmAiOlFZ+Dtoh93+D3zzHr8RRNZQhnCNMNbcegOvpEwZoL+06cJQ07h+th3fZ/7PVbVC6ngTAV/KoLFuO6+2KFcU651gEb5ugPSIb1D+Xp8V4+k3sEIGnw5mYe4If4k1lFYr6SCzmM2EQ8iWtmwjnBI9kTwe1TlfAmXh7H02by9fW2gsjKwtv0aaURKil4OdV7rDL1MXIFNrhdxohcZXYTnq47WisrKitaObbf5+yvkLi5J6lCNZZ+B6GC38VNBZBDidSS/+mSvh6s+srgC8pyKMvDtt+de3c9fU76ZPfuM8ud4Kv0fyP/LqfepMT/3oZxSqpZaTa1DaQYLY8TFsHYbWYsPoRhRWfL5eSSQbhUGgGC3YLbVMk6PitTFNGpAsNrC6D1VNBKgBHMejaiuRWEWGgsSDBTJjqWIl8kJLlsaLJ2tXDr6xGfT85bM2Q06a46x2HTgvdnV8z5YDy/27J4zt6x2VtkzjoYpkq36kaBr4eQSg7tyiVweWubXZugtadl58ydapfbORfKsDTuZ0OBgx4cfdjCf5tbWNITnL120fdOi1RV1C3uKGzNdwYLcMvZ3BxoPyTOCD1XvXTp7U10gWCVmTV9b3r2z0SkGWovb2hp9I89O8a2smlyaO8muMU+dRmtzp60IzAoFpjLr1n388boLyf0dRvxhsHZ0qbWqDkwqvvpkj4l0fY6EIXRi5sQSrAvsVYwXRy4qJ2EVtD1AN7a0HWth9ymvL1xc3WTUKK/TAHA/bXDVtVWfOMfuGxGZv4Ln/jVr9jc3j1yMv0tndmyt9Vq88Y9gH1wtLX3KWjot5++jWHgAoZZkQ14wGQ20Fli71UmKJAy4xKMSTGbVdybW7FDDAut9XpD5AzWrYO7zQ8qffqF8+Ynd/clrHcdyxGy3a/3+mfNnzC/cBsveTjnTvXf1o6vzOlZw7WtqtdmPK/Errz/6NNtD72zmNOZfbmYdTGHfoofqI79Oc+R2n1lrnL6pOm0Up7kwxhTW12Amm7WYkXR2qYrF2AmgmbAsxZjwy1xpg/m1Je2vrp8v/nz2xpmlBg4E9hrMU341wVpTOh/OfmGvAnra8q6uctr60ZQHV3Q+WMQJykMj8ZsWn2QBOmmHMB+m5pDIpTFonYigiaKAhGEiAHF7EliVnQkjoLVIMPtJpBKHYd3A8GYH9jJzrWwmHx5Qjp7vDAX0suGRym1vtm/9W1/HyR8vczfMs6Sk8DSv855/5dlX9oQq52hT8syyp2rx5Id17IAyAM3wIjQPMOHzytEB64q6D5zT91yNbnx3V/nqnd017S9Y0605k3izoXLpsxde2n38yoOV9s1LcjwzNjbdX6asnBVaBj/6/DwKwPkpcqbDG7BnsXoSqWnUAmottYF6jMSdVyYZh3zVXCjwTiwwHH6sGuRiEHQGzuRX6whZkp123oy1BWE2mEfJ/tvIRtM4ZM5bDXiMsPMaAKOTyc5uL57rqyyc5y5JE5pm1i2S2iUX0CcaQ6lC6Zog7JqSqZmYlosl2K6pwNA84zRnQW6SaALYZQGW5lhCtU/W34N6o+bKfZ8cf3/Cl/+iTX3wBzpOY4mRkeNf3rptycGSshQWgGbYt5jFc2e0+DglIrwl6DVWQ7BuwaJ3Xk1J4VL5urnLl/Wf+gHU/hZoZdKNym6lG+I34FaNeZKcSpJIo2IeCVvpdsDGfKvzJnAwmeD37Ow65ZWwSowpgwX5T69s/rB55dP5BcpgDKFV8p7q2sn/1uc93bVzT/w6UrCqDTWvfCq/oCD/qZXNoUj8BL5Kp6GU017frfNXkAtiiyf/SOCEeLqnd8R/Ql9GlCRfctS6k5chvIBuQ1zCCjoCHL2DHNHIXxMJ3kQeO8lbsUXONeSfA5EjcG6/E+KdhN4bP04vBhdi883+BFBzQbxFbvZzQeY9LNBZc0FNfn5NwfDn6rCTnTw6R8o+gfpf5hCom33cRuiTlss3KHmZjD+BPN+5gXuA2ziS/Q73mLxUkpbKN/eqwz5uK0X9F3h2d1V4nGNgZGBgAOJd776+iue3+crAzc4AAje5Bfcg0xz9YHEOBiYQBQA8FQlFAHicY2BkYGBnAAGOPgaG//85+hkYGVCBMgBGGwNYAAAAeJxjYGBgYB8EmKOPgQEAQ04BfgAAAAAAAA4AaAB+AMwA4AECAUIBbAGYAcICGAJYArQC4AMwA7AD3gQwBJYE3AUkBWYFigYgBmYGtAbqB1gIEghYCG4IhAi2COh4nGNgZGBgUGYoZWBnAAEmIOYCQgaG/2A+AwAYCQG2AHicXZBNaoNAGIZfE5PQCKFQ2lUps2oXBfOzzAESyDKBQJdGR2NQR3QSSE/QE/QEPUUPUHqsvsrXjTMw83zPvPMNCuAWP3DQDAejdm1GjzwS7pMmwi75XngAD4/CQ/oX4TFe4Qt7uMMbOzjuDc0EmXCP/C7cJ38Iu+RP4QEe8CU8pP8WHmOPX2EPz87TPo202ey2OjlnQSXV/6arOjWFmvszMWtd6CqwOlKHq6ovycLaWMWVydXKFFZnmVFlZU46tP7R2nI5ncbi/dDkfDtFBA2DDXbYkhKc+V0Bqs5Zt9JM1HQGBRTm/EezTmZNKtpcAMs9Yu6AK9caF76zoLWIWcfMGOSkVduvSWechqZsz040Ib2PY3urxBJTzriT95lipz+TN1fmAAAAeJxtkMl2wjAMRfOAhABlKm2h80C3+ajgCKKDY6cegP59TYBzukAL+z1Zsq8ctaJTTKPrsUQLbXQQI0EXKXroY4AbDDHCGBNMcYsZ7nCPB8yxwCOe8IwXvOIN7/jAJ76wxHfUqWX+OzgumWAjJMV17i0Ndlr6irLKO+qftdT7i6y4uFSUvCknay+lFYZIZaQcmfH/xIFdYn98bqhra1aKTM/6lWMnyaYirx1rFUQZFBkb2zJUtoXeJCeg0WnLtHeSFc3OtrnozNwqi0TkSpBMDB1nSde5oJXW23hTS2/T0LilglXX7dmFVxLnq5U0vYATHFk3zX3BOisoQHNDFDeZnqKDy9hRNawN7Vh727hFzcJ5c8TILrKZfH7tIPxAFP0BpLeJPA==) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle,.vjs-seek-to-live-control .vjs-icon-placeholder{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before,.vjs-seek-to-live-control .vjs-icon-placeholder:before{content:"\f111"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f115"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f11e"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f11f"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f120"}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-enter:before{content:"\f121"}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-exit:before{content:"\f122"}.video-js{display:block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js.vjs-fill{width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}body.vjs-full-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen{width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.63332em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.81666em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.js-focus-visible .vjs-menu li.vjs-menu-item:hover,.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.js-focus-visible .vjs-menu li.vjs-selected:hover,.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:5em}.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:10em}.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:14em}.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:25em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-liveui .vjs-progress-control{display:flex;align-items:center}.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.6666666667em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;top:-.3333333333em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;margin-right:0}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical{left:-3.5em;transition:left 0s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active{width:10em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3000em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;visibility:visible;opacity:1;position:relative;transition:none}.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{position:absolute;bottom:3em;left:.5em}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-liveui .vjs-live-control,.video-js:not(.vjs-live) .vjs-live-control{display:none}.video-js .vjs-seek-to-live-control{cursor:pointer;flex:none;display:inline-flex;height:100%;padding-left:.5em;padding-right:.5em;font-size:1em;line-height:3em;width:auto;min-width:4em}.vjs-no-flex .vjs-seek-to-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control,.video-js:not(.vjs-live) .vjs-seek-to-live-control{display:none}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge{cursor:auto}.vjs-seek-to-live-control .vjs-icon-placeholder{margin-right:.5em;color:#888}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder{color:red}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-live .vjs-time-control{display:none}.video-js .vjs-current-time,.vjs-no-flex .vjs-current-time{display:none}.video-js .vjs-duration,.vjs-no-flex .vjs-duration{display:none}.vjs-time-divider{display:none;line-height:3em}.vjs-live .vjs-time-divider{display:none}.video-js .vjs-play-control{cursor:pointer}.video-js .vjs-play-control .vjs-icon-placeholder{flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{transform:translateY(-1.5em)}.video-js .vjs-picture-in-picture-control{cursor:pointer;flex:none}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:"X";font-family:Arial,Helvetica,sans-serif;font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block;-webkit-animation:vjs-spinner-show 0s linear .3s forwards;animation:vjs-spinner-show 0s linear .3s forwards}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@-webkit-keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}@-webkit-keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"";font-size:1.5em;line-height:inherit}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" ";font-size:1.5em;line-height:inherit}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-control{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:auto;width:initial}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-live) .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-liveui) .vjs-subs-caps-button{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-custom-control-spacer{flex:auto;display:block}.video-js:not(.vjs-fullscreen).vjs-layout-tiny.vjs-no-flex .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui.vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-progress-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-progress-control{display:none}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;padding:20px 24px 0 24px}.vjs-track-settings-controls .vjs-default-button{margin-bottom:20px}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:1/-1}.vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content{grid-template-columns:1fr}}.vjs-track-setting>select{margin-right:1em;margin-bottom:.5em}.vjs-text-track-settings fieldset{margin:5px;padding:3px;border:none}.vjs-text-track-settings fieldset span{display:inline-block}.vjs-text-track-settings fieldset span>select{max-width:7.3em}.vjs-text-track-settings legend{color:#fff;margin:0 0 5px 0}.vjs-text-track-settings .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);display:block;margin:0 0 5px 0;padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:-1000}.js-focus-visible .video-js :focus:not(.focus-visible){outline:0;background:0 0}.video-js .vjs-menu :focus:not(:focus-visible),.video-js :focus:not(:focus-visible){outline:0;background:0 0} \ No newline at end of file +@charset "UTF-8";.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAABDkAAsAAAAAG6gAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPgAAAFZRiV3hY21hcAAAAYQAAADaAAADPv749/pnbHlmAAACYAAAC3AAABHQZg6OcWhlYWQAAA3QAAAAKwAAADYZw251aGhlYQAADfwAAAAdAAAAJA+RCLFobXR4AAAOHAAAABMAAACM744AAGxvY2EAAA4wAAAASAAAAEhF6kqubWF4cAAADngAAAAfAAAAIAE0AIFuYW1lAAAOmAAAASUAAAIK1cf1oHBvc3QAAA/AAAABJAAAAdPExYuNeJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGS7wTiBgZWBgaWQ5RkDA8MvCM0cwxDOeI6BgYmBlZkBKwhIc01hcPjI+FGJHcRdyA4RZgQRADK3CxEAAHic7dFZbsMgAEXRS0ycyZnnOeG7y+qC8pU1dHusIOXxuoxaOlwZYWQB0Aea4quIEN4E9LzKbKjzDeM6H/mua6Lmc/p8yhg0lvdYx15ZG8uOLQOGjMp3EzqmzJizYMmKNRu27Nhz4MiJMxeu3Ljz4Ekqm7T8P52G8PP3lnTOVk++Z6iN6QZzNN1F7ptuN7eGOjDUoaGODHVsuvU8MdTO9Hd5aqgzQ50b6sJQl4a6MtS1oW4MdWuoO0PdG+rBUI+GejLUs6FeDPVqqDdDvRvqw1CfhpqM9At0iFLaAAB4nJ1YDXBTVRZ+5/22TUlJ8we0pHlJm7RJf5O8F2j6EymlSPkpxaL8U2xpa3DKj0CBhc2IW4eWKSokIoLsuMqssM64f+jA4HSdWXXXscBq67IOs3FXZ1ZYWVyRFdo899yXtIBQZ90k7717zz3v3HPPOfd854YCCj9cL9dL0RQFOqCbGJnrHb5EayiKIWN8iA/hWBblo6hUWm8TtCDwE80WMJus/irwyxOdxeB0MDb14VNJHnXYoLLSl6FfCUYO9nYPTA8Epg9090LprfbBbZ2hY0UlJUXHQp3/vtWkS6EBv8+rPMq5u9692f/dNxJNiqwC1xPE9TCUgCsSdQWgE3XQD25lkG4CN2xmTcOXWBOyser6RN6KnGbKSbmQ3+d0OI1m2W8QzLLkI2sykrWAgJJEtA8vGGW/2Q+CmT3n8zS9wZwu2DCvtuZKZN3xkrLh36yCZuUomQSqGpY8t/25VfHVhw8z4ebGBtfLb0ya9PCaDc+8dGTvk2dsh6z7WzvowlXKUSWo9MJ15a3KrEP2loOr2Ojhw6iW6hf2BDdEccQvZGpaAy7YovSwq8kr7HGllxpd71rkS6G0Sf11sl9OvMK1+jwPPODxjUwkOim9CU3ix1wNjXDfmJSEn618Bs6lpWwUpU+8PCqLMY650zjq8VhCIP17NEKTx3eaLL+s5Pi6yJWaWjTHLR1jYzPSV9VF/6Ojdb/1kO3Mk3uhHC0x6gc1BjlKQ+nQFxTYdaJkZ7ySVxLBbhR1dsboNXp1tCYKW2LRaEzpYcIx2BKNxaL0ZaUnSqfFoiNhHKR/GkX6PWUSAaJelQaqZL1EpoHNsajSEyPSoJ9IjhIxTdjHLmwZvhRDOiFTY/YeQnvrVZmiTQtGncECXtFTBZLOVwwMRgoXHAkXzMzPn1nAJJ8jYSbMDaqN2waGLzNhih/bZynUBMpIWSg7VYi7DRx2m8ALkIdRCJwI6ArJx2EI8kaDWeTQKeAFk9fjl/1AvwktjQ1P7NjyMGQyfd4vjipX6M/i52D7Cq80kqlcxEcGXRr/FEcgs0u5uGgB4VWuMFfpdn2Re6Hi3PqzmxWKsz6+ae2Pn9hXXw/fqM859UiGC0oKYYILJBqJrsn1Z1E5qOs9rQCiUQRREjm8yJcbHF5cUJufX1vAHlefw0XgUoboS3ETfQlTxBC4SOtuE8VPRJTBSCQSjZCpk7Gqzu+masaZ2y7Zjehho4F3g82BNDkAHpORG4+OCS+f6JTPmtRn/PH1kch6d04sp7AQb25aQ/pqUyXeQ8vrebG8OYQdXOQ+585u0sdW9rqalzRURiJ+9F4MweRFrKUjl1GUYhH1A27WOHw5cTFSFPMo9EeUIGnQTZHIaJ7AHLaOKsOODaNF9jkBjYG2QEsQ2xjMUAx2bBEbeTBWMHwskBjngq56S/yfgkBnWBa4K9sqKtq2t1UI8S9He5XuBRbawAdatrQEAi30Aks2+LM8WeCbalVZkWNylvJ+dqJnzVb+OHlSoKW8nPCP7Rd+CcZ2DdWAGqJ2CBFOphgywFFCFBNtfAbGtNPBCwxvygHeYMZMY9ZboBqwq/pVrsbgN5tkv152ODlbMfiqwGMBgxa4Exz3QhovRIUp6acqZmQzRq0ypDXS2TPLT02YIkQETnOE445oOGxOmXAqUJNNG7XgupMjPq2ua9asrj5yY/yuKteO1Kx0YNJTufrirLe1mZnat7OL6rnUdCWenpW6I8mAnbsY8KWs1PuSovCW9A/Z25PQ24a7cNOqgmTkLmBMgh4THgc4b9k2IVv1/g/F5nGljwPLfOgHAzJzh45V/4+WenTzmMtR5Z7us2Tys909UHqrPY7KbckoxRvRHhmVc3cJGE97uml0R1S0jdULVl7EvZtDFVBF35N9cEdjpgmAiOlFZ+Dtoh93+D3zzHr8RRNZQhnCNMNbcegOvpEwZoL+06cJQ07h+th3fZ/7PVbVC6ngTAV/KoLFuO6+2KFcU651gEb5ugPSIb1D+Xp8V4+k3sEIGnw5mYe4If4k1lFYr6SCzmM2EQ8iWtmwjnBI9kTwe1TlfAmXh7H02by9fW2gsjKwtv0aaURKil4OdV7rDL1MXIFNrhdxohcZXYTnq47WisrKitaObbf5+yvkLi5J6lCNZZ+B6GC38VNBZBDidSS/+mSvh6s+srgC8pyKMvDtt+de3c9fU76ZPfuM8ud4Kv0fyP/LqfepMT/3oZxSqpZaTa1DaQYLY8TFsHYbWYsPoRhRWfL5eSSQbhUGgGC3YLbVMk6PitTFNGpAsNrC6D1VNBKgBHMejaiuRWEWGgsSDBTJjqWIl8kJLlsaLJ2tXDr6xGfT85bM2Q06a46x2HTgvdnV8z5YDy/27J4zt6x2VtkzjoYpkq36kaBr4eQSg7tyiVweWubXZugtadl58ydapfbORfKsDTuZ0OBgx4cfdjCf5tbWNITnL120fdOi1RV1C3uKGzNdwYLcMvZ3BxoPyTOCD1XvXTp7U10gWCVmTV9b3r2z0SkGWovb2hp9I89O8a2smlyaO8muMU+dRmtzp60IzAoFpjLr1n388boLyf0dRvxhsHZ0qbWqDkwqvvpkj4l0fY6EIXRi5sQSrAvsVYwXRy4qJ2EVtD1AN7a0HWth9ymvL1xc3WTUKK/TAHA/bXDVtVWfOMfuGxGZv4Ln/jVr9jc3j1yMv0tndmyt9Vq88Y9gH1wtLX3KWjot5++jWHgAoZZkQ14wGQ20Fli71UmKJAy4xKMSTGbVdybW7FDDAut9XpD5AzWrYO7zQ8qffqF8+Ynd/clrHcdyxGy3a/3+mfNnzC/cBsveTjnTvXf1o6vzOlZw7WtqtdmPK/Errz/6NNtD72zmNOZfbmYdTGHfoofqI79Oc+R2n1lrnL6pOm0Up7kwxhTW12Amm7WYkXR2qYrF2AmgmbAsxZjwy1xpg/m1Je2vrp8v/nz2xpmlBg4E9hrMU341wVpTOh/OfmGvAnra8q6uctr60ZQHV3Q+WMQJykMj8ZsWn2QBOmmHMB+m5pDIpTFonYigiaKAhGEiAHF7EliVnQkjoLVIMPtJpBKHYd3A8GYH9jJzrWwmHx5Qjp7vDAX0suGRym1vtm/9W1/HyR8vczfMs6Sk8DSv855/5dlX9oQq52hT8syyp2rx5Id17IAyAM3wIjQPMOHzytEB64q6D5zT91yNbnx3V/nqnd017S9Y0605k3izoXLpsxde2n38yoOV9s1LcjwzNjbdX6asnBVaBj/6/DwKwPkpcqbDG7BnsXoSqWnUAmottYF6jMSdVyYZh3zVXCjwTiwwHH6sGuRiEHQGzuRX6whZkp123oy1BWE2mEfJ/tvIRtM4ZM5bDXiMsPMaAKOTyc5uL57rqyyc5y5JE5pm1i2S2iUX0CcaQ6lC6Zog7JqSqZmYlosl2K6pwNA84zRnQW6SaALYZQGW5lhCtU/W34N6o+bKfZ8cf3/Cl/+iTX3wBzpOY4mRkeNf3rptycGSshQWgGbYt5jFc2e0+DglIrwl6DVWQ7BuwaJ3Xk1J4VL5urnLl/Wf+gHU/hZoZdKNym6lG+I34FaNeZKcSpJIo2IeCVvpdsDGfKvzJnAwmeD37Ow65ZWwSowpgwX5T69s/rB55dP5BcpgDKFV8p7q2sn/1uc93bVzT/w6UrCqDTWvfCq/oCD/qZXNoUj8BL5Kp6GU017frfNXkAtiiyf/SOCEeLqnd8R/Ql9GlCRfctS6k5chvIBuQ1zCCjoCHL2DHNHIXxMJ3kQeO8lbsUXONeSfA5EjcG6/E+KdhN4bP04vBhdi883+BFBzQbxFbvZzQeY9LNBZc0FNfn5NwfDn6rCTnTw6R8o+gfpf5hCom33cRuiTlss3KHmZjD+BPN+5gXuA2ziS/Q73mLxUkpbKN/eqwz5uK0X9F3h2d1V4nGNgZGBgAOJd776+iue3+crAzc4AAje5Bfcg0xz9YHEOBiYQBQA8FQlFAHicY2BkYGBnAAGOPgaG//85+hkYGVCBMgBGGwNYAAAAeJxjYGBgYB8EmKOPgQEAQ04BfgAAAAAAAA4AaAB+AMwA4AECAUIBbAGYAcICGAJYArQC4AMwA7AD3gQwBJYE3AUkBWYFigYgBmYGtAbqB1gIEghYCG4IhAi2COh4nGNgZGBgUGYoZWBnAAEmIOYCQgaG/2A+AwAYCQG2AHicXZBNaoNAGIZfE5PQCKFQ2lUps2oXBfOzzAESyDKBQJdGR2NQR3QSSE/QE/QEPUUPUHqsvsrXjTMw83zPvPMNCuAWP3DQDAejdm1GjzwS7pMmwi75XngAD4/CQ/oX4TFe4Qt7uMMbOzjuDc0EmXCP/C7cJ38Iu+RP4QEe8CU8pP8WHmOPX2EPz87TPo202ey2OjlnQSXV/6arOjWFmvszMWtd6CqwOlKHq6ovycLaWMWVydXKFFZnmVFlZU46tP7R2nI5ncbi/dDkfDtFBA2DDXbYkhKc+V0Bqs5Zt9JM1HQGBRTm/EezTmZNKtpcAMs9Yu6AK9caF76zoLWIWcfMGOSkVduvSWechqZsz040Ib2PY3urxBJTzriT95lipz+TN1fmAAAAeJxtkMl2wjAMRfOAhABlKm2h80C3+ajgCKKDY6cegP59TYBzukAL+z1Zsq8ctaJTTKPrsUQLbXQQI0EXKXroY4AbDDHCGBNMcYsZ7nCPB8yxwCOe8IwXvOIN7/jAJ76wxHfUqWX+OzgumWAjJMV17i0Ndlr6irLKO+qftdT7i6y4uFSUvCknay+lFYZIZaQcmfH/xIFdYn98bqhra1aKTM/6lWMnyaYirx1rFUQZFBkb2zJUtoXeJCeg0WnLtHeSFc3OtrnozNwqi0TkSpBMDB1nSde5oJXW23hTS2/T0LilglXX7dmFVxLnq5U0vYATHFk3zX3BOisoQHNDFDeZnqKDy9hRNawN7Vh727hFzcJ5c8TILrKZfH7tIPxAFP0BpLeJPA==) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle,.vjs-seek-to-live-control .vjs-icon-placeholder{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before,.vjs-seek-to-live-control .vjs-icon-placeholder:before{content:"\f111"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f115"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f11e"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f11f"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f120"}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-enter:before{content:"\f121"}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-exit:before{content:"\f122"}.video-js{display:block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js.vjs-fill{width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}body.vjs-full-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen:not(.vjs-ios-native-fs){width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.63332em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.81666em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.js-focus-visible .vjs-menu li.vjs-menu-item:hover,.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.js-focus-visible .vjs-menu li.vjs-selected:hover,.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:5em}.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:10em}.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:14em}.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:25em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-liveui .vjs-progress-control{display:flex;align-items:center}.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.6666666667em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;top:-.3333333333em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;margin-right:0}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical{left:-3.5em;transition:left 0s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active{width:10em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3000em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;visibility:visible;opacity:1;position:relative;transition:none}.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{position:absolute;bottom:3em;left:.5em}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-liveui .vjs-live-control,.video-js:not(.vjs-live) .vjs-live-control{display:none}.video-js .vjs-seek-to-live-control{cursor:pointer;flex:none;display:inline-flex;height:100%;padding-left:.5em;padding-right:.5em;font-size:1em;line-height:3em;width:auto;min-width:4em}.vjs-no-flex .vjs-seek-to-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control,.video-js:not(.vjs-live) .vjs-seek-to-live-control{display:none}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge{cursor:auto}.vjs-seek-to-live-control .vjs-icon-placeholder{margin-right:.5em;color:#888}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder{color:red}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-live .vjs-time-control{display:none}.video-js .vjs-current-time,.vjs-no-flex .vjs-current-time{display:none}.video-js .vjs-duration,.vjs-no-flex .vjs-duration{display:none}.vjs-time-divider{display:none;line-height:3em}.vjs-live .vjs-time-divider{display:none}.video-js .vjs-play-control{cursor:pointer}.video-js .vjs-play-control .vjs-icon-placeholder{flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{transform:translateY(-1.5em)}.video-js .vjs-picture-in-picture-control{cursor:pointer;flex:none}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:"X";font-family:Arial,Helvetica,sans-serif;font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block;-webkit-animation:vjs-spinner-show 0s linear .3s forwards;animation:vjs-spinner-show 0s linear .3s forwards}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@-webkit-keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}@-webkit-keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"";font-size:1.5em;line-height:inherit}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" ";font-size:1.5em;line-height:inherit}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-control{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:auto;width:initial}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-live) .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-liveui) .vjs-subs-caps-button{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-custom-control-spacer{flex:auto;display:block}.video-js:not(.vjs-fullscreen).vjs-layout-tiny.vjs-no-flex .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui.vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-progress-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-progress-control{display:none}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;padding:20px 24px 0 24px}.vjs-track-settings-controls .vjs-default-button{margin-bottom:20px}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:1/-1}.vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content{grid-template-columns:1fr}}.vjs-track-setting>select{margin-right:1em;margin-bottom:.5em}.vjs-text-track-settings fieldset{margin:5px;padding:3px;border:none}.vjs-text-track-settings fieldset span{display:inline-block}.vjs-text-track-settings fieldset span>select{max-width:7.3em}.vjs-text-track-settings legend{color:#fff;margin:0 0 5px 0}.vjs-text-track-settings .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);display:block;margin:0 0 5px 0;padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:-1000}.js-focus-visible .video-js :focus:not(.focus-visible){outline:0;background:0 0}.video-js .vjs-menu :focus:not(:focus-visible),.video-js :focus:not(:focus-visible){outline:0;background:0 0} \ No newline at end of file diff --git a/assets/js/global.js b/assets/js/global.js deleted file mode 100644 index efb447fb9..000000000 --- a/assets/js/global.js +++ /dev/null @@ -1,3 +0,0 @@ -// Disable Web Workers. Fixes Video.js CSP violation (created by `new Worker(objURL)`): -// Refused to create a worker from 'blob:http://host/id' because it violates the following Content Security Policy directive: "worker-src 'self'". -window.Worker = undefined; diff --git a/assets/js/video.min.js b/assets/js/video.min.js index ed10c74ef..890a3c84f 100644 --- a/assets/js/video.min.js +++ b/assets/js/video.min.js @@ -1,6 +1,6 @@ /** * @license - * Video.js 7.6.6 + * Video.js 7.10.2 * Copyright Brightcove, Inc. * Available under Apache License Version 2.0 * @@ -9,13 +9,18 @@ * Available under Apache License Version 2.0 * */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("global/window"),require("global/document")):"function"==typeof define&&define.amd?define(["global/window","global/document"],t):(e=e||self).videojs=t(e.window,e.document)}(this,function(v,h){v=v&&v.hasOwnProperty("default")?v.default:v,h=h&&h.hasOwnProperty("default")?h.default:h;var d="7.6.6",u=[],e=function(s,o){return function(e,t,i){var n=o.levels[t],r=new RegExp("^("+n+")$");if("log"!==e&&i.unshift(e.toUpperCase()+":"),i.unshift(s+":"),u&&u.push([].concat(i)),v.console){var a=v.console[e];a||"debug"!==e||(a=v.console.info||v.console.log),a&&n&&r.test(e)&&a[Array.isArray(i)?"apply":"call"](v.console,i)}}};var p=function t(i){function n(){for(var e=arguments.length,t=new Array(e),i=0;i',i=n.firstChild,n.setAttribute("style","display:none; position:absolute;"),h.body.appendChild(n));for(var a={},s=0;sx',e=t.firstChild.href}return e}function Mt(e){if("string"==typeof e){var t=/^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/.exec(e);if(t)return t.pop().toLowerCase()}return""}function Nt(e){var t=v.location,i=Ut(e);return(":"===i.protocol?t.protocol:i.protocol)+i.host!==t.protocol+t.host}var Bt=function(n){function e(e){var t;void 0===e&&(e=[]);for(var i=e.length-1;0<=i;i--)if(e[i].enabled){xt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,t}De(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.enabled&&xt(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.enabledChange_=function(){t.changing_||(t.changing_=!0,xt(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("enabledchange",e.enabledChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.enabledChange_&&(e.removeEventListener("enabledchange",e.enabledChange_),e.enabledChange_=null)},e}(Lt),jt=function(n){function e(e){var t;void 0===e&&(e=[]);for(var i=e.length-1;0<=i;i--)if(e[i].selected){Dt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,Object.defineProperty(Me(t),"selectedIndex",{get:function(){for(var e=0;e>0},ToUint32:function(e){return this.ToNumber(e)>>>0},ToUint16:function(e){var t=this.ToNumber(e);return zi(t)||0===t||!Gi(t)?0:function(e,t){var i=e%t;return Math.floor(0<=i?i:i+t)}(Pi(t)*Math.floor(Math.abs(t)),65536)},ToString:function(e){return nn(e)},ToObject:function(e){return this.CheckObjectCoercible(e),en(e)},CheckObjectCoercible:function(e,t){if(null==e)throw new tn(t||"Cannot call method on "+e);return e},IsCallable:Li,SameValue:function(e,t){return e===t?0!==e||1/e==1/t:zi(e)&&zi(t)},Type:function(e){return null===e?"Null":"undefined"==typeof e?"Undefined":"function"==typeof e||"object"==typeof e?"Object":"number"==typeof e?"Number":"boolean"==typeof e?"Boolean":"string"==typeof e?"String":void 0},IsPropertyDescriptor:function(e){if("Object"!==this.Type(e))return!1;var t={"[[Configurable]]":!0,"[[Enumerable]]":!0,"[[Get]]":!0,"[[Set]]":!0,"[[Value]]":!0,"[[Writable]]":!0};for(var i in e)if(Hi(e,i)&&!t[i])return!1;var n=Hi(e,"[[Value]]"),r=Hi(e,"[[Get]]")||Hi(e,"[[Set]]");if(n&&r)throw new tn("Property Descriptors may not be both accessor and data descriptors");return!0},IsAccessorDescriptor:function(e){return"undefined"!=typeof e&&(Ai(this,"Property Descriptor","Desc",e),!(!Hi(e,"[[Get]]")&&!Hi(e,"[[Set]]")))},IsDataDescriptor:function(e){return"undefined"!=typeof e&&(Ai(this,"Property Descriptor","Desc",e),!(!Hi(e,"[[Value]]")&&!Hi(e,"[[Writable]]")))},IsGenericDescriptor:function(e){return"undefined"!=typeof e&&(Ai(this,"Property Descriptor","Desc",e),!this.IsAccessorDescriptor(e)&&!this.IsDataDescriptor(e))},FromPropertyDescriptor:function(e){if("undefined"==typeof e)return e;if(Ai(this,"Property Descriptor","Desc",e),this.IsDataDescriptor(e))return{value:e["[[Value]]"],writable:!!e["[[Writable]]"],enumerable:!!e["[[Enumerable]]"],configurable:!!e["[[Configurable]]"]};if(this.IsAccessorDescriptor(e))return{get:e["[[Get]]"],set:e["[[Set]]"],enumerable:!!e["[[Enumerable]]"],configurable:!!e["[[Configurable]]"]};throw new tn("FromPropertyDescriptor must be called with a fully populated Property Descriptor")},ToPropertyDescriptor:function(e){if("Object"!==this.Type(e))throw new tn("ToPropertyDescriptor requires an object");var t={};if(Hi(e,"enumerable")&&(t["[[Enumerable]]"]=this.ToBoolean(e.enumerable)),Hi(e,"configurable")&&(t["[[Configurable]]"]=this.ToBoolean(e.configurable)),Hi(e,"value")&&(t["[[Value]]"]=e.value),Hi(e,"writable")&&(t["[[Writable]]"]=this.ToBoolean(e.writable)),Hi(e,"get")){var i=e.get;if("undefined"!=typeof i&&!this.IsCallable(i))throw new TypeError("getter must be a function");t["[[Get]]"]=i}if(Hi(e,"set")){var n=e.set;if("undefined"!=typeof n&&!this.IsCallable(n))throw new tn("setter must be a function");t["[[Set]]"]=n}if((Hi(t,"[[Get]]")||Hi(t,"[[Set]]"))&&(Hi(t,"[[Value]]")||Hi(t,"[[Writable]]")))throw new tn("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");return t}},an=ti.call(Function.call,String.prototype.replace),sn=/^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/,on=/[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+$/,un=ti.call(Function.call,Di());Ri(un,{getPolyfill:Di,implementation:xi,shim:function(){var e=Di();return Ri(String.prototype,{trim:e},{trim:function(){return String.prototype.trim!==e}}),e}});var ln=un,cn=Object.prototype.toString,hn=Object.prototype.hasOwnProperty,dn=function(e,t,i){if(!Li(t))throw new TypeError("iterator must be a function");var n;3<=arguments.length&&(n=i),"[object Array]"===cn.call(e)?function(e,t,i){for(var n=0,r=e.length;n=e?t.push(r):r.startTime===r.endTime&&r.startTime<=e&&r.startTime+.5>=e&&t.push(r)}if(o=!1,t.length!==this.activeCues_.length)o=!0;else for(var a=0;a","‎":"‎","‏":"‏"," ":" "},Mn={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},Nn={v:"title",lang:"lang"},Bn={rt:"ruby"};function jn(a,i){function e(){if(!i)return null;var e,t=i.match(/^([^<]*)(<[^>]*>?)?/);return e=t[1]?t[1]:t[2],i=i.substr(e.length),e}function t(e){return Rn[e]}function n(e){for(;f=e.match(/&(amp|lt|gt|lrm|rlm|nbsp);/);)e=e.replace(f[0],t);return e}function r(e,t){var i=Mn[e];if(!i)return null;var n=a.document.createElement(i);n.localName=i;var r=Nn[e];return r&&t&&(n[r]=t.trim()),n}for(var s,o,u,l=a.document.createElement("div"),c=l,h=[];null!==(s=e());)if("<"!==s[0])c.appendChild(a.document.createTextNode(n(s)));else{if("/"===s[1]){h.length&&h[h.length-1]===s.substr(2).replace(">","")&&(h.pop(),c=c.parentNode);continue}var d,p=On(s.substr(1,s.length-2));if(p){d=a.document.createProcessingInstruction("timestamp",p),c.appendChild(d);continue}var f=s.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);if(!f)continue;if(!(d=r(f[1],f[3])))continue;if(o=c,Bn[(u=d).localName]&&Bn[u.localName]!==o.localName)continue;f[2]&&(d.className=f[2].substr(1).replace("."," ")),h.push(f[1]),c.appendChild(d),c=d}return l}var Fn=[[1470,1470],[1472,1472],[1475,1475],[1478,1478],[1488,1514],[1520,1524],[1544,1544],[1547,1547],[1549,1549],[1563,1563],[1566,1610],[1645,1647],[1649,1749],[1765,1766],[1774,1775],[1786,1805],[1807,1808],[1810,1839],[1869,1957],[1969,1969],[1984,2026],[2036,2037],[2042,2042],[2048,2069],[2074,2074],[2084,2084],[2088,2088],[2096,2110],[2112,2136],[2142,2142],[2208,2208],[2210,2220],[8207,8207],[64285,64285],[64287,64296],[64298,64310],[64312,64316],[64318,64318],[64320,64321],[64323,64324],[64326,64449],[64467,64829],[64848,64911],[64914,64967],[65008,65020],[65136,65140],[65142,65276],[67584,67589],[67592,67592],[67594,67637],[67639,67640],[67644,67644],[67647,67669],[67671,67679],[67840,67867],[67872,67897],[67903,67903],[67968,68023],[68030,68031],[68096,68096],[68112,68115],[68117,68119],[68121,68147],[68160,68167],[68176,68184],[68192,68223],[68352,68405],[68416,68437],[68440,68466],[68472,68479],[68608,68680],[126464,126467],[126469,126495],[126497,126498],[126500,126500],[126503,126503],[126505,126514],[126516,126519],[126521,126521],[126523,126523],[126530,126530],[126535,126535],[126537,126537],[126539,126539],[126541,126543],[126545,126546],[126548,126548],[126551,126551],[126553,126553],[126555,126555],[126557,126557],[126559,126559],[126561,126562],[126564,126564],[126567,126570],[126572,126578],[126580,126583],[126585,126588],[126590,126590],[126592,126601],[126603,126619],[126625,126627],[126629,126633],[126635,126651],[1114109,1114109]];function Hn(e){for(var t=0;t=i[0]&&e<=i[1])return!0}return!1}function Vn(){}function qn(e,t,i){Vn.call(this),this.cue=t,this.cueDiv=jn(e,t.text);var n={color:"rgba(255, 255, 255, 1)",backgroundColor:"rgba(0, 0, 0, 0.8)",position:"relative",left:0,right:0,top:0,bottom:0,display:"inline",writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext"};this.applyStyles(n,this.cueDiv),this.div=e.document.createElement("div"),n={direction:function(e){var t=[],i="";if(!e||!e.childNodes)return"ltr";function r(e,t){for(var i=t.childNodes.length-1;0<=i;i--)e.push(t.childNodes[i])}function a(e){if(!e||!e.length)return null;var t=e.pop(),i=t.textContent||t.innerText;if(i){var n=i.match(/^.*(\n|\r)/);return n?n[e.length=0]:i}return"ruby"===t.tagName?a(e):t.childNodes?(r(e,t),a(e)):void 0}for(r(t,e);i=a(t);)for(var n=0;nh&&(c=c<0?-1:1,c*=Math.ceil(h/l)*l),r<0&&(c+=""===n.vertical?o.height:o.width,a=a.reverse()),i.move(d,c)}else{var p=i.lineHeight/o.height*100;switch(n.lineAlign){case"middle":r-=p/2;break;case"end":r-=p}switch(n.vertical){case"":t.applyStyles({top:t.formatStyle(r,"%")});break;case"rl":t.applyStyles({left:t.formatStyle(r,"%")});break;case"lr":t.applyStyles({right:t.formatStyle(r,"%")})}a=["+y","-x","+x","-y"],i=new Wn(t)}var f=function(e,t){for(var i,n=new Wn(e),r=1,a=0;ae.left&&this.tope.top},Wn.prototype.overlapsAny=function(e){for(var t=0;t=e.top&&this.bottom<=e.bottom&&this.left>=e.left&&this.right<=e.right},Wn.prototype.overlapsOppositeAxis=function(e,t){switch(t){case"+x":return this.lefte.right;case"+y":return this.tope.bottom}},Wn.prototype.intersectPercentage=function(e){return Math.max(0,Math.min(this.right,e.right)-Math.max(this.left,e.left))*Math.max(0,Math.min(this.bottom,e.bottom)-Math.max(this.top,e.top))/(this.height*this.width)},Wn.prototype.toCSSCompatValues=function(e){return{top:this.top-e.top,bottom:e.bottom-this.bottom,left:this.left-e.left,right:e.right-this.right,height:this.height,width:this.width}},Wn.getSimpleBoxPosition=function(e){var t=e.div?e.div.offsetHeight:e.tagName?e.offsetHeight:0,i=e.div?e.div.offsetWidth:e.tagName?e.offsetWidth:0,n=e.div?e.div.offsetTop:e.tagName?e.offsetTop:0;return{left:(e=e.div?e.div.getBoundingClientRect():e.tagName?e.getBoundingClientRect():e).left,right:e.right,top:e.top||n,height:e.height||t,bottom:e.bottom||n+(e.height||t),width:e.width||i}},$n.StringDecoder=function(){return{decode:function(e){if(!e)return"";if("string"!=typeof e)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(e))}}},$n.convertCueToDOMTree=function(e,t){return e&&t?jn(e,t):null};$n.processCues=function(n,r,e){if(!n||!r||!e)return null;for(;e.firstChild;)e.removeChild(e.firstChild);var a=n.document.createElement("div");if(a.style.position="absolute",a.style.left="0",a.style.right="0",a.style.top="0",a.style.bottom="0",a.style.margin="1.5%",e.appendChild(a),function(e){for(var t=0;t