diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e9232a475a..d6d8dabdb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -197,12 +197,12 @@ jobs: UPDATE_TO: yt-dlp/yt-dlp@2025.09.05 steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Needed for changelog persist-credentials: false - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.10" @@ -261,7 +261,7 @@ jobs: SKIP_ONEFILE_BUILD: ${{ (!matrix.onefile && '1') || '' }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -315,7 +315,7 @@ jobs: UPDATE_TO: yt-dlp/yt-dlp@2025.09.05 steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -435,11 +435,11 @@ jobs: PYI_WHEEL: pyinstaller-${{ matrix.pyi_version }}-py3-none-${{ matrix.platform_tag }}.whl steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python_version }} architecture: ${{ matrix.arch }} diff --git a/.github/workflows/challenge-tests.yml b/.github/workflows/challenge-tests.yml index 8a98545750..11e52040f8 100644 --- a/.github/workflows/challenge-tests.yml +++ b/.github/workflows/challenge-tests.yml @@ -37,11 +37,11 @@ jobs: env: QJS_VERSION: '2025-04-26' # Earliest version with rope strings steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python-version }} - name: Install Deno @@ -49,13 +49,13 @@ jobs: with: deno-version: '2.0.0' # minimum supported version - name: Install Bun - uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 + uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2 with: # minimum supported version is 1.0.31 but earliest available Windows version is 1.1.0 bun-version: ${{ (matrix.os == 'windows-latest' && '1.1.0') || '1.0.31' }} no-cache: true - name: Install Node - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: '20.0' # minimum supported version - name: Install QuickJS (Linux) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c9eb40df41..dbd643f69c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index 2d0dfae8a0..677ade52c7 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -32,7 +32,7 @@ concurrency: jobs: tests: name: Core Tests - if: "!contains(github.event.head_commit.message, 'ci skip')" + if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} permissions: contents: read runs-on: ${{ matrix.os }} @@ -57,12 +57,12 @@ jobs: - os: windows-latest python-version: pypy-3.11 steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python-version }} - name: Install test requirements diff --git a/.github/workflows/quick-test.yml b/.github/workflows/quick-test.yml index 7584790d7f..d807be1955 100644 --- a/.github/workflows/quick-test.yml +++ b/.github/workflows/quick-test.yml @@ -10,16 +10,16 @@ concurrency: jobs: tests: name: Core Test - if: "!contains(github.event.head_commit.message, 'ci skip all')" + if: ${{ !contains(github.event.head_commit.message, 'ci skip all') }} permissions: contents: read runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Set up Python 3.10 - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.10' - name: Install test requirements @@ -33,15 +33,15 @@ jobs: python3 ./devscripts/run_tests.py --pytest-args '--reruns 2 --reruns-delay 3.0' core check: name: Code check - if: "!contains(github.event.head_commit.message, 'ci skip all')" + if: ${{ !contains(github.event.head_commit.message, 'ci skip all') }} permissions: contents: read runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.10' - name: Install dev dependencies diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index 17b0eaf0a8..bc48e75b68 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -16,7 +16,7 @@ jobs: outputs: commit: ${{ steps.check_for_new_commits.outputs.commit }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false @@ -27,7 +27,7 @@ jobs: run: echo "head=$(git rev-parse HEAD)" | tee -a "${GITHUB_OUTPUT}" - name: Cache nightly commit hash - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 env: SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1 with: @@ -72,7 +72,7 @@ jobs: release: name: Publish Github release needs: [check_nightly] - if: ${{ needs.check_nightly.outputs.commit }} + if: needs.check_nightly.outputs.commit permissions: contents: write # May be needed to publish release id-token: write # Needed for trusted publishing diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ef565723d..992e80a0fb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,12 +79,12 @@ jobs: head_sha: ${{ steps.get_target.outputs.head_sha }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: true # Needed to git-push the release commit - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.10" # Keep this in sync with test-workflows.yml @@ -130,8 +130,7 @@ jobs: VERSION: ${{ steps.setup_variables.outputs.version }} GITHUB_EVENT_SENDER_LOGIN: ${{ github.event.sender.login }} GITHUB_EVENT_REF: ${{ github.event.ref }} - if: | - !inputs.prerelease && steps.setup_variables.outputs.target_repo == github.repository + if: steps.setup_variables.outputs.target_repo == github.repository && !inputs.prerelease run: | git config --global user.name "github-actions[bot]" git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" @@ -148,8 +147,7 @@ jobs: - name: Update master env: GITHUB_EVENT_REF: ${{ github.event.ref }} - if: | - vars.PUSH_VERSION_COMMIT && !inputs.prerelease && steps.setup_variables.outputs.target_repo == github.repository + if: vars.PUSH_VERSION_COMMIT && !inputs.prerelease && steps.setup_variables.outputs.target_repo == github.repository run: git push origin "${GITHUB_EVENT_REF}" build: @@ -169,18 +167,18 @@ jobs: publish_pypi: name: Publish to PyPI needs: [prepare, build] - if: ${{ needs.prepare.outputs.pypi_project }} + if: needs.prepare.outputs.pypi_project permissions: contents: read id-token: write # Needed for trusted publishing runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Needed for changelog persist-credentials: false - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.10" @@ -241,7 +239,7 @@ jobs: VERSION: ${{ needs.prepare.outputs.version }} HEAD_SHA: ${{ needs.prepare.outputs.head_sha }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false @@ -250,7 +248,7 @@ jobs: path: artifact pattern: build-* merge-multiple: true - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.10" @@ -295,8 +293,7 @@ jobs: GH_REPO: ${{ needs.prepare.outputs.target_repo }} TITLE_PREFIX: ${{ startswith(env.TARGET_REPO, 'yt-dlp/') && 'yt-dlp ' || '' }} TITLE: ${{ inputs.target != env.TARGET_REPO && inputs.target || needs.prepare.outputs.channel }} - if: | - inputs.prerelease && env.GH_TOKEN && env.GH_REPO && env.GH_REPO != github.repository + if: inputs.prerelease && env.GH_TOKEN && env.GH_REPO && env.GH_REPO != github.repository run: | gh release create \ --notes-file ARCHIVE_NOTES \ @@ -307,8 +304,7 @@ jobs: - name: Prune old release env: GH_TOKEN: ${{ github.token }} - if: | - env.TARGET_REPO == github.repository && env.TARGET_TAG != env.VERSION + if: env.TARGET_REPO == github.repository && env.TARGET_TAG != env.VERSION run: | gh release delete --yes --cleanup-tag "${TARGET_TAG}" || true git tag --delete "${TARGET_TAG}" || true @@ -321,8 +317,7 @@ jobs: TITLE_PREFIX: ${{ github.repository == 'yt-dlp/yt-dlp' && 'yt-dlp ' || '' }} TITLE: ${{ env.TARGET_TAG != env.VERSION && format('{0} ', env.TARGET_TAG) || '' }} PRERELEASE: ${{ inputs.prerelease && '1' || '0' }} - if: | - env.TARGET_REPO == github.repository + if: env.TARGET_REPO == github.repository run: | gh_options=( --notes-file "${NOTES_FILE}" diff --git a/.github/workflows/test-workflows.yml b/.github/workflows/test-workflows.yml index 8e0eba5ddd..21aa7744e4 100644 --- a/.github/workflows/test-workflows.yml +++ b/.github/workflows/test-workflows.yml @@ -37,10 +37,10 @@ jobs: contents: read runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.10" # Keep this in sync with release.yml's prepare job - name: Install requirements @@ -72,12 +72,12 @@ jobs: actions: read # Needed by zizmorcore/zizmor-action if repository is private runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0 + uses: zizmorcore/zizmor-action@135698455da5c3b3e55f73f4419e481ab68cdd95 # v0.4.1 with: advanced-security: false persona: pedantic - version: v1.19.0 + version: v1.22.0 diff --git a/Maintainers.md b/Maintainers.md index 43271e06d0..95feb306c0 100644 --- a/Maintainers.md +++ b/Maintainers.md @@ -41,14 +41,6 @@ Core Maintainers are responsible for reviewing and merging contributions, publis * Improved/fixed/added Bundestag, crunchyroll, pr0gramm, Twitter, WrestleUniverse etc -### [sepro](https://github.com/seproDev) - -* UX improvements: Warn when ffmpeg is missing, warn when double-clicking exe -* Helped in implementing support for external JavaScript runtimes/engines -* Code cleanup: Remove dead extractors, mark extractors as broken, enable/apply ruff rules -* Improved/fixed/added ArdMediathek, DRTV, Floatplane, MagentaMusik, Naver, Nebula, OnDemandKorea, Vbox7 etc - - ## Inactive Core Maintainers ### [pukkandan](https://github.com/pukkandan) @@ -77,6 +69,15 @@ Core Maintainers are responsible for reviewing and merging contributions, publis * Added playlist/series downloads for Hotstar, ParamountPlus, Rumble, SonyLIV, Trovo, TubiTv, Voot etc * Improved/fixed support for HiDive, HotStar, Hungama, LBRY, LinkedInLearning, Mxplayer, SonyLiv, TV2, Vimeo, VLive etc + +### [sepro](https://github.com/seproDev) + +* UX improvements: Warn when ffmpeg is missing, warn when double-clicking exe +* Helped in implementing support for external JavaScript runtimes/engines +* Code cleanup: Remove dead extractors, mark extractors as broken, enable/apply ruff rules +* Improved/fixed/added ArdMediathek, DRTV, Floatplane, MagentaMusik, Naver, Nebula, OnDemandKorea, Vbox7 etc + + ## Triage Maintainers Triage Maintainers are frequent contributors who can manage issues and pull requests. diff --git a/bundle/docker/linux/build.sh b/bundle/docker/linux/build.sh index 00dedaca75..e819776e19 100755 --- a/bundle/docker/linux/build.sh +++ b/bundle/docker/linux/build.sh @@ -6,14 +6,6 @@ if [[ -z "${PYTHON_VERSION:-}" ]]; then echo "Defaulting to using Python ${PYTHON_VERSION}" fi -function runpy { - "/opt/shared-cpython-${PYTHON_VERSION}/bin/python${PYTHON_VERSION}" "$@" -} - -function venvpy { - "python${PYTHON_VERSION}" "$@" -} - INCLUDES=( --include-extra pyinstaller --include-extra secretstorage @@ -23,26 +15,26 @@ if [[ -z "${EXCLUDE_CURL_CFFI:-}" ]]; then INCLUDES+=(--include-extra build-curl-cffi) fi -runpy -m venv /yt-dlp-build-venv +py"${PYTHON_VERSION}" -m venv /yt-dlp-build-venv # shellcheck disable=SC1091 source /yt-dlp-build-venv/bin/activate -# Inside the venv we use venvpy instead of runpy -venvpy -m ensurepip --upgrade --default-pip -venvpy -m devscripts.install_deps --omit-default --include-extra build -venvpy -m devscripts.install_deps "${INCLUDES[@]}" -venvpy -m devscripts.make_lazy_extractors -venvpy devscripts/update-version.py -c "${CHANNEL}" -r "${ORIGIN}" "${VERSION}" +# Inside the venv we can use python instead of py3.13 or py3.14 etc +python -m devscripts.install_deps "${INCLUDES[@]}" +python -m devscripts.make_lazy_extractors +python devscripts/update-version.py -c "${CHANNEL}" -r "${ORIGIN}" "${VERSION}" if [[ -z "${SKIP_ONEDIR_BUILD:-}" ]]; then mkdir -p /build - venvpy -m bundle.pyinstaller --onedir --distpath=/build + python -m bundle.pyinstaller --onedir --distpath=/build pushd "/build/${EXE_NAME}" chmod +x "${EXE_NAME}" - venvpy -m zipfile -c "/yt-dlp/dist/${EXE_NAME}.zip" ./ + python -m zipfile -c "/yt-dlp/dist/${EXE_NAME}.zip" ./ popd fi if [[ -z "${SKIP_ONEFILE_BUILD:-}" ]]; then - venvpy -m bundle.pyinstaller + python -m bundle.pyinstaller chmod +x "./dist/${EXE_NAME}" fi + +deactivate diff --git a/devscripts/changelog_override.json b/devscripts/changelog_override.json index ae4c1ade38..69aa5889f3 100644 --- a/devscripts/changelog_override.json +++ b/devscripts/changelog_override.json @@ -325,5 +325,17 @@ "when": "c63b4e2a2b81cc78397c8709ef53ffd29bada213", "short": "[cleanup] Misc (#14767)", "authors": ["bashonly", "seproDev", "matyb08"] + }, + { + "action": "change", + "when": "abf29e3e72e8a4dcae61e2ceaf37ce8405af61ab", + "short": "[ie/youtube] Fix `player_skip=js` extractor-arg (#15428)", + "authors": ["bashonly"] + }, + { + "action": "change", + "when": "e2ea6bd6ab639f910b99e55add18856974ff4c3a", + "short": "[ie] Fix prioritization of Youtube URL matching (#15596)", + "authors": ["Grub4K"] } ] diff --git a/pyproject.toml b/pyproject.toml index 96c69bf8e1..f29b3cba81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,10 +9,9 @@ authors = [ ] maintainers = [ {email = "maintainers@yt-dlp.org"}, - {name = "Grub4K", email = "contact@grub4k.xyz"}, + {name = "Grub4K", email = "contact@grub4k.dev"}, {name = "bashonly", email = "bashonly@protonmail.com"}, {name = "coletdjnz", email = "coletdjnz@protonmail.com"}, - {name = "sepro", email = "sepro@sepr0.com"}, ] description = "A feature-rich command-line audio/video downloader" readme = "README.md" @@ -70,7 +69,7 @@ secretstorage = [ "secretstorage", ] deno = [ - "deno>=2.6.5", # v2.6.5 fixes installation of incompatible binaries + "deno>=2.6.6", # v2.6.5 fixes compatibility, v2.6.6 adds integrity check ] build = [ "build", diff --git a/yt_dlp/extractor/tarangplus.py b/yt_dlp/extractor/tarangplus.py index 62f254dd6f..92aa6acc8d 100644 --- a/yt_dlp/extractor/tarangplus.py +++ b/yt_dlp/extractor/tarangplus.py @@ -11,6 +11,7 @@ from ..utils import ( OnDemandPagedList, clean_html, extract_attributes, + url_or_none, urljoin, ) from ..utils.traversal import ( @@ -128,7 +129,7 @@ class TarangPlusVideoIE(TarangPlusBaseIE): **traverse_obj(metadata, { 'id': ('content_id', {str}), 'title': ('title', {str}), - 'thumbnail': ('image', {str}), + 'thumbnail': ('image', {url_or_none}), }), **traverse_obj(hidden_inputs_data, { 'id': ('content_id', {str}), diff --git a/yt_dlp/extractor/youtube/_video.py b/yt_dlp/extractor/youtube/_video.py index f994b662fb..6372911b66 100644 --- a/yt_dlp/extractor/youtube/_video.py +++ b/yt_dlp/extractor/youtube/_video.py @@ -1690,7 +1690,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor): 'playable_in_embed': True, 'availability': 'public', 'live_status': 'not_live', - 'comment_count': 15, # XXX: minimum + 'comment_count': 15, # XXX: minimum, but investigate if this changes + 'comments': 'count:15', }, 'params': { 'skip_download': True, @@ -1723,7 +1724,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor): 'playable_in_embed': True, 'availability': 'unlisted', 'live_status': 'not_live', - 'comment_count': 9, # XXX: minimum + 'comment_count': 9, # XXX: minimum, but investigate if this changes + 'comments': 'count:9', + }, + 'params': { + 'skip_download': True, + 'getcomments': True, }, }] _WEBPAGE_TESTS = [{ @@ -1884,7 +1890,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): 'tv': 'tv-player-ias.vflset/tv-player-ias.js', 'tv_es6': 'tv-player-es6.vflset/tv-player-es6.js', 'phone': 'player-plasma-ias-phone-en_US.vflset/base.js', - 'tablet': 'player-plasma-ias-tablet-en_US.vflset/base.js', + 'tablet': 'player-plasma-ias-tablet-en_US.vflset/base.js', # Dead since 19712d96 (2025.11.06) } _INVERSE_PLAYER_JS_VARIANT_MAP = {v: k for k, v in _PLAYER_JS_VARIANT_MAP.items()}