Skip to main content

A search-based decoder for quantum error correction (QEC).

Project description

Tesseract Decoder

A Search-Based Decoder for Quantum Error Correction.

Licensed under the Apache 2.0 open-source license C++

InstallationUsagePython InterfacePaperHelpCitationContact

Tesseract is a Most Likely Error decoder designed for Low Density Parity Check (LDPC) quantum error-correcting codes. It applies pruning heuristics and manifold orientation techniques during a search over the error subsets to identify the most likely error configuration consistent with the observed syndrome. Tesseract achieves significant speed improvements over traditional integer programming-based decoders while maintaining comparable accuracy at moderate physical error rates.

We tested the Tesseract decoder for:

  • Surface codes
  • Color codes
  • Bivariate-bicycle codes
  • Transversal CNOT protocols for surface codes

Features

  • A* search: deploys A* search while running a Dijkstra algorithm with early stop for high performance.
  • Stim and DEM Support: processes Stim circuit files and Detector Error Model (DEM) files with arbitrary error models. Zero-probability error instructions are automatically removed when a DEM is loaded.
  • Parallel Decoding: uses multithreading to accelerate the decoding process, making it suitable for large-scale simulations.
  • Efficient Beam Search: implements a beam search algorithm to minimize decoding cost and enhance efficiency. Sampling and Shot Range Processing: supports sampling shots from circuits. When a detection error model is provided without an accompanying circuit, Tesseract requires detection events from files using --in. The decoder can also process specific shot ranges for flexible experiment setups.
  • Detailed Statistics: provides comprehensive statistics output, including shot counts, error counts, and processing times.
  • Heuristics: includes flexible heuristic options: --beam, --det-penalty, --beam-climbing, --no-revisit-dets, --at-most-two-errors-per-detector, and --pqlimit to improve performance while maintaining a low logical error rate. To learn more about these options, use ./bazel-bin/src/tesseract --help
  • Visualization tool: open the viz directory in your browser to view decoding results. See viz/README.md for instructions on generating the visualization JSON.

Installation

Tesseract relies on the following external libraries:

  • argparse: For command-line argument parsing.
  • nlohmann/json: For JSON handling (used for statistics output).
  • Stim: For quantum circuit simulation and error model handling.

Build Instructions

Tesseract uses Bazel as its build system. To build the decoder:

bazel build src:all

Running Tests

Unit tests are executed with Bazel. Run the quick test suite using:

bazel test //src:all

By default the tests use reduced parameters and finish in under 30 seconds. To run a more exhaustive suite with additional shots and larger distances, set:

TESSERACT_LONG_TESTS=1 bazel test //src:all

Usage

The file tesseract_main.cc provides the main entry point for Tesseract Decoder. It can decode error events from Stim circuits, DEM files, and pre-existing detection event files.

Basic Usage:

./tesseract --circuit CIRCUIT_FILE.stim --sample-num-shots N --print-stats

To decode pre-generated detection events, provide the input file using --in SHOTS_FILE --in-format FORMAT.

Example with Advanced Options:

./tesseract \
        --pqlimit 1000000 \
        --at-most-two-errors-per-detector \
        --det-order-seed 232852747 \
        --circuit circuit_file.stim \
        --sample-seed 232856747 \
        --sample-num-shots 10000 \
        --threads 32 \
        --print-stats \
        --beam 23 \
        --num-det-orders 1 \
        --shot-range-begin 582 \
        --shot-range-end 583

Example Usage

Sampling Shots from a Circuit:

./tesseract --circuit surface_code.stim --sample-num-shots 1000 --out predictions.01 --out-format 01

Using a Detection Event File:

./tesseract --in events.01 --in-format 01 --dem surface_code.dem --out decoded.txt

Using a Detection Event File and Observable Flips:

./tesseract --in events.01 --in-format 01 --obs_in obs.01 --obs-in-format 01 --dem surface_code.dem --out decoded.txt

Tesseract supports reading and writing from all of Stim's standard output formats.

Performance Optimization

