Skip to main content

Converts any human-readable content into clean, structured AI-readable JSON.

Project description

Reversal Engine

Nouveaux endpoints PR3 (mai 2026)

Reversal expose désormais des endpoints avancés pour l’orchestration, la synthèse multi-source, la planification adaptative et l’observabilité produit.

Endpoints PR3

Endpoint Description
POST /v1/reverse/stream Reverse streaming SSE (résultats progressifs, planification adaptative)
POST /v1/reverse/smart Reverse intelligent avec World Model + extraction orientée intention
POST /v1/analyze Analyse rapide du contenu + détection d'intention agent
GET /v1/explain/last Retourne la dernière explication de décision du World Model
POST /v1/heal Auto-correction de conversion avec relances contrôlées
POST /v1/confidence/check Vérifie si l'automatisation est sûre ou si revue humaine est requise
POST /v1/benchmark/run Lance la comparaison direct vs World Model
POST /v1/learning/feedback Alias feedback pour l'apprentissage adaptatif
POST /v1/optimize/plan Sélectionne la meilleure stratégie parmi des candidats selon des objectifs multiples
POST /v1/synthesize Fusionne plusieurs sources en un rapport synthétique structuré
POST /v1/cache/predict Prédiction et préremplissage du cache pour accélérer les accès
POST /v1/collaborative/decision Décision collaborative multi-modèle (world models)
GET /v1/kpi/dashboard Dashboard KPI produit (latence, volume, taux succès, drift, etc.)

Exemples d’utilisation

Streaming SSE

curl -N -X POST https://your-reversal-instance/v1/reverse/stream \
  -H "Authorization: Bearer rev_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"source": "https://lemonde.fr/article/2025/…"}'
# ↳ Reçoit des events: plan_update, partial_result, final_result

Optimisation multi-objectif

curl -X POST https://your-reversal-instance/v1/optimize/plan \
  -H "Authorization: Bearer rev_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"candidates":[{"strategy":"static_fetch","quality":0.5,"time_normalized":0.1,"cost_normalized":0.1,"completeness":0.5},{"strategy":"rendered_browser","quality":0.9,"time_normalized":0.4,"cost_normalized":0.5,"completeness":0.9}],"objectives":{"quality":0.8,"speed":0.1,"cost":0.05,"completeness":0.05}}'
# ↳ { "selected": { ... } }

Synthèse multi-source

curl -X POST https://your-reversal-instance/v1/synthesize \
  -H "Authorization: Bearer rev_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"sources": ["https://example.com/a", "https://example.com/b"], "synthesis_goal": "rapport trimestriel", "strategy": "hierarchical_merge"}'
# ↳ { "source_count": 2, "strategy": "hierarchical_merge", ... }

Prédiction cache

curl -X POST https://your-reversal-instance/v1/cache/predict \
  -H "Authorization: Bearer rev_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"candidates": [{"source": "https://example.com/a", "score": 0.9}, {"source": "https://example.com/b", "score": 0.8}], "max_prefetch": 2}'
# ↳ { "count": 2, "prefetched": [...] }

Décision collaborative

curl -X POST https://your-reversal-instance/v1/collaborative/decision \
  -H "Authorization: Bearer rev_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"content_type": "url", "render_model": "spa", "access_model": "public", "interaction_type": "dynamic_app"}'
# ↳ { "selected_strategy": ..., "models": [...] }

Dashboard KPI

curl -X GET https://your-reversal-instance/v1/kpi/dashboard \
  -H "Authorization: Bearer rev_xxxxxxxx"
# ↳ { "kpis": {...}, "retention": {...} }

Intent Profiles (détaillé)

L'endpoint POST /v1/reverse/smart adapte l'extraction selon agent_goal.

Payload de base:

curl -X POST https://your-reversal-instance/v1/reverse/smart \
  -H "Authorization: Bearer rev_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "https://example.com",
    "agent_goal": "Explain what OpenClaw is and whether I should try it",
    "explain_mode": true,
    "max_healing_attempts": 2
  }'
