Media ingestion, processing and analysis service for keble short videos (PlayRef -> EnrichmentResult).
Project description
keble-video-enrichment
短视频媒体处理与理解服务。可通过 keble-data-infra-contract 接收通用视频引用
(ShortVideo + PlayRef),
完成安全摄取、校验、checksum、ffprobe、音频/关键帧提取、ASR、OCR,输出结构化
EnrichmentResult 供 Data Infra / Search / GraphRAG 消费。
keble-tiktok负责找到视频,keble-video-enrichment负责处理和理解视频。
0.2.0 exact metering release
The public package now resolves keble-helpers>=1.51.0, keble-db>=1.9.0,
and keble-data-infra-contract==0.2.0 entirely from the registry. No Git source
override or repository credential is required to install or build the service.
Existing 0.1.x deployments have no production data migration obligation; the
first operational rollout may start from a clean database and object prefix.
Side effects if changes:
- Data Infra consumes terminal attempt history and canonical usage from the
0.2.0contract before the Ideas platform writes immutable cost facts. - ASR/OCR route selection, quota profiles, price evidence, and credentials stay environment-owned by this service; package publication does not activate a route or claim a 100K/day production quota.
财务用量与批量准入
本服务只拥有媒体执行事实与路由策略,不拥有货币价格。每个 ASR、OCR、本地媒体处理结果均发出
UsageAccountingEvent,精确区分音频秒、图像帧、token 与本地 compute millisecond;事件携带不可变的
producer attempt/profile identity,但不携带单价或金额。终态 Job 以 schema v2 保存每次分析尝试,因此
全失败调用与“先失败、后重试成功”的调用都能由 Data Infra 传给 Platform 财务账本,不能因没有 Result
而消失。修改这些事件或 identity 时,必须同时检查 application/analysis.py、
application/service.py、domain/job.py 与 Data Infra consumer contract。
ASR 与 OCR 在完成共同的媒体准备后并发执行,并先分别预留预算;最终账面事实按实际 provider 响应结算,
不会把预留值冒充实际金额。批量准入由可替换的 QuotaAdmissionStore 管理:测试可用进程内实现,生产必须
使用 Redis Lua 原子脚本,在所有 replica 之间共享并发 lease 与 UTC 日额度。默认上限为 16 个并发 Job、
每天 7,500 个 Job,lease 必须长于 Job timeout;这些是安全容量设置,不是 provider RPM/TPM 或价格。
生产如缺 Redis、额度小于目标视频量或 lease 配置不安全会在启动时 fail closed。
Hosted ASR/OCR 另有一层精确到 operation/provider/deployment/region/billing-mode 的 immutable quota profile。
scripts/compile_provider_quota_profiles.py 校验来源、时间、选择器与 content-addressed key;生产必须通过
KVE_PROVIDER_QUOTA_PROFILE_PATH 加载 compiled file,并设置 KVE_REQUIRE_PROVIDER_QUOTA_COVERAGE=1。
Redis Lua 会原子预留 RPM、input/output/total TPM、并发、audio-seconds/day 与 provider credits/day;拒绝不会
留下部分计数,crash lease 会按 TTL 回收。默认 5,000 个三分钟视频、30% headroom 的 preflight 至少要求
ASR 5 RPM、remote OCR 55 RPM,因此当前 3-RPM Whisper deployment 会明确拒绝启动,而不是在运行中排队到
第二天。OPENAI_MAX_RETRIES=0 是 production 要求:physical retry 必须成为可计量的 Job attempt,不能藏在
SDK 内。示例见 docs/examples/provider-quota-profiles.example.uncompiled.json,
容量与 live 证据见 docs/benchmarks/2026-07-13-video-capacity-and-live-calibration.md。
项目是什么 / 不是什么
是:由 Keble 根据现有系统边界实现的媒体摄取与分析服务;包含 Job 状态、幂等、重试、部分成功、 Artifact 生命周期和 ASR/OCR 规范化。AWS Media2Cloud 仅作为成熟架构参照,用于验证职责分离方向, 不是实现模板或运行时依赖。
不是:视频数据源(不调用 EchoTik/FastMoss 私有 API);通用 Contract 仓库(不定义 ShortVideo);
Web 管理后台/MAM/内容审核平台/视频编辑工具。
为什么独立
媒体处理是长耗时、重依赖(ffmpeg/ASR/OCR)、易部分失败的工作负载,与轻量 contract 层和渠道
连接器的定位冲突。keble-data-infra 执行计划的决策 D5 已锁定独立仓库。
详见 ADR-001。
与相邻仓库的关系
- keble-data-infra-contract:本项目可选
data-infraadapter 的唯一上游 package 依赖(ShortVideo/PlayRef/ProviderId);Git source 暂时固定到已推送 contract commit, 私有源码安装需要 repository credential,package 发布后改为 registry version。独立 REST/OCR image 不安装这个可选 adapter,因此 production image 不包含 Git 或源码凭证。 - keble-data-infra-api:通过 HTTP 提交/读取 enrichment,并实现 contract 中的 consumer Protocol;本项目不导入 API/runtime distribution。
- keble-tiktok:互不依赖。它产出 PlayRef,本项目消费标准化后的引用;渠道差异在进入本项目前 已被抹平。详见 ADR-004。
成熟参照与 Keble 自主决策
AWS Media2Cloud 用于验证稳定资产身份、摄取与分析分离、完整性校验、持久化任务状态和完成通知等原则。 本项目没有复制其 Step Functions、Lambda、DynamoDB、SNS、MediaConvert、Transcribe、Rekognition 或完整 部署模板。Keble 根据轻量部署、现有 MongoDB/Redis、可替换 AI Engine、合规保留策略和 Data Infra 边界, 独立定义并实现了 Domain Contract、Application Workflow、Repository、Adapter、部分成功和 durable CompletionEvent 交付。
代码与测试证据见架构文档;逐组件参照范围和未采用 项见 Media2Cloud mapping。
MVP
一个 PlayRef → 安全获取 → 校验 + checksum → ffprobe → 音频/关键帧提取 → 一次 ASR + 一次 OCR → 结构化 JSON → 清理临时原始媒体。合规 gate 通过前,开发全程使用本地合成测试视频。
目标架构
当前实现通过 Port 连接 FastAPI、异步本地 Runner、MongoDB、Aliyun OSS 和 Redis Stream;这些选择来自 Keble 的部署条件与已批准决策,不表示已具备 AWS 式多机编排或生产弹性。 全部图与规则:docs/architecture/keble-video-enrichment-architecture.md。
当前状态
Phase 00(规划)与 Reference Baseline Reconciliation 已完成;Phase 01(Project Baseline and
Contracts)、Phase 02(Single Video Ingestion)、Phase 03(Media Processing)与 Phase 04(ASR/OCR)
已完成;Phase 04 的 Azure OCR adapter 与独立 REST service 已使用仓库自有合成媒体通过真实
gpt-5.6-luna smoke;Azure hosted Whisper 与 Azure Speech Batch 已在同一组自有 EN/ZH fixture 上完成
真实对比,production route 仍等待 owner threshold/label approval。Phase 05 已完成 MongoDB 编排持久化;
Phase 06 已完成 REST Job/Result 查询、
durable Mongo outbox、keble-db Redis Stream publisher 与 v1 consumer contract。真实 Mongo/Redis/
provider 测试保留显式 gate。
Phase 07 应用开发已完成:通用 Artifact Store、Aliyun OSS adapter、配置/wiring、结构化日志、Prometheus、
quota、清理调度、Linux x86_64 Docker runtime、runbook 与安全评审均已落地。新的深圳开发 bucket 已通过
delete/list preflight、put/head、完整与 range get、checksum、最终 delete 和空前缀审计。Bucket-level
oss:ListObjects 与 object-level CRUD policy 已形成可用绑定,因此冷启动 artifact lookup、TTL cleanup
所需的完整 OSS live gate 已通过;users/phase-07-live-e2e/ 下残留对象计数为零。
EnrichmentSettings.from_env() 是 runtime/test 读取 KVE_* 的单一强类型入口;显式构造 adapter
settings 时直接传 Pydantic 字段,不再把 _env_file 这个框架内部参数散落到调用方。
所有 settings loader 都把 .env.example 中空白的可选成本/凭证值视为“未配置”,不会把空字符串
误解析成整数,也不会把未知成本错误地当作零成本;仍为必填的 benchmark threshold 保持 fail-closed。
示例凭证保持空白而不是可被误认作真实 key 的占位字符串,因此复制 .env.example 不会抢先选择
错误的 OpenAI/Azure provider;真实 secret 只写入 gitignored .env 或部署 secret store。
共享 dotenv 同时包含 OPENAI_*_MODEL 与 Azure deployment 时,model/provenance 也严格按已选 provider
解析,OpenAI 默认值不得覆盖 Azure deployment。若音频与 OCR 位于不同 Azure resources,
AZURE_KEY_ASR/AZURE_ENDPOINT_ASR 独立拥有 ASR credential boundary,而 AZURE_KEY/AZURE_ENDPOINT
只归 OCR 使用;ASR 不会静默 fallback 到 OCR resource,禁止把一个 resource 的 key 与另一个 endpoint 拼接。
Azure OCR 使用 Responses API,AZURE_OCR_VERSION 必须为 2025-03-01-preview 或更新版本;
兼容 OpenAI Audio route 独立使用 AZURE_ASR_VERSION/AZURE_ASR_DEPLOYMENT。大规模 route 另有
Azure Speech batch、OpenAI mini transcription 与 baked local Whisper Turbo 三种强类型选择;禁止让
audio transcription 与 OCR 共享 deployment/API version。
tests/live/test_synthetic_video_ocr_service_live.py 覆盖仓库自有视频下载、ffmpeg keyframe、真实 OCR、
Job/Result 持久化、REST 读取、completion event 与 workspace 清理;它不替代 OSS 或 ASR gate。
tests/live/test_owned_sample_video_batch_live.py 以显式付费 gate 将 umbrella docs/medias/sample-vid*.mp4
五个不同视频逐一走完 HTTP fetch、ffprobe、duration-aware 单帧选择、真实 OCR、result/event 与 workspace
清理;每个视频硬限制一个唯一帧/一次 provider call,避免把验收测试变成无界模型支出。
tests/live/test_owned_sample_video_local_asr_live.py 在禁止网络的 baked Whisper image 中将同一批五个视频
走完 fetch、ffprobe、audio extraction、本地 ASR、result/event 与 workspace 清理;121.945s 音频在该
Docker CPU host 上用 161.838s 完成,识别出四个 English 与一个 Vietnamese 样本,ASR provider call 为零。
这些结果证明执行链和语言输出,不代表文字准确率已经通过 owner 的人工验收。
两个 owned-media live tests 使用 pytest -s 时都会输出无凭证的 human_review_samples,使 owner 能逐视频
检查 transcript/OCR text;测试仍只在 tmp_path 写中间文件并清理 workspace。
当前非 root production image 已使用现有认证 Mongo/Redis、typed OSS/Azure 配置启动并达到 Docker
healthy;验证使用唯一 Mongo/Redis namespace,停止后已清理,且未提交媒体或写入 OSS。
RAM policy 若限制写入既有用户前缀,live gate 通过 KVE_ALIYUN_OSS_PREFIX 注入该前缀并在其下追加
唯一 phase-07-live-e2e/{run_id};测试先对不存在的唯一 key 验证 DeleteObject 权限,无法清理时在
上传前失败,且不得绕过前缀向 bucket root 写入。
共享 backend env 使用 oss-cn-shenzhen region spelling,而 Alibaba v2 signer 使用 cn-shenzhen;
AliyunOssSettings 在 Pydantic boundary 统一这两种输入,避免 live/runtime 产生无效签名。
规模化成本边界
当前 AsrEngine/OcrEngine Port 与 normalized Result contract 继续作为唯一分析边界。关键帧已改为按
完整 duration 抽取有界 candidates、按时间窗口
选择视觉变化最大的画面,并用 64-bit perceptual hash 去重;静态/重复画面不会再重复触发 OCR,十帧预算也
不再只覆盖视频开头十秒。OcrEngine 接收完整 ExtractedFrame,因此 OCR 与 confidence fallback 会保留
scene selection 的真实 source timestamp,不再用数组下标伪造秒数。
Dockerfile.paddle 现提供 x86_64 PP-OCRv5 Mobile mass-volume profile:一个 local batch 处理全部唯一帧,
ConfidenceFallbackOcrEngine 只把空结果、未知 confidence 或低于阈值的帧发送到付费 vision adapter;
base Dockerfile 保留为 compatibility/canary profile,不是海量 OCR 部署入口。PP-OCR model 在 image build
阶段缓存,production startup 会验证 inference.json/weights/config,禁止 runtime 静默下载。
模型选择与 batch predict() 边界分别依据
PP-OCRv5 official comparison
和 official OCR pipeline API。
ASR analysis artifact 使用 lossless 16 kHz mono FLAC。ffmpeg silencedetect 先建立 source-to-analysis
timeline,再删除静音并保留 speech padding;ASR segment 会映射回原视频时间。若上游提供由
keble-data-infra 授权、绑定 source reference 与实际 media SHA-256 的 canonical transcript,则服务直接复用,
跳过音频提取和付费 ASR;caption 文本本身不会被误当作授权 transcript。
ASR route registry 只允许显式配置的 openai_mini、azure_batch 或 local_whisper,不做静默 provider
fallback。Hosted default 为 JSON-only gpt-4o-mini-transcribe;没有 provider segment timestamps 时,整段
文本使用 compact audio 的完整 duration,而不会伪造零长度。Azure Speech batch 固定当前实现支持的 GA
2025-10-15;production composition 通过 canonical audio artifact_id 从 OSS 生成一小时 HTTPS signed URL,
URL 不写入 Job/Result/log,且其 TTL 必须长于 bounded batch timeout。local route 固定 baked
large-v3-turbo CTranslate2 artifacts,并禁止 runtime download。
三条 adapter 共用 normalized transcript、VAD timeline 和 cost estimator,但 owner 已选择 public-API-only
production policy,因此最终 selector 只比较 hosted Whisper 与 Azure Speech batch;local Whisper 仅保留为
offline engineering canary。AnalysisCostBudget 在 provider call
前 fail closed:未知价格或 worst-case estimate 超预算会返回 typed ANALYSIS_BUDGET_EXCEEDED,不会先花费
再报警。
仓库自有中英文语音 fixture、manifest SHA-256、WER/CER、realtime factor 与 cost/min runner 已落地;fixture
标记为 machine_generated_pending_owner_review。Baked local Whisper route 已独立测量;hosted mini 可通过
RUN_LIVE_OPENAI_ASR=1 独立测量而不伪造 acceptance threshold。ASR-specific Azure Whisper 已在相同
EN/ZH fixtures 上通过:WER 0.0909、CER 0.0625、6.596s audio / 6.764s wall、realtime factor
0.975;repeat warm run 为 4.445s wall / 1.484 realtime factor。Microsoft public retail defaults are
6000 micros/audio-minute for global Azure Whisper and 3000 for standard Azure Speech batch, reviewed
2026-07-12; regional Whisper deployments override the default through env. Recommended canary thresholds are
WER 0.15, CER 0.10, realtime factor 0.5, and cost ceiling 8000, but route selection still fails closed until
KVE_ASR_BENCHMARK_OWNER_APPROVED=1. The authenticated two-public-route measurement now passes with automatic
isolated OSS upload/sign/delete: Azure Speech Batch measured WER 0.0909, CER 0.046875, 133.34s wall,
realtime factor 0.0495, and 3002 micros/audio-minute; hosted Whisper measured WER 0.0909, CER 0.0625,
5.47s wall, realtime factor 1.206, and 5995 micros/audio-minute. Both processed 6.596s of identical audio.
Under the recommended short-video threshold, hosted Whisper is the only passing speed candidate and therefore remains
the default. Azure Batch remains a cheaper backlog candidate only after a separate multi-file coordinator proves
forecast bulk capacity; one-job-per-video queue latency must not be mislabeled as throughput. 仓库自有 OCR fixture
已在非 root amd64 Paddle image 中通过真实 PP-OCRv5 Mobile inference:KEBLE OCR 42、原始 9750 ms
timestamp、provider_calls=0。Direct OpenAI and local-compute prices remain operator-owned and unknown rather than
reusing Azure rates or being mislabeled free.
The owner has now approved those thresholds. A fresh configured-route run selects
openai_mini with WER 0.0909, CER 0.0625, realtime factor 0.7945, and
5995 micros/audio-minute. The repository installs httpx[socks] because the
OpenAI/Azure client intentionally honors the environment-owned SOCKS proxy; it
must not bypass that network boundary. Azure Speech Batch remains a separately
credentialed, currently unprovisioned backlog candidate—not an implicit reuse of
AZURE_ENDPOINT_ASR/AZURE_KEY_ASR.
The provider-quota gate is separate from route-quality approval. Compile an operator-reviewed profile before production startup:
uv run python scripts/compile_provider_quota_profiles.py \
docs/examples/provider-quota-profiles.example.uncompiled.json \
/run/keble/provider-quota-profiles.json
The checked-in example intentionally records the observed 3-RPM ASR quota and therefore compiles as evidence but fails the 5,000-video capacity preflight. Do not raise that value without a provider/source record, and do not treat a missing value as unlimited.
Routing 与 gate 配置见 .env.example。不具备 ffmpeg/ffprobe 的主机使用 portable-offline
命令;依赖这些 production binaries 的 media integration modules 明确标记为 container,并在 Linux
image/CI 的完整 not live suite 中执行:
uv run pytest -q -m "not live and not slow and not eval and not local_stack and not db_stack and not container"
uv run pytest -q -m eval
uv run ruff check .
npx --yes pyright .
真实 route 分别使用 RUN_LIVE_OPENAI_ASR、RUN_LIVE_AZURE_SPEECH_BATCH、
RUN_LOCAL_WHISPER_ASR;public-API measurement 还要求 RUN_LIVE_ASR_BENCHMARK=1 与
RUN_ALIYUN_OSS_LIVE_E2E=1。测试会上传两份 exact owned fixtures、生成 bounded signed URLs,并在 module
teardown 后断言 prefix 为空;不再手工粘贴 URL。只有 production selection 额外要求显式
KVE_ASR_BENCHMARK_OWNER_APPROVED=1。RUN_LIVE_OPENAI_ASR=1 uv run --env-file .env pytest -q tests/live/test_hosted_mini_asr_live.py measures only the hosted route and never selects it.
The owner-approved configured-route gate is
RUN_LIVE_OPENAI_ASR=1 uv run --env-file .env pytest -q -s tests/evals/test_owner_approved_hosted_asr_live.py.
Gate 不会因 credential 存在而自动开启。
The accelerated distributed capacity gates are:
KVE_TEST_REDIS_URI=redis://127.0.0.1:19736/15 \
uv run pytest -q -s tests/integration/events/test_provider_limits_real_redis.py
KVE_TEST_REDIS_URI=redis://127.0.0.1:19736/15 \
uv run pytest -q -s tests/integration/capacity/test_video_day_replay.py
The 5,000 replay uses cached providers and accounts 15,000 audio-minutes; it is control-plane and cleanup evidence, not a claim that the 3-RPM hosted route can finish the wall-clock workload.
x86_64 local-primary image:
export GH_TOKEN="$(gh auth token)"
docker build --secret id=gh_token,env=GH_TOKEN \
--platform linux/amd64 -f Dockerfile.paddle \
-t keble-video-enrichment:paddle-local .
Baked local-ASR candidate image:
export GH_TOKEN="$(gh auth token)"
docker build --secret id=gh_token,env=GH_TOKEN -f Dockerfile.whisper \
-t keble-video-enrichment:whisper-local .
The BuildKit secret is required only while uv resolves the exact private
keble-db release-candidate commit. The Dockerfiles remove Git and its temporary
authorization header in the same layer; the token is not copied into the image.
Dockerfile.whisper pins the MIT CTranslate2 conversion
dropbox-dash/faster-whisper-large-v3-turbo at immutable revision
0a363e9161cbc7ed1431c9597a8ceaf0c4f78fcf. Build time downloads the six approved files,
writes their SHA-256 manifest, verifies it, and makes /opt/faster-whisper read-only. Startup
rehashes the artifact set before loading with local_files_only=True; runtime never downloads
weights. This is the independently measurable local-ASR candidate, not an automatic production
winner and not a replacement for the PP-OCR mass-volume image.
Apple Silicon host 可运行 unit 与真实 macOS local canary,但 Paddle 3.3.0 没有 Linux arm64 PyPI wheel;
因此 production image 必须在 x86_64 builder 构建,或由 CI 使用 --platform linux/amd64 构建。
历史 base/Paddle ASR-composition images 为 sha256:36ce878d... / sha256:262bf83a...。
当前 Mongo runtime candidate 是从 exact 9db27c8 lock 重建的 Paddle image
sha256:eae43a9a8faec480d35986d9c9e77f08036233e8ee5ed42443ed3dbb6be1d8ca;它以
non-root kve 运行、不含 Git 或 /root/.gitconfig,并已通过真实 Job POST -> GET。
Paddle image 的 Docker uncompressed size 为约 3.18 GB(Paddle runtime + OpenCV + ffmpeg);这是
部署/cold-start 成本,不得把“provider call 为 0”误解成“总成本为 0”。正式放量前仍需比较常驻 worker
amortization、smaller inference runtime 和 hosted OCR 的总拥有成本。
旧 image digest 是 ASR route 组合 smoke 的历史证据,不是最终 Mongo runtime candidate:完整服务链证明
registry keble-db 1.8.1 会把 BSON datetime 解码为 naive 值并令严格 Job 读取失败。发布 keble-db 1.9.0
之前,pyproject.toml/uv.lock 必须固定 pushed UTC/cleanup checkpoint 9db27c8;所有后续 production image
必须从该 lock 重建并通过真实 Job POST -> GET,禁止仅以 /health 代替持久化读取证明。
状态权威表: Master Plan §24。
合规 gate
授权(OD-00)通过前:禁止下载/处理/保存任何真实第三方视频;允许契约、文档、本地合成视频、 脱敏 fixture、单元测试与本地 HTTP server 集成测试。 详见 架构文档 §10 与 open-decisions。
文档入口
- Master Plan(总入口)
- Contract 权威定义
- 架构文档
- ADR-001 ~ 008
- 审计报告(data-infra / tiktok / 基础设施 / Media2Cloud)
- Open Decisions
- Current Handoff
Composer 执行入口
- 读 composer-execution-guide.md;
- Phase 07 应用开发已完成;外部验证入口见 Phase 07 和 Operations Runbook。
当前是否允许进入编码阶段
Phase 05/06 已完成;Phase 07 application development 已完成;OD-01/OD-02/OD-06 均为
DECIDED。 Data Platform 双入口保持 owner-approved、DEFERRED、NON-BLOCKING。剩余工作是 gated
Aliyun OSS、生产 Mongo/Redis/provider 和目标服务器部署验证,不是未完成的应用编码。
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 keble_video_enrichment-0.2.0.tar.gz.
File metadata
- Download URL: keble_video_enrichment-0.2.0.tar.gz
- Upload date:
- Size: 573.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1befb655ec26b9e146f637b60d62e416e951023fdaa33902e155d03fb2956bbb
|
|
| MD5 |
10438a7394ff03bcbbc05037964c4bf2
|
|
| BLAKE2b-256 |
c44ec1f2d5181a24dad68088ed05d694d8489fba1c34fb1058ba2c2195830432
|
File details
Details for the file keble_video_enrichment-0.2.0-py3-none-any.whl.
File metadata
- Download URL: keble_video_enrichment-0.2.0-py3-none-any.whl
- Upload date:
- Size: 165.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2ace0278fcd789dc17074f8f8e8fa4c4b1aebd53ae3e01aed3bd77f3c650233
|
|
| MD5 |
03786bcbbea7d74d112b3ffcd06929a4
|
|
| BLAKE2b-256 |
4c63260b344f6edf0fc0d6a3e62f4d3c79d06ba9b6402944079d347a9beae083
|