PHPackages                             gryfoss/int-precision-helper - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. gryfoss/int-precision-helper

ActiveLibrary[Database &amp; ORM](/categories/database)

gryfoss/int-precision-helper
============================

Helper class for handling decimal precision by storing floats as integers to avoid floating-point precision issues in database storage and calculations.

v1.1.0(6mo ago)0712MITPHPPHP &gt;=8.4CI passing

Since Oct 11Pushed 6mo agoCompare

[ Source](https://github.com/GryfOSS/int-precision-helper)[ Packagist](https://packagist.org/packages/gryfoss/int-precision-helper)[ RSS](/packages/gryfoss-int-precision-helper/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (2)

IntPrecisionHelper
==================

[](#intprecisionhelper)

[![Tests](https://github.com/GryfOSS/int-precision-helper/workflows/Tests/badge.svg)](https://github.com/GryfOSS/int-precision-helper/actions)[![PHP Version](https://camo.githubusercontent.com/bfb98d885e37493cddcc01059ebf02a8872de9da37c12691b8bb6d13fcdca735/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342532422d626c75652e737667)](https://www.php.net/)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![Coverage](https://camo.githubusercontent.com/f751cf9ce74c566617800f7e88d9896e9bd6e07fad747e3144ae9ef03e880788/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f7665726167652d3130302532352d627269676874677265656e2e737667)](#testing)

A robust PHP library for handling decimal precision by storing floating-point numbers as integers, designed to eliminate floating-point precision issues in database storage and financial calculations.

Installation
------------

[](#installation)

```
composer require gryfoss/int-precision-helper
```

Purpose
-------

[](#purpose)

This library solves common floating-point precision issues by storing decimal numbers as integers. For example:

- `12.34` is stored as `1234` (multiplied by 100)
- All calculations are performed on integers to maintain precision
- Results are converted back to decimal representation when needed

This approach is particularly useful for:

- **Financial calculations** - Ensuring precise monetary computations
- **Percentage calculations** - Accurate rate and ratio calculations
- **Database storage** - Consistent decimal representation across systems
- **Scientific calculations** - Where precision is critical

Why PHP 8.4+ is Required
------------------------

[](#why-php-84-is-required)

This library requires **PHP 8.4 or higher** because it utilizes PHP's native `bcround()` function, which was introduced in PHP 8.4. The `bcround()` function provides:

- **High-precision rounding** for decimal calculations
- **Consistent behavior** across different platforms
- **Performance optimization** over custom rounding implementations
- **BCMath integration** for seamless mathematical operations

Core Functionality
------------------

[](#core-functionality)

### Input Conversion Methods

[](#input-conversion-methods)

#### `fromString(string $value, bool $lessPrecise = false): int`

[](#fromstringstring-value-bool-lessprecise--false-int)

Converts a string representation of a decimal number to a normalized integer.

**Parameters:**

- `$value` - String representation of a decimal number (e.g., "12.34", "0.05")
- `$lessPrecise` - Optional performance mode for large numbers

**Example:**

```
$normalized = IntPrecisionHelper::fromString("12.34"); // Returns: 1234
$normalized = IntPrecisionHelper::fromString("0.05");  // Returns: 5
```

**Validation:** Throws `InvalidArgumentException` for invalid input formats.

#### `fromFloat(float $value, bool $lessPrecise = false): int`

[](#fromfloatfloat-value-bool-lessprecise--false-int)

Converts a float to a normalized integer representation.

**Parameters:**

- `$value` - Float value to convert
- `$lessPrecise` - Optional performance mode

**Example:**

```
$normalized = IntPrecisionHelper::fromFloat(12.34); // Returns: 1234
$normalized = IntPrecisionHelper::fromFloat(0.99);  // Returns: 99
```

#### `normalize(mixed $value, bool $lessPrecise = false): int`

[](#normalizemixed-value-bool-lessprecise--false-int)

Universal conversion method that automatically detects input type and converts to normalized integer.

**Parameters:**

- `$value` - Value to normalize (float, string, or integer)
- `$lessPrecise` - Optional performance mode for large numbers

**Examples:**

```
// Float input
$normalized = IntPrecisionHelper::normalize(12.34);   // Returns: 1234

// String input
$normalized = IntPrecisionHelper::normalize("12.34"); // Returns: 1234

// Integer input (multiplied by precision factor)
$normalized = IntPrecisionHelper::normalize(12);      // Returns: 1200
```

**Error Handling:** Throws `InvalidArgumentException` for unsupported types (arrays, objects, etc.) or invalid string formats.

### Output Conversion Methods

[](#output-conversion-methods)

#### `denormalize(int $normalizedValue): float`

[](#denormalizeint-normalizedvalue-float)

Converts a normalized integer back to its decimal representation as a float.

**Parameters:**

- `$normalizedValue` - Normalized integer value

**Example:**

```
$float = IntPrecisionHelper::denormalize(1234); // Returns: 12.34
$float = IntPrecisionHelper::denormalize(99);   // Returns: 0.99
```

#### `toView(int $value, int $decimalPlaces = 2): string`

[](#toviewint-value-int-decimalplaces--2-string)

Converts a normalized integer back to a human-readable string representation.

**Parameters:**

- `$value` - Normalized integer value
- `decimalPlaces` - Number of decimal places to display (default: 2)

**Example:**

```
$display = IntPrecisionHelper::toView(1234);    // Returns: "12.34"
$display = IntPrecisionHelper::toView(1234, 3); // Returns: "1.234"
```

#### `toFloat(int $value): float`

[](#tofloatint-value-float)

Converts a normalized integer back to a float representation.

**Example:**

```
$float = IntPrecisionHelper::toFloat(1234); // Returns: 12.34
```

### Mathematical Operations

[](#mathematical-operations)

#### `normMul(int ...$numbers): int`

[](#normmulint-numbers-int)

Performs multiplication on normalized integers while maintaining precision.

**Example:**

```
// 12.34 * 2.00 = 24.68
$result = IntPrecisionHelper::normMul(1234, 200); // Returns: 2468

// Multiple values: 12.34 * 2.00 * 1.50
$result = IntPrecisionHelper::normMul(1234, 200, 150); // Returns: 3702
```

**Protection:** Throws `OverflowException` if result would exceed PHP\_INT\_MAX.

#### `normDiv(int $dividend, int $divisor): int`

[](#normdivint-dividend-int-divisor-int)

Performs division on normalized integers with precision preservation.

**Example:**

```
// 12.34 / 2.00 = 6.17
$result = IntPrecisionHelper::normDiv(1234, 200); // Returns: 617
```

**Protection:** Throws `DivisionByZeroError` if divisor is zero.

#### `normAdd(int ...$numbers): int`

[](#normaddint-numbers-int)

Adds multiple normalized integers.

**Example:**

```
// 12.34 + 5.67 + 8.90 = 26.91
$result = IntPrecisionHelper::normAdd(1234, 567, 890); // Returns: 2691
```

#### `normSub(int $minuend, int $subtrahend): int`

[](#normsubint-minuend-int-subtrahend-int)

Subtracts two normalized integers.

**Example:**

```
// 12.34 - 5.67 = 6.67
$result = IntPrecisionHelper::normSub(1234, 567); // Returns: 667
```

### Utility Methods

[](#utility-methods)

#### `calculatePercentage(int $value, int $total): ?int`

[](#calculatepercentageint-value-int-total-int)

Calculates percentage as a normalized integer.

**Example:**

```
// 50 out of 200 = 25.00%
$percentage = IntPrecisionHelper::calculatePercentage(50, 200); // Returns: 2500
$display = IntPrecisionHelper::toView($percentage); // Returns: "25.00"
```

#### `normCompare(int $a, int $b): int`

[](#normcompareint-a-int-b-int)

Compares two normalized integers.

**Returns:**

- `-1` if `$a < $b`
- `0` if `$a == $b`
- `1` if `$a > $b`

**Example:**

```
$comparison = IntPrecisionHelper::normCompare(1234, 567); // Returns: 1
```

#### `isValid(mixed $value): bool`

[](#isvalidmixed-value-bool)

Validates if a value is a valid normalized integer.

**Example:**

```
$isValid = IntPrecisionHelper::isValid(1234);    // Returns: true
$isValid = IntPrecisionHelper::isValid("1234");  // Returns: false
$isValid = IntPrecisionHelper::isValid(12.34);   // Returns: false
```

Usage Examples
--------------

[](#usage-examples)

### Basic Conversions

[](#basic-conversions)

```
use GryfOSS\Formatter\IntPrecisionHelper;

// String to normalized integer
$normalized = IntPrecisionHelper::fromString("12.34"); // 1234

// Float to normalized integer
$normalized = IntPrecisionHelper::fromFloat(12.34); // 1234

// Universal normalize method (auto-detects type)
$normalized = IntPrecisionHelper::normalize(12.34);    // 1234 (float)
$normalized = IntPrecisionHelper::normalize("12.34");  // 1234 (string)
$normalized = IntPrecisionHelper::normalize(12);       // 1200 (integer)

// Back to string representation
$display = IntPrecisionHelper::toView(1234); // "12.34"

// Back to float
$float = IntPrecisionHelper::toFloat(1234); // 12.34

// Using denormalize (alias for toFloat)
$float = IntPrecisionHelper::denormalize(1234); // 12.34
```

### Round-Trip Conversions

[](#round-trip-conversions)

```
// Demonstrate precision preservation
$originalFloat = 12.34;
$normalized = IntPrecisionHelper::normalize($originalFloat);
$restored = IntPrecisionHelper::denormalize($normalized);
// $restored === 12.34 (exact match)

$originalString = "99.99";
$normalized = IntPrecisionHelper::normalize($originalString);
$restored = IntPrecisionHelper::denormalize($normalized);
// $restored === 99.99 (exact match)

$originalInt = 100;
$normalized = IntPrecisionHelper::normalize($originalInt);
$restored = IntPrecisionHelper::denormalize($normalized);
// $restored === 100.0 (converted to float)
```

### Mathematical Operations

[](#mathematical-operations-1)

```
// Multiplication: 12.34 * 2.00 = 24.68
$result = IntPrecisionHelper::normMul(1234, 200); // 2468

// Division: 12.34 / 2.00 = 6.17
$result = IntPrecisionHelper::normDiv(1234, 200); // 617

// Addition
$result = IntPrecisionHelper::normAdd(1234, 567, 890); // 2691

// Subtraction
$result = IntPrecisionHelper::normSub(1234, 567); // 667
```

Quick Reference
---------------

[](#quick-reference)

### New Universal Methods (Recommended)

[](#new-universal-methods-recommended)

#### `normalize(mixed $value, bool $lessPrecise = false): int`

[](#normalizemixed-value-bool-lessprecise--false-int-1)

**One method to convert any supported type to normalized integer:**

- ✅ **Floats**: `normalize(12.34)` → `1234`
- ✅ **Strings**: `normalize("12.34")` → `1234`
- ✅ **Integers**: `normalize(12)` → `1200`
- ❌ **Arrays/Objects**: Throws `InvalidArgumentException`

#### `denormalize(int $normalizedValue): float`

[](#denormalizeint-normalizedvalue-float-1)

**Convert normalized integer back to decimal float:**

- `denormalize(1234)` → `12.34`
- `denormalize(99)` → `0.99`

### Type-Specific Methods (Legacy)

[](#type-specific-methods-legacy)

Input TypeMethodExampleString`fromString("12.34")``1234`Float`fromFloat(12.34)``1234`Integer`$value * 100`ManualOutput TypeMethodExampleString`toView(1234)``"12.34"`Float`toFloat(1234)` or `denormalize(1234)``12.34`### When to Use Each Method

[](#when-to-use-each-method)

- 🎯 **Use `normalize()`** when input type varies or unknown
- ⚡ **Use `fromString()`/`fromFloat()`** for known types (slight performance benefit)
- 📊 **Use `denormalize()`** for float output
- 📝 **Use `toView()`** for formatted string display

Advanced Features &amp; Error Handling
--------------------------------------

[](#advanced-features--error-handling)

### Input Validation

[](#input-validation)

The library provides comprehensive input validation with descriptive error messages:

```
try {
    $result = IntPrecisionHelper::fromString("invalid");
} catch (InvalidArgumentException $e) {
    echo "Invalid input format: " . $e->getMessage();
}

try {
    $result = IntPrecisionHelper::fromString(""); // Empty string
} catch (InvalidArgumentException $e) {
    echo "Input cannot be empty";
}

// Universal normalize method with type validation
try {
    $result = IntPrecisionHelper::normalize([1, 2, 3]); // Array input
} catch (InvalidArgumentException $e) {
    echo "Invalid input type: " . $e->getMessage();
    // Output: "Input value must be a float, string, or int. Got array"
}

try {
    $result = IntPrecisionHelper::normalize("1.23e2"); // Scientific notation
} catch (InvalidArgumentException $e) {
    echo "Scientific notation not supported: " . $e->getMessage();
}
```

### Division by Zero Protection

[](#division-by-zero-protection)

All division operations are protected against division by zero:

```
try {
    $result = IntPrecisionHelper::normDiv(1234, 0);
} catch (DivisionByZeroError $e) {
    echo "Cannot divide by zero";
}

try {
    $percentage = IntPrecisionHelper::calculatePercentage(50, 0);
} catch (DivisionByZeroError $e) {
    echo "Total cannot be zero for percentage calculation";
}
```

### Overflow Protection

[](#overflow-protection)

The library detects and prevents integer overflow conditions:

```
try {
    $result = IntPrecisionHelper::normMul(PHP_INT_MAX, PHP_INT_MAX);
} catch (OverflowException $e) {
    echo "Result would exceed maximum integer value";
}
```

### Performance Modes

[](#performance-modes)

For performance-critical applications with very large numbers:

```
// Standard precision (recommended for most use cases)
$result = IntPrecisionHelper::fromString("12.34");
$result = IntPrecisionHelper::normalize("12.34");

// Less precise but faster for very large numbers
$result = IntPrecisionHelper::fromString("12.34", true);
$result = IntPrecisionHelper::fromFloat(12.34, true);
$result = IntPrecisionHelper::normalize("12.34", true);
$result = IntPrecisionHelper::normalize(12.34, true);
```

Breaking Changes from Original
------------------------------

[](#breaking-changes-from-original)

⚠️ **Important**: The legacy `NormMul` and `NormDiv` methods have been removed due to PHP's case-insensitive function names conflicting with the new `normMul` and `normDiv` methods.

**Migration Guide:**

- `NormMul()` → `normMul()`
- `NormDiv()` → `normDiv()`
- `calculatePercentage()` now returns `int|null` instead of `float|null`

Configuration &amp; Customization
---------------------------------

[](#configuration--customization)

### Custom Precision Factor

[](#custom-precision-factor)

You can customize the precision factor by extending the class:

```
class CustomPrecisionHelper extends IntPrecisionHelper
{
    protected const PRECISION_FACTOR = 1000; // 3 decimal places instead of 2
    protected const DECIMAL_PLACES = 3;
}

// Usage
$normalized = CustomPrecisionHelper::fromString("12.345"); // Returns: 12345
$display = CustomPrecisionHelper::toView(12345);           // Returns: "12.345"
```

### Available Constants

[](#available-constants)

- `PRECISION_FACTOR` - Multiplier for decimal conversion (default: 100)
- `DECIMAL_PLACES` - Default decimal places for output (default: 2)

Requirements
------------

[](#requirements)

- **PHP 8.4+** - Required for native `bcround()` function support
- **BCMath extension** - Essential for high-precision mathematical operations
- **64-bit system** - Recommended for handling larger integer values

Testing &amp; Quality Assurance
-------------------------------

[](#testing--quality-assurance)

This library maintains **100% code coverage** and follows rigorous testing standards to ensure reliability and precision.

### Test Coverage Statistics

[](#test-coverage-statistics)

- 📊 **100% Code Coverage** - Complete line coverage with comprehensive testing
- 🧪 **74 Test Cases** - Comprehensive unit test suite
- ✅ **151 Assertions** - Detailed validation of all functionality
- 🎯 **556 Feature Scenarios** - Behavior-driven development tests
- 🚀 **Edge Case Coverage** - All error conditions and boundary cases tested
- � **Continuous Integration** - Automated testing on every commit

### Running Tests Locally

[](#running-tests-locally)

#### Unit Tests with Coverage

[](#unit-tests-with-coverage)

```
# Run complete test suite with coverage report
./vendor/bin/phpunit

# Generate detailed HTML coverage report
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-html coverage-html

# Use the provided coverage script
./test-coverage.sh
```

#### Feature Tests (Behavioral Testing)

[](#feature-tests-behavioral-testing)

```
# Run Behat feature tests
./vendor/bin/behat

# Run with detailed output
./vendor/bin/behat --format=pretty
```

#### Quick Test Coverage Check

[](#quick-test-coverage-check)

```
# Fast coverage validation
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text
```

### Test Categories

[](#test-categories)

#### Unit Tests (`tests/IntPrecisionHelperTest.php`)

[](#unit-tests-testsintprecisionhelpertestphp)

- ✅ **Conversion Methods** - String/float to integer and back
- ✅ **Universal Normalize/Denormalize** - Type-agnostic conversion methods
- ✅ **Mathematical Operations** - Multiplication, division, addition, subtraction
- ✅ **Error Handling** - Invalid inputs, overflow, division by zero
- ✅ **Edge Cases** - Boundary values, special numbers, large integers
- ✅ **Utility Functions** - Comparison, validation, percentage calculations

#### Feature Tests (`features/`)

[](#feature-tests-features)

- ✅ **Division Operations** - Comprehensive division scenarios
- ✅ **Edge Cases** - Boundary conditions and error states
- ✅ **Float Conversion** - Float input/output validation
- ✅ **Multiplication** - Complex multiplication scenarios
- ✅ **Normalize/Denormalize** - Universal conversion and round-trip testing
- ✅ **String Conversion** - String parsing and formatting
- ✅ **View Conversion** - Display formatting and precision

### Continuous Integration

[](#continuous-integration)

The project uses GitHub Actions for automated testing:

- **Automated Test Execution** - Runs on every push and pull request
- **Coverage Validation** - Ensures 100% coverage is maintained
- **Multi-environment Testing** - Tests across different PHP configurations
- **Quality Gates** - Prevents merging code that breaks tests or reduces coverage

Contributing
------------

[](#contributing)

We welcome contributions from the community! Whether you're fixing bugs, adding features, improving documentation, or reporting issues, your help makes this library better for everyone.

### How to Contribute

[](#how-to-contribute)

#### 🐛 Reporting Issues

[](#-reporting-issues)

Found a bug or have a feature request? Please [open an issue](https://github.com/GryfOSS/int-precision-helper/issues) with:

- **Clear description** of the problem or feature request
- **Steps to reproduce** (for bugs)
- **Expected vs actual behavior**
- **PHP version** and system information
- **Code examples** demonstrating the issue

#### 🔧 Pull Requests

[](#-pull-requests)

Ready to contribute code? We'd love your help! Please:

1. **Fork the repository** and create a feature branch
2. **Write tests** for any new functionality
3. **Ensure 100% coverage** is maintained
4. **Follow PSR-12** coding standards
5. **Update documentation** as needed
6. **Submit a pull request** with a clear description

#### 📋 Contribution Checklist

[](#-contribution-checklist)

Before submitting a pull request, ensure:

- All tests pass: `./vendor/bin/phpunit`
- Feature tests pass: `./vendor/bin/behat`
- 100% code coverage maintained
- Code follows PSR-12 standards
- Documentation is updated
- CHANGELOG.md is updated (for notable changes)

#### 🎯 Areas for Contribution

[](#-areas-for-contribution)

We especially welcome contributions in these areas:

- **Performance optimizations** for large number operations
- **Additional mathematical operations** (modulo, power, etc.)
- **Documentation improvements** and examples
- **Bug fixes** and edge case handling
- **Platform compatibility** testing

#### 💡 Feature Requests

[](#-feature-requests)

Have an idea for a new feature? We'd love to hear it! Consider:

- **Mathematical operations** that would benefit from precision handling
- **Integration helpers** for popular frameworks
- **Performance improvements** for specific use cases
- **Developer experience** enhancements

### Development Setup

[](#development-setup)

```
# Clone your fork
git clone https://github.com/YOUR_USERNAME/int-precision-helper.git
cd int-precision-helper

# Install dependencies
composer install

# Run tests to ensure everything works
./vendor/bin/phpunit
./vendor/bin/behat
```

### Code of Conduct

[](#code-of-conduct)

Please note that this project follows a **Code of Conduct**. By participating, you agree to:

- Be respectful and inclusive
- Focus on constructive feedback
- Help create a welcoming environment for all contributors

Getting Help
------------

[](#getting-help)

Need help getting started or have questions?

- 📖 Check the [documentation](README.md) and [TESTING.md](TESTING.md)
- 🐛 Search [existing issues](https://github.com/GryfOSS/int-precision-helper/issues)
- 💬 Open a [new issue](https://github.com/GryfOSS/int-precision-helper/issues/new) for questions
- 📧 Contact the maintainers for complex queries

**Thank you for contributing to IntPrecisionHelper!** 🚀

License
-------

[](#license)

MIT License

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance66

Regular maintenance activity

Popularity8

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~9 days

Total

2

Last Release

201d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b76a5fac115d24d698d09cc939a6922bf309732ae61d0f2f215ae9e7397658ea?d=identicon)[ideaconnect](/maintainers/ideaconnect)

---

Top Contributors

[![bpacholek](https://avatars.githubusercontent.com/u/3039162?v=4)](https://github.com/bpacholek "bpacholek (1 commits)")

---

Tags

databasedecimalprecisionfinancialcalculationsfloating-point

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/gryfoss-int-precision-helper/health.svg)

```
[![Health](https://phpackages.com/badges/gryfoss-int-precision-helper/health.svg)](https://phpackages.com/packages/gryfoss-int-precision-helper)
```

###  Alternatives

[doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.

9.7k578.4M5.6k](/packages/doctrine-dbal)[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[doctrine/doctrine-bundle

Symfony DoctrineBundle

4.8k241.3M3.3k](/packages/doctrine-doctrine-bundle)[doctrine/migrations

PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easily deploying changes to it. It is a very easy to use and a powerful tool.

4.8k204.8M438](/packages/doctrine-migrations)[doctrine/data-fixtures

Data Fixtures for all Doctrine Object Managers

2.9k136.1M516](/packages/doctrine-data-fixtures)[robmorgan/phinx

Phinx makes it ridiculously easy to manage the database migrations for your PHP app.

4.5k46.2M403](/packages/robmorgan-phinx)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