Here are some tips for improving performance:

  • Parallelism over shots: increase --threads to leverage multicore processors for faster decoding.
  • Beam Search: use --beam to control the trade-off between accuracy and speed. Smaller beam sizes result in faster decoding but potentially lower accuracy.
  • Beam Climbing: enable --beam-climbing for enhanced cost-based decoding.
  • At most two errors per detector: enable --at-most-two-errors-per-detector to improve performance.
  • Priority Queue limit: use --pqlimit to limit the size of the priority queue.

Output Formats

  • Observable flips output: predictions of logical errors.
  • DEM usage frequency output: if --dem-out is specified, outputs estimated error frequencies.
  • Statistics output: includes number of shots, errors, low confidence shots, and processing time.

Python Interface

Full Python wrapper documentation

This repository contains the C++ implementation of the Tesseract quantum error correction decoder, along with a Python wrapper. The Python wrapper/interface exposes the decoding algorithms and helper utilities, allowing Python users to leverage this high-performance decoding algorithm.

For installation:

pip install tesseract-decoder

The following example demonstrates how to create and use the Tesseract decoder using the Python interface.

from tesseract_decoder import tesseract
import stim
import numpy as np


# 1. Define a detector error model (DEM)
dem = stim.DetectorErrorModel("""
    error(0.1) D0 D1 L0
    error(0.2) D1 D2 L1
    detector(0, 0, 0) D0
    detector(1, 0, 0) D1
    detector(2, 0, 0) D2
""")

# 2. Create the decoder configuration
config = tesseract.TesseractConfig(dem=dem, det_beam=50)

# 3. Create a decoder instance
decoder = config.compile_decoder()

# 4. Simulate detector outcomes
syndrome = np.array([0, 1, 1], dtype=bool)

# 5a. Decode to observables
flipped_observables = decoder.decode(syndrome)
print(f"Flipped observables: {flipped_observables}")

# 5b. Alternatively, decode to errors
decoder.decode_to_errors(syndrome)
predicted_errors = decoder.predicted_errors_buffer
# Indices of predicted errors
print(f"Predicted errors indices: {predicted_errors}")
# Print properties of predicted errors
for i in predicted_errors:
    print(f"    {i}: {decoder.errors[i]}")

Using Tesseract with Sinter

Tesseract can be easily integrated into Sinter workflows. Sinter is a tool for running and organizing quantum error correction simulations.

Here's an example of how to use Tesseract as a decoder for multiple Sinter tasks:

import stim
import sinter
from tesseract_decoder import make_tesseract_sinter_decoders_dict, TesseractSinterDecoder
import tesseract_decoder

if __name__ == "__main__":  
    # Define a list of Sinter task(s) with different circuits/decoders.
    tasks = []
    # Depolarizing noise probability.
    p = 0.005
    # These are the sensible defaults given by make_tesseract_sinter_decoders_dict().
    # Note that `tesseract-short-beam` and `tesseract-long-beam` are the two sets of parameters used in the [Tesseract paper](https://arxiv.org/pdf/2503.10988).
    decoders = ['tesseract', 'tesseract-long-beam', 'tesseract-short-beam']
    decoder_dict = make_tesseract_sinter_decoders_dict()
    # You can also make your own custom Tesseract Decoder to-be-used with Sinter.
    decoders.append('custom-tesseract-decoder')
    decoder_dict['custom-tesseract-decoder'] = TesseractSinterDecoder(
        det_beam=10,
        beam_climbing=True,
        no_revisit_dets=True,
        merge_errors=True,
        pqlimit=1_000,
        num_det_orders=5,
        det_order_method=tesseract_decoder.utils.DetOrder.DetIndex,
        seed=2384753,
    )

    for distance in [3, 5, 7]:
        for decoder in decoders:
            circuit = stim.Circuit.generated(
                "surface_code:rotated_memory_x",
                distance=distance,
                rounds=3,
                after_clifford_depolarization=p
            )
            tasks.append(sinter.Task(
                circuit=circuit,
                decoder=decoder,
                json_metadata={"d": distance, "decoder": decoder},
            ))

    # Collect decoding outcomes per task from Sinter.
    results = sinter.collect(
        num_workers=8,
        tasks=tasks,
        max_shots=10_000,
        decoders=decoders,
        custom_decoders=decoder_dict,
        print_progress=True,
    )

    # Print samples as CSV data.
    print(sinter.CSV_HEADER)
    for sample in results:
        print(sample.to_csv_line())

