Skip to main content

Biblioteca Python para análise de qualidade e saúde de código

Project description

🔍 CodeHealthAnalyzer

Uma biblioteca Python completa para análise de qualidade e saúde de código

🇧🇷 Português | 🇺🇸 English

Python Version License Code Style

🚀 Visão Geral

CodeHealthAnalyzer é uma biblioteca Python moderna e abrangente para análise de qualidade de código. Ela combina múltiplas ferramentas de análise em uma interface unificada, fornecendo insights detalhados sobre a saúde do seu código.

✨ Principais Funcionalidades

  • 🚨 Análise de Violações: Detecta funções, classes e módulos que excedem limites de tamanho
  • 🎨 Análise de Templates: Identifica CSS/JS inline em templates HTML que podem ser extraídos
  • ⚠️ Integração com Ruff: Analisa erros de linting e os categoriza por prioridade
  • 📊 Score de Qualidade: Calcula um score de 0-100 baseado na saúde geral do código
  • 🎯 Priorização Inteligente: Sugere ações baseadas na criticidade dos problemas
  • 📈 Relatórios Múltiplos: Gera relatórios em JSON, HTML, Markdown e CSV
  • 🖥️ CLI Amigável: Interface de linha de comando completa e intuitiva
  • 🔧 Altamente Configurável: Personalize limites, regras e categorias

📦 Instalação

Instalação via pip (recomendado)

# Instalação básica
pip install codehealthanalyzer

# Instalação com dashboard web interativo
pip install codehealthanalyzer[web]

# Instalação completa (web + desenvolvimento)
pip install codehealthanalyzer[web,dev]

Instalação para desenvolvimento

git clone https://github.com/imparcialista/codehealthanalyzer.git
cd codehealthanalyzer
pip install -e .[web,dev]

Dependências

  • Python 3.8+
  • ruff >= 0.1.0
  • click >= 8.0.0
  • rich >= 12.0.0 (opcional, para saída colorida)

🎯 Uso Rápido

🌐 Dashboard Interativo

# Iniciar dashboard web com métricas em tempo real
codehealthanalyzer dashboard

# Dashboard em host e porta específicos
codehealthanalyzer dashboard --host 0.0.0.0 --port 8080

# Dashboard com reload automático para desenvolvimento
codehealthanalyzer dashboard --reload

Funcionalidades do Dashboard:

  • 📊 Métricas em tempo real com atualizações automáticas
  • 📈 Gráficos interativos de tendência de qualidade
  • 🎯 Visualização de violações por tipo
  • 📋 Tabela de arquivos com problemas
  • 🔄 WebSockets para atualizações instantâneas
  • 📱 Interface responsiva e moderna

CLI (Interface de Linha de Comando)

# Análise completa do projeto atual (o diretório padrão é '.')
codehealthanalyzer analyze

# Por padrão, um JSON é gerado em ./reports/full_report.json
# Formatos adicionais (HTML, Markdown ou todos):
codehealthanalyzer analyze --format html
codehealthanalyzer analyze --format markdown
codehealthanalyzer analyze --format all

# Desativar JSON padrão
codehealthanalyzer analyze --format html --no-json

# Definir diretório de saída (padrão: ./reports)
codehealthanalyzer analyze --format all --output out/

# Apenas score de qualidade
codehealthanalyzer score

# Informações do projeto
codehealthanalyzer info

# Análise específica de violações
codehealthanalyzer violations --format all

# Análise específica de templates
codehealthanalyzer templates --format all

# Análise específica de erros (Ruff)
codehealthanalyzer errors --format all

## Comandos disponíveis

- `analyze [PROJECT_PATH]` (padrão: `.`): análise completa (violations, templates, errors) e geração de relatórios.
- `violations [PROJECT_PATH]`: apenas violações de tamanho/linhas.
- `templates [PROJECT_PATH]`: apenas templates HTML com CSS/JS inline.
- `errors [PROJECT_PATH]`: apenas erros Ruff.
- `score [PROJECT_PATH]`: exibe apenas o score de qualidade.
- `info [PROJECT_PATH]`: informações básicas do projeto.
- `dashboard [PROJECT_PATH]`: inicia a UI web (FastAPI) com métricas ao vivo.
- `format [PROJECT_PATH]`: aplica auto-fixes e formatação (isort + black + ruff --fix).
- `lint [PROJECT_PATH]`: executa checagens (ruff, isort --check, black --check, bandit).