Intent Quand l'utiliser Champs clés retournés
summary Vue d'ensemble rapide main_idea, key_points, conclusion
critical_analysis Analyse technique et critique technical_analysis, critical_points, maturity_level
decision_support Aide au choix / arbitrage options, recommendation
tutorial Expliquer comment faire prerequisites, steps, common_pitfalls
fact_extraction Extraire faits/données vérifiables facts[]
comparison Comparer alternatives options, tradeoffs, recommendation
news_briefing Brief d'actualités main_idea, key_points, context
research Revue approfondie hypothesis, method, evidence, limitations

Exemple critical_analysis:

{
  "source": "https://openclaw.ai",
  "agent_goal": "Explain what OpenClaw is and evaluate it critically",
  "explain_mode": true
}

Réponse (extrait):

{
  "intent_detected": "critical_analysis",
  "quality_score": 0.92,
  "data": {
    "overview": "...",
    "technical_analysis": "...",
    "critical_points": {
      "limitations": ["..."],
      "risks": ["..."],
      "caveats": ["..."]
    },
    "maturity_level": "beta",
    "verdict": "..."
  }
}

Exemple decision_support:

{
  "source": "https://example.com/stack-comparison",
  "agent_goal": "Should I choose framework A or B for a production app?"
}

Réponse (extrait):

{
  "intent_detected": "decision_support",
  "data": {
    "options": [
      {
        "name": "A",
        "pros": ["..."],
        "cons": ["..."],
        "costs": {"financial": "...", "time": "...", "complexity": "..."},
        "risks": ["..."]
      },
      {
        "name": "B",
        "pros": ["..."],
        "cons": ["..."],
        "costs": {"financial": "...", "time": "...", "complexity": "..."},
        "risks": ["..."]
      }
    ],
    "recommendation": {
      "best_option": "...",
      "reasoning": "...",
      "conditions": "..."
    }
  }
}

Exemple tutorial:

{
  "source": "https://docs.example.com/install",
  "agent_goal": "How to install and configure this project step by step"
}

Réponse (extrait):

{
  "intent_detected": "tutorial",
  "data": {
    "prerequisites": ["..."],
    "steps": [{"number": 1, "action": "...", "explanation": "..."}],
    "examples": ["..."],
    "common_pitfalls": ["..."],
    "troubleshooting": ["..."]
  }
}

Observabilité et tests SLA/charge

Les nouveaux endpoints sont couverts par des tests e2e de charge et de latence (voir tests/test_pr3_api_and_sla.py). Le dashboard KPI expose les métriques produit en temps réel.

Web Runtime Intelligence Layer. Clean, structured intelligence from any URL — for your AI agents.

Raw HTML, broken PDFs, noisy spreadsheets — your agents fail on them, hallucinate on them, or overflow their context window. Reversal normalizes any source into structured, enriched JSON in < 2s. Every time. Every format.

WITHOUT REVERSAL                      WITH REVERSAL
─────────────────────                 ──────────────────────────────────────
Agent → reads raw HTML      →  50–70% accuracy, hallucinations, timeouts
Agent → reads complex PDF   →  parsing errors, missed tables
Agent → reads Excel         →  context overflow, partial data

Agent → calls Reversal → gets structured intelligence  →  99% accuracy, < 2s

Positioning

Reversal is not just a scraper or HTML parser. Reversal is a web runtime intelligence layer — it classifies pages, scores extraction quality, extracts structured metadata, semantically chunks content for LLMs, maps the link graph, and detects SPA/auth requirements.

"OpenClaw/Hermes3 are the pilot. Reversal is the clean road."


What It Does — The Reliability Gap

Scenario Without Reversal With Reversal
Messy HTML / news article Hallucinations, ads injected Clean normalized text
Complex PDF layout Parsing errors, missed tables 99% extraction accuracy
Excel / dashboard screenshot Context overflow, partial data Structured JSON rows
Long document (> context window) Truncation silently Compressed summary + key points
Multiple sources in one pipeline N re-implementations Universal schema, one call

Native Agent Integrations