should get something like:

    shots,    errors,  discards, seconds,decoder,strong_id,json_metadata,custom_counts  
    10000,        42,         0,   0.071,tesseract,1b3fce6286e438f38c00c8f6a5005947373515ab08e6446a7dd9ecdbef12d4cc,"{""d"":3,""decoder"":""tesseract""}",  
    10000,        49,         0,   0.546,custom-tesseract-decoder,7b082bec7541be858e239d7828a432e329cd448356bbdf051b8b8aa76c86625a,"{""d"":3,""decoder"":""custom-tesseract-decoder""}", 
    10000,        13,         0,    7.64,tesseract-long-beam,217a3542f56319924576658a6da7081ea2833f5167cf6d77fbc7071548e386a9,"{""d"":5,""decoder"":""tesseract-long-beam""}",  
    10000,        42,         0,   0.743,tesseract-short-beam,cf4a4b0ce0e4c7beec1171f58eddffe403ed7359db5016fca2e16174ea577057,"{""d"":3,""decoder"":""tesseract-short-beam""}",  
    10000,        34,         0,   0.924,tesseract-long-beam,8cfa0f2e4061629e13bc98fe213285dc00eb90f21bba36e08c76bcdf213a1c09,"{""d"":3,""decoder"":""tesseract-long-beam""}",  
    10000,        10,         0,   0.439,tesseract,8274ea5ffec15d6e71faed5ee1057cdd7e497cbaee4c6109784f8a74669d7f96,"{""d"":5,""decoder"":""tesseract""}",  
    10000,         8,         0,    3.93,custom-tesseract-decoder,8e4f5ab5dde00fec74127eea39ea52d5a98ae6ccfc277b5d9be450f78acc1c45,"{""d"":5,""decoder"":""custom-tesseract-decoder""}",  
    10000,        10,         0,    5.74,tesseract-short-beam,bf696535d62a25720c3a0c624ec5624002efe3f6cb0468963eee702efb48abc1,"{""d"":5,""decoder"":""tesseract-short-beam""}",  
    10000,         5,         0,    1.27,tesseract,3f94c61f1503844df6cf0d200b74ac01bfbc5e29e70cedbfc2faad67047e7887,"{""d"":7,""decoder"":""tesseract""}",  
    10000,         4,         0,    25.0,tesseract-long-beam,4d510f0acf511e24a833a93c956b683346696d8086866fadc73063fb09014c23,"{""d"":7,""decoder"":""tesseract-long-beam""}",  
    10000,         1,         0,    18.6,tesseract-short-beam,75782ce4593022fcedad4c73104711f05c9c635db92869531f78da336945b121,"{""d"":7,""decoder"":""tesseract-short-beam""}",  
    10000,         4,         0,    11.6,custom-tesseract-decoder,48f256a28fff47c58af7bffdf98fdee1d41a721751ee965c5d3c5712ac795dc8,"{""d"":7,""decoder"":""custom-tesseract-decoder""}",  

This example runs simulations for a repetition code with different distances [3, 5, 7] with different Tesseract default decoders.

Sinter can also be used at the command line. Here is an example of this using Tesseract:

sinter collect \
    --circuits "example_circuit.stim" \
    --decoders tesseract \
    --custom_decoders_module_function "tesseract_decoder:make_tesseract_sinter_decoders_dict" \
    --max_shots 100_000 \
    --max_errors 100
    --processes auto \
    --save_resume_filepath "stats.csv" \

Sinter efficiently manages the execution of these tasks, and Tesseract is used for decoding. For more usage examples, see the tests in src/py/tesseract_sinter_compat_test.py.

Good Starting Points for Tesseract Configurations:

The Tesseract paper recommends two setup for starting your exploration with tesseract:

(1) Long-beam setup:

tesseract_config = tesseract.TesseractConfig(
    dem=dem,
    pqlimit=1_000_000,
    det_beam=20,
    beam_climbing=True,
    det_orders=tesseract_decoder.utils.build_det_orders(
        dem=dem,
        num_det_orders=21,
        method=tesseract_decoder.utils.DetOrder.DetIndex,
    ),
    no_revisit_dets=True,
)

(2) Short-beam setup:

tesseract_config = tesseract.TesseractConfig(
    dem=dem,
    pqlimit=200_000,
    det_beam=15,
    beam_climbing=True,
    det_orders=tesseract_decoder.utils.build_det_orders(
        dem=dem,
        num_det_orders=16,
        method=tesseract_decoder.utils.DetOrder.DetIndex,
    ),
    no_revisit_dets=True,
)

For det_order, you can use two other options of DetIndex and DetCoordinate as well. These values balance decoding speed and accuracy across the benchmarks reported in the paper and can be adjusted for specific use cases.

Help

We are committed to providing a friendly, safe, and welcoming environment for all. Please read and respect our Code of Conduct.

Citation

When publishing articles or otherwise writing about Tesseract Decoder, please cite the following:

@misc{beni2025tesseractdecoder,
    title={Tesseract: A Search-Based Decoder for Quantum Error Correction},
    author = {Aghababaie Beni, Laleh and Higgott, Oscar and Shutty, Noah},
    year={2025},
    eprint={2503.10988},
    archivePrefix={arXiv},
    primaryClass={quant-ph},
    doi = {10.48550/arXiv.2503.10988},
    url={https://arxiv.org/abs/2503.10988},
}

Hacking on the Python module locally

To install your own build of Tesseract python module locally so that you can easily modify and hack on it, use something like the following:

bazel build --define TARGET_VERSION="py3.12.9" --define VERSION="v0.0.0dev"  :tesseract_decoder_wheel
pip uninstall --y tesseract_decoder
pip install bazel-bin/tesseract_decoder-0.0.0.dev0-py3.12.9-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
python testscript.py

Contact

For any questions or concerns not addressed here, please email tesseract-decoder-dev@google.com.

Disclaimer

Tesseract Decoder is not an officially supported Google product. This project is not eligible for the Google Open Source Software Vulnerability Rewards Program.

Copyright 2025 Google LLC.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

tesseract_decoder-0.1.1.dev20260227192315-py313-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded Python 3.13manylinux: glibc 2.39+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py313-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded Python 3.13manylinux: glibc 2.35+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py313-none-macosx_11_0_arm64.whl (3.2 MB view details)

Uploaded Python 3.13macOS 11.0+ ARM64

tesseract_decoder-0.1.1.dev20260227192315-py312-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded Python 3.12manylinux: glibc 2.39+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py312-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded Python 3.12manylinux: glibc 2.35+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py312-none-macosx_11_0_arm64.whl (3.2 MB view details)

Uploaded Python 3.12macOS 11.0+ ARM64

tesseract_decoder-0.1.1.dev20260227192315-py311-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded Python 3.11manylinux: glibc 2.39+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py311-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl (3.6 MB view details)

Uploaded Python 3.11manylinux: glibc 2.35+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py311-none-macosx_11_0_arm64.whl (3.2 MB view details)

Uploaded Python 3.11macOS 11.0+ ARM64

tesseract_decoder-0.1.1.dev20260227192315-py310-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded Python 3.10manylinux: glibc 2.39+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py310-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl (3.6 MB view details)

Uploaded Python 3.10manylinux: glibc 2.35+ x86-64

tesseract_decoder-0.1.1.dev20260227192315-py310-none-macosx_11_0_arm64.whl (3.2 MB view details)

Uploaded Python 3.10macOS 11.0+ ARM64

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py313-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py313-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d964c9b87b7fee5e8e87d3312c55c11329cad1bd8bbf966dd61ebf77b3d3a209
MD5 e5780d9e42090de99dec2f33e885e2de
BLAKE2b-256 52fe97e6e206ae05311379505edddb77aa36ddeb9d1bdf98f37cf8a8c63fa49f

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py313-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py313-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f5fe91a818b3747196dd0e609339a0032a4cb84537debc67ba8fade49dffdc00
MD5 70138aff087440888065652f905de578
BLAKE2b-256 5c1b8f61d65774a9628579d6182710862019d4891b882fd10860533ecaf08220

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py313-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py313-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9f5d74bd0ed492297ce9d4539e277e83aec0e425203ab9371147a3256ca8a17d
MD5 eb0e3809a34b94ce11a7a43b1c3f644e
BLAKE2b-256 1c341c51bfa74f4e7b160f5cedbe0f07f5a363e8c982e96e02c49c334fa5278b

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py312-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py312-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7074e3c2a3d1879b488111532328158ea4ba6d573ed0b1b84b41f88473b627f2
MD5 9591017b2e6b02e3410b26a510e75e8b
BLAKE2b-256 e7ea40cb1fec4cc6df8464a98524291cee2a9df9b3fe29b61919da22ff1840f2

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py312-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py312-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 71c91ac2919e39acd7f14f316ff66093033b3aa911951816c808a456dea51439
MD5 dc7b6019805c502a4f24f8e61c38fa58
BLAKE2b-256 4566b60e97b263338f6b8a257d18f2c9900c27c443ffcbeac9518b22a34d6bda

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py312-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py312-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 336fb9cc87e36f40846306ef41a9ec7f6c5f88ce74c64fda06590e74ca7e9e4c
MD5 3975953f36b3951caa665b0ccb40d429
BLAKE2b-256 e695c5d86e77b628f48f163a11fb0a8c21f7d3ad4352645c9069e98bb4ae23d1

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py311-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py311-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c2240fc88029598bf4bbd001b76e9d94fd2625705a04fec139c1e780d8cd212a
MD5 9f5d3c00b1ad9315b9c22fa85dc03aa0
BLAKE2b-256 47bcdb809a4eedb218b6473afeb93ed547c975fa3f399a30928ad2bbe68ef79d

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py311-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py311-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 47fb2e5f9359be9c1dfb17a0e9849b7129b9cb89c78367729b3eb57c3674cf24
MD5 92527b04fae4dfbada7ad95fe0ec6147
BLAKE2b-256 17ae8ef0c58109c17dbdc0e650bbe624cd4c2db4644d37d6e0858f79ecd1a19c

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py311-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py311-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 69a9c934b52f4c12bc64d399ce65b9104c8f55d08ee47aa1ef8dae0610c2032b
MD5 078cdd00c1efd6bc371c296f9a67845b
BLAKE2b-256 96a91dde949d58452a17276b1f782d5c0b9062715ab92831686e57cc6be0601f

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py310-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py310-none-manylinux_2_39_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7475ecb791b90a07185bdd98b75f779c4fbf28c00e78dcb19f4a98b8b939a135
MD5 b42b8f607d54ccf4b5fba85c00940b3b
BLAKE2b-256 0dc448139563e103ee57522ecc3974146bea8b173559a556a85cc150e0dd1f04

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py310-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py310-none-manylinux_2_35_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d09780932d8d0f4b29b2cb30b5def0c82ccddac269e233a12327b8da75ea0dd8
MD5 23a9aa7a05f4dad7815d089734478dc7
BLAKE2b-256 f94091d8c4b3c25ea882acf2ad0fb3d4e84bbcd51e6e522f24e019de7b6ebf1b

See more details on using hashes here.

File details

Details for the file tesseract_decoder-0.1.1.dev20260227192315-py310-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tesseract_decoder-0.1.1.dev20260227192315-py310-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 771334a4eb937e9fcb596280f003376301a8f6c95dd48813d9e18a8a109321ca
MD5 5b9c4e5e4bf214edef655dad523d82ec
BLAKE2b-256 f13a089a4e303b1181e1e2292efced2ee5baf3b82d4308274c1a8e2abb260d76

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