### Opções comuns úteis

- `--output`, `-o`: diretório de saída dos relatórios. Padrão: `./reports`.
- `--format`, `-f`: formato adicional do relatório: `html`, `markdown` ou `all`.
- `--no-json`: por padrão, sempre é gerado um JSON. Use esta flag para NÃO gerar o JSON.
- `--config`, `-c`: caminho para um `config.json` com suas preferências.
- `--no-default-excludes`: não aplicar as exclusões padrão (tests, scripts, reports, venv etc.).

Exemplos por comando

```bash
# analyze: JSON + HTML + MD em ./reports
codehealthanalyzer analyze --format all

# analyze: HTML apenas, sem JSON
codehealthanalyzer analyze --format html --no-json

# violations: JSON por padrão + HTML/MD
codehealthanalyzer violations --format all

# templates: JSON por padrão + HTML/MD
codehealthanalyzer templates --format all

# errors (Ruff): JSON por padrão + HTML/MD
codehealthanalyzer errors --format all

# desativar exclusões padrão e usar config.json
codehealthanalyzer analyze --no-default-excludes --config config.json

# format: aplicar auto-fixes e formatação
codehealthanalyzer format
codehealthanalyzer format --no-ruff   # p.ex., só isort + black

# lint: checar qualidade e segurança
codehealthanalyzer lint

### API Python

```python
from codehealthanalyzer import CodeAnalyzer

# Inicializa o analisador
analyzer = CodeAnalyzer('/path/to/project')

# Gera relatório completo
report = analyzer.generate_full_report(output_dir='reports/')

# Obtém score de qualidade
score = analyzer.get_quality_score()
print(f"Score de Qualidade: {score}/100")

# Análises individuais
violations = analyzer.analyze_violations()
templates = analyzer.analyze_templates()
errors = analyzer.analyze_errors()

📊 Exemplo de Saída

📊 RESUMO DA ANÁLISE
==================================================
✅ Score de Qualidade: 85/100 - Excelente!
📁 Arquivos analisados: 124
⚠️  Arquivos com violações: 8
🎨 Templates: 15
🔍 Erros Ruff: 0
🔥 Issues de alta prioridade: 2

🎯 PRIORIDADES DE AÇÃO:
1. 🔴 Violações de Alta Prioridade (2)
2. 🟡 Templates com Muito CSS/JS Inline (3)

🔧 Configuração

Arquivo de Configuração JSON

{
  "limits": {
    "python_function": {"yellow": 30, "red": 50},
    "python_class": {"yellow": 300, "red": 500},
    "python_module": {"yellow": 500, "red": 1000},
    "html_template": {"yellow": 150, "red": 200},
    "test_file": {"yellow": 400, "red": 600}
  },
  "target_dir": "src/",
  "ruff_fix": true,
  "templates_dir": ["templates/", "app/templates/"],
  "file_rules": {
    "critical_files": ["main.py", "core.py"],
    "skip_patterns": [".git", "__pycache__", "node_modules"]
  },
  "exclude_dirs": ["legacy/", "playground/"]
}

Uso com Configuração

codehealthanalyzer analyze . --config config.json
import json
from codehealthanalyzer import CodeAnalyzer

with open('config.json') as f:
    config = json.load(f)

analyzer = CodeAnalyzer('/path/to/project', config)