Agent / Framework Integration Method
GitHub Copilot REST API / Python SDK
Claude Desktop MCP native (.mcp.json)
Claude Code MCP native (reverse_read)
OpenAI Codex MCP (MCP_CONFIG=.mcp.json)
ChatGPT Plugin / function calling
OpenClaw / ClawHub Skill natif (reverse_read, batch_reverse)
Hermes3 (Nous Research) Skill ClawHub
Cursor / Windsurf MCP native (.cursor/mcp.json)
LangChain Python SDK (reversal-sdk)
CrewAI Python SDK
Vercel AI SDK TypeScript SDK (reversal-client)
AutoGPT REST API

GitHub Copilot

from reversal_sdk import ReversalClient
client = ReversalClient(api_key="rev_xxxxxxxx")
result = client.reverse("https://example.com")
print(result["summary"])

Claude Code / Claude Desktop

Ajoutez .mcp.json à la racine du projet :

{
  "mcpServers": {
    "reversal": {
      "url": "https://your-reversal-instance/v1/mcp",
      "headers": { "Authorization": "Bearer rev_xxxxxxxx" }
    }
  }
}

Ou en stdio (self-hosted) :

{
  "mcpServers": {
    "reversal": {
      "command": "uvx",
      "args": ["reversal-engine", "--mcp"],
      "env": { "ANTHROPIC_API_KEY": "sk-ant-…" }
    }
  }
}

OpenAI Codex

export MCP_CONFIG=.mcp.json
# → reverse_read(url) disponible nativement

ChatGPT (function calling)

{
  "name": "reversal_reverse",
  "description": "Analyse une URL ou fichier et retourne JSON structuré.",
  "parameters": { "type": "object", "properties": { "source": { "type": "string" } }, "required": ["source"] }
}
// Appel : POST /v1/reverse ou /v1/optimize/plan (PR3)

OpenClaw / ClawHub

# Bibliothèque ClawHub → « Add Reversal skill »
# L'agent peut appeler directement :
reverse_read(source)          # → JSON structuré
batch_reverse(sources)        # → liste de résultats
detect_content_type(source)   # → type de contenu
reverse_with_planning(source, agent_goal)   # → extraction orientée intention + planification
analyze_content_only(source, agent_goal)    # → analyse rapide (sans conversion complète)
explain_last_decision()       # → explication de la dernière décision World Model

Hermes3 (Nous Research via ClawHub)

> Analyse https://example.com/annual-report.pdf
← { "title": "…", "content_type": "pdf", "summary": "…", "key_points": […] }

Supported Sources

Source Output
🌐 Any URL / Webpage Structured JSON with title, content, links
📄 PDF Pages, text, metadata
📝 Word (.docx) Paragraphs, headings, structure
📊 Excel (.xlsx) Sheets, headers, rows as objects
🗃️ CSV Headers + rows as JSON array
🖼️ Image / Dashboard Metrics, tables, text (via Claude Vision)
📃 Plain Text Lines, word count, content

Install

git clone <your-repo>
cd REVERSAL
pip install -r requirements.txt
export ANTHROPIC_API_KEY=your_key_here   # only needed for image parsing

Usage

As Python Library

from reversal_engine import reverse

# Read a webpage
result = reverse("https://example.com")

# Read a PDF
result = reverse("/path/to/report.pdf")

# Read a dashboard screenshot
result = reverse("/path/to/dashboard.png")

# Read an Excel file
result = reverse("/path/to/data.xlsx")

print(result["data"]["title"])
print(result["content_type"])
print(result["processed_in_ms"])

As CLI Tool

# Read a URL
python -m reversal_engine.cli https://example.com

# Read a PDF and save output
python -m reversal_engine.cli report.pdf --output result.json

# Just detect content type
python -m reversal_engine.cli dashboard.png --detect-only

# Compact output for piping
python -m reversal_engine.cli data.xlsx --format compact | jq '.data.sheets[0].rows'

As REST API

# Start the server
python -m reversal_engine.api_server

# Call it
curl -X POST http://localhost:8000/reverse \
  -H "Content-Type: application/json" \
  -d '{"source": "https://example.com"}'

As MCP Server (for Claude Code / AI Agents)

.mcp.json is already configured at the project root. Add your real API key there, then reload Claude Code — it will see reverse_read() as a native tool:

reverse_read("https://example.com")
reverse_read("/path/to/report.pdf")
reverse_read("/path/to/dashboard.png")

The MCP server also exposes an HTTP endpoint for remote agents:

curl -X POST https://your-reversal-instance/v1/mcp \
  -H "Authorization: Bearer rev_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Python SDK

pip install reversal-sdk
from reversal_sdk import ReversalClient

client = ReversalClient(api_key="rev_xxxxxxxx")

# Analyse simple
result = client.reverse("https://example.com")
print(result["summary"])

# Lot de sources
results = client.batch(["https://a.com", "https://b.com/data.pdf"])

# PR3 – Optimisation multi-objectif
client.optimize_plan([...], objectives={"quality": 0.8, "speed": 0.1})

# PR3 – Synthèse multi-source
client.synthesize(["https://a.com", "https://b.com"], synthesis_goal="rapport")

TypeScript SDK

npm install reversal-client
import { ReversalClient } from "reversal-client";

const client = new ReversalClient({ apiKey: "rev_xxxxxxxx" });
const result = await client.reverse("https://example.com");
console.log(result.summary);

// Vercel AI SDK
import { tool } from "ai";
import { z } from "zod";

const reversalTool = tool({
  description: "Analyse une URL/document et retourne un résumé structuré.",
  parameters: z.object({ url: z.string().url() }),
  execute: async ({ url }) => {
    const r = await client.reverse(url);
    return { summary: r.summary, keyPoints: r.key_points };
  },
});

Universal Output Schema

Every source returns the same envelope:

{
  "reversal_engine": "1.0",
  "status": "ok | partial | blocked",
  "content_type": "url | pdf | word | excel | csv | image | text",
  "source": "original source string",
  "processed_in_ms": 142.5,
  "data": {
    "request_id": "uuid4",

    "page_type": {
      "primary": "article | ecommerce | docs | forum | video | dashboard | wiki | social_feed | unknown",
      "render_model": "static | spa",
      "access_model": "public | auth_required"
    },
    "quality": {
      "content_completeness": 0.87,
      "main_content_confidence": 0.91,
      "noise_ratio": 0.12,
      "structured_data_present": true
    },
    "structured_data": {
      "json_ld": [],
      "opengraph": {},
      "twitter_card": {}
    },

    "title": "...",
    "description": "...",
    "lang": "en",

    "chunks": [
      {"type": "heading", "level": 1, "text": "...", "section": ""},
      {"type": "paragraph", "text": "...", "section": "intro"},
      {"type": "list_item", "text": "...", "section": "..."},
      {"type": "code", "text": "...", "section": "..."}
    ],
    "content": ["flat paragraph list (backward compat)"],
    "headings": [],
    "word_count": 1234,
    "summary_hint": "first 300 chars...",

    "links": {
      "internal": [],
      "external": [],
      "navigation": [],
      "pagination": [],
      "social": [],
      "asset": []
    },
    "images": [],
    "content_hash": "sha256:...",

    "fetched_at": 1234567890.0,
    "http_status": 200,
    "content_length_bytes": 45678
  }
}

For SPA / blocked pages, a runtime block is added at the envelope level:

{
  "runtime": {
    "requires_rendering": true,
    "requires_auth": false,
    "blocked_by": null,
    "recommended_strategy": "rendered_browser"
  }
}

Project Structure

