Download Counter-Strike demos from 5EPlay, Perfect World Arena, and Steam share-code sources.
Project description
CS Demo Downloader
CS Demo Downloader downloads Counter-Strike demo files from supported Chinese CS platforms. It provides a scriptable CLI, a Python API, and a Docker entrypoint for scheduled/server usage.
Table of Contents
- Quick Start
- Supported Platforms
- Configuration
- Install
- CLI Usage
- Docker Usage
- Python API Usage
- Scheduled Downloads
- Tests
- Notes and Limitations
- License
Supported Platforms
The current implementation supports three platforms:
| Platform | CLI value | Required account fields | Notes |
|---|---|---|---|
| 5EPlay | 5e |
userid |
The user id is read from a 5E player profile URL. |
| Perfect World Arena | pwa |
steamid, access_token |
Requires a valid Perfect World Arena web/client token. Demo URLs are signed before download. |
| Steam official matchmaking | steam |
steamid, api_key, steamidkey, knowncode |
Implements Steam Web API share-code iteration. Real replay URL resolution still requires Steam Game Coordinator full match info. |
No other platforms are implemented at the moment.
Features
- Download demos from 5EPlay, Perfect World Arena, and Steam official matchmaking.
- Use CLI automation or import the Python API directly.
- Docker image for server and scheduled downloads.
- Automatically extracts downloaded ZIP and BZ2 demo archives.
- Rejects unsafe ZIP entries that try to extract outside the target directory.
- Fails fast for explicit missing or malformed CLI config files.
Quick Start
Use Docker if you want the simplest installed/server setup:
mkdir -p config demos
cp config.jsonc.example config/config.jsonc
# Edit config/config.jsonc before running the container.
docker run --rm \
-v "$(pwd)/config:/config" \
-v "$(pwd)/demos:/demos" \
ghcr.io/wangchudi/cs-demo-downloader:latest
The container now starts in idle scheduler mode by default. It does not download demos until you explicitly enable scheduling or run a manual download command.
Use a local Python install if you want CLI/API development from a clone:
pip install "$(python scripts/select_private_signer_wheel.py wheelhouse)"
pip install -e .
cs-demo-downloader --help
PWA downloads require the private compiled cs-demo-pwa-signer wheel. Public tests mock that boundary.
Project Layout
Repository layout
.
├── pyproject.toml # Python package metadata
├── cli.py # Compatibility CLI wrapper
├── src/cs_demo_downloader/ # Installable Python package
├── tests/ # unittest test suite
├── Dockerfile
├── docker-compose.yml
├── config.jsonc.example
└── requirements.txt
Requirements
- Python 3.11+ recommended.
- CLI/runtime dependencies are declared in
pyproject.toml.requirements.txtis kept for compatibility. - Docker, if you want containerized execution.
Use python3 on Linux/macOS if python is not mapped to Python 3.
Configuration
Copy the JSONC example config and fill in your account information:
cp config.jsonc.example config.jsonc
The loader accepts both the new nested JSONC schema and the previous config.json schema for backward compatibility. label replaces name as the clearer display-only field; old name values are still accepted when loading legacy configs.
Full JSONC schema example
Example schema:
{
// "." downloads into the current working directory.
"download_path": ".",
"scheduler": {
"enabled": false,
"interval_seconds": 86400,
"run_on_start": false,
"config": "/config/config.jsonc",
"output": "/demos",
"platforms": "all"
},
"five_e": {
"users": [
{
"label": "example_5e_user", // Display-only label.
"userid": "YOUR_5E_USERID_HERE"
}
]
},
"pwa": {
"default_access_token": "SHARED_PWA_ACCESS_TOKEN",
"signature_provider": "compiled",
"pvp_alive_dll": "cache/PvpAlive.dll",
"pvp_alive_bridge_exe": "",
"pvp_alive_wine_executable": "wine",
"pvp_alive_timeout": "10",
"users": [
{
"label": "pwa_target_1",
"steamid": "TARGET_STEAM_ID_1"
},
{
"label": "pwa_target_2",
"steamid": "TARGET_STEAM_ID_2"
},
{
"label": "pwa_target_with_custom_token",
"steamid": "TARGET_STEAM_ID_3",
"access_token": "OPTIONAL_TARGET_SPECIFIC_PWA_ACCESS_TOKEN"
}
]
},
"steam": {
"users": [
{
"label": "example_steam_user",
"steamid": "YOUR_STEAM_ID64_HERE",
"api_key": "YOUR_STEAM_WEB_API_KEY_HERE",
"steamidkey": "YOUR_STEAM_ID_KEY_HERE",
"knowncode": "CSGO-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
}
],
"resolver": {
"type": "boiler",
"executable_path": "boiler-writter",
"auto_download": "true",
"cache_dir": "",
"timeout": "60"
},
"gc": {
"username_env": "STEAM_GC_USERNAME",
"password_env": "STEAM_GC_PASSWORD",
"two_factor_secret_env": "STEAM_GC_TWO_FACTOR_SECRET",
"auth_code_env": "STEAM_GC_AUTH_CODE",
"sentry_dir": "",
"timeout": "30"
}
}
}
Platform credential notes
5EPlay User ID
Open a 5E player profile URL and use the profile id segment. For example:
https://www.5eplay.com/player/11814738gjdwn7
The userid value is 11814738gjdwn7.
Perfect World Arena Steam ID and Access Token
- Log in to the Perfect World Arena web page or client.
- Open browser developer tools.
- Inspect authenticated network requests or cookies.
- Fill
pwa.default_access_tokenand each targetsteamidinconfig.jsonc.
PWA demo download links are now generated with the current signed query parameters and the downloader sends the required PWA request headers for the final file request. Tokens can expire. If PWA downloads stop working, refresh the token first.
PWA signing is provided by the private compiled cs-demo-pwa-signer wheel. The public downloader repository does not include the signing algorithm source. The s parameter calculation was obtained through reverse-engineering work by Sisyphus; to reduce ongoing maintenance burden, it has been packaged into the wheel and does not affect normal downloader usage. Install the private wheel before using PWA downloads; see docs/private-pwa-signer-wheel.md for the required wheel contract and verification checklist. If another project wants to implement demo downloading without relying on this pip package, contact wangchudi666@gmail.com.
If one PWA access token can access multiple target Steam accounts, set it once as pwa.default_access_token and add one pwa.users entry per target steamid. A user-specific access_token can override the default for a single target.
Steam Official Matchmaking Credentials
Steam official matchmaking support uses Valve's ICSGOPlayers_730/GetNextMatchSharingCode/v1 Web API. You need:
steamid: your SteamID64.api_key: a Steam Web API key fromhttps://steamcommunity.com/dev/apikey.steamidkey: the match sharing authentication key shown by CS2/CS:GO.knowncode: one existing official matchmaking share code, used as the cursor for fetching newer matches. The API returns the next share code afterknowncode; the downloader can iterate share codes locally. Steam does not expose the final replay URL through this Web API alone. A real.dem.bz2URL must be read from Steam Game Coordinator full match info, typically the matchmapfield. Until a GC resolver is configured, the Steam platform will report that no real replay URL can be resolved instead of returning a fake download URL.
Steam Demo URL Resolvers
Steam official matchmaking has two optional resolver backends:
boiler: local-machine backend usingakiver/boiler-writter. Steam must be running and logged in on the same machine. This avoids storing Steam passwords and is recommended for local CLI usage. Configuresteam.resolver.type = "boiler". Setsteam.resolver.auto_download = "true"to download the latest boiler-writter release into the local cache automatically, or setsteam.resolver.executable_pathto a manually installed binary.steam-login: headless backend using optionalsteam/csgodependencies. It reads credentials only from environment variables such asSTEAM_GC_USERNAMEandSTEAM_GC_PASSWORD; do not store Steam credentials in your config file. Live Steam login still requires a real account and cannot be verified by local unit tests.
Docker images do not bundle boiler-writter and cannot use the local Steam resolver unless you provide a working Steam client environment yourself.
When working from a local clone, install optional resolver dependencies as needed:
pip install -e .[steam-boiler]
pip install -e .[steam-login]
Install
Install the latest release from PyPI:
pip install cs-demo-downloader
Optional extras:
# Steam official matchmaking resolver using local Steam + boiler-writter parser deps
pip install "cs-demo-downloader[steam-boiler]"
# Steam official matchmaking resolver using steam-login/csgo GC deps
pip install "cs-demo-downloader[steam-login]"
You can also install the current main branch directly from GitHub:
pip install git+https://github.com/WangChuDi/CS-Demo-Downloader.git
For local development from this repository, use editable installs instead:
pip install "$(python scripts/select_private_signer_wheel.py wheelhouse)"
pip install -e .
On Windows PowerShell:
$wheel = python scripts/select_private_signer_wheel.py wheelhouse
pip install $wheel
pip install -e .
The private signer wheel is required only for real PWA signing. Public tests mock that boundary.
The package installs this console command:
cs-demo-downloader- CLI downloader.
CLI Usage
Common commands:
| Task | Command |
|---|---|
| Show help | cs-demo-downloader --help |
| Download all configured platforms | cs-demo-downloader download --all --config config.jsonc |
| Download 5EPlay only | cs-demo-downloader download --platform 5e --config config.jsonc |
| Download PWA only | cs-demo-downloader download --platform pwa --config config.jsonc |
| Download Steam only | cs-demo-downloader download --platform steam --config config.jsonc |
| Export 5E/PWA metadata | cs-demo-downloader metadata --all --config config.jsonc --pretty |
| Start internal scheduler | cs-demo-downloader schedule --config config.jsonc |
| Refresh cached PWA DLL manually | cs-demo-downloader update-pvpalive-dll --target cache/PvpAlive.dll |
CLI command examples and notes
Show help:
cs-demo-downloader --help
cs-demo-downloader download --help
cs-demo-downloader schedule --help
Download all configured platforms:
cs-demo-downloader download --all --config config.jsonc
Download only 5EPlay demos:
cs-demo-downloader download --platform 5e --config config.jsonc
Download only Perfect World Arena demos:
cs-demo-downloader download --platform pwa --config config.jsonc
Download only Steam official matchmaking demos:
cs-demo-downloader download --platform steam --config config.jsonc
Export normalized metadata for configured 5E/PWA users without downloading demo files:
cs-demo-downloader metadata --all --config config.jsonc --pretty
cs-demo-downloader metadata --platform pwa --config config.jsonc --limit 5 --include-raw
The metadata command prints a JSON list. URL query secrets such as PWA access_token and signatures are redacted by default, including when --include-raw is used.
Each match keeps the original backward-compatible fields such as platform, match_id, demo_url, demo_available, teams, players, round_results, raw_summary, and raw_detail. Newer exports also include:
schema_version: metadata shape version, currently1.1.exported_at: UTC export timestamp added at serialization time.duration_seconds: derived fromstarted_atandended_atwhen both timestamps are valid.demo: grouped demo state with redactedurl,available, source/details, and platform demo flags when available.rounds: normalized round list. For PWA this mergesreport.resultsandround_simple_listby round number while preservinground_resultsfor older consumers.
Update the cached PWA PvpAlive.dll explicitly without downloading the full official client ZIP:
cs-demo-downloader update-pvpalive-dll --target cache/PvpAlive.dll
This command reads the official latest.yml, derives the matching ZIP URL, uses HTTP Range requests to fetch only the ZIP tail, central directory, local header, and compressed plugin/PvpAlive.dll data, validates size and CRC32, then atomically replaces the target cache file. It writes version metadata next to the DLL as PvpAlive.dll.json; if the cached metadata already matches the latest client, the DLL data is not downloaded again. Pass --force to refresh anyway. It does not modify the installed Perfect World Arena client and is not used by the normal Python signing path unless you explicitly call it.
Override the configured download directory:
cs-demo-downloader download --all --config config.jsonc --output ./demos
Run the internal scheduler in foreground mode:
cs-demo-downloader schedule --config config.jsonc --enabled --interval-seconds 86400 --run-on-start
The scheduler stays idle by default and prints an idle message until it receives SIGINT or SIGTERM. Automatic downloads are opt-in through CLI flags, environment variables, or the optional scheduler config section.
When --config is provided explicitly, the CLI exits with a non-zero status if that file is missing or invalid. This is intentional so Docker, cron, and other automation can detect configuration problems.
Python API Usage
You can also use the installed package from your own Python scripts. The public modules are small function wrappers around each platform downloader plus the shared download/extract helpers.
Python examples
5EPlay
from cs_demo_downloader.core.downloader_5e import get_all_demo_urls
from cs_demo_downloader.core.utils import download_and_extract
demo_urls = get_all_demo_urls("YOUR_5E_USERID")
for match_id, demo_url in demo_urls.items():
print("downloading", match_id)
download_and_extract(demo_url, "./demos")
Perfect World Arena / PWA
PWA downloads need both the signed URL and the PWA download headers. Do not print or persist generated URLs because they contain access_token.
from cs_demo_downloader.core.downloader_pwa import (
build_download_headers,
get_all_demo_urls,
)
from cs_demo_downloader.core.utils import download_and_extract
steamid = "YOUR_STEAM_ID64"
access_token = "YOUR_PWA_ACCESS_TOKEN"
headers = build_download_headers(steamid)
demo_urls = get_all_demo_urls(steamid, access_token, size=20)
for match_id, demo_url in demo_urls.items():
print("downloading", match_id)
download_and_extract(demo_url, "./demos", headers=headers)
If you only need the signed URL for integration with another downloader:
from cs_demo_downloader.core.downloader_pwa import get_demo_url
demo_url = get_demo_url("MATCH_ID", "YOUR_PWA_ACCESS_TOKEN")
Metadata export from Python
After installing the pip package, you can collect normalized metadata directly. Use metadata_list_to_dicts() before writing JSON so schema fields, export timestamps, URL redaction, and optional raw-field removal are handled consistently with the CLI.
import json
from cs_demo_downloader.core.downloader_5e import get_all_demo_metadata as get_5e_metadata
from cs_demo_downloader.core.downloader_pwa import get_all_demo_metadata as get_pwa_metadata
from cs_demo_downloader.core.metadata import metadata_list_to_dicts
matches = []
matches.extend(get_5e_metadata("YOUR_5E_USERID", limit=10))
matches.extend(get_pwa_metadata("YOUR_STEAM_ID64", "YOUR_PWA_ACCESS_TOKEN", size=10))
payload = metadata_list_to_dicts(matches, redact_sensitive_urls=True, include_raw=False)
print(json.dumps(payload, ensure_ascii=False, indent=2))
For real PWA metadata, the private cs-demo-pwa-signer wheel must be installed because match-list fallback responses and demo URLs require the compiled signing/decryption boundary. 5E metadata does not require that wheel.
Steam Official Matchmaking
Steam Web API share-code iteration is available through downloader_steam. A real replay URL still requires a Steam GC resolver such as the built-in boiler-writter resolver.
from cs_demo_downloader.core.downloader_steam import get_all_demo_urls
from cs_demo_downloader.steam.boiler_resolver import BoilerWritterResolver
resolver = BoilerWritterResolver(auto_download=True)
demo_urls = get_all_demo_urls(
api_key="YOUR_STEAM_WEB_API_KEY",
steamid="YOUR_STEAM_ID64",
steamidkey="YOUR_MATCH_SHARING_AUTH_KEY",
knowncode="CSGO-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx",
demo_url_resolver=resolver.resolve_demo_url,
)
Config helpers
To reuse the same JSONC config file as the CLI:
from cs_demo_downloader.core.config import load_config
config = load_config("config.jsonc")
for user in config.get_users_pwa():
print(user.label, user.steamid)
PWA DLL cache updater
The updater is available as a Python function if you need to refresh a cached PvpAlive.dll for a separate integration:
from cs_demo_downloader.pwa_dll_updater import update_cached_pvp_alive_dll
dll_path = update_cached_pvp_alive_dll(target_path="cache/PvpAlive.dll", force=False)
print(dll_path)
The current downloader uses the private compiled signer wheel by default on every platform. If you explicitly need the DLL fallback, set pwa.signature_provider to one of these values:
compiled: default private compiled wheel signer; no DLL or Wine involved.pvp_alive_native: call the packaged 32-bit bridge directly on Windows.pvp_alive_wine: call the packaged 32-bit bridge through Wine on Linux.
The DLL is never committed or bundled. Refresh it explicitly when needed:
cs-demo-downloader update-pvpalive-dll --target cache/PvpAlive.dll
Python users can also call the bridge helper directly:
from cs_demo_downloader.pwa_bridge import call_pvp_alive_swap_data
signature = call_pvp_alive_swap_data(
dll_path="cache/PvpAlive.dll",
inner_json='{"your":"payload"}',
)
Linux Wine usage is explicit:
from cs_demo_downloader.pwa_bridge import call_pvp_alive_swap_data_wine
signature = call_pvp_alive_swap_data_wine(
dll_path="cache/PvpAlive.dll",
inner_json='{"your":"payload"}',
)
macOS users should use a macOS-compatible private signer wheel; this project does not include a macOS Wine/QEMU fallback.
Docker Usage
Published GitHub Container Registry images:
| Image | Platforms | Notes |
|---|---|---|
ghcr.io/wangchudi/cs-demo-downloader:latest |
linux/amd64, linux/arm64 |
Default image. Uses the private compiled signer wheel and does not include Wine. |
ghcr.io/wangchudi/cs-demo-downloader:latest-wine |
linux/amd64 |
Wine-enabled image for explicit pvp_alive_wine DLL bridge use. |
Pull the default image:
docker pull ghcr.io/wangchudi/cs-demo-downloader:latest
Images are published automatically when a v* Git tag is pushed or a GitHub Release is published. Release images are tagged as latest, the full semantic version such as 0.1.0, and shorter version aliases such as 0.1 and 0 when applicable.
Wine-enabled images are published separately with a -wine suffix, for example:
docker pull ghcr.io/wangchudi/cs-demo-downloader:latest-wine
The Wine image is currently built for linux/amd64 only because the packaged PWA bridge is a 32-bit Windows executable.
Start the default container with mounted config and output directories:
mkdir -p config demos
cp config.jsonc.example config/config.jsonc
# Edit config/config.jsonc before running the container.
docker run --rm \
-v "$(pwd)/config:/config" \
-v "$(pwd)/demos:/demos" \
ghcr.io/wangchudi/cs-demo-downloader:latest
By default, the image runs cs-demo-downloader schedule and stays idle unless scheduling is explicitly enabled. Because disabled scheduler mode does not load /config/config.jsonc, the container can be started as a prepared environment without a config file.
Local Docker builds, Wine image, and Compose
You can also build the image locally from this repository:
cp /path/to/cs_demo_pwa_signer-0.1.0-*.whl wheelhouse/
docker build --build-arg PYTHON_VERSION=3.12 -t cs-demo-downloader .
docker build --build-arg PYTHON_VERSION=3.12 -f Dockerfile.wine -t cs-demo-downloader:wine .
Prepare mounted directories and config:
mkdir -p config demos
cp config.jsonc.example config/config.jsonc
# Edit config/config.jsonc before running the container.
Run one manual download on demand:
docker run --rm \
-v "$(pwd)/config:/config" \
-v "$(pwd)/demos:/demos" \
ghcr.io/wangchudi/cs-demo-downloader:latest \
download --all --config /config/config.jsonc --output /demos
The Docker entrypoint runs:
cs-demo-downloader schedule
Enable automatic scheduled downloads with environment variables:
docker run --rm \
-e CS_DEMO_SCHEDULE_ENABLED=true \
-e CS_DEMO_SCHEDULE_CONFIG=/config/config.jsonc \
-e CS_DEMO_SCHEDULE_OUTPUT=/demos \
-e CS_DEMO_SCHEDULE_INTERVAL_SECONDS=86400 \
-e CS_DEMO_SCHEDULE_RUN_ON_START=false \
-e CS_DEMO_SCHEDULE_PLATFORMS=all \
-v "$(pwd)/config:/config" \
-v "$(pwd)/demos:/demos" \
ghcr.io/wangchudi/cs-demo-downloader:latest
You can also store the same scheduler settings in the optional scheduler section of config.jsonc. Environment variables override config values.
The default Linux container uses the private compiled signer wheel and does not include Wine. If you want to refresh a cached DLL, mount a cache directory and run the updater explicitly:
docker run --rm \
-v "$(pwd)/cache:/cache" \
ghcr.io/wangchudi/cs-demo-downloader:latest \
update-pvpalive-dll --target /cache/PvpAlive.dll
To use the Linux Wine bridge image, switch to the -wine tag and set the config to "signature_provider": "pvp_alive_wine" with "pvp_alive_dll": "/cache/PvpAlive.dll":
docker run --rm \
-v "$(pwd)/config:/config" \
-v "$(pwd)/demos:/demos" \
-v "$(pwd)/cache:/cache" \
ghcr.io/wangchudi/cs-demo-downloader:latest-wine
Docker Compose
docker compose up -d cs-demo-downloader
docker-compose.yml uses ghcr.io/wangchudi/cs-demo-downloader:latest by default, starts in idle scheduler mode, and mounts ./config, ./demos, and ./cache. Uncomment the example scheduler environment variables in the compose file to opt in to automatic downloads. Run one manual download through Compose with:
docker compose run --rm cs-demo-downloader download --all --config /config/config.jsonc --output /demos
To start the Wine variant:
docker compose --profile wine up -d cs-demo-downloader-wine
Scheduled Downloads
Use either the built-in scheduler or an external scheduler such as cron. Example crontab entry for a daily 03:00 one-shot run:
0 3 * * * docker run --rm -v /home/user/config:/config -v /home/user/demos:/demos ghcr.io/wangchudi/cs-demo-downloader:latest download --all --config /config/config.jsonc --output /demos
Make sure /home/user/config/config.jsonc exists before scheduling the one-shot job.
Tests
Run the local unittest suite:
python3 -m unittest discover
Run a syntax/bytecode check:
python3 -m compileall src tests cli.py
The tests are local and deterministic. They do not require real 5EPlay/PWA/Steam credentials or network access. The install tests create temporary virtual environments, install the package with pip install, and verify that the installed package contains the bundled signer manifest, loads the matching vendored signer binary from site-packages, and relies on pip build isolation to provide the wheel build dependency instead of requiring a manual wheel install.
Notes and Limitations
- The project currently supports 5EPlay and Perfect World Arena downloads. Steam official matchmaking share-code iteration is implemented, but real Steam replay URL resolution requires a Steam GC full-match-info resolver.
- PWA access tokens may expire and must be refreshed manually.
- Demo availability depends on the upstream platform APIs.
- Downloaded files and local configs are intentionally ignored by git.
- Cached
PvpAlive.dllfiles undercache/orvendor/PvpAlive/are intentionally ignored by git and must not be committed. - PWA signing requires the private
cs-demo-pwa-signerwheel. The public source tree must not contain the signer algorithm source or an sdist for that package. If another project wants to implement demo downloading without relying on this pip package, contactwangchudi666@gmail.com. - A 32-bit Windows C++ bridge executable is packaged for explicit DLL fallback use. Linux uses the private compiled signer by default; Wine is available only through the explicit
pvp_alive_wineprovider or*-wineDocker image. QEMU fallback is intentionally not included.
License
This project is licensed under the MIT License. See LICENSE for details.
If you believe any content in this project infringes your rights, please contact the maintainer by opening a GitHub issue or emailing wangchudi666@gmail.com.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cs_demo_downloader-1.1.0.tar.gz.
File metadata
- Download URL: cs_demo_downloader-1.1.0.tar.gz
- Upload date:
- Size: 3.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d8843913789e42235bb53aebc348dcc37217e5f40903720631aece35d9676ca
|
|
| MD5 |
b3b348fc24f41fba00d2a97b689da02e
|
|
| BLAKE2b-256 |
69ec474d994a57fda5b9926b4d192b234334bdfe19d2743991bca7c9358b509c
|
File details
Details for the file cs_demo_downloader-1.1.0-py3-none-any.whl.
File metadata
- Download URL: cs_demo_downloader-1.1.0-py3-none-any.whl
- Upload date:
- Size: 3.7 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6923f9b2edca210ba885d99ad35df162b77c5d3f91b774ab87afb2ae6c5b7d2
|
|
| MD5 |
781dec3bc958eba1ef558338f06ebd1f
|
|
| BLAKE2b-256 |
8ef4bf225bfae8cc47176ccb45248e9685b251247bdc3153c1f65d5aa233b4a0
|