Novas opções de configuração

  • templates_dir:

    • Define um ou mais diretórios onde os templates HTML serão buscados.
    • Aceita string (ex.: "templates/") ou lista de strings (ex.: ["templates/", "app/templates/"]).
    • Padrões automáticos: templates/ e luarco/templates/ (se existirem no projeto).
  • target_dir (ErrorsAnalyzer/Ruff):

    • Diretório raiz analisado pelo Ruff. Padrão agora é "." (raiz do projeto).
  • ruff_fix (ErrorsAnalyzer):

    • Quando true, executa ruff check --fix antes de coletar os erros.
    • Padrão: false.
  • Exclusões de diretórios (padrão e personalizadas):

    • Por padrão, os analisadores ignoram diretórios não relacionados a código-fonte:
      • .git, __pycache__, .pytest_cache, node_modules, .ruff_cache
      • tests, scripts, reports, dist, build, site-packages
      • .tox, .nox, .venv, venv, .env, migrations
    • Para desativar as exclusões padrão: use a flag --no-default-excludes nos comandos analyze, violations, templates, errors.
    • Para definir exclusões personalizadas via config:
      {
        "exclude_dirs": ["legacy/", "playground/"]
      }
      

Observação para Windows (encoding do console)

Para evitar problemas de encoding (CP1252) no console do Windows, a CLI usa apenas caracteres ASCII. Se desejar usar emojis/Unicode, configure o terminal para UTF-8. Exemplo no PowerShell:

$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()

🌍 Traduções

  • Arquivos compilados .mo agora são incluídos no pacote distribuído.
  • Para compilar localmente, use scripts/compile_translations.py (requer gettext ou fallback Python embutido).

🔁 Integração Contínua (CI)

  • Lint com Ruff (ruff check).
  • Testes com pytest.
  • Matriz Python: 3.8 a 3.12.
  • (Opcional) Build de documentação Sphinx.

📈 Tipos de Análise

🚨 Análise de Violações

Detecta:

  • Funções muito longas (> 50 linhas)
  • Classes muito grandes (> 500 linhas)
  • Módulos muito extensos (> 1000 linhas)
  • Templates HTML muito longos (> 200 linhas)

🎨 Análise de Templates

Identifica:

  • CSS inline em atributos style
  • JavaScript inline em eventos (onclick, etc.)
  • Tags <style> com muito conteúdo
  • Tags <script> com muito código

⚠️ Análise de Erros

Integra com Ruff para detectar:

  • Erros de sintaxe
  • Problemas de estilo
  • Imports não utilizados
  • Variáveis não definidas
  • Complexidade excessiva

📊 Score de Qualidade

O score é calculado baseado em:

  • Violações de alta prioridade: -10 pontos cada
  • Erros de linting: -2 pontos cada
  • Templates problemáticos: -5 pontos cada
  • Base: 100 pontos

Interpretação

  • 80-100: 🟢 Excelente
  • 60-79: 🟡 Bom
  • 0-59: 🔴 Precisa melhorar

🎯 Categorização Inteligente

Arquivos

  • Arquivo Crítico: Arquivos essenciais do sistema
  • Views Admin: Interfaces administrativas
  • Blueprint Crítico: Rotas críticas da aplicação
  • Template Base: Templates fundamentais

Prioridades

  • Alta: Problemas que afetam funcionalidade
  • Média: Problemas de manutenibilidade
  • Baixa: Melhorias recomendadas

📋 Formatos de Relatório

JSON

{
  "metadata": {
    "generated_at": "2024-01-15T10:30:00",
    "generator": "CodeHealthAnalyzer v1.0.0"
  },
  "summary": {
    "quality_score": 85,
    "total_files": 124,
    "violation_files": 8
  },
  "priorities": [...],
  "violations": [...],
  "templates": [...],
  "errors": [...]
}

HTML

Relatório completo e navegável, com:

  • Resumo (Score, totais)
  • Prioridades de ação
  • Tabela de Arquivos com Violações (arquivo, prioridade, nº violações, linhas)
  • Tabela de Erros (Ruff)
  • Tabela de Templates (CSS/JS chars)

Markdown

Relatório rico em Markdown com:

  • Resumo em tabela
  • Prioridades
  • Tabelas para Violações, Erros e Templates

CSV

Dados tabulares para análise em planilhas.

🛠️ API Avançada

Analisadores Individuais

from codehealthanalyzer.analyzers import (
    ViolationsAnalyzer,
    TemplatesAnalyzer,
    ErrorsAnalyzer
)

# Análise específica de violações
violations_analyzer = ViolationsAnalyzer('/path/to/project')
violations_report = violations_analyzer.analyze()

# Análise específica de templates
templates_analyzer = TemplatesAnalyzer('/path/to/project')
templates_report = templates_analyzer.analyze()