REVERSAL/
├── reversal_engine/
│   ├── __init__.py          # Public API: reverse(), detect()
│   ├── engine.py            # Core orchestrator + universal schema envelope
│   ├── detector.py          # Content type auto-detection
│   ├── pr3_engine.py        # PR3 orchestration primitives (mai 2026)
│   │                        #   collaborative_world_models_decision
│   │                        #   optimize_multiple_objectives
│   │                        #   synthesize_cross_format
│   │                        #   predictive_cache_prefetch
│   │                        #   reverse_stream_events
│   ├── mcp_server.py        # MCP server stdio + HTTP /v1/mcp
│   ├── api_server.py        # REST API (FastAPI) — 30+ routes
│   ├── auth.py              # Auth, registration, OTP, OAuth Google/GitHub
│   ├── cache.py             # Cache adaptatif + prédiction
│   ├── observability.py     # Prometheus, structlog, dashboard KPI
│   ├── jobs.py              # Async jobs (poll + SSE)
│   ├── upload.py            # Upload sécurisé (multi-format)
│   ├── webhooks.py          # Webhooks Stripe / Paddle
│   ├── cli.py               # CLI interface
│   ├── compressor.py        # Compression de contenu
│   ├── worker.py            # Background worker
│   └── parsers/
│       ├── url_parser.py    # Web runtime intelligence layer
│       ├── file_parsers.py  # PDF, Word, Excel, CSV, Text
│       └── image_parser.py  # Image / Dashboard (Claude Vision)
├── sdk/
│   ├── python/              # Python SDK (pip install reversal-sdk)
│   │   └── reversal_sdk/    #   client.py, models.py, exceptions.py
│   └── typescript/          # TypeScript SDK (npm install reversal-client)
│       └── src/             #   client.ts, types.ts, errors.ts
├── tests/
│   ├── test_pr3_engine.py   # Tests unitaires PR3
│   ├── test_pr3_api_and_sla.py  # Tests API + SLA/charge PR3
│   └── ...                  # 20+ autres modules de test
├── ui/
│   └── src/
│       ├── App.jsx          # UI principale + documentation
│       ├── AgentShowcase.jsx # Section "Reversal inside your agents"
│       └── KpiDemo.jsx      # Démo interactive dashboard KPI
├── .mcp.json                # Claude Code / Cursor MCP config
├── requirements.txt
└── README.md

API Key Note

Image/dashboard parsing uses Claude Vision. All other parsers (URL, PDF, Word, Excel, CSV, Text) work without any API key.

To enable vision:

export ANTHROPIC_API_KEY=your_real_key_here

Or add it to .mcp.json under env.ANTHROPIC_API_KEY.


Complete REST API Reference

Auth

Method Route Description
POST /v1/register Créer un compte, retourne api_key
POST /v1/register/request-otp Demande OTP par email
GET /v1/auth/config Config captcha/OTP côté client
POST /v1/auth/oauth/exchange Échange un oauth_code one-shot contre api_key
GET /v1/auth/google OAuth Google (redirect)
GET /v1/auth/github OAuth GitHub (redirect)

Reversal Core

Method Route Description
POST /v1/reverse Analyse une source (sync ou async 202)
POST /v1/reverse/stream Streaming SSE en temps réel
POST /v1/reverse/smart Conversion intelligente (World Model + extraction orientée intention)
POST /v1/analyze Analyse de complexité + patterns + intention détectée
GET /v1/explain/last Dernière explication de stratégie sélectionnée
POST /v1/heal Relance auto-corrective de la conversion intelligente
POST /v1/confidence/check Décision proceed/review selon seuil de confiance
POST /v1/benchmark/run Benchmark direct vs World Model
POST /v1/batch Lot jusqu'à 10 sources
POST /v1/detect Détecte le type de contenu
POST /v1/feedback Envoie un feedback utilisateur
POST /v1/learning/feedback Alias feedback pour apprentissage adaptatif
GET /v1/insights/{key} Patterns appris par la mémoire adaptative
GET /v1/insights/{key}/history Historique time-series d'un pattern

PR3 — Orchestration Avancée

Method Route Description
POST /v1/optimize/plan Sélectionne la meilleure stratégie (multi-objectif)
POST /v1/synthesize Fusionne plusieurs sources en rapport structuré
POST /v1/cache/predict Prédiction et préremplissage du cache
POST /v1/collaborative/decision Décision collaborative multi-modèle

Fichiers

Method Route Description
POST /v1/upload Upload d'un fichier (PDF, image, Excel…)
DELETE /v1/files/{file_id} Supprime un fichier uploadé

Jobs Asynchrones

Method Route Description
GET /v1/jobs/{job_id} Statut et résultat d'un job
GET /v1/jobs Liste des jobs de l'utilisateur
GET /v1/jobs/{job_id}/stream SSE streaming d'un job (plan premium)

Compte