# Análise específica de erros
errors_analyzer = ErrorsAnalyzer('/path/to/project')
errors_report = errors_analyzer.analyze()

Geração de Relatórios

from codehealthanalyzer.reports import ReportGenerator, ReportFormatter

generator = ReportGenerator()
formatter = ReportFormatter()

# Gera relatório consolidado
full_report = generator.generate_full_report(
    violations=violations_report,
    templates=templates_report,
    errors=errors_report,
    output_dir='reports/'
)

# Converte para diferentes formatos
html_content = generator.generate_html_report(full_report, 'report.html')
markdown_content = formatter.to_markdown(full_report, 'report.md')
formatter.to_csv(full_report, 'report.csv')

Utilitários

from codehealthanalyzer.utils import (
    Categorizer,
    PathValidator,
    FileHelper,
    ColorHelper
)

# Categorização
categorizer = Categorizer()
category = categorizer.categorize_file(Path('src/main.py'))
priority = categorizer.determine_priority('file', {'lines': 150, 'type': 'python'})

# Validação
validator = PathValidator()
is_valid = validator.is_python_project('/path/to/project')
project_info = validator.get_project_info('/path/to/project')

# Helpers
file_helper = FileHelper()
data = file_helper.read_json('config.json')
file_helper.write_json(data, 'output.json')

# Cores para terminal
print(ColorHelper.success("Sucesso!"))
print(ColorHelper.error("Erro!"))
print(ColorHelper.warning("Aviso!"))

🧪 Testes

# Instala dependências de desenvolvimento
pip install -e ".[dev]"

# Executa testes
pytest

# Executa testes com cobertura
pytest --cov=codehealthanalyzer

# Executa linting
ruff check codehealthanalyzer/
black --check codehealthanalyzer/

🧰 Ferramentas de Qualidade e Segurança (para seu projeto)

Além de usar o CodeHealthAnalyzer, recomendamos rodar as seguintes ferramentas diretamente no seu projeto (exemplos a seguir). Substitua luarco/ pelo diretório do seu projeto.

Ruff (Linter & Auto-fix)

# Verificar erros com ruff
ruff check luarco/

# Corrigir erros automaticamente (quando possível)
ruff check luarco/ --fix

# Ver apenas erros críticos
ruff check luarco/ --select=F821,F841,E9

Black (Formatação automática)

# Black - Formatação automática
black .

isort (Organização de imports)

# isort - Organização de imports
isort .

Bandit (Segurança)

# bandit - Segurança (gera relatório JSON)
bandit -r luarco/ -f json -o bandit-report.json

Observações:

  • É comum rodar ruff check --fix, depois isort . e black . para padronizar o código.
  • Você pode integrar essas ferramentas no seu CI, semelhante ao nosso workflow em .github/workflows/ci.yml.

🤝 Contribuição

  1. Fork o projeto
  2. Crie uma branch para sua feature (git checkout -b feature/AmazingFeature)
  3. Commit suas mudanças (git commit -m 'Add some AmazingFeature')
  4. Push para a branch (git push origin feature/AmazingFeature)
  5. Abra um Pull Request

Diretrizes de Contribuição

  • Siga o estilo de código existente
  • Adicione testes para novas funcionalidades
  • Atualize a documentação quando necessário
  • Use commits semânticos

📄 Licença

Este projeto está licenciado sob a Licença MIT - veja o arquivo LICENSE para detalhes.

🙏 Agradecimentos

  • Ruff - Linter Python ultrarrápido
  • Click - Framework para CLI
  • Rich - Formatação rica para terminal

📞 Suporte


Feito com ❤️ pela equipe Imparcialista


🔍 CodeHealthAnalyzer

A comprehensive Python library for code quality and health analysis

Python Version License Code Style

🇧🇷 Português | 🇺🇸 English

🚀 Overview

CodeHealthAnalyzer is a modern and comprehensive Python library for code quality analysis. It combines multiple analysis tools into a unified interface, providing detailed insights into your code's health.