Method Route Description
GET /v1/me Infos compte et quota
GET /v1/upgrade Informations plan et upgrade
GET /v1/history Historique des appels
GET /v1/kpi/dashboard Dashboard KPI produit (latence, volume, drift…)

Système

Method Route Description
GET /health Health check
GET /metrics Prometheus metrics
GET /versions Version de l'API
GET /well-known/reversal.json Manifeste public de compatibilité et de référencement
POST /v1/mcp MCP HTTP endpoint (JSON-RPC 2.0)
POST /webhook/stripe Stripe webhook
POST /webhook/paddle Paddle webhook

Async Jobs

Pour les sources volumineuses, /v1/reverse retourne 202 Accepted avec un job_id :

# Lancer
POST /v1/reverse  { "job_id": "abc123", "status": "pending" }

# Poller
GET /v1/jobs/abc123  { "status": "done", "result": { ... } }

# Ou streaming (plan premium)
GET /v1/jobs/abc123/stream  # SSE events

Deployment Modes (Open Core)

Reversal supports two editions via environment variable:

  • REVERSAL_EDITION=saas (default): full product behavior, including paid features according to plan entitlements.
  • REVERSAL_EDITION=oss: premium SaaS features are disabled to keep the public edition limited to the free/open-source core.

Premium features disabled in oss mode:

  • /v1/batch
  • webhook_url usage on async jobs
  • /v1/jobs/{job_id}/stream (SSE)
  • /v1/upgrade and Stripe webhook activation

GitHub Actions And Monitoring

The repository now includes two operational workflows:

  • CI on push and pull request to main: Python tests, Ruff, frontend lint/build, and Docker smoke build.
  • Uptime Monitor every 15 minutes and on manual dispatch: checks the production backend health endpoint, the production frontend homepage, and the Prometheus metrics endpoint when a token is configured.

Recommended repository secrets

  • METRICS_TOKEN: required only if production protects /metrics.
  • MCP_API_KEY: optional, enables synthetic MCP checks (initialize, tools/list) in uptime monitor.
  • NPM_TOKEN: required for npm publication in the existing release workflow.
  • PYPI_API_TOKEN_REVERSAL_ENGINE: optional fallback token for first reversal-engine publish when Trusted Publishing cannot create a new PyPI project.

Public compatibility manifest

The endpoint GET /well-known/reversal.json exposes a machine-readable manifest for platform listings and MCP clients. It includes:

  • MCP HTTP and stdio transport details
  • supported auth flows
  • release version and API version
  • platform readiness flags
  • per-platform discovery hints for Replit, ElevenLabs, Lovable, and Emergent
  • security and support contact links

This is the canonical reference to share when submitting Reversal to platform directories or partner forms.

Production endpoints checked by the monitor

  • Backend health: https://reversal-api.onrender.com/health
  • Frontend: https://reversal-71h.pages.dev
  • Metrics: https://reversal-api.onrender.com/metrics

If the monitor fails, GitHub Actions will mark the scheduled run as failed, which makes alerting and diagnosis easier from the Actions tab.

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

reversal_engine-1.1.4.tar.gz (169.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reversal_engine-1.1.4-py3-none-any.whl (137.3 kB view details)

Uploaded Python 3

File details

Details for the file reversal_engine-1.1.4.tar.gz.

File metadata

  • Download URL: reversal_engine-1.1.4.tar.gz
  • Upload date:
  • Size: 169.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for reversal_engine-1.1.4.tar.gz
Algorithm Hash digest
SHA256 1f65ffa72d3b16c1da04be06203cdf808eb59e930eb6b6deedcce2da83ee2350
MD5 4dfdc0cd16bc9f42c12f415885a1d805
BLAKE2b-256 b8ac42c6b6e388a3b0a19a307f699c74efa886e6a296d2f3726748bd41827cd5

See more details on using hashes here.

File details

Details for the file reversal_engine-1.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for reversal_engine-1.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 8c21a761cff91bba1f42c16b26baec5f33be07b1641da80df7cc2843b8fcffe7
MD5 c144b285d3142508353ac0eb1904b625
BLAKE2b-256 0909c56fb1248de40828c01f0018f1dc8728a8de49464803656de5ecc713910d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page