✨ Key Features

  • 🚨 Violations Analysis: Detects functions, classes, and modules that exceed size limits
  • 🎨 Template Analysis: Identifies inline CSS/JS in HTML templates that can be extracted
  • ⚠️ Ruff Integration: Analyzes linting errors and categorizes them by priority
  • 📊 Quality Score: Calculates a 0-100 score based on overall code health
  • 🎯 Smart Prioritization: Suggests actions based on problem criticality
  • 📈 Multiple Reports: Generates reports in JSON, HTML, Markdown, and CSV
  • 🖥️ Friendly CLI: Complete and intuitive command-line interface
  • 🔧 Highly Configurable: Customize limits, rules, and categories

📦 Installation

Installation via pip (recommended)

# Basic installation
pip install codehealthanalyzer

# Installation with interactive web dashboard
pip install codehealthanalyzer[web]

# Complete installation (web + development)
pip install codehealthanalyzer[web,dev]

Development Installation

git clone https://github.com/imparcialista/codehealthanalyzer.git
cd codehealthanalyzer
pip install -e .[web,dev]

Dependencies

  • Python 3.8+
  • ruff >= 0.1.0
  • click >= 8.0.0
  • rich >= 12.0.0 (optional, for colored output)

🎯 Quick Start

🌐 Interactive Dashboard

# Start web dashboard with real-time metrics
codehealthanalyzer dashboard .

# Dashboard on specific host and port
codehealthanalyzer dashboard . --host 0.0.0.0 --port 8080

# Dashboard with auto-reload for development
codehealthanalyzer dashboard . --reload

Dashboard Features:

  • 📊 Real-time metrics with automatic updates
  • 📈 Interactive quality trend charts
  • 🎯 Violations visualization by type
  • 📋 Problem files table
  • 🔄 WebSockets for instant updates
  • 📱 Responsive and modern interface

CLI (Command Line Interface)

# Complete analysis of current project
codehealthanalyzer analyze .

# Analysis with HTML output
codehealthanalyzer analyze . --format html --output reports/

# Quality score only
codehealthanalyzer score .

# Project information
codehealthanalyzer info .

# Specific violations analysis
codehealthanalyzer violations . --output violations.json

Python API

from codehealthanalyzer import CodeAnalyzer

# Initialize analyzer
analyzer = CodeAnalyzer('/path/to/project')

# Generate complete report
report = analyzer.generate_full_report(output_dir='reports/')

# Get quality score
score = analyzer.get_quality_score()
print(f"Quality Score: {score}/100")

# Individual analyses
violations = analyzer.analyze_violations()
templates = analyzer.analyze_templates()
errors = analyzer.analyze_errors()

📊 Example Output

📊 ANALYSIS SUMMARY
==================================================
✅ Quality Score: 85/100 - Excellent!
📁 Files analyzed: 124
⚠️  Files with violations: 8
🎨 Templates: 15
🔍 Ruff Errors: 0
🔥 High priority issues: 2

🎯 ACTION PRIORITIES:
1. 🔴 High Priority Violations (2)
2. 🟡 Templates with Too Much Inline CSS/JS (3)

🔧 Configuration

JSON Configuration File

{
  "limits": {
    "python_function": {"yellow": 30, "red": 50},
    "python_class": {"yellow": 300, "red": 500},
    "python_module": {"yellow": 500, "red": 1000},
    "html_template": {"yellow": 150, "red": 200},
    "test_file": {"yellow": 400, "red": 600}
  },
  "target_dir": "src/",
  "file_rules": {
    "critical_files": ["main.py", "core.py"],
    "skip_patterns": [".git", "__pycache__", "node_modules"]
  }
}

Usage with Configuration

codehealthanalyzer analyze . --config config.json
import json
from codehealthanalyzer import CodeAnalyzer

with open('config.json') as f:
    config = json.load(f)

analyzer = CodeAnalyzer('/path/to/project', config)

📈 Analysis Types

🚨 Violations Analysis

Detects:

  • Functions too long (> 50 lines)
  • Classes too large (> 500 lines)
  • Modules too extensive (> 1000 lines)
  • HTML templates too long (> 200 lines)

🎨 Template Analysis

Identifies:

  • Inline CSS in style attributes
  • Inline JavaScript in events (onclick, etc.)
  • <style> tags with too much content
  • <script> tags with too much code

⚠️ Error Analysis

Integrates with Ruff to detect:

  • Syntax errors
  • Style issues
  • Unused imports
  • Undefined variables
  • Excessive complexity

📊 Quality Score

The score is calculated based on:

  • High priority violations: -10 points each
  • Linting errors: -2 points each
  • Problematic templates: -5 points each
  • Base: 100 points

Interpretation

  • 80-100: 🟢 Excellent
  • 60-79: 🟡 Good
  • 0-59: 🔴 Needs improvement

🌐 Internationalization

Language Support

CodeHealthAnalyzer supports multiple languages:

  • Portuguese (Brazil): Default language
  • English: Full translation available

Setting Language

from codehealthanalyzer.i18n import set_language

# Set to English
set_language('en')

# Set to Portuguese (Brazil)
set_language('pt_BR')

# Auto-detect system language
from codehealthanalyzer.i18n import auto_configure_language
auto_configure_language()

Environment Variable

# Set language via environment
export CODEHEALTHANALYZER_LANG=en
codehealthanalyzer analyze .

🛠️ Advanced API

Individual Analyzers

from codehealthanalyzer.analyzers import (
    ViolationsAnalyzer,
    TemplatesAnalyzer,
    ErrorsAnalyzer
)

# Specific violations analysis
violations_analyzer = ViolationsAnalyzer('/path/to/project')
violations_report = violations_analyzer.analyze()

# Specific templates analysis
templates_analyzer = TemplatesAnalyzer('/path/to/project')
templates_report = templates_analyzer.analyze()

# Specific errors analysis
errors_analyzer = ErrorsAnalyzer('/path/to/project')
errors_report = errors_analyzer.analyze()

Report Generation

from codehealthanalyzer.reports import ReportGenerator, ReportFormatter

generator = ReportGenerator()
formatter = ReportFormatter()

# Generate consolidated report
full_report = generator.generate_full_report(
    violations=violations_report,
    templates=templates_report,
    errors=errors_report,
    output_dir='reports/'
)

# Convert to different formats
html_content = generator.generate_html_report(full_report, 'report.html')
markdown_content = formatter.to_markdown(full_report, 'report.md')
formatter.to_csv(full_report, 'report.csv')

🧪 Testing

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=codehealthanalyzer

# Run linting
ruff check codehealthanalyzer/
black --check codehealthanalyzer/

🤝 Contributing

  1. Fork the project
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Contribution Guidelines

  • Follow existing code style
  • Add tests for new features
  • Update documentation when necessary
  • Use semantic commits

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Ruff - Ultra-fast Python linter
  • Click - CLI framework
  • Rich - Rich terminal formatting

📞 Support


Made with ❤️ by the Imparcialista team

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

codehealthanalyzer-1.1.8.tar.gz (59.8 kB view details)

Uploaded Source

Built Distribution

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

codehealthanalyzer-1.1.8-py3-none-any.whl (53.1 kB view details)

Uploaded Python 3

File details

Details for the file codehealthanalyzer-1.1.8.tar.gz.

File metadata

  • Download URL: codehealthanalyzer-1.1.8.tar.gz
  • Upload date:
  • Size: 59.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for codehealthanalyzer-1.1.8.tar.gz
Algorithm Hash digest
SHA256 c2ef66787eb10ad1e1998c6aa03bf7e97108580163f2f56c1d534775e13c2337
MD5 d9694a39a2a7adbc0041eeafdf9ae0c5
BLAKE2b-256 483bf76d2e34a379b9f91a52dbf249d45bf033e0ebae572a81875f944272ef5e

See more details on using hashes here.

File details

Details for the file codehealthanalyzer-1.1.8-py3-none-any.whl.

File metadata

File hashes

Hashes for codehealthanalyzer-1.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 43e8b025ad9db2eaf2f5140daa9a5d9d2ea1c032a619224eee1b46df5a33b1b5
MD5 3528e2849c0f4f507adc5b8cf6f52c9c
BLAKE2b-256 b3f980f8bdeb6fa3d0af59b4f6eee9a7430150183d43138e283fc75fc04c740b

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