[
  {
    "path": ".editorconfig",
    "content": "# EditorConfig http://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# This applies to all files\n[*]\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\ncharset = utf-8\nindent_style = space\nindent_size = 4\n\n[*.{yml,yaml}]\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "/.allowed-licenses          export-ignore\n/.editorconfig              export-ignore\n/.gitattributes             export-ignore\n/.github/                   export-ignore\n/.gitignore                 export-ignore\n/.readthedocs.yml           export-ignore\n/bin/                       export-ignore\n/build/                     export-ignore\n/captainhook.json           export-ignore\n/CHANGELOG.md               export-ignore\n/composer.lock              export-ignore\n/codecov.yml                export-ignore\n/CODE_OF_CONDUCT.md         export-ignore\n/CONTRIBUTING.md            export-ignore\n/conventional-commits.json  export-ignore\n/docs/                      export-ignore\n/phpbench.json              export-ignore\n/phpcs.xml.dist             export-ignore\n/phpstan-tests.neon         export-ignore\n/phpstan.neon.dist          export-ignore\n/phpunit.xml.dist           export-ignore\n/resources/                 export-ignore\n/SECURITY.md                export-ignore\n/tests/                     export-ignore\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "* @ramsey\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Bug_Report.md",
    "content": "---\nname: Bug Report\nabout: Create a bug report to help us improve\nlabels: bug\nassignees:\n---\n<!--- Provide a general summary of the issue you're having in the title above. -->\n\n## Description\n<!-- Provide a short and clear description of the bug. -->\n\n## Steps to reproduce\n<!--\nProvide steps to reproduce the behavior you are experiencing. Please try to keep\nthis as short as possible. If able, create a reproducible script outside of any\nframework you are using. This will help us to quickly debug the issue.\n-->\n1. Step one...\n2. Step two...\n3. Step three...\n\n## Expected behavior\n<!-- Provide a short and clear description of what you expect to happen. -->\n\n## Screenshots or output\n<!-- If applicable, add screenshots or program output to help explain your problem. -->\n\n## Environment details\n<!-- Provide details about the system where you're using this package. -->\n- version of this package: *e.g. 1.0.0, 1.0.1, 1.1.0*\n- PHP version: *e.g. 7.3.16, 7.4.4*\n- OS: *e.g. Windows 10, Linux (Ubuntu 18.04.1), macOS Catalina (10.15.3)*\n\n## Additional context\n<!-- Provide any additional context that may help us debug the problem. -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Feature_Request.md",
    "content": "---\nname: Feature Request\nabout: Suggest a feature for this project\nlabels: enhancement\nassignees:\n---\n<!--- Provide a general summary of your feature request in the title above. -->\n\n<!-- Give your feature a short title here. -->\n## My feature title\n<!-- Provide a short and clear description of the feature. -->\n\n## Background/problem\n<!--\nProvide background details to show why this feature is necessary. Is your\nfeature request related to a problem? If so, please describe the problem.\nProvide as much detail as possible.\n-->\n\n## Proposal/solution\n<!--\nProvide a short and clear description of the solution you'd like. Include code\nexamples, if possible. Feel free to use pseudo-code to show how you think the\nfeature should work.\n-->\n\n## Alternatives\n<!-- Describe any alternative solutions or features you've considered. -->\n\n## Additional context\n<!-- Please provide any other context or code examples that may help. -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Question.md",
    "content": "---\nname: Question\nabout: Ask a question about how to use this library\nlabels: question\nassignees:\n---\n<!--- Provide a general summary of your question in the title above. -->\n\n<!-- Write your question here. -->\n## How do I... ?\n<!-- Provide any additional context that may help us answer your question. -->\n\n## Example code\n<!--\nIf your question is about code that you've written, provide a short and clear\nexample of what you're trying to accomplish. Try to keep this as short as\npossible. If able, please provide an example outside of any framework you are\nusing. This will help us to quickly respond to your question.\n-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"composer\"\n    allow:\n      - dependency-type: all\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    open-pull-requests-limit: 1\n    versioning-strategy: \"increase-if-necessary\"\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    open-pull-requests-limit: 1\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "<!--- Provide a general summary of your changes in the title above. -->\n\n## Description\n<!--- Describe your changes in detail. -->\n\n## Motivation and context\n<!--- Why is this change required? What problem does it solve? -->\n<!--- If it fixes an open issue, please link to the issue here. -->\n\n## How has this been tested?\n<!--- Please describe in detail how you tested your changes. -->\n<!--- Include details of your testing environment, and the tests you ran to -->\n<!--- see how your change affects other areas of the code, etc. -->\n\n## Types of changes\n<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->\n- [ ] Bug fix (non-breaking change which fixes an issue)\n- [ ] New feature (non-breaking change which adds functionality)\n- [ ] Breaking change (fix or feature that would cause existing functionality to change)\n\n## PR checklist\n<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->\n<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->\n- [ ] My change requires a change to the documentation.\n- [ ] I have updated the documentation accordingly.\n- [ ] I have read the **CONTRIBUTING.md** document.\n- [ ] I have added tests to cover my changes.\n"
  },
  {
    "path": ".github/workflows/continuous-integration.yml",
    "content": "# GitHub Actions Documentation: https://docs.github.com/en/actions\n\nname: \"Continuous Integration\"\n\non:\n  push:\n    branches:\n      - \"*.x\"\n    tags:\n      - \"*\"\n  pull_request:\n    branches:\n      - \"*.x\"\n\n# Cancels all previous workflow runs for the same branch that have not yet completed.\nconcurrency:\n  # The concurrency group contains the workflow name and the branch name.\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\nenv:\n  COMPOSER_ROOT_VERSION: \"1.99.99\"\n\njobs:\n  coding-standards:\n    name: \"Coding standards\"\n    runs-on: \"ubuntu-latest\"\n\n    steps:\n      - name: \"Checkout repository\"\n        uses: \"actions/checkout@v6\"\n\n      - name: \"Install PHP\"\n        uses: \"shivammathur/setup-php@v2\"\n        with:\n          php-version: \"latest\"\n          coverage: \"none\"\n\n      - name: \"Install dependencies (Composer)\"\n        uses: \"ramsey/composer-install@v4\"\n        with:\n          dependency-versions: \"highest\"\n\n      - name: \"Check syntax (php-parallel-lint)\"\n        run: \"composer dev:lint:syntax\"\n\n      - name: \"Check coding standards (PHP_CodeSniffer)\"\n        run: \"composer dev:lint:style\"\n\n  static-analysis:\n    name: \"Static analysis\"\n    runs-on: \"ubuntu-latest\"\n\n    steps:\n      - name: \"Checkout repository\"\n        uses: \"actions/checkout@v6\"\n\n      - name: \"Install PHP\"\n        uses: \"shivammathur/setup-php@v2\"\n        with:\n          php-version: \"latest\"\n          coverage: \"none\"\n\n      - name: \"Install dependencies (Composer)\"\n        uses: \"ramsey/composer-install@v4\"\n        with:\n          dependency-versions: \"highest\"\n\n      - name: \"Statically analyze code (PHPStan)\"\n        run: \"composer dev:analyze:phpstan\"\n\n  benchmark:\n    name: \"Benchmark\"\n    needs: [\"coding-standards\", \"static-analysis\"]\n    runs-on: \"ubuntu-latest\"\n\n    strategy:\n      fail-fast: false\n      matrix:\n        php-version:\n          - \"8.0\"\n          - \"8.1\"\n          - \"8.2\"\n          - \"8.3\"\n          - \"8.4\"\n          - \"8.5\"\n\n    steps:\n      - name: \"Checkout repository\"\n        uses: \"actions/checkout@v6\"\n\n      - name: \"Install dependencies (apt)\"\n        run: |\n          sudo apt-get update\n          sudo apt-get -y install libsodium-dev uuid-dev\n\n      - name: \"Install PHP\"\n        uses: \"shivammathur/setup-php@v2\"\n        with:\n          php-version: \"${{ matrix.php-version }}\"\n          extensions: bcmath, gmp, sodium, uuid\n          coverage: \"none\"\n          ini-values: \"memory_limit=-1\"\n\n      - name: \"Install dependencies (Composer)\"\n        uses: \"ramsey/composer-install@v4\"\n        with:\n          dependency-versions: \"highest\"\n\n      - name: \"Run benchmarks (PHPBench)\"\n        run: \"composer dev:bench\"\n\n  code-coverage:\n    name: \"Code coverage\"\n    needs: [\"coding-standards\", \"static-analysis\"]\n    runs-on: \"ubuntu-latest\"\n\n    steps:\n      - name: \"Checkout repository\"\n        uses: \"actions/checkout@v6\"\n\n      - name: \"Install dependencies (apt)\"\n        run: |\n          sudo apt-get update\n          sudo apt-get -y install libsodium-dev uuid-dev\n\n      - name: \"Install PHP\"\n        uses: \"shivammathur/setup-php@v2\"\n        with:\n          php-version: \"latest\"\n          extensions: bcmath, gmp, sodium, uuid\n          coverage: \"xdebug\"\n          ini-values: \"memory_limit=-1\"\n\n      - name: \"Install dependencies (Composer)\"\n        uses: \"ramsey/composer-install@v4\"\n        with:\n          dependency-versions: \"highest\"\n\n      - name: \"Run unit tests (PHPUnit)\"\n        run: \"composer dev:test:coverage:ci\"\n\n      - name: \"Publish coverage report to Codecov\"\n        uses: \"codecov/codecov-action@v5\"\n\n      - name: \"Upload test results to Codecov\"\n        if: ${{ !cancelled() }}\n        uses: \"codecov/test-results-action@v1\"\n        with:\n          disable_search: true\n          file: \"./build/junit.xml\"\n\n  unit-tests:\n    name: \"Unit Tests\"\n    needs: [\"code-coverage\"]\n    runs-on: ${{ matrix.operating-system }}\n\n    strategy:\n      fail-fast: false\n      matrix:\n        php-version:\n          - \"8.0\"\n          - \"8.1\"\n          - \"8.2\"\n          - \"8.3\"\n          - \"8.4\"\n          - \"8.5\"\n        operating-system:\n          - \"ubuntu-latest\"\n          - \"windows-latest\"\n        dependency-versions:\n          - \"locked\"\n          - \"highest\"\n\n    steps:\n      - name: \"Configure Git (for Windows)\"\n        if: ${{ matrix.operating-system == 'windows-latest' }}\n        run: |\n          git config --system core.autocrlf false\n          git config --system core.eol lf\n\n      - name: \"Checkout repository\"\n        uses: \"actions/checkout@v6\"\n\n      - name: \"Install dependencies (apt)\"\n        if: ${{ matrix.operating-system == 'ubuntu-latest' }}\n        run: |\n          sudo apt-get update\n          sudo apt-get -y install libsodium-dev uuid-dev\n\n      - name: \"Install PHP\"\n        uses: \"shivammathur/setup-php@v2\"\n        with:\n          php-version: \"${{ matrix.php-version }}\"\n          extensions: bcmath, gmp, sodium, uuid\n          coverage: \"none\"\n          ini-values: \"memory_limit=-1\"\n\n      - name: \"Downgrade brick/math in lock file for PHP 8.0\"\n        run: |\n          composer update brick/math:\"0.8.16\"\n\n      - name: \"Install dependencies (Composer)\"\n        uses: \"ramsey/composer-install@v4\"\n        with:\n          dependency-versions: \"${{ matrix.dependency-versions }}\"\n\n      - name: \"Run unit tests (PHPUnit)\"\n        run: \"composer dev:test:unit\"\n"
  },
  {
    "path": ".github/workflows/merge-me.yml",
    "content": "# Merge Me! Documentation: https://github.com/ridedott/merge-me-action/\n\nname: \"Merge Dependabot PRs\"\n\non:\n  workflow_run:\n    types:\n      - \"completed\"\n    workflows:\n      - \"Continuous Integration\"\n\njobs:\n  merge-me:\n    name: \"Merge me!\"\n    runs-on: \"ubuntu-latest\"\n    steps:\n      - name: \"Auto-merge\"\n        if: ${{ github.event.workflow_run.conclusion == 'success' }}\n        uses: \"ridedott/merge-me-action@v2\"\n        with:\n          # This must be used as the GitHub Actions token does not support pushing\n          # to protected branches.\n          #\n          # Create a token with repository permissions:\n          # https://github.com/settings/tokens/new?scopes=repo&description=Merge+Me!+GitHub+Actions+Workflow\n          #\n          # Set MERGE_TOKEN as an environment variable on your repository:\n          # https://github.com/yourname/repo-name/settings/secrets/actions/new\n          GITHUB_TOKEN: ${{ secrets.MERGE_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "/captainhook.config.json\n/phpcs.xml\n/phpunit.xml\n/vendor/\n"
  },
  {
    "path": ".readthedocs.yml",
    "content": "version: 2\n\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.12\"\n\nsphinx:\n  configuration: docs/conf.py\n\nformats: all\n\npython:\n  install:\n    - requirements: docs/requirements.txt\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# ramsey/uuid Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)\nand this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).\n\n\n## 4.9.2 - 2025-12-14\n\n### Fixed\n\n* Remove explicit `(int)` cast to avoid float-string cast warnings in PHP 8.5.\n* Bump the lowest supported version of brick/math to `^0.8.16` from `^0.8.8`. ramsey/uuid had been using `BigInteger::toBytes()` in `UnixTimeGenerator` (for version 7 UUIDs) since v4.6.0, but it wasn't added to brick/math until v0.8.16.\n\n\n## 4.9.1 - 2025-09-04\n\n### Fixed\n\n* Allow brick/math version `^0.14`; fixed in [#617](https://github.com/ramsey/uuid/pull/617).\n* Default to `microtime()` instead of `DateTimeImmutable` in `Ramsey\\Uuid\\Generator\\UnixTimeGenerator`.\n\n\n## 4.9.0 - 2025-06-25\n\n### Added\n\n* Add new `@pure` annotations to the following ([#605](https://github.com/ramsey/uuid/pull/605)):\n  * `Ramsey\\Uuid\\Codec\\CodecInterface::encode()`\n  * `Ramsey\\Uuid\\Codec\\CodecInterface::encodeBinary()`\n  * `Ramsey\\Uuid\\Codec\\CodecInterface::decode()`\n  * `Ramsey\\Uuid\\Codec\\CodecInterface::decodeBytes()`\n  * `Ramsey\\Uuid\\Fields\\FieldsInterface::getBytes()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::add()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::subtract()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::multiply()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::divide()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::fromBase()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::toBase()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::toHexadecimal()`\n  * `Ramsey\\Uuid\\Math\\CalculatorInterface::toInteger()`\n  * `Ramsey\\Uuid\\Nonstandard\\Uuid`\n  * `Ramsey\\Uuid\\Rfc4122\\Fields::isMax()`\n  * `Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getVersion()`\n  * `Ramsey\\Uuid\\Rfc4122\\FieldsInterface::isNil()`\n  * `Ramsey\\Uuid\\Type\\Time::getSeconds()`\n  * `Ramsey\\Uuid\\Type\\Time::getMicroseconds()`\n  * `Ramsey\\Uuid\\Type\\TypeInterface::toString()`\n  * `Ramsey\\Uuid\\UuidInterface::getBytes()`\n  * `Ramsey\\Uuid\\UuidInterface::toString()`\n  * `Ramsey\\Uuid\\Validator\\ValidatorInterface::validate()`\n\n### Fixed\n\n* Restore the `@pure` annotations that were removed in 4.8.0 ([#603](https://github.com/ramsey/uuid/pull/603)).\n\n\n## 4.8.1 - 2025-06-01\n\n### Fixed\n\n* This tagged release ensures the stable documentation build matches the current stable release.\n\n\n## 4.8.0 - 2025-06-01\n\n### Deprecated\n\nThe following will be removed in ramsey/uuid 5.0.0:\n\n* `Ramsey\\Uuid\\Codec\\OrderedTimeCodec` is deprecated; please migrate to [version 6 UUIDs](https://uuid.ramsey.dev/en/stable/rfc4122/version6.html).\n* `Ramsey\\Uuid\\Codec\\TimestampFirstCombCodec` is deprecated; please migrate to [version 7 UUIDs](https://uuid.ramsey.dev/en/stable/rfc4122/version7.html).\n* `Ramsey\\Uuid\\Codec\\TimestampLastCombCodec` is deprecated; please use `Ramsey\\Uuid\\Codec\\StringCodec` instead.\n* `Ramsey\\Uuid\\Generator\\CombGenerator` is deprecated; please migrate to [version 7 UUIDs](https://uuid.ramsey.dev/en/stable/rfc4122/version7.html).\n\n### Fixed\n\n* Allow brick/math version `^0.13`; fixed in [#589](https://github.com/ramsey/uuid/pull/589).\n* Update call to `str_getcsv()` to avoid deprecation notice in PHP 8.4; fixed in [#590](https://github.com/ramsey/uuid/pull/590).\n* Hexadecimal is never an empty string; fixed in [#593](https://github.com/ramsey/uuid/pull/593).\n* Update docblocks for `Uuid::fromBytes()`, `Uuid::fromString()`, `Uuid::fromDateTime()`, `Uuid::fromHexadecimal()`, and `Uuid::fromInteger()` to note that each can throw `InvalidArgumentException`, addressing PHPStan errors occurring at call sites; fixed in [#552](https://github.com/ramsey/uuid/pull/552).\n* `getVariant()` for `MaxUuid` now correctly returns `Uuid::RESERVED_FUTURE`, as specified in [RFC 9562, section 5.10](https://www.rfc-editor.org/rfc/rfc9562#section-5.10).\n* `getVariant()` for `NilUuid` now correctly returns `Uuid::RESERVED_NCS`, as specified in [RFC 9562, section 5.9](https://www.rfc-editor.org/rfc/rfc9562#section-5.9).\n\n\n## 4.7.6 - 2024-04-27\n\n### Fixed\n\n* Allow brick/math version `^0.12`.\n\n\n## 4.7.5 - 2023-11-08\n\n### Fixed\n\n* Protect against UUIDv7 collisions within the same millisecond, as reported\n  in [#518](https://github.com/ramsey/uuid/issues/518) and fixed in\n  [#522](https://github.com/ramsey/uuid/pull/522).\n* Improve the return type hint for `UuidInterface::compareTo()`.\n\n\n## 4.7.4 - 2023-04-15\n\n### Fixed\n\n* Allow brick/math version `^0.11`.\n* Add explicit `Stringable` interface to `UuidInterface`.\n* Fix namespace conflict reported in [#490](https://github.com/ramsey/uuid/issues/490).\n* Fix unserialize error with `OrderedTimeCodec` reported in\n  [#494](https://github.com/ramsey/uuid/issues/494).\n\n\n## 4.7.3 - 2023-01-12\n\n### Fixed\n\n* The original 4.7.2 tag accidentally pointed to a commit in the 5.x branch. I\n  have replaced the 4.7.2 tag with a new tag that points to the correct commit,\n  but I am creating this tag to help notify users and automated processes who\n  might have already updated to the bad 4.7.2 tag.\n\n\n## 4.7.2 - 2023-01-12\n\n### Fixed\n\n* Amend Psalm assertion syntax on `Uuid::isValid()` to prevent incorrect type\n  inference ([#486](https://github.com/ramsey/uuid/pull/486)).\n* Re-tagged with the correct commit hash, since the first tag was pointing to\n  a commit in the 5.x branch.\n\n\n## 4.7.1 - 2022-12-31\n\n### Fixed\n\n* Allow the use of ramsey/collection ^2.0 with ramsey/uuid.\n\n\n## 4.7.0 - 2022-12-19\n\n### Added\n\n* Add `Uuid::fromHexadecimal()` and `UuidFactory::fromHexadecimal()`. These\n  methods are not required by the interfaces.\n\n### Fixed\n\n* Ignore MAC addresses consisting of all zeroes (i.e., `00:00:00:00:00:00`).\n\n\n## 4.6.0 - 2022-11-05\n\n### Added\n\n* Add support for version 8, Unix Epoch time UUIDs, as defined in\n  [draft-ietf-uuidrev-rfc4122bis-00, section 5.8][version8]. While still an\n  Internet-Draft, version 8 is stable and unlikely to change in any way that\n  breaks compatibility.\n  * Use `Ramsey\\Uuid\\Uuid::uuid8()` to generate version 8 UUIDs.\n  * Version 8 UUIDs are of type `Ramsey\\Uuid\\Rfc4122\\UuidV8`.\n  * The constant `Ramsey\\Uuid\\Uuid::UUID_TYPE_CUSTOM` exists for version 8 UUIDs.\n\n### Fixed\n\n* Ensure monotonicity of version 7 UUIDs.\n\n\n## 4.5.1 - 2022-09-16\n\n### Fixed\n\n* Update RFC 4122 validator to recognize version 6 and 7 UUIDs.\n\n\n## 4.5.0 - 2022-09-15\n\n### Added\n\n* Promote version 6, reordered time UUIDs from the `Nonstandard` namespace to\n  the `Rfc4122` namespace. Version 6 UUIDs are defined in\n  [draft-ietf-uuidrev-rfc4122bis-00, section 5.6][version6]. While still an\n  Internet-Draft version 6 is stable and unlikely to change in any way that\n  breaks compatibility.\n* Add support for version 7, Unix Epoch time UUIDs, as defined in\n  [draft-ietf-uuidrev-rfc4122bis-00, section 5.7][version7]. While still an\n  Internet-Draft, version 7 is stable and unlikely to change in any way that\n  breaks compatibility.\n  * Use `Ramsey\\Uuid\\Uuid::uuid7()` to generate version 7 UUIDs.\n  * Version 7 UUIDs are of type `Ramsey\\Uuid\\Rfc4122\\UuidV7`.\n  * The constant `Ramsey\\Uuid\\Uuid::UUID_TYPE_UNIX_TIME` exists for version\n    7 UUIDs.\n* Add `Ramsey\\Uuid\\Converter\\Time\\UnixTimeConverter` and\n  `Ramsey\\Uuid\\Generator\\UnixTimeGenerator` to support version 7 UUID generation.\n* Add support for [max UUIDs][] through `Ramsey\\Uuid\\Uuid::MAX` and\n  `Ramsey\\Uuid\\Rfc4122\\MaxUuid`.\n\n### Changed\n\n* The lowest version of brick/math allowed is now `^0.8.8`.\n\n### Deprecated\n\nThe following will be removed in ramsey/uuid 5.0.0:\n\n* `Ramsey\\Uuid\\Nonstandard\\UuidV6` is deprecated in favor of\n  `Ramsey\\Uuid\\Rfc4122\\UuidV6`.\n* `Ramsey\\Uuid\\Uuid::UUID_TYPE_PEABODY`; use\n  `Ramsey\\Uuid\\Uuid::UUID_TYPE_REORDERED_TIME` instead.\n\n### Fixed\n\n* For `Ramsey\\Uuid\\Uuid::isValid()`, Psalm now asserts the UUID is a\n  non-empty-string when it is valid.\n* Nil UUIDs are properly treated as RFC 4122 variants, and `getVariant()` now\n  returns a `2` when called on a nil UUID.\n\n\n## 4.4.0 - 2022-08-05\n\n### Changed\n\n* Allow brick/math 0.10.\n* Remove dev dependency to moontoast/math.\n* Un-deprecate `UuidInterface::getUrn()`.\n\n\n## 4.3.1 - 2022-03-27\n\n### Deprecated\n\nThe following will be removed in ramsey/uuid 5.0.0:\n\n* `Ramsey\\Uuid\\Generator\\RandomLibAdapter`\n\n\n## 4.3.0 - 2022-03-26\n\n### Changed\n\n* Remove support for PHP 7.2, 7.3, and 7.4. This is not a BC break, since\n  Composer will do the right thing for your environment and select a compatible\n  version of this library.\n* Require `ext-ctype` extension. For applications that run in environments where\n  the `ext-ctype` is not present, please require a polyfill, such as\n  [symfony/polyfill-ctype](https://packagist.org/packages/symfony/polyfill-ctype).\n* Use `iterable<UuidBuilderInterface>` instead of `BuilderCollection` types.\n* Use `iterable<NodeProviderInterface>` instead of `NodeProviderCollection` types.\n\n### Deprecated\n\nThe following will be removed in ramsey/uuid 5.0.0:\n\n* `Ramsey\\Uuid\\Builder\\BuilderCollection`\n* `Ramsey\\Uuid\\Provider\\Node\\NodeProviderCollection`\n* Dependency on ramsey/collection\n\n### Fixed\n\n* Support valid UUIDs in uppercase in `LazyUuidFromString`.\n\n\n## 4.2.3 - 2021-09-25\n\n### Fixed\n\n* Switch back to `^8.0` in the PHP version requirement.\n\n\n## 4.2.2 - 2021-09-24\n\n### Fixed\n\n* Indicate support for PHP 8.1, using `~8.1.0` to prevent installations on 8.2\n  until the library is ready.\n\n\n## 4.2.1 - 2021-08-10\n\n### Fixed\n\n* Fix *soft* BC break with `Uuid::fromString()` signature. The change from\n  `string` to `non-empty-string` on the parameter annotation introduced a\n  BC break for those using static analysis tools. This release reverts this\n  change and provides an assertion to guard against empty strings.\n  See [ramsey/uuid#383](https://github.com/ramsey/uuid/pull/383).\n\n\n## 4.2.0 - 2021-08-06\n\n### Added\n\n* Add `Ramsey\\Uuid\\Exception\\UuidExceptionInterface` for all ramsey/uuid\n  exceptions to implement. See [ramsey/uuid#340](https://github.com/ramsey/uuid/pull/340).\n\n### Fixed\n\n* Fix serialization of UUIDs.\n  See [ramsey/uuid#361](https://github.com/ramsey/uuid/pull/361).\n\n\n## 4.1.3 - 2021-09-25\n\n### Fixed\n\n* Switch back to `^8.0` in the PHP version requirement.\n\n\n## 4.1.2 - 2021-09-24\n\n### Fixed\n\n* Lock 4.1.x to `~8.0.0` to indicate it does not support PHP 8.1.\n\n\n## 4.1.1 - 2020-08-18\n\n### Fixed\n\n* Allow use of brick/math version 0.9\n\n\n## 4.1.0 - 2020-07-28\n\n### Changed\n\n* Improve performance of `Uuid::fromString()`, `Uuid::fromBytes()`,\n  `UuidInterface#toString()`, and `UuidInterface#getBytes()`. See PR\n  [#324](https://github.com/ramsey/uuid/pull/324) for more information.\n\n\n## 4.0.3 - 2021-09-25\n\n### Fixed\n\n* Switch back to `^8.0` in the PHP version requirement.\n\n\n## 4.0.2 - 2021-09-24\n\n### Fixed\n\n* Lock 4.0.x to `~8.0.0` to indicate it does not support PHP 8.1.\n\n\n## 4.0.1 - 2020-03-29\n\n### Fixed\n\n* Fix collection deserialization errors due to upstream `allowed_classes` being\n  set to `false`. For details, see [ramsey/uuid#303](https://github.com/ramsey/uuid/issues/303)\n  and [ramsey/collection#47](https://github.com/ramsey/collection/issues/47).\n\n\n## 4.0.0 - 2020-03-22\n\n### Added\n\n* Add support for version 6 UUIDs, as defined by <http://gh.peabody.io/uuidv6/>,\n  including the static method `Uuid::uuid6()`, which returns a\n  `Nonstandard\\UuidV6` instance.\n* Add ability to generate version 2 (DCE Security) UUIDs, including the static\n  method `Uuid::uuid2()`, which returns an `Rfc4122\\UuidV2` instance.\n* Add classes to represent each version of RFC 4122 UUID. When generating new\n  UUIDs or creating UUIDs from existing strings, bytes, or integers, if the UUID\n  is an RFC 4122 variant, one of these instances will be returned:\n  * `Rfc4122\\UuidV1`\n  * `Rfc4122\\UuidV2`\n  * `Rfc4122\\UuidV3`\n  * `Rfc4122\\UuidV4`\n  * `Rfc4122\\UuidV5`\n  * `Rfc4122\\NilUuid`\n* Add classes to represent version 6 UUIDs, GUIDs, and nonstandard\n  (non-RFC 4122 variant) UUIDs:\n  * `Nonstandard\\UuidV6`\n  * `Guid\\Guid`\n  * `Nonstandard\\Uuid`\n* Add `Uuid::fromDateTime()` to create version 1 UUIDs from instances of\n  `\\DateTimeInterface`.\n* The `\\DateTimeInterface` instance returned by `UuidInterface::getDateTime()`\n  (and now `Rfc4122\\UuidV1::getDateTime()`) now includes microseconds, as\n  specified by the version 1 UUID.\n* Add `Validator\\ValidatorInterface` and `Validator\\GenericValidator` to allow\n  flexibility in validating UUIDs/GUIDs.\n  * The default validator continues to validate UUID strings using the same\n    relaxed validation pattern found in the 3.x series of ramsey/uuid.\n  * Introduce `Rfc4122\\Validator` that may be used for strict validation of\n    RFC 4122 UUID strings.\n  * Add ability to change the default validator used by `Uuid` through\n    `FeatureSet::setValidator()`.\n  * Add `getValidator()` and `setValidator()` to `UuidFactory`.\n* Add `Provider\\Node\\StaticNodeProvider` to assist in setting a custom static\n  node value with the multicast bit set for version 1 UUIDs.\n* Add the following new exceptions:\n  * `Exception\\BuilderNotFoundException` -\n    Thrown to indicate that no suitable UUID builder could be found.\n  * `Exception\\DateTimeException` -\n    Thrown to indicate that the PHP DateTime extension encountered an\n    exception/error.\n  * `Exception\\DceSecurityException` -\n    Thrown to indicate an exception occurred while dealing with DCE Security\n    (version 2) UUIDs.\n  * `Exception\\InvalidArgumentException` -\n    Thrown to indicate that the argument received is not valid. This extends the\n    built-in PHP `\\InvalidArgumentException`, so there should be no BC breaks\n    with ramsey/uuid throwing this exception, if you are catching the PHP\n    exception.\n  * `Exception\\InvalidBytesException` -\n    Thrown to indicate that the bytes being operated on are invalid in some way.\n  * `Exception\\NameException` -\n    Thrown to indicate that an error occurred while attempting to hash a\n    namespace and name.\n  * `Exception\\NodeException` -\n    Throw to indicate that attempting to fetch or create a node ID encountered\n    an error.\n  * `Exception\\RandomSourceException` -\n    Thrown to indicate that the source of random data encountered an error.\n  * `Exception\\TimeSourceException` -\n    Thrown to indicate that the source of time encountered an error.\n  * `Exception\\UnableToBuildUuidException` -\n    Thrown to indicate a builder is unable to build a UUID.\n* Introduce a `Builder\\FallbackBuilder`, used by `FeatureSet` to help decide\n  whether to return a `Uuid` or `Nonstandard\\Uuid` when decoding a\n  UUID string or bytes.\n* Add `Rfc4122\\UuidInterface` to specifically represent RFC 4122 variant UUIDs.\n* Add `Rfc4122\\UuidBuilder` to build RFC 4122 variant UUIDs. This replaces the\n  existing `Builder\\DefaultUuidBuilder`, which is now deprecated.\n* Introduce `Math\\CalculatorInterface` for representing calculators to perform\n  arithmetic operations on integers.\n* Depend on [brick/math](https://github.com/brick/math) for the\n  `Math\\BrickMathCalculator`, which is the default calculator used by this\n  library when math cannot be performed in native PHP due to integer size\n  limitations. The calculator is configurable and may be changed, if desired.\n* Add `Converter\\Number\\GenericNumberConverter` and\n  `Converter\\Time\\GenericTimeConverter` which will use the calculator provided\n  to convert numbers and time to values for UUIDs.\n* Introduce `Type\\Hexadecimal`, `Type\\Integer`, `Type\\Decimal`, and `Type\\Time`\n  for improved type-safety when dealing with arbitrary string values.\n* Add a `Type\\TypeInterface` that each of the ramsey/uuid types implements.\n* Add `Fields\\FieldsInterface` and `Rfc4122\\FieldsInterface` to define\n  field layouts for UUID variants. The implementations `Rfc4122\\Fields`,\n  `Guid\\Fields`, and `Nonstandard\\Fields` store the 16-byte,\n  binary string representation of the UUID internally, and these manage\n  conversion of the binary string into the hexadecimal field values.\n* Introduce `Builder\\BuilderCollection` and `Provider\\Node\\NodeProviderCollection`.\n  These are typed collections for providing builders and node providers to\n  `Builder\\FallbackBuilder` and `Provider\\Node\\FallbackNodeProvider`, respectively.\n* Add `Generator\\NameGeneratorInterface` to support alternate methods of\n  generating bytes for version 3 and version 5 name-based UUID. By default,\n  ramsey/uuid uses the `Generator\\DefaultNameGenerator`, which uses the standard\n  algorithm this library has used since the beginning. You may choose to use the\n  new `Generator\\PeclUuidNameGenerator` to make use of the new\n  `uuid_generate_md5()` and `uuid_generate_sha1()` functions in\n  [ext-uuid version 1.1.0](https://pecl.php.net/package/uuid).\n\n### Changed\n\n* Set minimum required PHP version to 7.2.\n* This library now works on 32-bit and 64-bit systems, with no degradation in\n  functionality.\n* By default, the following static methods will now return specific instance\n  types. This should not cause any BC breaks if typehints target `UuidInterface`:\n  * `Uuid::uuid1` returns `Rfc4122\\UuidV1`\n  * `Uuid::uuid3` returns `Rfc4122\\UuidV3`\n  * `Uuid::uuid4` returns `Rfc4122\\UuidV4`\n  * `Uuid::uuid5` returns `Rfc4122\\UuidV5`\n* Accept `Type\\Hexadecimal` for the `$node` parameter for\n  `UuidFactoryInterface::uuid1()`. This is in addition to the `int|string` types\n  already accepted, so there are no BC breaks. `Type\\Hexadecimal` is now the\n  recommended type to pass for `$node`.\n* Out of the box, `Uuid::fromString()`, `Uuid::fromBytes()`, and\n  `Uuid::fromInteger()` will now return either an `Rfc4122\\UuidInterface`\n  instance or an instance of `Nonstandard\\Uuid`, depending on whether the input\n  contains an RFC 4122 variant UUID with a valid version identifier. Both\n  implement `UuidInterface`, so BC breaks should not occur if typehints use the\n  interface.\n* Change `Uuid::getFields()` to return an instance of `Fields\\FieldsInterface`.\n  Previously, it returned an array of integer values (on 64-bit systems only).\n* `Uuid::getDateTime()` now returns an instance of `\\DateTimeImmutable` instead\n  of `\\DateTime`.\n* Make the following changes to `UuidInterface`:\n  * `getHex()` now returns a `Type\\Hexadecimal` instance.\n  * `getInteger()` now returns a `Type\\Integer` instance. The `Type\\Integer`\n    instance holds a string representation of a 128-bit integer. You may then\n    use a math library of your choice (bcmath, gmp, etc.) to operate on the\n    string integer.\n  * `getDateTime()` now returns `\\DateTimeInterface` instead of `\\DateTime`.\n  * Add `__toString()` method.\n  * Add `getFields()` method. It returns an instance of `Fields\\FieldsInterface`.\n* Add the following new methods to `UuidFactoryInterface`:\n  * `uuid2()`\n  * `uuid6()`\n  * `fromDateTime()`\n  * `fromInteger()`\n  * `getValidator()`\n* This library no longer throws generic exceptions. However, this should not\n  result in BC breaks, since the new exceptions extend from built-in PHP\n  exceptions that this library previously threw.\n  * `Exception\\UnsupportedOperationException` is now descended from\n    `\\LogicException`. Previously, it descended from `\\RuntimeException`.\n* Change required constructor parameters for `Uuid`:\n  * Change the first required constructor parameter for `Uuid` from\n    `array $fields` to `Rfc4122\\FieldsInterface $fields`.\n  * Add `Converter\\TimeConverterInterface $timeConverter` as the fourth\n    required constructor parameter for `Uuid`.\n* Change the second required parameter of `Builder\\UuidBuilderInterface::build()`\n  from `array $fields` to `string $bytes`. Rather than accepting an array of\n  hexadecimal strings as UUID fields, the `build()` method now expects a byte\n  string.\n* Add `Converter\\TimeConverterInterface $timeConverter` as the second required\n  constructor parameter for `Rfc4122\\UuidBuilder`. This also affects the\n  now-deprecated `Builder\\DefaultUuidBuilder`, since this class now inherits\n  from `Rfc4122\\UuidBuilder`.\n* Add `convertTime()` method to `Converter\\TimeConverterInterface`.\n* Add `getTime()` method to `Provider\\TimeProviderInterface`. It replaces the\n  `currentTime()` method.\n* `Provider\\Node\\FallbackNodeProvider` now accepts only a\n  `Provider\\Node\\NodeProviderCollection` as its constructor parameter.\n* `Provider\\Time\\FixedTimeProvider` no longer accepts an array but accepts only\n  `Type\\Time` instances.\n* `Provider\\NodeProviderInterface::getNode()` now returns `Type\\Hexadecimal`\n  instead of `string|false|null`.\n* `Converter/TimeConverterInterface::calculateTime()` now returns\n  `Type\\Hexadecimal` instead of `array`. The value is the full UUID timestamp\n  value (count of 100-nanosecond intervals since the Gregorian calendar epoch)\n  in hexadecimal format.\n* Change methods in `NumberConverterInterface` to accept and return string values\n  instead of `mixed`; this simplifies the interface and makes it consistent.\n* `Generator\\DefaultTimeGenerator` no longer adds the variant and version bits\n  to the bytes it returns. These must be applied to the bytes afterwards.\n* When encoding to bytes or decoding from bytes, `OrderedTimeCodec` now checks\n  whether the UUID is an RFC 4122 variant, version 1 UUID. If not, it will throw\n  an exception—`InvalidArgumentException` when using\n  `OrderedTimeCodec::encodeBinary()` and `UnsupportedOperationException` when\n  using `OrderedTimeCodec::decodeBytes()`.\n\n### Deprecated\n\nThe following functionality is deprecated and will be removed in ramsey/uuid\n5.0.0.\n\n* The following methods from `UuidInterface` and `Uuid` are deprecated. Use their\n  counterparts on the `Rfc4122\\FieldsInterface` returned by `Uuid::getFields()`.\n  * `getClockSeqHiAndReservedHex()`\n  * `getClockSeqLowHex()`\n  * `getClockSequenceHex()`\n  * `getFieldsHex()`\n  * `getNodeHex()`\n  * `getTimeHiAndVersionHex()`\n  * `getTimeLowHex()`\n  * `getTimeMidHex()`\n  * `getTimestampHex()`\n  * `getVariant()`\n  * `getVersion()`\n* The following methods from `Uuid` are deprecated. Use the `Rfc4122\\FieldsInterface`\n  instance returned by `Uuid::getFields()` to get the `Type\\Hexadecimal` value\n  for these fields. You may use the new `Math\\CalculatorInterface::toIntegerValue()`\n  method to convert the `Type\\Hexadecimal` instances to instances of\n  `Type\\Integer`. This library provides `Math\\BrickMathCalculator`, which may be\n  used for this purpose, or you may use the arbitrary-precision arithmetic\n  library of your choice.\n  * `getClockSeqHiAndReserved()`\n  * `getClockSeqLow()`\n  * `getClockSequence()`\n  * `getNode()`\n  * `getTimeHiAndVersion()`\n  * `getTimeLow()`\n  * `getTimeMid()`\n  * `getTimestamp()`\n* `getDateTime()` on `UuidInterface` and `Uuid` is deprecated. Use this method\n  only on instances of `Rfc4122\\UuidV1` or `Nonstandard\\UuidV6`.\n* `getUrn()` on `UuidInterface` and `Uuid` is deprecated. It is available on\n  `Rfc4122\\UuidInterface` and classes that implement it.\n* The following methods are deprecated and have no direct replacements. However,\n  you may obtain the same information by calling `UuidInterface::getHex()` and\n  splitting the return value in half.\n  * `UuidInterface::getLeastSignificantBitsHex()`\n  * `UuidInterface::getMostSignificantBitsHex()`\n  * `Uuid::getLeastSignificantBitsHex()`\n  * `Uuid::getMostSignificantBitsHex()`\n  * `Uuid::getLeastSignificantBits()`\n  * `Uuid::getMostSignificantBits()`\n* `UuidInterface::getNumberConverter()` and `Uuid::getNumberConverter()` are\n  deprecated. There is no alternative recommendation, so plan accordingly.\n* `Builder\\DefaultUuidBuilder` is deprecated; transition to `Rfc4122\\UuidBuilder`.\n* `Converter\\Number\\BigNumberConverter` is deprecated; transition to\n  `Converter\\Number\\GenericNumberConverter`.\n* `Converter\\Time\\BigNumberTimeConverter` is deprecated; transition to\n  `Converter\\Time\\GenericTimeConverter`.\n* The classes for representing and generating *degraded* UUIDs are deprecated.\n  These are no longer necessary; this library now behaves the same on 32-bit and\n  64-bit systems.\n  * `Builder\\DegradedUuidBuilder`\n  * `Converter\\Number\\DegradedNumberConverter`\n  * `Converter\\Time\\DegradedTimeConverter`\n  * `DegradedUuid`\n* The `Uuid::UUID_TYPE_IDENTIFIER` constant is deprecated. Use\n  `Uuid::UUID_TYPE_DCE_SECURITY` instead.\n* The `Uuid::VALID_PATTERN` constant is deprecated. Use\n  `Validator\\GenericValidator::getPattern()` or `Rfc4122\\Validator::getPattern()`\n  instead.\n\n### Removed\n\n* Remove the following bytes generators and recommend\n  `Generator\\RandomBytesGenerator` as a suitable replacement:\n  * `Generator\\MtRandGenerator`\n  * `Generator\\OpenSslGenerator`\n  * `Generator\\SodiumRandomGenerator`\n* Remove `Exception\\UnsatisfiedDependencyException`. This library no longer\n  throws this exception.\n* Remove the method `Provider\\TimeProviderInterface::currentTime()`. Use\n  `Provider\\TimeProviderInterface::getTime()` instead.\n\n\n## 4.0.0-beta2 - 2020-03-01\n\n## Added\n\n* Add missing convenience methods for `Rfc4122\\UuidV2`.\n* Add `Provider\\Node\\StaticNodeProvider` to assist in setting a custom static\n  node value with the multicast bit set for version 1 UUIDs.\n\n## Changed\n\n* `Provider\\NodeProviderInterface::getNode()` now returns `Type\\Hexadecimal`\n  instead of `string|false|null`.\n\n\n## 4.0.0-beta1 - 2020-02-27\n\n### Added\n\n* Add `ValidatorInterface::getPattern()` to return the regular expression\n  pattern used by the validator.\n* Add `v6()` helper function for version 6 UUIDs.\n\n### Changed\n\n* Set the pattern constants on validators as `private`. Use the `getPattern()`\n  method instead.\n* Change the `$node` parameter for `UuidFactoryInterface::uuid6()` to accept\n  `null` or `Type\\Hexadecimal`.\n* Accept `Type\\Hexadecimal` for the `$node` parameter for\n  `UuidFactoryInterface::uuid1()`. This is in addition to the `int|string` types\n  already accepted, so there are no BC breaks. `Type\\Hexadecimal` is now the\n  recommended type to pass for `$node`.\n\n### Removed\n\n* Remove `currentTime()` method from `Provider\\Time\\FixedTimeProvider` and\n  `Provider\\Time\\SystemTimeProvider`; it had previously been removed from\n  `Provider\\TimeProviderInterface`.\n\n\n## 4.0.0-alpha5 - 2020-02-23\n\n### Added\n\n* Introduce `Builder\\BuilderCollection` and `Provider\\Node\\NodeProviderCollection`.\n\n### Changed\n\n* `Builder\\FallbackBuilder` now accepts only a `Builder\\BuilderCollection` as\n  its constructor parameter.\n* `Provider\\Node\\FallbackNodeProvider` now accepts only a `Provider\\Node\\NodeProviderCollection`\n  as its constructor parameter.\n* `Provider\\Time\\FixedTimeProvider` no longer accepts an array but accepts only\n  `Type\\Time` instances.\n\n\n## 4.0.0-alpha4 - 2020-02-23\n\n### Added\n\n* Add a `Type\\TypeInterface` that each of the ramsey/uuid types implements.\n* Support version 6 UUIDs; see <http://gh.peabody.io/uuidv6/>.\n\n### Changed\n\n* Rename `Type\\IntegerValue` to `Type\\Integer`. It was originally named\n  `IntegerValue` because static analysis sees `Integer` in docblock annotations\n  and treats it as the native `int` type. `Integer` is not a reserved word in\n  PHP, so it should be named `Integer` for consistency with other types in this\n  library. When using it, a class alias prevents static analysis from\n  complaining.\n* Mark `Guid\\Guid` and `Nonstandard\\Uuid` classes as `final`.\n* Add `uuid6()` method to `UuidFactoryInterface`.\n\n### Deprecated\n\n* `Uuid::UUID_TYPE_IDENTIFIER` is deprecated. Use `Uuid::UUID_TYPE_DCE_SECURITY`\n  instead.\n* `Uuid::VALID_PATTERN` is deprecated. Use `Validator\\GenericValidator::VALID_PATTERN`\n  instead.\n\n\n## 4.0.0-alpha3 - 2020-02-21\n\n### Fixed\n\n* Fix microsecond rounding error on 32-bit systems.\n\n\n## 4.0.0-alpha2 - 2020-02-21\n\n### Added\n\n* Add `Uuid::fromDateTime()` to create version 1 UUIDs from instances of\n  `\\DateTimeInterface`.\n* Add `Generator\\NameGeneratorInterface` to support alternate methods of\n  generating bytes for version 3 and version 5 name-based UUID. By default,\n  ramsey/uuid uses the `Generator\\DefaultNameGenerator`, which uses the standard\n  algorithm this library has used since the beginning. You may choose to use the\n  new `Generator\\PeclUuidNameGenerator` to make use of the new\n  `uuid_generate_md5()` and `uuid_generate_sha1()` functions in ext-uuid version\n  1.1.0.\n\n### Changed\n\n* Add `fromDateTime()` method to `UuidFactoryInterface`.\n* Change `UuidInterface::getHex()` to return a `Ramsey\\Uuid\\Type\\Hexadecimal` instance.\n* Change `UuidInterface::getInteger()` to return a `Ramsey\\Uuid\\Type\\IntegerValue` instance.\n\n### Fixed\n\n* Round microseconds to six digits when getting DateTime from v1 UUIDs. This\n  circumvents a needless exception for an otherwise valid time-based UUID.\n\n\n## 4.0.0-alpha1 - 2020-01-22\n\n### Added\n\n* Add `Validator\\ValidatorInterface` and `Validator\\GenericValidator` to allow\n  flexibility in validating UUIDs/GUIDs.\n  * Add ability to change the default validator used by `Uuid` through\n    `FeatureSet::setValidator()`.\n  * Add `getValidator()` and `setValidator()` to `UuidFactory`.\n* Add an internal `InvalidArgumentException` that descends from the built-in\n  PHP `\\InvalidArgumentException`. All places that used to throw\n  `\\InvalidArgumentException` now throw `Ramsey\\Uuid\\Exception\\InvalidArgumentException`.\n  This should not cause any BC breaks, however.\n* Add an internal `DateTimeException` that descends from the built-in PHP\n  `\\RuntimeException`. `Uuid::getDateTime()` may throw this exception if\n  `\\DateTimeImmutable` throws an error or exception.\n* Add `RandomSourceException` that descends from the built-in PHP\n  `\\RuntimeException`. `DefaultTimeGenerator`, `RandomBytesGenerator`, and\n  `RandomNodeProvider` may throw this exception if `random_bytes()` or\n  `random_int()` throw an error or exception.\n* Add `Fields\\FieldsInterface` and `Rfc4122\\FieldsInterface` to define\n  field layouts for UUID variants. The implementations `Rfc4122\\Fields`,\n  `Guid\\Fields`, and `Nonstandard\\Fields` store the 16-byte,\n  binary string representation of the UUID internally, and these manage\n  conversion of the binary string into the hexadecimal field values.\n* Add `Rfc4122\\UuidInterface` to specifically represent RFC 4122 variant UUIDs.\n* Add classes to represent each version of RFC 4122 UUID. When generating new\n  UUIDs or creating UUIDs from existing strings, bytes, or integers, if the UUID\n  is an RFC 4122 variant, one of these instances will be returned:\n  * `Rfc4122\\UuidV1`\n  * `Rfc4122\\UuidV2`\n  * `Rfc4122\\UuidV3`\n  * `Rfc4122\\UuidV4`\n  * `Rfc4122\\UuidV5`\n  * `Rfc4122\\NilUuid`\n* Add `Rfc4122\\UuidBuilder` to build RFC 4122 variant UUIDs. This replaces the\n  existing `Builder\\DefaultUuidBuilder`, which is now deprecated.\n* Add ability to generate version 2 (DCE Security) UUIDs, including the static\n  method `Uuid::uuid2()`, which returns an `Rfc4122\\UuidV2` instance.\n* Add classes to represent GUIDs and nonstandard (non-RFC 4122 variant) UUIDs:\n  * `Guid\\Guid`\n  * `Nonstandard\\Uuid`.\n* Introduce a `Builder\\FallbackBuilder`, used by `FeatureSet` to help decide\n  whether to return a `Uuid` or `Nonstandard\\Uuid` when decoding a\n  UUID string or bytes.\n* Introduce `Type\\Hexadecimal`, `Type\\IntegerValue`, and `Type\\Time` for\n  improved type-safety when dealing with arbitrary string values.\n* Introduce `Math\\CalculatorInterface` for representing calculators to perform\n  arithmetic operations on integers.\n* Depend on [brick/math](https://github.com/brick/math) for the\n  `Math\\BrickMathCalculator`, which is the default calculator used by this\n  library when math cannot be performed in native PHP due to integer size\n  limitations. The calculator is configurable and may be changed, if desired.\n* Add `Converter\\Number\\GenericNumberConverter` and\n  `Converter\\Time\\GenericTimeConverter` which will use the calculator provided\n  to convert numbers and time to values for UUIDs.\n* The `\\DateTimeInterface` instance returned by `UuidInterface::getDateTime()`\n  (and now `Rfc4122\\UuidV1::getDateTime()`) now includes microseconds, as\n  specified by the version 1 UUID.\n\n### Changed\n\n* Set minimum required PHP version to 7.2.\n* Add `__toString()` method to `UuidInterface`.\n* The `UuidInterface::getDateTime()` method now specifies `\\DateTimeInterface`\n  as the return value, rather than `\\DateTime`; `Uuid::getDateTime()` now\n  returns an instance of `\\DateTimeImmutable` instead of `\\DateTime`.\n* Add `getFields()` method to `UuidInterface`.\n* Add `getValidator()` method to `UuidFactoryInterface`.\n* Add `uuid2()` method to `UuidFactoryInterface`.\n* Add `convertTime()` method to `Converter\\TimeConverterInterface`.\n* Add `getTime()` method to `Provider\\TimeProviderInterface`.\n* Change `Uuid::getFields()` to return an instance of `Fields\\FieldsInterface`.\n  Previously, it returned an array of integer values (on 64-bit systems only).\n* Change the first required constructor parameter for `Uuid` from\n  `array $fields` to `Rfc4122\\FieldsInterface $fields`.\n* Introduce `Converter\\TimeConverterInterface $timeConverter` as fourth required\n  constructor parameter for `Uuid` and second required constructor parameter for\n  `Builder\\DefaultUuidBuilder`.\n* Change `UuidInterface::getInteger()` to always return a `string` value instead\n  of `mixed`. This is a string representation of a 128-bit integer. You may then\n  use a math library of your choice (bcmath, gmp, etc.) to operate on the\n  string integer.\n* Change the second required parameter of `Builder\\UuidBuilderInterface::build()`\n  from `array $fields` to `string $bytes`. Rather than accepting an array of\n  hexadecimal strings as UUID fields, the `build()` method now expects a byte\n  string.\n* `Generator\\DefaultTimeGenerator` no longer adds the variant and version bits\n  to the bytes it returns. These must be applied to the bytes afterwards.\n* `Converter/TimeConverterInterface::calculateTime()` now returns\n  `Type\\Hexadecimal` instead of `array`. The value is the full UUID timestamp\n  value (count of 100-nanosecond intervals since the Gregorian calendar epoch)\n  in hexadecimal format.\n* Change methods in converter interfaces to accept and return string values\n  instead of `mixed`; this simplifies the interface and makes it consistent:\n  * `NumberConverterInterface::fromHex(string $hex): string`\n  * `NumberConverterInterface::toHex(string $number): string`\n  * `TimeConverterInterface::calculateTime(string $seconds, string $microseconds): array`\n* `UnsupportedOperationException` is now descended from `\\LogicException`.\n  Previously, it descended from `\\RuntimeException`.\n* When encoding to bytes or decoding from bytes, `OrderedTimeCodec` now checks\n  whether the UUID is an RFC 4122 variant, version 1 UUID. If not, it will throw\n  an exception—`InvalidArgumentException` when using\n  `OrderedTimeCodec::encodeBinary()` and `UnsupportedOperationException` when\n  using `OrderedTimeCodec::decodeBytes()`.\n* Out of the box, `Uuid::fromString()`, `Uuid::fromBytes()`, and\n  `Uuid::fromInteger()` will now return either an `Rfc4122\\UuidInterface`\n  instance or an instance of `Nonstandard\\Uuid`, depending on whether the input\n  contains an RFC 4122 variant UUID with a valid version identifier. Both\n  implement `UuidInterface`, so BC breaks should not occur if typehints use the\n  interface.\n* By default, the following static methods will now return the specific instance\n  types. This should not cause any BC breaks if typehints target `UuidInterface`:\n  * `Uuid::uuid1` returns `Rfc4122\\UuidV1`\n  * `Uuid::uuid3` returns `Rfc4122\\UuidV3`\n  * `Uuid::uuid4` returns `Rfc4122\\UuidV4`\n  * `Uuid::uuid5` returns `Rfc4122\\UuidV5`\n\n### Deprecated\n\nThe following functionality is deprecated and will be removed in ramsey/uuid\n5.0.0.\n\n* The following methods from `UuidInterface` and `Uuid` are deprecated. Use their\n  counterparts on the `Rfc4122\\FieldsInterface` returned by `Uuid::getFields()`.\n  * `getClockSeqHiAndReservedHex()`\n  * `getClockSeqLowHex()`\n  * `getClockSequenceHex()`\n  * `getFieldsHex()`\n  * `getNodeHex()`\n  * `getTimeHiAndVersionHex()`\n  * `getTimeLowHex()`\n  * `getTimeMidHex()`\n  * `getTimestampHex()`\n  * `getVariant()`\n  * `getVersion()`\n* The following methods from `Uuid` are deprecated. Use the `Rfc4122\\FieldsInterface`\n  instance returned by `Uuid::getFields()` to get the `Type\\Hexadecimal` value\n  for these fields, and then use the arbitrary-precision arithmetic library of\n  your choice to convert them to string integers.\n  * `getClockSeqHiAndReserved()`\n  * `getClockSeqLow()`\n  * `getClockSequence()`\n  * `getNode()`\n  * `getTimeHiAndVersion()`\n  * `getTimeLow()`\n  * `getTimeMid()`\n  * `getTimestamp()`\n* `getDateTime()` on `UuidInterface` and `Uuid` is deprecated. Use this method\n  only on instances of `Rfc4122\\UuidV1`.\n* `getUrn()` on `UuidInterface` and `Uuid` is deprecated. It is available on\n  `Rfc4122\\UuidInterface` and classes that implement it.\n* The following methods are deprecated and have no direct replacements. However,\n  you may obtain the same information by calling `UuidInterface::getHex()` and\n  splitting the return value in half.\n  * `UuidInterface::getLeastSignificantBitsHex()`\n  * `UuidInterface::getMostSignificantBitsHex()`\n  * `Uuid::getLeastSignificantBitsHex()`\n  * `Uuid::getMostSignificantBitsHex()`\n  * `Uuid::getLeastSignificantBits()`\n  * `Uuid::getMostSignificantBits()`\n* `UuidInterface::getNumberConverter()` and `Uuid::getNumberConverter()` are\n  deprecated. There is no alternative recommendation, so plan accordingly.\n* `Builder\\DefaultUuidBuilder` is deprecated; transition to\n  `Rfc4122\\UuidBuilder`.\n* `Converter\\Number\\BigNumberConverter` is deprecated; transition to\n  `Converter\\Number\\GenericNumberConverter`.\n* `Converter\\Time\\BigNumberTimeConverter` is deprecated; transition to\n  `Converter\\Time\\GenericTimeConverter`.\n* `Provider\\TimeProviderInterface::currentTime()` is deprecated; transition to\n  the `getTimestamp()` method on the same interface.\n* The classes for representing and generating *degraded* UUIDs are deprecated.\n  These are no longer necessary; this library now behaves the same on 32-bit and\n  64-bit PHP.\n  * `Builder\\DegradedUuidBuilder`\n  * `Converter\\Number\\DegradedNumberConverter`\n  * `Converter\\Time\\DegradedTimeConverter`\n  * `DegradedUuid`\n\n### Removed\n\n* Remove the following bytes generators and recommend\n  `Generator\\RandomBytesGenerator` as a suitable replacement:\n  * `Generator\\MtRandGenerator`\n  * `Generator\\OpenSslGenerator`\n  * `Generator\\SodiumRandomGenerator`\n* Remove `Exception\\UnsatisfiedDependencyException`. This library no longer\n  throws this exception.\n\n\n## 3.9.7 - 2022-12-19\n\n### Fixed\n\n* Add `#[ReturnTypeWillChange]` to `Uuid::jsonSerialize()` method.\n\n\n## 3.9.6 - 2021-09-25\n\n### Fixed\n\n* Switch back to `^8.0` in the PHP version requirement.\n\n\n## 3.9.5 - 2021-09-24\n\n### Fixed\n\n* Indicate support for PHP 8.1, using `~8.1.0` to prevent installations on 8.2\n  until the library is ready.\n\n\n## 3.9.4 - 2021-08-06\n\n### Fixed\n\n* Allow installation of paragonie/random_compat v9.99.100 (for PHP 8 compatibility).\n\n\n## 3.9.3 - 2020-02-20\n\n### Fixed\n\n* For v1 UUIDs, round down for timestamps so that microseconds do not bump the\n  timestamp to the next second.\n\n  As an example, consider the case of timestamp `1` with  `600000` microseconds\n  (`1.600000`). This is the first second after midnight on January 1, 1970, UTC.\n  Previous versions of this library had a bug that would round this to `2`, so\n  the rendered time was `1970-01-01 00:00:02`. This was incorrect. Despite\n  having `600000` microseconds, the time should not round up to the next second.\n  Rather, the time should be `1970-01-01 00:00:01.600000`. Since this version of\n  ramsey/uuid does not support microseconds, the microseconds are dropped, and\n  the time is `1970-01-01 00:00:01`. No rounding should occur.\n\n\n## 3.9.2 - 2019-12-17\n\n### Fixed\n\n* Check whether files returned by `/sys/class/net/*/address` are readable\n  before attempting to read them. This avoids a PHP warning that was being\n  emitted on hosts that do not grant permission to read these files.\n\n\n## 3.9.1 - 2019-12-01\n\n### Fixed\n\n* Fix `RandomNodeProvider` behavior on 32-bit systems. The `RandomNodeProvider`\n  was converting a 6-byte string to a decimal number, which is a 48-bit,\n  unsigned integer. This caused problems on 32-bit systems and has now been\n  resolved.\n\n\n## 3.9.0 - 2019-11-30\n\n### Added\n\n* Add function API as convenience. The functions are available in the\n  `Ramsey\\Uuid` namespace.\n  * `v1(int|string|null $node = null, int|null $clockSeq = null): string`\n  * `v3(string|UuidInterface $ns, string $name): string`\n  * `v4(): string`\n  * `v5(string|UuidInterface $ns, string $name): string`\n\n### Changed\n\n* Use paragonie/random-lib instead of ircmaxell/random-lib. This is a\n  non-breaking change.\n* Use a high-strength generator by default, when using `RandomLibAdapter`. This\n  is a non-breaking change.\n\n### Deprecated\n\nThese will be removed in ramsey/uuid version 4.0.0:\n\n* `MtRandGenerator`, `OpenSslGenerator`, and `SodiumRandomGenerator` are\n  deprecated in favor of using the default `RandomBytesGenerator`.\n\n### Fixed\n\n* Set `ext-json` as a required dependency in `composer.json`.\n* Use `PHP_OS` instead of `php_uname()` when determining the system OS, for\n  cases when `php_uname()` is disabled for security reasons.\n\n\n## 3.8.0 - 2018-07-19\n\n### Added\n\n* Support discovery of MAC addresses on FreeBSD systems\n* Use a polyfill to provide PHP ctype functions when running on systems where the\n  ctype functions are not part of the PHP build\n* Disallow a trailing newline character when validating UUIDs\n* Annotate thrown exceptions for improved IDE hinting\n\n\n## 3.7.3 - 2018-01-19\n\n### Fixed\n\n* Gracefully handle cases where `glob()` returns false when searching\n  `/sys/class/net/*/address` files on Linux\n* Fix off-by-one error in `DefaultTimeGenerator`\n\n### Security\n\n* Switch to `random_int()` from `mt_rand()` for better random numbers\n\n\n## 3.7.2 - 2018-01-13\n\n### Fixed\n\n* Check sysfs on Linux to determine the node identifier; this provides a\n  reliable way to identify the node on Docker images, etc.\n\n\n## 3.7.1 - 2017-09-22\n\n### Fixed\n\n* Set the multicast bit for random nodes, according to RFC 4122, §4.5\n\n### Security\n\n* Use `random_bytes()` when generating random nodes\n\n\n## 3.7.0 - 2017-08-04\n\n### Added\n\n* Add the following UUID version constants:\n    * `Uuid::UUID_TYPE_TIME`\n    * `Uuid::UUID_TYPE_IDENTIFIER`\n    * `Uuid::UUID_TYPE_HASH_MD5`\n    * `Uuid::UUID_TYPE_RANDOM`\n    * `Uuid::UUID_TYPE_HASH_SHA1`\n\n\n## 3.6.1 - 2017-03-26\n\n### Fixed\n\n* Optimize UUID string decoding by using `str_pad()` instead of `sprintf()`\n\n\n## 3.6.0 - 2017-03-18\n\n### Added\n\n* Add `InvalidUuidStringException`, which is thrown when attempting to decode an\n  invalid string UUID; this does not introduce any BC issues, since the new\n  exception inherits from the previously used `InvalidArgumentException`\n\n### Fixed\n\n* Improve memory usage when generating large quantities of UUIDs (use `str_pad()`\n  and `dechex()` instead of `sprintf()`)\n\n\n## 3.5.2 - 2016-11-22\n\n### Fixed\n\n* Improve test coverage\n\n\n## 3.5.1 - 2016-10-02\n\n### Fixed\n\n* Fix issue where the same UUIDs were not being treated as equal when using\n  mixed cases\n\n\n## 3.5.0 - 2016-08-02\n\n### Added\n\n* Add `OrderedTimeCodec` to store UUID in an optimized way for InnoDB\n\n### Fixed\n\n* Fix invalid node generation in `RandomNodeProvider`\n* Avoid multiple unnecessary system calls by caching failed attempt to retrieve\n  system node\n\n\n## 3.4.1 - 2016-04-23\n\n### Fixed\n\n* Fix test that violated a PHP CodeSniffer rule, breaking the build\n\n\n## 3.4.0 - 2016-04-23\n\n### Added\n\n* Add `TimestampFirstCombCodec` and `TimestampLastCombCodec` codecs to provide\n  the ability to generate [COMB sequential UUIDs] with the timestamp encoded as\n  either the first 48 bits or the last 48 bits\n* Improve logic of `CombGenerator` for COMB sequential UUIDs\n\n\n## 3.3.0 - 2016-03-22\n\n### Security\n\n* Drop the use of OpenSSL as a fallback and use [paragonie/random_compat] to\n  support `RandomBytesGenerator` in versions of PHP earlier than 7.0;\n  this addresses and fixes the [collision issue]\n\n\n## 3.2.0 - 2016-02-17\n\n### Added\n\n* Add `SodiumRandomGenerator` to allow use of the [PECL libsodium extension] as\n  a random bytes generator when creating UUIDs\n\n\n## 3.1.0 - 2015-12-17\n\n### Added\n\n* Implement the PHP `Serializable` interface to provide the ability to\n  serialize/unserialize UUID objects\n\n\n## 3.0.1 - 2015-10-21\n\n### Added\n\n* Adopt the [Contributor Code of Conduct] for this project\n\n\n## 3.0.0 - 2015-09-28\n\nThe 3.0.0 release represents a significant step for the ramsey/uuid library.\nWhile the simple and familiar API used in previous versions remains intact, this\nrelease provides greater flexibility to integrators, including the ability to\ninject your own number generators, UUID codecs, node and time providers, and\nmore.\n\n*Please note: The changelog for 3.0.0 includes all notes from the alpha and beta\nversions leading up to this release.*\n\n### Added\n\n* Add a number of generators that may be used to override the library defaults\n  for generating random bytes (version 4) or time-based (version 1) UUIDs\n  * `CombGenerator` to allow generation of sequential UUIDs\n  * `OpenSslGenerator` to generate random bytes on systems where\n    `openssql_random_pseudo_bytes()` is present\n  * `MtRandGenerator` to provide a fallback in the event other random generators\n    are not present\n  * `RandomLibAdapter` to allow use of [ircmaxell/random-lib]\n  * `RandomBytesGenerator` for use with PHP 7; ramsey/uuid will default to use\n    this generator when running on PHP 7\n  * Refactor time-based (version 1) UUIDs into a `TimeGeneratorInterface` to\n    allow for other sources to generate version 1 UUIDs in this library\n  * `PeclUuidTimeGenerator` and `PeclUuidRandomGenerator` for creating version\n    1 or version 4 UUIDs using the pecl-uuid extension\n* Add a `setTimeGenerator` method on `UuidFactory` to override the default time\n  generator\n* Add option to enable `PeclUuidTimeGenerator` via `FeatureSet`\n* Support GUID generation by configuring a `FeatureSet` to use GUIDs\n* Allow UUIDs to be serialized as JSON through `JsonSerializable`\n\n### Changed\n\n* Change root namespace from \"Rhumsaa\" to \"Ramsey;\" in most cases, simply\n  making this change in your applications is the only upgrade path you will\n  need—everything else should work as expected\n* No longer consider `Uuid` class as `final`; everything is now based around\n  interfaces and factories, allowing you to use this package as a base to\n  implement other kinds of UUIDs with different dependencies\n* Return an object of type `DegradedUuid` on 32-bit systems to indicate that\n  certain features are not available\n* Default `RandomLibAdapter` to a medium-strength generator with\n  [ircmaxell/random-lib]; this is configurable, so other generator strengths may\n  be used\n\n### Removed\n\n* Remove `PeclUuidFactory` in favor of using pecl-uuid with generators\n* Remove `timeConverter` and `timeProvider` properties, setters, and getters in\n  both `FeatureSet` and `UuidFactory` as those are now exclusively used by the\n  default `TimeGenerator`\n* Move UUID [Doctrine field type] to [ramsey/uuid-doctrine]\n* Move `uuid` console application to [ramsey/uuid-console]\n* Remove `Uuid::VERSION` package version constant\n\n### Fixed\n\n* Improve GUID support to ensure that:\n  * On little endian (LE) architectures, the byte order of the first three\n    fields is LE\n  * On big endian (BE) architectures, it is the same as a GUID\n  * String representation is always the same\n* Fix exception message for `DegradedNumberConverter::fromHex()`\n\n\n## 3.0.0-beta1 - 2015-08-31\n\n### Fixed\n\n* Improve GUID support to ensure that:\n  * On little endian (LE) architectures, the byte order of the first three\n    fields is LE\n  * On big endian (BE) architectures, it is the same as a GUID\n  * String representation is always the same\n* Fix exception message for `DegradedNumberConverter::fromHex()`\n\n\n## 3.0.0-alpha3 - 2015-07-28\n\n### Added\n\n* Enable use of custom `TimeGenerator` implementations\n* Add a `setTimeGenerator` method on `UuidFactory` to override the default time\n  generator\n* Add option to enable `PeclUuidTimeGenerator` via `FeatureSet`\n\n### Removed\n\n* Remove `timeConverter` and `timeProvider` properties, setters, and getters in\n  both `FeatureSet` and `UuidFactory` as those are now exclusively used by the\n  default `TimeGenerator`\n\n\n## 3.0.0-alpha2 - 2015-07-28\n\n### Added\n\n* Refactor time-based (version 1) UUIDs into a `TimeGeneratorInterface` to allow\n  for other sources to generate version 1 UUIDs in this library\n* Add `PeclUuidTimeGenerator` and `PeclUuidRandomGenerator` for creating version\n  1 or version 4 UUIDs using the pecl-uuid extension\n* Add `RandomBytesGenerator` for use with PHP 7. ramsey/uuid will default to use\n  this generator when running on PHP 7\n\n### Changed\n\n* Default `RandomLibAdapter` to a medium-strength generator with\n  [ircmaxell/random-lib]; this is configurable, so other generator strengths may\n  be used\n\n### Removed\n\n* Remove `PeclUuidFactory` in favor of using pecl-uuid with generators\n\n\n## 3.0.0-alpha1 - 2015-07-16\n\n### Added\n\n* Allow dependency injection through `UuidFactory` and/or extending `FeatureSet`\n  to override any package defaults\n* Add a number of generators that may be used to override the library defaults:\n  * `CombGenerator` to allow generation of sequential UUIDs\n  * `OpenSslGenerator` to generate random bytes on systems where\n    `openssql_random_pseudo_bytes()` is present\n  * `MtRandGenerator` to provide a fallback in the event other random generators\n    are not present\n  * `RandomLibAdapter` to allow use of [ircmaxell/random-lib]\n* Support GUID generation by configuring a `FeatureSet` to use GUIDs\n* Allow UUIDs to be serialized as JSON through `JsonSerializable`\n\n### Changed\n\n* Change root namespace from \"Rhumsaa\" to \"Ramsey;\" in most cases, simply\n  making this change in your applications is the only upgrade path you will\n  need—everything else should work as expected\n* No longer consider `Uuid` class as `final`; everything is now based around\n  interfaces and factories, allowing you to use this package as a base to\n  implement other kinds of UUIDs with different dependencies\n* Return an object of type `DegradedUuid` on 32-bit systems to indicate that\n  certain features are not available\n\n### Removed\n\n* Move UUID [Doctrine field type] to [ramsey/uuid-doctrine]\n* Move `uuid` console application to [ramsey/uuid-console]\n* Remove `Uuid::VERSION` package version constant\n\n\n## 2.9.0 - 2016-03-22\n\n### Security\n\n* Drop the use of OpenSSL as a fallback and use [paragonie/random_compat] to\n  support `RandomBytesGenerator` in versions of PHP earlier than 7.0;\n  this addresses and fixes the [collision issue]\n\n\n## 2.8.4 - 2015-12-17\n\n### Added\n\n* Add support for symfony/console v3 in the `uuid` CLI application\n\n\n## 2.8.3 - 2015-08-31\n\n### Fixed\n\n* Fix exception message in `Uuid::calculateUuidTime()`\n\n\n## 2.8.2 - 2015-07-23\n\n### Fixed\n\n* Ensure the release tag makes it into the rhumsaa/uuid package\n\n\n## 2.8.1 - 2015-06-16\n\n### Fixed\n\n* Use `passthru()` and output buffering in `getIfconfig()`\n* Cache the system node in a static variable so that we process it only once per\n  runtime\n\n\n## 2.8.0 - 2014-11-09\n\n### Added\n\n* Add static `fromInteger()` method to create UUIDs from string integer or\n  `Moontoast\\Math\\BigNumber`\n\n### Fixed\n\n* Improve Doctrine conversion to Uuid or string for the ramsey/uuid [Doctrine field type]\n\n\n## 2.7.4 - 2014-10-29\n\n### Fixed\n\n* Change loop in `generateBytes()` from `foreach` to `for`\n\n\n## 2.7.3 - 2014-08-27\n\n### Fixed\n\n* Fix upper range for `mt_rand` used in version 4 UUIDs\n\n\n## 2.7.2 - 2014-07-28\n\n### Changed\n\n* Upgrade to PSR-4 autoloading\n\n\n## 2.7.1 - 2014-02-19\n\n### Fixed\n\n* Move moontoast/math and symfony/console to require-dev\n* Support symfony/console 2.3 (LTS version)\n\n\n## 2.7.0 - 2014-01-31\n\n### Added\n\n* Add `Uuid::VALID_PATTERN` constant containing a UUID validation regex pattern\n\n\n## 2.6.1 - 2014-01-27\n\n### Fixed\n\n* Fix bug where `uuid` console application could not find the Composer\n  autoloader when installed in another project\n\n\n## 2.6.0 - 2014-01-17\n\n### Added\n\n* Introduce `uuid` console application for generating and decoding UUIDs from\n  CLI (run `./bin/uuid` for details)\n* Add `Uuid::getInteger()` to retrieve a `Moontoast\\Math\\BigNumber`\n  representation of the 128-bit integer representing the UUID\n* Add `Uuid::getHex()` to retrieve the hexadecimal representation of the UUID\n* Use `netstat` on Linux to capture the node for a version 1 UUID\n* Require moontoast/math as part of the regular package requirements\n\n\n## 2.5.0 - 2013-10-30\n\n### Added\n\n* Use `openssl_random_pseudo_bytes()`, if available, to generate random bytes\n\n\n## 2.4.0 - 2013-07-29\n\n### Added\n\n* Return `null` from `Uuid::getVersion()` if the UUID isn't an RFC 4122 variant\n* Support string UUIDs without dashes passed to `Uuid::fromString()`\n\n\n## 2.3.0 - 2013-07-16\n\n### Added\n\n* Support creation of UUIDs from bytes with `Uuid::fromBytes()`\n\n\n## 2.2.0 - 2013-07-04\n\n### Added\n\n* Add `Doctrine\\UuidType::requiresSQLCommentHint()` method\n\n\n## 2.1.2 - 2013-07-03\n\n### Fixed\n\n* Fix cases where the system node was coming back with uppercase hexadecimal\n  digits; this ensures that case in the node is converted to lowercase\n\n\n## 2.1.1 - 2013-04-29\n\n### Fixed\n\n* Fix bug in `Uuid::isValid()` where the NIL UUID was not reported as valid\n\n\n## 2.1.0 - 2013-04-15\n\n### Added\n\n* Allow checking the validity of a UUID through the `Uuid::isValid()` method\n\n\n## 2.0.0 - 2013-02-11\n\n### Added\n\n* Support UUID generation on 32-bit platforms\n\n### Changed\n\n* Mark `Uuid` class `final`\n* Require moontoast/math on 64-bit platforms for\n  `Uuid::getLeastSignificantBits()` and `Uuid::getMostSignificantBits()`; the\n  integers returned by these methods are *unsigned* 64-bit integers and\n  unsupported even on 64-bit builds of PHP\n* Move `UnsupportedOperationException` to the `Exception` subnamespace\n\n\n## 1.1.2 - 2012-11-29\n\n### Fixed\n\n* Relax [Doctrine field type] conversion rules for UUIDs\n\n\n## 1.1.1 - 2012-08-27\n\n### Fixed\n\n* Remove `final` keyword from `Uuid` class\n\n\n## 1.1.0 - 2012-08-06\n\n### Added\n\n* Support ramsey/uuid UUIDs as a Doctrine Database Abstraction Layer (DBAL)\n  field mapping type\n\n\n## 1.0.0 - 2012-07-19\n\n### Added\n\n* Support generation of version 1, 3, 4, and 5 UUIDs\n\n\n[comb sequential uuids]: http://www.informit.com/articles/article.aspx?p=25862&seqNum=7\n[paragonie/random_compat]: https://github.com/paragonie/random_compat\n[collision issue]: https://github.com/ramsey/uuid/issues/80\n[contributor code of conduct]: https://github.com/ramsey/uuid/blob/main/CODE_OF_CONDUCT.md\n[pecl libsodium extension]: http://pecl.php.net/package/libsodium\n[ircmaxell/random-lib]: https://github.com/ircmaxell/RandomLib\n[doctrine field type]: http://doctrine-dbal.readthedocs.org/en/latest/reference/types.html\n[ramsey/uuid-doctrine]: https://github.com/ramsey/uuid-doctrine\n[ramsey/uuid-console]: https://github.com/ramsey/uuid-console\n[version6]: https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6\n[version7]: https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7\n[version8]: https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8\n[max uuids]: https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#section-5.4\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n  advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project maintainer(s) at <ben@benramsey.com>. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 1.4, available at <http://contributor-covenant.org/version/1/4>.\n\n[homepage]: http://contributor-covenant.org\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nContributions are welcome. This project accepts pull requests on [GitHub][].\n\nThis project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By\nparticipating in this project and its community, you are expected to uphold this\ncode.\n\n## Communication Channels\n\nYou can find help and discussion in the following places:\n\n* GitHub Issues: <https://github.com/ramsey/uuid/issues>\n\n## Reporting Bugs\n\nReport bugs using the project's [issue tracker][issues].\n\n⚠️ _**ATTENTION!!!** DO NOT include passwords or other sensitive information in\nyour bug report._\n\nWhen submitting a bug report, please include enough information to reproduce the\nbug. A good bug report includes the following sections:\n\n* **Description**\n\n  Provide a short and clear description of the bug.\n\n* **Steps to reproduce**\n\n  Provide steps to reproduce the behavior you are experiencing. Please try to\n  keep this as short as possible. If able, create a reproducible script outside\n  of any framework you are using. This will help us to quickly debug the issue.\n\n* **Expected behavior**\n\n  Provide a short and clear description of what you expect to happen.\n\n* **Screenshots or output**\n\n  If applicable, add screenshots or program output to help explain your problem.\n\n* **Environment details**\n\n  Provide details about the system where you're using this package, such as PHP\n  version and operating system.\n\n* **Additional context**\n\n  Provide any additional context that may help us debug the problem.\n\n## Fixing Bugs\n\nThis project welcomes pull requests to fix bugs!\n\nIf you see a bug report that you'd like to fix, please feel free to do so.\nFollowing the directions and guidelines described in the \"Adding New Features\"\nsection below, you may create bugfix branches and send pull requests.\n\n## Adding New Features\n\nIf you have an idea for a new feature, it's a good idea to check out the\n[issues][] or active [pull requests][] first to see if anyone is already working\non the feature. If not, feel free to submit an issue first, asking whether the\nfeature is beneficial to the project. This will save you from doing a lot of\ndevelopment work only to have your feature rejected. We don't enjoy rejecting\nyour hard work, but some features don't fit with the goals of the project.\n\nWhen you do begin working on your feature, here are some guidelines to consider:\n\n* Your pull request description should clearly detail the changes you have made.\n  We will use this description to update the CHANGELOG. If there is no\n  description, or it does not adequately describe your feature, we may ask you\n  to update the description.\n* ramsey/uuid follows a superset of **[PSR-12 coding standard][psr-12]**.\n  Please ensure your code does, too. _Hint: run `composer phpcs` to check._\n* Please **write tests** for any new features you add.\n* Please **ensure that tests pass** before submitting your pull request.\n  ramsey/uuid automatically runs tests for pull requests. However,\n  running the tests locally will help save time. _Hint: run `composer test`._\n* **Use topic/feature branches.** Please do not ask to pull from your main branch.\n    * For more information, see \"[Understanding the GitHub flow][gh-flow].\"\n* **Submit one feature per pull request.** If you have multiple features you\n  wish to submit, please break them into separate pull requests.\n\n## Developing\n\nTo develop this project, you will need [PHP](https://www.php.net) 8.0 or greater\nand [Composer](https://getcomposer.org).\n\nAfter cloning this repository locally, execute the following commands:\n\n``` bash\ncd /path/to/repository\ncomposer install\n```\n\nNow, you are ready to develop!\n\n### Tooling\n\nThis project uses [CaptainHook](https://github.com/captainhook-git/captainhook)\nto validate all staged changes prior to commit.\n\n### Commands\n\nTo see all the commands available for contributing to this project:\n\n``` bash\ncomposer list\n```\n\n### Coding Standards\n\nThis project follows a superset of [PSR-12](https://www.php-fig.org/psr/psr-12/)\ncoding standards, enforced by [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer).\n\nCaptainHook will run coding standards checks before committing.\n\nYou may lint the codebase manually using the following commands:\n\n``` bash\n# Lint\ncomposer dev:lint\n\n# Attempt to auto-fix coding standards issues\ncomposer dev:lint:fix\n```\n\n### Static Analysis\n\nThis project uses [PHPStan](https://github.com/phpstan/phpstan) to provide\nstatic analysis of PHP code.\n\nCaptainHook will run static analysis checks before committing.\n\nYou may run static analysis manually across the whole codebase with the\nfollowing command:\n\n``` bash\n# Static analysis\ncomposer dev:analyze\n```\n\n### Project Structure\n\nThis project uses [pds/skeleton](https://github.com/php-pds/skeleton) as its\nbase folder structure and layout.\n\n### Running Tests\n\nThe following must pass before we will accept a pull request. If this does not\npass, it will result in a complete build failure. Before you can run this, be\nsure to `composer install`.\n\nTo run all the tests and coding standards checks, execute the following from the\ncommand line, while in the project root directory:\n\n```\ncomposer test\n```\n\nCaptainHook will automatically run all tests before pushing to the remote\nrepository.\n\n[github]: https://github.com/ramsey/uuid\n[issues]: https://github.com/ramsey/uuid/issues\n[pull requests]: https://github.com/ramsey/uuid/pulls\n[psr-12]: https://www.php-fig.org/psr/psr-12/\n[gh-flow]: https://guides.github.com/introduction/flow/\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2012-2025 Ben Ramsey <ben@benramsey.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">ramsey/uuid</h1>\n\n<p align=\"center\">\n    <strong>A PHP library for generating and working with UUIDs.</strong>\n</p>\n\n<p align=\"center\">\n    <a href=\"https://github.com/ramsey/uuid\"><img src=\"http://img.shields.io/badge/source-ramsey/uuid-blue.svg?style=flat-square\" alt=\"Source Code\"></a>\n    <a href=\"https://packagist.org/packages/ramsey/uuid\"><img src=\"https://img.shields.io/packagist/v/ramsey/uuid.svg?style=flat-square&label=release\" alt=\"Download Package\"></a>\n    <a href=\"https://php.net\"><img src=\"https://img.shields.io/packagist/php-v/ramsey/uuid.svg?style=flat-square&colorB=%238892BF\" alt=\"PHP Programming Language\"></a>\n    <a href=\"https://github.com/ramsey/uuid/blob/4.x/LICENSE\"><img src=\"https://img.shields.io/packagist/l/ramsey/uuid.svg?style=flat-square&colorB=darkcyan\" alt=\"Read License\"></a>\n    <a href=\"https://github.com/ramsey/uuid/actions/workflows/continuous-integration.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/ramsey/uuid/continuous-integration.yml?branch=4.x&logo=github&style=flat-square\" alt=\"Build Status\"></a>\n    <a href=\"https://app.codecov.io/gh/ramsey/uuid/branch/4.x\"><img src=\"https://img.shields.io/codecov/c/github/ramsey/uuid/4.x?label=codecov&logo=codecov&style=flat-square\" alt=\"Codecov Code Coverage\"></a>\n</p>\n\nramsey/uuid is a PHP library for generating and working with universally unique\nidentifiers (UUIDs).\n\nThis project adheres to a [code of conduct](CODE_OF_CONDUCT.md).\nBy participating in this project and its community, you are expected to\nuphold this code.\n\nMuch inspiration for this library came from the [Java][javauuid] and\n[Python][pyuuid] UUID libraries.\n\n## Installation\n\nThe preferred method of installation is via [Composer][]. Run the following\ncommand to install the package and add it as a requirement to your project's\n`composer.json`:\n\n```bash\ncomposer require ramsey/uuid\n```\n\n## Upgrading to Version 4\n\nSee the documentation for a thorough upgrade guide:\n\n* [Upgrading ramsey/uuid Version 3 to 4](https://uuid.ramsey.dev/en/stable/upgrading/3-to-4.html)\n\n## Documentation\n\nPlease see <https://uuid.ramsey.dev> for documentation, tips, examples, and\nfrequently asked questions.\n\n## Contributing\n\nContributions are welcome! To contribute, please familiarize yourself with\n[CONTRIBUTING.md](CONTRIBUTING.md).\n\n## Coordinated Disclosure\n\nKeeping user information safe and secure is a top priority, and we welcome the\ncontribution of external security researchers. If you believe you've found a\nsecurity issue in software that is maintained in this repository, please read\n[SECURITY.md][] for instructions on submitting a vulnerability report.\n\n## ramsey/uuid for Enterprise\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of ramsey/uuid and thousands of other packages are working with\nTidelift to deliver commercial support and maintenance for the open source\npackages you use to build your applications. Save time, reduce risk, and improve\ncode health, while paying the maintainers of the exact packages you use.\n[Learn more.](https://tidelift.com/subscription/pkg/packagist-ramsey-uuid?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)\n\n## Copyright and License\n\nThe ramsey/uuid library is copyright © [Ben Ramsey](https://benramsey.com/) and\nlicensed for use under the MIT License (MIT). Please see [LICENSE][] for more\ninformation.\n\n[rfc4122]: http://tools.ietf.org/html/rfc4122\n[conduct]: https://github.com/ramsey/uuid/blob/4.x/CODE_OF_CONDUCT.md\n[javauuid]: http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html\n[pyuuid]: http://docs.python.org/3/library/uuid.html\n[composer]: http://getcomposer.org/\n[contributing.md]: https://github.com/ramsey/uuid/blob/4.x/CONTRIBUTING.md\n[security.md]: https://github.com/ramsey/uuid/blob/4.x/SECURITY.md\n[license]: https://github.com/ramsey/uuid/blob/4.x/LICENSE\n"
  },
  {
    "path": "SECURITY.md",
    "content": "<!--\n    This policy template was created using the HackerOne Policy Builder [1],\n    with guidance from the National Telecommunications and Information\n    Administration Coordinated Vulnerability Disclosure Template [2].\n -->\n\n# Vulnerability Disclosure Policy (VDP)\n\n## Brand Promise\n\n<!--\n    This is your brand promise. Its objective is to \"demonstrate a clear, good\n    faith commitment to customers and other stakeholders potentially impacted by\n    security vulnerabilities\" [2].\n-->\n\nKeeping user information safe and secure is a top priority, and we welcome the\ncontribution of external security researchers.\n\n## Scope\n\n<!--\n    This is your initial scope. It tells vulnerability finders and reporters\n    \"which systems and capabilities are 'fair game' versus 'off limits'\" [2].\n    For software packages, this is often a list of currently maintained versions\n    of the package.\n-->\n\nIf you believe you've found a security issue in software that is maintained in\nthis repository, we encourage you to notify us.\n\n| Version      | In scope | Source code                             |\n| ------------ | -------- |-----------------------------------------|\n| latest (4.x) | ✅       | https://github.com/ramsey/uuid/tree/4.x |\n| 3.9          | ✅       | https://github.com/ramsey/uuid/tree/3.x |\n| 3.8          | ✅       | https://github.com/ramsey/uuid/tree/3.x |\n\n## How to Submit a Report\n\n<!--\n    This is your communication process. It tells security researchers how to\n    contact you to report a vulnerability. It may be a link to a web form that\n    uses HTTPS for secure communication, or it may be an email address.\n    Optionally, you may choose to include a PGP public key, so that researchers\n    may send you encrypted messages.\n-->\n\nTo submit a vulnerability report, please contact us at security@ramsey.dev.\nYour submission will be reviewed and validated by a member of our team.\n\n## Safe Harbor\n\n<!--\n    This section assures vulnerability finders and reporters that they will\n    receive good faith responses to their good faith acts. In other words,\n    \"we will not take legal action if...\" [2].\n-->\n\nWe support safe harbor for security researchers who:\n\n* Make a good faith effort to avoid privacy violations, destruction of data, and\n  interruption or degradation of our services.\n* Only interact with accounts you own or with explicit permission of the account\n  holder. If you do encounter Personally Identifiable Information (PII) contact\n  us immediately, do not proceed with access, and immediately purge any local\n  information.\n* Provide us with a reasonable amount of time to resolve vulnerabilities prior\n  to any disclosure to the public or a third party.\n\nWe will consider activities conducted consistent with this policy to constitute\n\"authorized\" conduct and will not pursue civil action or initiate a complaint to\nlaw enforcement. We will help to the extent we can if legal action is initiated\nby a third party against you.\n\nPlease submit a report to us before engaging in conduct that may be inconsistent\nwith or unaddressed by this policy.\n\n## Preferences\n\n<!--\n    The preferences section sets expectations based on priority and submission\n    volume, rather than legal objection or restriction [2].\n\n    According to the NTIA [2]:\n\n        This section is a living document that sets expectations for preferences\n        and priorities, typically maintained by the support and engineering\n        team. This can outline classes of vulnerabilities, reporting style\n        (crash dumps, CVSS scoring, proof-of-concept, etc.), tools, etc. Too\n        many preferences can set the wrong tone or make reporting findings\n        difficult to navigate. This section also sets expectations to the\n        researcher community for what types of issues are considered important\n        or not.\n-->\n\n* Please provide detailed reports with reproducible steps and a clearly defined\n  impact.\n* Include the version number of the vulnerable package in your report\n* Social engineering (e.g. phishing, vishing, smishing) is prohibited.\n\n<!--\n    References\n\n    [1] HackerOne. Policy builder. Retrieved from https://hackerone.com/policy-builder/\n\n    [2] NTIA Safety Working Group. 2016. \"Early stage\" coordinated vulnerability\n    disclosure template: Version 1.1. (15 December 2016). Retrieved from\n    https://www.ntia.doc.gov/files/ntia/publications/ntia_vuln_disclosure_early_stage_template.pdf\n-->\n\n## Encryption Key for security@ramsey.dev\n\nFor increased privacy when reporting sensitive issues, you may encrypt your message using the following public key:\n\n```\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBF+Z9gEBEACbT/pIx8RR0K18t8Z2rDnmEV44YdT7HNsMdq+D6SAlx8UUb6AU\njGIbV9dgBgGNtOLU1pxloaJwL9bWIRbj+X/Qb2WNIP//Vz1Y40ox1dSpfCUrizXx\nkb4p58Xml0PsB8dg3b4RDUgKwGC37ne5xmDnigyJPbiB2XJ6Xc46oPCjh86XROTK\nwEBB2lY67ClBlSlvC2V9KmbTboRQkLdQDhOaUosMb99zRb0EWqDLaFkZVjY5HI7i\n0pTveE6dI12NfHhTwKjZ5pUiAZQGlKA6J1dMjY2unxHZkQj5MlMfrLSyJHZxccdJ\nxD94T6OTcTHt/XmMpI2AObpewZDdChDQmcYDZXGfAhFoJmbvXsmLMGXKgzKoZ/ls\nRmLsQhh7+/r8E+Pn5r+A6Hh4uAc14ApyEP0ckKeIXw1C6pepHM4E8TEXVr/IA6K/\nz6jlHORixIFX7iNOnfHh+qwOgZw40D6JnBfEzjFi+T2Cy+JzN2uy7I8UnecTMGo3\n5t6astPy6xcH6kZYzFTV7XERR6LIIVyLAiMFd8kF5MbJ8N5ElRFsFHPW+82N2HDX\nc60iSaTB85k6R6xd8JIKDiaKE4sSuw2wHFCKq33d/GamYezp1wO+bVUQg88efljC\n2JNFyD+vl30josqhw1HcmbE1TP3DlYeIL5jQOlxCMsgai6JtTfHFM/5MYwARAQAB\ntBNzZWN1cml0eUByYW1zZXkuZGV2iQJUBBMBCAA+FiEE4drPD+/ofZ570fAYq0bv\nvXQCywIFAl+Z9gECGwMFCQeGH4AFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ\nq0bvvXQCywIkEA//Qcwv8MtTCy01LHZd9c7VslwhNdXQDYymcTyjcYw8x7O22m4B\n3hXE6vqAplFhVxxkqXB2ef0tQuzxhPHNJgkCE4Wq4i+V6qGpaSVHQT2W6DN/NIhL\nvS8OdScc6zddmIbIkSrzVVAtjwehFNEIrX3DnbbbK+Iku7vsKT5EclOluIsjlYoX\ngoW8IeReyDBqOe2H3hoCGw6EA0D/NYV2bJnfy53rXVIyarsXXeOLp7eNEH6Td7aW\nPVSrMZJe1t+knrEGnEdrXWzlg4lCJJCtemGv+pKBUomnyISXSdqyoRCCzvQjqyig\n2kRebUX8BXPW33p4OXPj9sIboUOjZwormWwqqbFMO+J4TiVCUoEoheI7emPFRcNN\nQtPJrjbY1++OznBc0GRpfeUkGoU1cbRl1bnepnFIZMTDLkrVW6I1Y4q8ZVwX3BkE\nN81ctFrRpHBlU36EdHvjPQmGtuiL77Qq3fWmMv7yTvK1wHJAXfEb0ZJWHZCbck3w\nl0CVq0Z+UUAOM8Rp1N0N8m92xtapav0qCFU9qzf2J5qX6GRmWv+d29wPgFHzDWBm\nnnrYYIA4wJLx00U6SMcVBSnNe91B+RfGY5XQhbWPjQQecOGCSDsxaFAq2MeOVJyZ\nbIjLYfG9GxoLKr5R7oLRJvZI4nKKBc1Kci/crZbdiSdQhSQGlDz88F1OHeCIdQQQ\nEQgAHRYhBOhdAxHd+lus86YQ57Atl5icjAcbBQJfmfdIAAoJELAtl5icjAcbFVcA\n/1LqB3ZjsnXDAvvAXZVjSPqofSlpMLeRQP6IM/A9Odq0AQCZrtZc1knOMGEcjppK\nRk+sy/R0Mshy8TDuaZIRgh2Ux7kCDQRfmfYBARAAmchKzzVz7IaEq7PnZDb3szQs\nT/+E9F3m39yOpV4fEB1YzObonFakXNT7Gw2tZEx0eitUMqQ/13jjfu3UdzlKl2bR\nqA8LrSQRhB+PTC9A1XvwxCUYhhjGiLzJ9CZL6hBQB43qHOmE9XJPme90geLsF+gK\nu39Waj1SNWzwGg+Gy1Gl5f2AJoDTxznreCuFGj+Vfaczt/hlfgqpOdb9jsmdoE7t\n3DSWppA9dRHWwQSgE6J28rR4QySBcqyXS6IMykqaJn7Z26yNIaITLnHCZOSY8zhP\nha7GFsN549EOCgECbrnPt9dmI2+hQE0RO0e7SOBNsIf5sz/i7urhwuj0CbOqhjc2\nX1AEVNFCVcb6HPi/AWefdFCRu0gaWQxn5g+9nkq5slEgvzCCiKYzaBIcr8qR6Hb4\nFaOPVPxO8vndRouq57Ws8XpAwbPttioFuCqF4u9K+tK/8e2/R8QgRYJsE3Cz/Fu8\n+pZFpMnqbDEbK3DL3ss+1ed1sky+mDV8qXXeI33XW5hMFnk1JWshUjHNlQmE6ftC\nU0xSTMVUtwJhzH2zDp8lEdu7qi3EsNULOl68ozDr6soWAvCbHPeTdTOnFySGCleG\n/3TonsoZJs/sSPPJnxFQ1DtgQL6EbhIwa0ZwU4eKYVHZ9tjxuMX3teFzRvOrJjgs\n+ywGlsIURtEckT5Y6nMAEQEAAYkCPAQYAQgAJhYhBOHazw/v6H2ee9HwGKtG7710\nAssCBQJfmfYBAhsMBQkHhh+AAAoJEKtG7710AssC8NcP/iDAcy1aZFvkA0EbZ85p\ni7/+ywtE/1wF4U4/9OuLcoskqGGnl1pJNPooMOSBCfreoTB8HimT0Fln0CoaOm4Q\npScNq39JXmf4VxauqUJVARByP6zUfgYarqoaZNeuFF0S4AZJ2HhGzaQPjDz1uKVM\nPE6tQSgQkFzdZ9AtRA4vElTH6yRAgmepUsOihk0b0gUtVnwtRYZ8e0Qt3ie97a73\nDxLgAgedFRUbLRYiT0vNaYbainBsLWKpN/T8odwIg/smP0Khjp/ckV60cZTdBiPR\nszBTPJESMUTu0VPntc4gWwGsmhZJg/Tt/qP08XYo3VxNYBegyuWwNR66zDWvwvGH\nmuMv5UchuDxp6Rt3JkIO4voMT1JSjWy9p8krkPEE4V6PxAagLjdZSkt92wVLiK5x\ny5gNrtPhU45YdRAKHr36OvJBJQ42CDaZ6nzrzghcIp9CZ7ANHrI+QLRM/csz+AGA\nszSp6S4mc1lnxxfbOhPPpebZPn0nIAXoZnnoVKdrxBVedPQHT59ZFvKTQ9Fs7gd3\nsYNuc7tJGFGC2CxBH4ANDpOQkc5q9JJ1HSGrXU3juxIiRgfA26Q22S9c71dXjElw\nRi584QH+bL6kkYmm8xpKF6TVwhwu5xx/jBPrbWqFrtbvLNrnfPoapTihBfdIhkT6\nnmgawbBHA02D5xEqB5SU3WJu\n=eJNx\n-----END PGP PUBLIC KEY BLOCK-----\n```\n"
  },
  {
    "path": "build/.gitignore",
    "content": "*\n!.gitignore\n!cache\n!cache/.gitkeep\n!logs\n!logs/.gitkeep\n"
  },
  {
    "path": "build/cache/.gitkeep",
    "content": ""
  },
  {
    "path": "build/logs/.gitkeep",
    "content": ""
  },
  {
    "path": "captainhook.json",
    "content": "{\n    \"config\": {\n        \"ansi-colors\": true,\n        \"fail-on-first-error\": false,\n        \"plugins\": [],\n        \"verbosity\": \"normal\"\n    },\n    \"commit-msg\": {\n        \"enabled\": false,\n        \"actions\": []\n    },\n    \"pre-push\": {\n        \"enabled\": true,\n        \"actions\": [\n            {\n                \"action\": \"composer test\"\n            }\n        ]\n    },\n    \"pre-commit\": {\n        \"enabled\": true,\n        \"actions\": [\n            {\n                \"action\": \"composer validate\",\n                \"conditions\": [\n                    {\n                        \"exec\": \"\\\\CaptainHook\\\\App\\\\Hook\\\\Condition\\\\FileStaged\\\\Any\",\n                        \"args\": [[\"composer.json\"]]\n                    }\n                ]\n            },\n            {\n                \"action\": \"composer normalize --dry-run\",\n                \"conditions\": [\n                    {\n                        \"exec\": \"\\\\CaptainHook\\\\App\\\\Hook\\\\Condition\\\\FileStaged\\\\Any\",\n                        \"args\": [[\"composer.json\"]]\n                    }\n                ]\n            },\n            {\n                \"action\": \"composer dev:lint:syntax -- {$STAGED_FILES|of-type:php}\",\n                \"conditions\": [\n                    {\n                        \"exec\": \"\\\\CaptainHook\\\\App\\\\Hook\\\\Condition\\\\FileStaged\\\\OfType\",\n                        \"args\": [\"php\"]\n                    }\n                ]\n            },\n            {\n                \"action\": \"composer dev:lint:style -- {$STAGED_FILES|of-type:php}\",\n                \"conditions\": [\n                    {\n                        \"exec\": \"\\\\CaptainHook\\\\App\\\\Hook\\\\Condition\\\\FileStaged\\\\OfType\",\n                        \"args\": [\"php\"]\n                    }\n                ]\n            }\n        ]\n    },\n    \"prepare-commit-msg\": {\n        \"enabled\": false,\n        \"actions\": []\n    },\n    \"post-commit\": {\n        \"enabled\": false,\n        \"actions\": []\n    },\n    \"post-merge\": {\n        \"enabled\": true,\n        \"actions\": [\n            {\n                \"action\": \"composer install --ansi\",\n                \"conditions\": [\n                    {\n                        \"exec\": \"\\\\CaptainHook\\\\App\\\\Hook\\\\Condition\\\\FileChanged\\\\Any\",\n                        \"args\": [[\"composer.json\", \"composer.lock\"]]\n                    }\n                ]\n            }\n        ]\n    },\n    \"post-checkout\": {\n        \"enabled\": true,\n        \"actions\": [\n            {\n                \"action\": \"composer install --ansi\",\n                \"conditions\": [\n                    {\n                        \"exec\": \"\\\\CaptainHook\\\\App\\\\Hook\\\\Condition\\\\FileChanged\\\\Any\",\n                        \"args\": [[\"composer.json\", \"composer.lock\"]]\n                    }\n                ]\n            }\n        ]\n    },\n    \"post-rewrite\": {\n        \"enabled\": false,\n        \"actions\": []\n    },\n    \"post-change\": {\n        \"enabled\": false,\n        \"actions\": []\n    }\n}\n"
  },
  {
    "path": "codecov.yml",
    "content": "codecov:\n    require_ci_to_pass: yes\n\ncoverage:\n    precision: 2\n    round: down\n    range: \"70...100\"\n    status:\n        project:\n            default:\n                target: auto\n                threshold: 0%\n        patch:\n            default:\n                target: auto\n                threshold: 0%\n\nparsers:\n    gcov:\n        branch_detection:\n            conditional: yes\n            loop: yes\n            method: no\n            macro: no\n\ncomment:\n    layout: \"reach,diff,flags,tree\"\n    behavior: default\n    require_changes: false\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"ramsey/uuid\",\n    \"description\": \"A PHP library for generating and working with universally unique identifiers (UUIDs).\",\n    \"license\": \"MIT\",\n    \"type\": \"library\",\n    \"keywords\": [\n        \"uuid\",\n        \"identifier\",\n        \"guid\"\n    ],\n    \"require\": {\n        \"php\": \"^8.0\",\n        \"brick/math\": \"^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14\",\n        \"ramsey/collection\": \"^1.2 || ^2.0\"\n    },\n    \"require-dev\": {\n        \"captainhook/captainhook\": \"^5.25\",\n        \"captainhook/plugin-composer\": \"^5.3\",\n        \"dealerdirect/phpcodesniffer-composer-installer\": \"^1.0\",\n        \"ergebnis/composer-normalize\": \"^2.47\",\n        \"mockery/mockery\": \"^1.6\",\n        \"paragonie/random-lib\": \"^2\",\n        \"php-mock/php-mock\": \"^2.6\",\n        \"php-mock/php-mock-mockery\": \"^1.5\",\n        \"php-parallel-lint/php-parallel-lint\": \"^1.4.0\",\n        \"phpbench/phpbench\": \"^1.2.14\",\n        \"phpstan/extension-installer\": \"^1.4\",\n        \"phpstan/phpstan\": \"^2.1\",\n        \"phpstan/phpstan-mockery\": \"^2.0\",\n        \"phpstan/phpstan-phpunit\": \"^2.0\",\n        \"phpunit/phpunit\": \"^9.6\",\n        \"slevomat/coding-standard\": \"^8.18\",\n        \"squizlabs/php_codesniffer\": \"^3.13\"\n    },\n    \"replace\": {\n        \"rhumsaa/uuid\": \"self.version\"\n    },\n    \"suggest\": {\n        \"ext-bcmath\": \"Enables faster math with arbitrary-precision integers using BCMath.\",\n        \"ext-gmp\": \"Enables faster math with arbitrary-precision integers using GMP.\",\n        \"ext-uuid\": \"Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.\",\n        \"paragonie/random-lib\": \"Provides RandomLib for use with the RandomLibAdapter\",\n        \"ramsey/uuid-doctrine\": \"Allows the use of Ramsey\\\\Uuid\\\\Uuid as Doctrine field type.\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"prefer-stable\": true,\n    \"autoload\": {\n        \"psr-4\": {\n            \"Ramsey\\\\Uuid\\\\\": \"src/\"\n        },\n        \"files\": [\n            \"src/functions.php\"\n        ]\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Ramsey\\\\Uuid\\\\Benchmark\\\\\": \"tests/benchmark/\",\n            \"Ramsey\\\\Uuid\\\\StaticAnalysis\\\\\": \"tests/static-analysis/\",\n            \"Ramsey\\\\Uuid\\\\Test\\\\\": \"tests/\"\n        }\n    },\n    \"config\": {\n        \"allow-plugins\": {\n            \"captainhook/plugin-composer\": true,\n            \"dealerdirect/phpcodesniffer-composer-installer\": true,\n            \"ergebnis/composer-normalize\": true,\n            \"phpstan/extension-installer\": true\n        },\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"captainhook\": {\n            \"force-install\": true\n        }\n    },\n    \"scripts\": {\n        \"dev:analyze\": \"@dev:analyze:phpstan\",\n        \"dev:analyze:phpstan\": \"phpstan analyse --ansi --memory-limit 1G\",\n        \"dev:bench\": \"@php -d 'error_reporting=24575' vendor/bin/phpbench run\",\n        \"dev:build:clean\": \"git clean -fX build/\",\n        \"dev:lint\": [\n            \"@dev:lint:syntax\",\n            \"@dev:lint:style\"\n        ],\n        \"dev:lint:fix\": \"phpcbf --cache=build/cache/phpcs.cache\",\n        \"dev:lint:style\": \"phpcs --cache=build/cache/phpcs.cache --colors\",\n        \"dev:lint:syntax\": \"parallel-lint --colors src/ tests/\",\n        \"dev:test\": [\n            \"@dev:lint\",\n            \"@dev:bench\",\n            \"@dev:analyze\",\n            \"@dev:test:unit\"\n        ],\n        \"dev:test:coverage:ci\": \"@php -d 'xdebug.mode=coverage' vendor/bin/phpunit --colors=always --coverage-text --coverage-clover build/coverage/clover.xml --coverage-cobertura build/coverage/cobertura.xml --coverage-crap4j build/coverage/crap4j.xml --coverage-xml build/coverage/coverage-xml --log-junit build/junit.xml\",\n        \"dev:test:coverage:html\": \"@php -d 'xdebug.mode=coverage' vendor/bin/phpunit --colors=always --coverage-html build/coverage/coverage-html/\",\n        \"dev:test:unit\": \"phpunit --colors=always\",\n        \"test\": \"@dev:test\"\n    },\n    \"scripts-descriptions\": {\n        \"dev:analyze\": \"Runs all static analysis checks.\",\n        \"dev:analyze:phpstan\": \"Runs the PHPStan static analyzer.\",\n        \"dev:bench\": \"Runs PHPBench benchmark tests.\",\n        \"dev:build:clean\": \"Cleans the build/ directory.\",\n        \"dev:lint\": \"Runs all linting checks.\",\n        \"dev:lint:fix\": \"Auto-fixes coding standards issues, if possible.\",\n        \"dev:lint:style\": \"Checks for coding standards issues.\",\n        \"dev:lint:syntax\": \"Checks for syntax errors.\",\n        \"dev:test\": \"Runs linting, static analysis, and unit tests.\",\n        \"dev:test:coverage:ci\": \"Runs unit tests and generates CI coverage reports.\",\n        \"dev:test:coverage:html\": \"Runs unit tests and generates HTML coverage report.\",\n        \"dev:test:unit\": \"Runs unit tests.\",\n        \"test\": \"Runs linting, static analysis, and unit tests.\"\n    }\n}\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "_build/\n"
  },
  {
    "path": "docs/LICENSE",
    "content": "Attribution 4.0 International\n\n=======================================================================\n\nCreative Commons Corporation (\"Creative Commons\") is not a law firm and\ndoes not provide legal services or legal advice. Distribution of\nCreative Commons public licenses does not create a lawyer-client or\nother relationship. Creative Commons makes its licenses and related\ninformation available on an \"as-is\" basis. Creative Commons gives no\nwarranties regarding its licenses, any material licensed under their\nterms and conditions, or any related information. Creative Commons\ndisclaims all liability for damages resulting from their use to the\nfullest extent possible.\n\nUsing Creative Commons Public Licenses\n\nCreative Commons public licenses provide a standard set of terms and\nconditions that creators and other rights holders may use to share\noriginal works of authorship and other material subject to copyright\nand certain other rights specified in the public license below. The\nfollowing considerations are for informational purposes only, are not\nexhaustive, and do not form part of our licenses.\n\n     Considerations for licensors: Our public licenses are\n     intended for use by those authorized to give the public\n     permission to use material in ways otherwise restricted by\n     copyright and certain other rights. Our licenses are\n     irrevocable. Licensors should read and understand the terms\n     and conditions of the license they choose before applying it.\n     Licensors should also secure all rights necessary before\n     applying our licenses so that the public can reuse the\n     material as expected. Licensors should clearly mark any\n     material not subject to the license. This includes other CC-\n     licensed material, or material used under an exception or\n     limitation to copyright. More considerations for licensors:\n    wiki.creativecommons.org/Considerations_for_licensors\n\n     Considerations for the public: By using one of our public\n     licenses, a licensor grants the public permission to use the\n     licensed material under specified terms and conditions. If\n     the licensor's permission is not necessary for any reason--for\n     example, because of any applicable exception or limitation to\n     copyright--then that use is not regulated by the license. Our\n     licenses grant only permissions under copyright and certain\n     other rights that a licensor has authority to grant. Use of\n     the licensed material may still be restricted for other\n     reasons, including because others have copyright or other\n     rights in the material. A licensor may make special requests,\n     such as asking that all changes be marked or described.\n     Although not required by our licenses, you are encouraged to\n     respect those requests where reasonable. More considerations\n     for the public:\n    wiki.creativecommons.org/Considerations_for_licensees\n\n=======================================================================\n\nCreative Commons Attribution 4.0 International Public License\n\nBy exercising the Licensed Rights (defined below), You accept and agree\nto be bound by the terms and conditions of this Creative Commons\nAttribution 4.0 International Public License (\"Public License\"). To the\nextent this Public License may be interpreted as a contract, You are\ngranted the Licensed Rights in consideration of Your acceptance of\nthese terms and conditions, and the Licensor grants You such rights in\nconsideration of benefits the Licensor receives from making the\nLicensed Material available under these terms and conditions.\n\n\nSection 1 -- Definitions.\n\n  a. Adapted Material means material subject to Copyright and Similar\n     Rights that is derived from or based upon the Licensed Material\n     and in which the Licensed Material is translated, altered,\n     arranged, transformed, or otherwise modified in a manner requiring\n     permission under the Copyright and Similar Rights held by the\n     Licensor. For purposes of this Public License, where the Licensed\n     Material is a musical work, performance, or sound recording,\n     Adapted Material is always produced where the Licensed Material is\n     synched in timed relation with a moving image.\n\n  b. Adapter's License means the license You apply to Your Copyright\n     and Similar Rights in Your contributions to Adapted Material in\n     accordance with the terms and conditions of this Public License.\n\n  c. Copyright and Similar Rights means copyright and/or similar rights\n     closely related to copyright including, without limitation,\n     performance, broadcast, sound recording, and Sui Generis Database\n     Rights, without regard to how the rights are labeled or\n     categorized. For purposes of this Public License, the rights\n     specified in Section 2(b)(1)-(2) are not Copyright and Similar\n     Rights.\n\n  d. Effective Technological Measures means those measures that, in the\n     absence of proper authority, may not be circumvented under laws\n     fulfilling obligations under Article 11 of the WIPO Copyright\n     Treaty adopted on December 20, 1996, and/or similar international\n     agreements.\n\n  e. Exceptions and Limitations means fair use, fair dealing, and/or\n     any other exception or limitation to Copyright and Similar Rights\n     that applies to Your use of the Licensed Material.\n\n  f. Licensed Material means the artistic or literary work, database,\n     or other material to which the Licensor applied this Public\n     License.\n\n  g. Licensed Rights means the rights granted to You subject to the\n     terms and conditions of this Public License, which are limited to\n     all Copyright and Similar Rights that apply to Your use of the\n     Licensed Material and that the Licensor has authority to license.\n\n  h. Licensor means the individual(s) or entity(ies) granting rights\n     under this Public License.\n\n  i. Share means to provide material to the public by any means or\n     process that requires permission under the Licensed Rights, such\n     as reproduction, public display, public performance, distribution,\n     dissemination, communication, or importation, and to make material\n     available to the public including in ways that members of the\n     public may access the material from a place and at a time\n     individually chosen by them.\n\n  j. Sui Generis Database Rights means rights other than copyright\n     resulting from Directive 96/9/EC of the European Parliament and of\n     the Council of 11 March 1996 on the legal protection of databases,\n     as amended and/or succeeded, as well as other essentially\n     equivalent rights anywhere in the world.\n\n  k. You means the individual or entity exercising the Licensed Rights\n     under this Public License. Your has a corresponding meaning.\n\n\nSection 2 -- Scope.\n\n  a. License grant.\n\n       1. Subject to the terms and conditions of this Public License,\n          the Licensor hereby grants You a worldwide, royalty-free,\n          non-sublicensable, non-exclusive, irrevocable license to\n          exercise the Licensed Rights in the Licensed Material to:\n\n            a. reproduce and Share the Licensed Material, in whole or\n               in part; and\n\n            b. produce, reproduce, and Share Adapted Material.\n\n       2. Exceptions and Limitations. For the avoidance of doubt, where\n          Exceptions and Limitations apply to Your use, this Public\n          License does not apply, and You do not need to comply with\n          its terms and conditions.\n\n       3. Term. The term of this Public License is specified in Section\n          6(a).\n\n       4. Media and formats; technical modifications allowed. The\n          Licensor authorizes You to exercise the Licensed Rights in\n          all media and formats whether now known or hereafter created,\n          and to make technical modifications necessary to do so. The\n          Licensor waives and/or agrees not to assert any right or\n          authority to forbid You from making technical modifications\n          necessary to exercise the Licensed Rights, including\n          technical modifications necessary to circumvent Effective\n          Technological Measures. For purposes of this Public License,\n          simply making modifications authorized by this Section 2(a)\n          (4) never produces Adapted Material.\n\n       5. Downstream recipients.\n\n            a. Offer from the Licensor -- Licensed Material. Every\n               recipient of the Licensed Material automatically\n               receives an offer from the Licensor to exercise the\n               Licensed Rights under the terms and conditions of this\n               Public License.\n\n            b. No downstream restrictions. You may not offer or impose\n               any additional or different terms or conditions on, or\n               apply any Effective Technological Measures to, the\n               Licensed Material if doing so restricts exercise of the\n               Licensed Rights by any recipient of the Licensed\n               Material.\n\n       6. No endorsement. Nothing in this Public License constitutes or\n          may be construed as permission to assert or imply that You\n          are, or that Your use of the Licensed Material is, connected\n          with, or sponsored, endorsed, or granted official status by,\n          the Licensor or others designated to receive attribution as\n          provided in Section 3(a)(1)(A)(i).\n\n  b. Other rights.\n\n       1. Moral rights, such as the right of integrity, are not\n          licensed under this Public License, nor are publicity,\n          privacy, and/or other similar personality rights; however, to\n          the extent possible, the Licensor waives and/or agrees not to\n          assert any such rights held by the Licensor to the limited\n          extent necessary to allow You to exercise the Licensed\n          Rights, but not otherwise.\n\n       2. Patent and trademark rights are not licensed under this\n          Public License.\n\n       3. To the extent possible, the Licensor waives any right to\n          collect royalties from You for the exercise of the Licensed\n          Rights, whether directly or through a collecting society\n          under any voluntary or waivable statutory or compulsory\n          licensing scheme. In all other cases the Licensor expressly\n          reserves any right to collect such royalties.\n\n\nSection 3 -- License Conditions.\n\nYour exercise of the Licensed Rights is expressly made subject to the\nfollowing conditions.\n\n  a. Attribution.\n\n       1. If You Share the Licensed Material (including in modified\n          form), You must:\n\n            a. retain the following if it is supplied by the Licensor\n               with the Licensed Material:\n\n                 i. identification of the creator(s) of the Licensed\n                    Material and any others designated to receive\n                    attribution, in any reasonable manner requested by\n                    the Licensor (including by pseudonym if\n                    designated);\n\n                ii. a copyright notice;\n\n               iii. a notice that refers to this Public License;\n\n                iv. a notice that refers to the disclaimer of\n                    warranties;\n\n                 v. a URI or hyperlink to the Licensed Material to the\n                    extent reasonably practicable;\n\n            b. indicate if You modified the Licensed Material and\n               retain an indication of any previous modifications; and\n\n            c. indicate the Licensed Material is licensed under this\n               Public License, and include the text of, or the URI or\n               hyperlink to, this Public License.\n\n       2. You may satisfy the conditions in Section 3(a)(1) in any\n          reasonable manner based on the medium, means, and context in\n          which You Share the Licensed Material. For example, it may be\n          reasonable to satisfy the conditions by providing a URI or\n          hyperlink to a resource that includes the required\n          information.\n\n       3. If requested by the Licensor, You must remove any of the\n          information required by Section 3(a)(1)(A) to the extent\n          reasonably practicable.\n\n       4. If You Share Adapted Material You produce, the Adapter's\n          License You apply must not prevent recipients of the Adapted\n          Material from complying with this Public License.\n\n\nSection 4 -- Sui Generis Database Rights.\n\nWhere the Licensed Rights include Sui Generis Database Rights that\napply to Your use of the Licensed Material:\n\n  a. for the avoidance of doubt, Section 2(a)(1) grants You the right\n     to extract, reuse, reproduce, and Share all or a substantial\n     portion of the contents of the database;\n\n  b. if You include all or a substantial portion of the database\n     contents in a database in which You have Sui Generis Database\n     Rights, then the database in which You have Sui Generis Database\n     Rights (but not its individual contents) is Adapted Material; and\n\n  c. You must comply with the conditions in Section 3(a) if You Share\n     all or a substantial portion of the contents of the database.\n\nFor the avoidance of doubt, this Section 4 supplements and does not\nreplace Your obligations under this Public License where the Licensed\nRights include other Copyright and Similar Rights.\n\n\nSection 5 -- Disclaimer of Warranties and Limitation of Liability.\n\n  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE\n     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS\n     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF\n     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,\n     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,\n     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR\n     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,\n     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT\n     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT\n     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.\n\n  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE\n     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,\n     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,\n     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,\n     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR\n     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN\n     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR\n     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR\n     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.\n\n  c. The disclaimer of warranties and limitation of liability provided\n     above shall be interpreted in a manner that, to the extent\n     possible, most closely approximates an absolute disclaimer and\n     waiver of all liability.\n\n\nSection 6 -- Term and Termination.\n\n  a. This Public License applies for the term of the Copyright and\n     Similar Rights licensed here. However, if You fail to comply with\n     this Public License, then Your rights under this Public License\n     terminate automatically.\n\n  b. Where Your right to use the Licensed Material has terminated under\n     Section 6(a), it reinstates:\n\n       1. automatically as of the date the violation is cured, provided\n          it is cured within 30 days of Your discovery of the\n          violation; or\n\n       2. upon express reinstatement by the Licensor.\n\n     For the avoidance of doubt, this Section 6(b) does not affect any\n     right the Licensor may have to seek remedies for Your violations\n     of this Public License.\n\n  c. For the avoidance of doubt, the Licensor may also offer the\n     Licensed Material under separate terms or conditions or stop\n     distributing the Licensed Material at any time; however, doing so\n     will not terminate this Public License.\n\n  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public\n     License.\n\n\nSection 7 -- Other Terms and Conditions.\n\n  a. The Licensor shall not be bound by any additional or different\n     terms or conditions communicated by You unless expressly agreed.\n\n  b. Any arrangements, understandings, or agreements regarding the\n     Licensed Material not stated herein are separate from and\n     independent of the terms and conditions of this Public License.\n\n\nSection 8 -- Interpretation.\n\n  a. For the avoidance of doubt, this Public License does not, and\n     shall not be interpreted to, reduce, limit, restrict, or impose\n     conditions on any use of the Licensed Material that could lawfully\n     be made without permission under this Public License.\n\n  b. To the extent possible, if any provision of this Public License is\n     deemed unenforceable, it shall be automatically reformed to the\n     minimum extent necessary to make it enforceable. If the provision\n     cannot be reformed, it shall be severed from this Public License\n     without affecting the enforceability of the remaining terms and\n     conditions.\n\n  c. No term or condition of this Public License will be waived and no\n     failure to comply consented to unless expressly agreed to by the\n     Licensor.\n\n  d. Nothing in this Public License constitutes or may be interpreted\n     as a limitation upon, or waiver of, any privileges and immunities\n     that apply to the Licensor or You, including from the legal\n     processes of any jurisdiction or authority.\n\n\n=======================================================================\n\nCreative Commons is not a party to its public\nlicenses. Notwithstanding, Creative Commons may elect to apply one of\nits public licenses to material it publishes and in those instances\nwill be considered the “Licensor.” The text of the Creative Commons\npublic licenses is dedicated to the public domain under the CC0 Public\nDomain Dedication. Except for the limited purpose of indicating that\nmaterial is shared under a Creative Commons public license or as\notherwise permitted by the Creative Commons policies published at\ncreativecommons.org/policies, Creative Commons does not authorize the\nuse of the trademark \"Creative Commons\" or any other trademark or logo\nof Creative Commons without its prior written consent including,\nwithout limitation, in connection with any unauthorized modifications\nto any of its public licenses or any other arrangements,\nunderstandings, or agreements concerning use of licensed material. For\nthe avoidance of doubt, this paragraph does not form part of the\npublic licenses.\n\nCreative Commons may be contacted at creativecommons.org.\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "docs/README.md",
    "content": "# ramsey/uuid Documentation\n\nChanges to the documentation are automatically built by [Read the Docs][] and viewable from <https://uuid.ramsey.dev>.\n\n## Getting Started\n\nIt's probably best to do this in a virtualenv environment, so set one up first:\n\n``` bash\npip install virtualenvwrapper\nmkvirtualenv ramsey-uuid-docs\ncd docs/\nworkon ramsey-uuid-docs\npip install -r requirements.txt\n```\n\n## Building the Docs\n\nTo build the docs, change to the `docs/` directory, and make sure you're working on the virtualenv environment created\nin the last step.\n\n``` bash\ncd docs/\nworkon ramsey-uuid-docs\nmake html\n```\n\nThen, to view the docs after building them:\n\n``` bash\nopen _build/html/index.html\n```\n\n[read the docs]: https://readthedocs.org\n"
  },
  {
    "path": "docs/_static/.gitkeep",
    "content": ""
  },
  {
    "path": "docs/conf.py",
    "content": "# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common options. For a full\n# list see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\n# -- Path setup --------------------------------------------------------------\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n\nimport os\nimport sphinx_rtd_theme\nimport sys\nimport datetime\n\nfrom pygments.lexers.web import PhpLexer\nfrom sphinx.highlighting import lexers\nfrom subprocess import Popen, PIPE\n\ndef get_version():\n    if os.environ.get('READTHEDOCS') == 'True':\n        return os.environ.get('READTHEDOCS_VERSION')\n\n    pipe = Popen('git branch | grep \\\\*', stdout=PIPE, shell=True, universal_newlines=True)\n    version = pipe.stdout.read()\n\n    if version:\n        return version[2:]\n    else:\n        return 'unknown'\n\n\n# -- Project information -----------------------------------------------------\n\nproject = 'ramsey/uuid'\ncopyright = '2012-{year}, Ben Ramsey'.format(year = datetime.date.today().strftime('%Y'))\nauthor = 'Ben Ramsey'\n\nversion = get_version().strip()\nrelease = version\n\ntoday = datetime.date.today().strftime('%Y-%m-%d')\n\n\n# -- General configuration ---------------------------------------------------\n\nmaster_doc = 'index'\nhighlight_language = 'php'\n\n# enable highlighting for PHP code not between ``<?php ... ?>`` by default\nlexers['php'] = PhpLexer(startinline=True)\nlexers['php-annotations'] = PhpLexer(startinline=True)\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc',\n    'sphinx.ext.todo',\n    'sphinxcontrib.phpdomain',\n]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This pattern also affects html_static_path and html_extra_path.\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\npygments_style = 'sphinx'\n\n\n# -- Options for HTML output -------------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\nhtml_theme = \"sphinx_rtd_theme\"\nhtml_theme_options = {\n    'collapse_navigation': False,\n    'display_version': False\n}\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\nhtml_title = \"ramsey/uuid %s Manual\" % get_version()\nhtml_show_sphinx = False\n\nhtmlhelp_basename = 'ramsey-uuid-doc'\n\nhtml_context = {\n    \"display_github\": True,\n    \"github_user\": \"ramsey\",\n    \"github_repo\": \"uuid\",\n    \"github_version\": version,\n    \"conf_py_path\": \"/docs/\",\n}\n\ncurrent_year = datetime.date.today().strftime('%Y')\nrst_prolog = \"\"\"\n.. |current_year| replace:: {0}\n\"\"\".format(current_year)\n"
  },
  {
    "path": "docs/copyright.rst",
    "content": ".. _copyright:\n\n=========\nCopyright\n=========\n\nCopyright © 2012-|current_year| `Ben Ramsey <https://benramsey.com>`_ and\n`contributors <https://github.com/ramsey/uuid/contributors>`_.\n\nDocumentation for ramsey/uuid is licensed under the Creative Commons Attribution 4.0 International License. To view a\ncopy of this license, visit http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box\n1866, Mountain View, CA 94042, USA.\n\nramsey/uuid is open source software: you can distribute it and/or modify it under the terms of the MIT License (the\n\"License\"). You may not use ramsey/uuid except in compliance with the License.\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an\n\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific\nlanguage governing permissions and limitations under the License.\n\nYou should have received a copy of the MIT License along with this program. If not, see\nhttps://opensource.org/license/mit/.\n"
  },
  {
    "path": "docs/customize/calculators.rst",
    "content": ".. _customize.calculators:\n\n=========================\nUsing a Custom Calculator\n=========================\n\nBy default, ramsey/uuid uses `brick/math`_  as its internal calculator. However, you may change the calculator, if your\nneeds require something else.\n\nTo swap the default calculator with your custom one, first make an adapter that wraps your custom calculator and\nimplements :php:interface:`Ramsey\\\\Uuid\\\\Math\\\\CalculatorInterface`. This might look something like this:\n\n.. code-block:: php\n    :caption: Create a custom calculator wrapper that implements CalculatorInterface\n    :name: customize.calculators.wrapper-example\n\n    namespace MyProject;\n\n    use Other\\OtherCalculator;\n    use Ramsey\\Uuid\\Math\\CalculatorInterface;\n    use Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n    use Ramsey\\Uuid\\Type\\NumberInterface;\n\n    class MyUuidCalculator implements CalculatorInterface\n    {\n        private $internalCalculator;\n\n        public function __construct(OtherCalculator $customCalculator)\n        {\n            $this->internalCalculator = $customCalculator;\n        }\n\n        public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface\n        {\n            $value = $augend->toString();\n\n            foreach ($addends as $addend) {\n                $value = $this->internalCalculator->plus($value, $addend->toString());\n            }\n\n            return new IntegerObject($value);\n        }\n\n        /* ... Class truncated for brevity ... */\n\n    }\n\nThe easiest way to use your custom calculator wrapper is to instantiate a new FeatureSet, set the calculator on it, and\npass the FeatureSet into a new UuidFactory. Using the factory, you may then generate and work with UUIDs, using your\ncustom calculator.\n\n.. code-block:: php\n    :caption: Use your custom calculator wrapper when working with UUIDs\n    :name: customize.calculators.use-wrapper-example\n\n    use MyProject\\MyUuidCalculator;\n    use Other\\OtherCalculator;\n    use Ramsey\\Uuid\\FeatureSet;\n    use Ramsey\\Uuid\\UuidFactory;\n\n    $otherCalculator = new OtherCalculator();\n    $myUuidCalculator = new MyUuidCalculator($otherCalculator);\n\n    $featureSet = new FeatureSet();\n    $featureSet->setCalculator($myUuidCalculator);\n\n    $factory = new UuidFactory($featureSet);\n\n    $uuid = $factory->uuid1();\n\n.. _brick/math: https://github.com/brick/math\n"
  },
  {
    "path": "docs/customize/factory.rst",
    "content": ".. _customize.factory:\n\n===========================\nReplace the Default Factory\n===========================\n\nIn many of the examples throughout this documentation, we've seen how to configure the factory and then use that factory\nto generate and work with UUIDs.\n\nFor example:\n\n.. code-block:: php\n    :caption: Configure the factory and use it to generate a version 1 UUID\n    :name: customize.factory.example\n\n    use Ramsey\\Uuid\\Codec\\OrderedTimeCodec;\n    use Ramsey\\Uuid\\UuidFactory;\n\n    $factory = new UuidFactory();\n    $codec = new OrderedTimeCodec($factory->getUuidBuilder());\n\n    $factory->setCodec($codec);\n\n    $orderedTimeUuid = $factory->uuid1();\n\nWhen doing this, the default behavior of ramsey/uuid is left intact. If we call ``Uuid::uuid1()`` to generate a version\n1 UUID after configuring the factory as shown above, it won't use :ref:`OrderedTimeCodec <customize.ordered-time-codec>`\nto generate the UUID.\n\n.. code-block:: php\n    :caption: The behavior differs between $factory->uuid1() and Uuid::uuid1()\n    :name: customize.factory.behavior-example\n\n    $orderedTimeUuid = $factory->uuid1();\n\n    printf(\n        \"UUID: %s\\nBytes: %s\\n\\n\",\n        $orderedTimeUuid->toString(),\n        bin2hex($orderedTimeUuid->getBytes())\n    );\n\n    $uuid = Uuid::uuid1();\n\n    printf(\n        \"UUID: %s\\nBytes: %s\\n\\n\",\n        $uuid->toString(),\n        bin2hex($uuid->getBytes())\n    );\n\nIn this example, we print out details for two different UUIDs. The first was generated with the :ref:`OrderedTimeCodec\n<customize.ordered-time-codec>` using ``$factory->uuid1()``. The second was generated using ``Uuid::uuid1()``. It looks\nsomething like this:\n\n.. code-block:: text\n\n    UUID: 2ff06620-6251-11ea-9791-0242ac130003\n    Bytes: 11ea62512ff0662097910242ac130003\n\n    UUID: 2ff09730-6251-11ea-ba64-0242ac130003\n    Bytes: 2ff09730625111eaba640242ac130003\n\nNotice the arrangement of the bytes. The first set of bytes has been rearranged, according to the ordered-time codec\nrules, but the second set of bytes remains in the same order as the UUID string.\n\n*Configuring the factory does not change the default behavior.*\n\nIf we want to change the default behavior, we must *replace* the factory used by the Uuid static methods, and we can do\nthis using the :php:meth:`Uuid::setFactory() <Ramsey\\\\Uuid\\\\Uuid::setFactory>` static method.\n\n.. code-block:: php\n    :caption: Replace the factory to globally affect Uuid behavior\n    :name: customize.factory.replace-factory-example\n\n    Uuid::setFactory($factory);\n\n    $uuid = Uuid::uuid1();\n\nNow, every time we call :php:meth:`Uuid::uuid() <Ramsey\\\\Uuid\\\\Uuid::uuid1>`, ramsey/uuid will use the factory configured\nwith the :ref:`OrderedTimeCodec <customize.ordered-time-codec>` to generate version 1 UUIDs.\n\n.. warning::\n\n    Calling :php:meth:`Uuid::setFactory() <Ramsey\\\\Uuid\\\\Uuid::setFactory>` to replace the factory will change the\n    behavior of Uuid no matter where it is used, so keep this in mind when replacing the factory. If you replace the\n    factory deep inside a method somewhere, any later code that calls a static method on :php:class:`Ramsey\\\\Uuid\\\\Uuid`\n    will use the new factory to generate UUIDs.\n"
  },
  {
    "path": "docs/customize/ordered-time-codec.rst",
    "content": ".. _customize.ordered-time-codec:\n\n==================\nOrdered-time Codec\n==================\n\n.. attention::\n\n    The :php:class:`Ramsey\\\\Uuid\\\\Codec\\\\OrderedTimeCodec` class is deprecated. Please migrate to\n    :ref:`version 6, reordered Gregorian time UUIDs <rfc4122.version6>`.\n\nUUIDs arrange their bytes according to the standard recommended by `RFC 9562`_ (formerly `RFC 4122`_). Unfortunately,\nthis means the bytes aren't in an arrangement that supports sorting by creation time or an otherwise incrementing value.\nThe Percona article, \"`Storing UUID Values in MySQL`_,\" explains at length the problems this can cause. It also\nrecommends a solution: the *ordered-time UUID*.\n\n`RFC 9562 version 1, Gregorian time UUIDs <https://www.rfc-editor.org/rfc/rfc9562#section-5.1>`_ rearrange the bytes of\nthe time fields so that the lowest bytes appear first, the middle bytes are next, and the highest bytes come last.\nLogical sorting is not possible with this arrangement.\n\nAn ordered-time UUID is a version 1 UUID with the time fields arranged in logical order so that the UUIDs can be sorted\nby creation time. These UUIDs are *monotonically increasing*, each one coming after the previously-created one, in a\nproper sort order.\n\n.. code-block:: php\n    :caption: Use the ordered-time codec to generate a version 1 UUID\n    :name: customize.ordered-time-codec-example\n\n    use Ramsey\\Uuid\\Codec\\OrderedTimeCodec;\n    use Ramsey\\Uuid\\UuidFactory;\n\n    $factory = new UuidFactory();\n    $codec = new OrderedTimeCodec($factory->getUuidBuilder());\n\n    $factory->setCodec($codec);\n\n    $orderedTimeUuid = $factory->uuid1();\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\nDate: %s\\nNode: %s\\nBytes: %s\\n\",\n        $orderedTimeUuid->toString(),\n        $orderedTimeUuid->getFields()->getVersion(),\n        $orderedTimeUuid->getDateTime()->format('r'),\n        $orderedTimeUuid->getFields()->getNode()->toString(),\n        bin2hex($orderedTimeUuid->getBytes())\n    );\n\nThis will use the ordered-time codec to generate a version 1 UUID and will print out details about the UUID similar to these:\n\n.. code-block:: text\n\n    UUID: 593200aa-61ae-11ea-bbf2-0242ac130003\n    Version: 1\n    Date: Mon, 09 Mar 2020 02:33:23 +0000\n    Node: 0242ac130003\n    Bytes: 11ea61ae593200aabbf20242ac130003\n\n.. attention::\n\n    Only the byte representation is rearranged. The string representation follows the format of a standard version 1\n    UUID. This means only the byte representation of an ordered-time codec encoded UUID may be used for sorting, such as\n    with database results.\n\n    To store the byte representation to a database field, see :ref:`database.bytes`.\n\n.. hint::\n\n    If you use this codec and store the bytes of the UUID to the database, as recommended above, you will need to use\n    this codec to decode the bytes, as well. Otherwise, the UUID string value will be incorrect.\n\n    .. code-block:: php\n\n        // Using a factory configured with the OrderedTimeCodec, as shown above.\n        $orderedTimeUuid = $factory->fromBytes($bytes);\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _Storing UUID Values in MySQL: https://www.percona.com/blog/store-uuid-optimized-way/\n"
  },
  {
    "path": "docs/customize/timestamp-first-comb-codec.rst",
    "content": ".. _customize.timestamp-first-comb-codec:\n\n==========================\nTimestamp-first COMB Codec\n==========================\n\n.. attention::\n\n    The :php:class:`Ramsey\\\\Uuid\\\\Codec\\\\TimestampFirstCombCodec` class is deprecated. Please migrate to\n    :ref:`version 7, Unix Epoch time UUIDs <rfc4122.version7>`.\n\n:ref:`Version 4, random UUIDs <rfc4122.version4>` are doubly problematic when it comes to sorting and storing to\ndatabases (see :ref:`database.order`), since their values are random, and there is no timestamp associated with them\nthat may be rearranged, like with the :ref:`ordered-time codec <customize.ordered-time-codec>`. In 2002, Jimmy Nilsson\nrecognized this problem with random UUIDs and proposed a solution he called \"COMBs\" (see \"`The Cost of GUIDs as Primary\nKeys`_\").\n\nSo-called because they *combine* random bytes with a timestamp, the timestamp-first COMB codec replaces the first 48\nbits of a version 4, random UUID with a Unix timestamp and microseconds, creating an identifier that can be sorted by\ncreation time. These UUIDs are *monotonically increasing*, each one coming after the previously-created one, in a proper\nsort order.\n\n.. code-block:: php\n    :caption: Use the timestamp-first COMB codec to generate a version 4 UUID\n    :name: customize.timestamp-first-comb-codec-example\n\n    use Ramsey\\Uuid\\Codec\\TimestampFirstCombCodec;\n    use Ramsey\\Uuid\\Generator\\CombGenerator;\n    use Ramsey\\Uuid\\UuidFactory;\n\n    $factory = new UuidFactory();\n    $codec = new TimestampFirstCombCodec($factory->getUuidBuilder());\n\n    $factory->setCodec($codec);\n\n    $factory->setRandomGenerator(new CombGenerator(\n        $factory->getRandomGenerator(),\n        $factory->getNumberConverter()\n    ));\n\n    $timestampFirstComb = $factory->uuid4();\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\nBytes: %s\\n\",\n        $timestampFirstComb->toString(),\n        $timestampFirstComb->getFields()->getVersion(),\n        bin2hex($timestampFirstComb->getBytes())\n    );\n\nThis will use the timestamp-first COMB codec to generate a version 4 UUID with the timestamp replacing the first 48 bits\nand will print out details about the UUID similar to these:\n\n.. code-block:: text\n\n    UUID: 9009ebcc-cd99-4b5f-90cf-9155607d2de9\n    Version: 4\n    Bytes: 9009ebcccd994b5f90cf9155607d2de9\n\nNote that the bytes are in the same order as the string representation. Unlike the :ref:`ordered-time codec\n<customize.ordered-time-codec>`, the timestamp-first COMB codec affects both the string representation and the byte\nrepresentation. This means either the string UUID or the bytes may be stored to a datastore and sorted. To learn more,\nsee :ref:`database`.\n\n.. _The Cost of GUIDs as Primary Keys: https://web.archive.org/web/20240118030355/https://www.informit.com/articles/printerfriendly/25862\n"
  },
  {
    "path": "docs/customize/validators.rst",
    "content": ".. _customize.validators:\n\n========================\nUsing a Custom Validator\n========================\n\nBy default, ramsey/uuid validates UUID strings with the lenient validator :php:class:`Ramsey\\\\Uuid\\\\Validator\\\\GenericValidator`.\nThis validator ensures the string is 36 characters, has the dashes in the correct places, and uses only hexadecimal\nvalues. It does not ensure the string is of the `RFC 9562`_ (formerly `RFC 4122`_) variant or contains a valid version.\n\nThe validator :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\Validator` validates UUID strings to ensure they match the `RFC 9562`_\n(formerly `RFC 4122`_) variant and contain a valid version. Since it is not enabled by default, you will need to\nconfigure ramsey/uuid to use it, if you want stricter validation.\n\n.. code-block:: php\n    :caption: Set an alternate validator to use for Uuid::isValid()\n    :name: customize.validators-example\n\n    use Ramsey\\Uuid\\Rfc4122\\Validator as Rfc4122Validator;\n    use Ramsey\\Uuid\\Uuid;\n    use Ramsey\\Uuid\\UuidFactory;\n\n    $factory = new UuidFactory();\n    $factory->setValidator(new Rfc4122Validator());\n\n    Uuid::setFactory($factory);\n\n    if (!Uuid::isValid('2bfb5006-087b-9553-5082-e8f39337ad29')) {\n        echo \"This UUID is not valid!\\n\";\n    }\n\n.. tip::\n\n    If you want to use your own validation, create a class that implements :php:interface:`Ramsey\\\\Uuid\\\\Validator\\\\ValidatorInterface`\n    and use the same method to set your validator on the factory.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/customize.rst",
    "content": ".. _customize:\n\n=============\nCustomization\n=============\n\n.. toctree::\n    :titlesonly:\n    :hidden:\n\n    customize/ordered-time-codec\n    customize/timestamp-first-comb-codec\n    customize/calculators\n    customize/validators\n    customize/factory\n\nramsey/uuid offers a variety of ways to modify the standard behavior of the library through dependency injection. Using\n`FeatureSet`_, `UuidFactory`_, and :php:meth:`Uuid::setFactory() <Ramsey\\\\Uuid\\\\Uuid::setFactory()>`, you are able to\nreplace just about any `builder`_, `codec`_, `converter`_, `generator`_, `provider`_, and more.\n\nOrdered-time Codec *(deprecated)*\n    The ordered-time codec exists to rearrange the bytes of a version 1, Gregorian time UUID so that the timestamp\n    portion of the UUID is monotonically increasing. To learn more, see :ref:`customize.ordered-time-codec`.\n\nTimestamp-first COMB Codec *(deprecated)*\n    The timestamp-first COMB codec replaces part of a version 4, random UUID with a timestamp, so that the UUID becomes\n    monotonically increasing. To learn more, see :ref:`customize.timestamp-first-comb-codec`.\n\nUsing a Custom Calculator\n    It's possible to replace the default calculator ramsey/uuid uses. If your requirements require a different solution\n    for making calculations, see :ref:`customize.calculators`.\n\nUsing a Custom Validator\n    If your requirements require a different level of validation or a different UUID format, you may replace the default\n    validator. See :ref:`customize.validators`, to learn more.\n\nReplace the Default Factory\n    Not only are you able to inject alternate builders, codecs, etc. into the factory and use the factory to generate\n    UUIDs, you may also replace the global, static factory used by the static methods on the Uuid class. To find out\n    how, see :ref:`customize.factory`.\n\n.. _UuidFactory: https://github.com/ramsey/uuid/blob/4.x/src/UuidFactory.php\n.. _FeatureSet: https://github.com/ramsey/uuid/blob/4.x/src/FeatureSet.php\n.. _codec: https://github.com/ramsey/uuid/tree/4.x/src/Codec\n.. _builder: https://github.com/ramsey/uuid/tree/4.x/src/Builder\n.. _converter: https://github.com/ramsey/uuid/tree/4.x/src/Converter\n.. _provider: https://github.com/ramsey/uuid/tree/4.x/src/Provider\n.. _generator: https://github.com/ramsey/uuid/tree/4.x/src/Generator\n"
  },
  {
    "path": "docs/database.rst",
    "content": ".. _database:\n\n===================\nUsing In a Database\n===================\n\n.. tip::\n\n    `ramsey/uuid-doctrine`_ allows the use of ramsey/uuid as a `Doctrine field type`_. If you use Doctrine, it's a great\n    option for working with UUIDs and databases.\n\nThere are several strategies to consider when working with UUIDs in a database. Among these are whether to store the\nstring representation or bytes and whether the UUID column should be treated as a primary key. We'll discuss a few of\nthese approaches here, but the final decision on how to use UUIDs in a database is up to you since your needs will be\ndifferent from those of others.\n\n.. note::\n\n    All database code examples in this section assume the use of `MariaDB`_ and `PHP Data Objects (PDO)`_. If using a\n    different database engine or connection library, your code will differ, but the general concepts should remain the\n    same.\n\n.. _database.string:\n\nStoring As a String\n###################\n\nPerhaps the easiest way to store a UUID to a database is to create a ``char(36)`` column and store the UUID as a string.\nWhen stored as a string, UUIDs require no special treatment in SQL statements or when displaying them.\n\nThe primary drawback is the size. At 36 characters, UUIDs can take up a lot of space, and when handling a lot of data,\nthis can add up.\n\n.. code-block:: sql\n    :caption: Create a table with a column for UUIDs\n    :name: database.uuid-column-example\n\n    CREATE TABLE `notes` (\n        `uuid` char(36) NOT NULL,\n        `notes` text NOT NULL\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\nUsing this database table, we can store the string UUID using code similar to this (assume some of the variables in this\nexample have been set beforehand):\n\n.. code-block:: php\n    :caption: Store a string UUID to the uuid column\n    :name: database.uuid-column-store-example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid4();\n\n    $dbh = new PDO($dsn, $username, $password);\n\n    $sth = $dbh->prepare('\n        INSERT INTO notes (\n            uuid,\n            notes\n        ) VALUES (\n            :uuid,\n            :notes\n        )\n    ');\n\n    $sth->execute([\n        ':uuid' => $uuid->toString(),\n        ':notes' => $notes,\n    ]);\n\n.. _database.bytes:\n\nStoring As Bytes\n################\n\nIn :ref:`the previous example <database.uuid-column-store-example>`, we saw how to store the string representation of a\nUUID to a ``char(36)`` column. As discussed, the primary drawback is the size. However, if we store the UUID in byte\nform, we only need a ``char(16)`` column, saving over half the space.\n\nThe primary drawback with this approach is ease-of-use. Since the UUID bytes are stored in the database, querying and\nselecting data becomes more difficult.\n\n.. code-block:: sql\n    :caption: Create a table with a column for UUID bytes\n    :name: database.uuid-bytes-example\n\n    CREATE TABLE `notes` (\n        `uuid` char(16) NOT NULL,\n        `notes` text NOT NULL\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\nUsing this database table, we can store the UUID bytes using code similar to this (again, assume some of the variables\nin this example have been set beforehand):\n\n.. code-block:: php\n    :caption: Store UUID bytes to the uuid column\n    :name: database.uuid-bytes-store-example\n\n    $sth->execute([\n        ':uuid' => $uuid->getBytes(),\n        ':notes' => $notes,\n    ]);\n\nNow, when we ``SELECT`` the records from the database, we will need to convert the ``notes.uuid`` column to a\nramsey/uuid object, so that we are able to use it.\n\n.. code-block:: php\n    :caption: Covert database UUID bytes to UuidInterface instance\n    :name: database.uuid-bytes-convert-example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid4();\n\n    $dbh = new PDO($dsn, $username, $password);\n\n    $sth = $dbh->prepare('SELECT uuid, notes FROM notes');\n    $sth->execute();\n\n    foreach ($sth->fetchAll() as $record) {\n        $uuid = Uuid::fromBytes($record['uuid']);\n\n        printf(\n            \"UUID: %s\\nNotes: %s\\n\\n\",\n            $uuid->toString(),\n            $record['notes']\n        );\n    }\n\nWe'll also need to query the database using the bytes.\n\n.. code-block:: php\n    :caption: Look-up the record from the database, using the UUID bytes\n    :name: database.uuid-bytes-select-example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::fromString('278198d3-fa96-4833-abab-82f9e67f4712');\n\n    $dbh = new PDO($dsn, $username, $password);\n\n    $sth = $dbh->prepare('\n        SELECT uuid, notes\n        FROM notes\n        WHERE uuid = :uuid\n    ');\n\n    $sth->execute([\n        ':uuid' => $uuid->getBytes(),\n    ]);\n\n    $record = $sth->fetch();\n\n    if ($record) {\n        $uuid = Uuid::fromBytes($record['uuid']);\n\n        printf(\n            \"UUID: %s\\nNotes: %s\\n\\n\",\n            $uuid->toString(),\n            $record['notes']\n        );\n    }\n\n.. _database.pk:\n\nUsing As a Primary Key\n######################\n\nIn the previous examples, we didn't use the UUID as a primary key, but it's logical to use the ``notes.uuid`` field as a\nprimary key. There's nothing wrong with this approach, but there are a couple of points to consider:\n\n* InnoDB stores data in the primary key order\n* All the secondary keys also contain the primary key (in InnoDB)\n\nWe'll deal with the first point in the section, :ref:`database.order`. For the second point, if you are using the string\nversion of the UUID (i.e., ``char(36)``), then not only will the primary key be large and take up a lot of space, but\nevery secondary key that uses that primary key will also be much larger.\n\nFor this reason, if you choose to use UUIDs as primary keys, it might be worth the drawbacks to use UUID bytes (i.e.,\n``char(16)``) instead of the string representation (see :ref:`database.bytes`).\n\n.. hint::\n\n    If not using InnoDB with MySQL or MariaDB, consult your database engine documentation to find whether it also has\n    similar properties that will factor into your use of UUIDs.\n\n.. _database.uk:\n\nUsing As a Unique Key\n#####################\n\nInstead of :ref:`using UUIDs as a primary key <database.pk>`, you may choose to use an ``AUTO_INCREMENT`` column with\nthe ``int unsigned`` data type as a primary key, while using a ``char(36)`` for UUIDs and setting a ``UNIQUE KEY`` on\nthis column. This will aid in lookups while helping keep your secondary keys small.\n\n.. code-block:: sql\n    :caption: Use an auto-incrementing column as primary key, with UUID as a unique key\n    :name: database.id-auto-increment-uuid-unique-key\n\n    CREATE TABLE `notes` (\n        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,\n        `uuid` char(36) NOT NULL,\n        `notes` text NOT NULL,\n        PRIMARY KEY (`id`),\n        UNIQUE KEY `notes_uuid_uk` (`uuid`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\n.. _database.order:\n\nInsertion Order and Sorting\n###########################\n\nUUID versions 1, 2, 3, 4, and 5 are not *monotonically increasing*. If using these versions as primary keys, the inserts\nwill be random, and the data will be scattered on disk (for InnoDB). Over time, as the database size grows, lookups will\nbecome slower and slower.\n\n.. tip::\n\n    See Percona's \"`Storing UUID Values in MySQL`_\" post, for more details on the performance of UUIDs as primary keys.\n\nTo minimize these problems, two solutions have been devised:\n\n1. :ref:`rfc4122.version6` UUIDs\n2. :ref:`rfc4122.version7` UUIDs\n\n.. note::\n\n    We previously recommended the use of the :ref:`timestamp-first COMB <customize.timestamp-first-comb-codec>` or\n    :ref:`ordered-time <customize.ordered-time-codec>` codecs to solve these problems. However, UUID versions 6 and 7\n    were defined to provide these solutions in a standardized way.\n\n.. _ramsey/uuid-doctrine: https://github.com/ramsey/uuid-doctrine\n.. _Doctrine field type: https://www.doctrine-project.org/projects/doctrine-dbal/en/stable/reference/types.html\n.. _MariaDB: https://mariadb.org\n.. _PHP Data Objects (PDO): https://www.php.net/pdo\n.. _Storing UUID Values in MySQL: https://www.percona.com/blog/store-uuid-optimized-way/\n"
  },
  {
    "path": "docs/faq.rst",
    "content": ".. _faq:\n\n=================================\nFrequently Asked Questions (FAQs)\n=================================\n\n.. contents::\n    :local:\n    :depth: 1\n\n.. _faq.rhumsaa-abandoned:\n\nHow do I fix \"rhumsaa/uuid is abandoned\" messages?\n##################################################\n\nWhen installing your project's dependencies using Composer, you might see the following message:\n\n.. code-block:: text\n\n    Package rhumsaa/uuid is abandoned; you should avoid using it. Use ramsey/uuid instead.\n\nDon't panic. Simply execute the following commands with Composer:\n\n.. code-block:: bash\n\n    composer remove rhumsaa/uuid\n    composer require ramsey/uuid=^2.9\n\nAfter doing so, you will have the latest ramsey/uuid package in the 2.x series, and there will be no need to modify any\ncode; the namespace in the 2.x series is still ``Rhumsaa``.\n\n.. _faq.final:\n\nWhy does ramsey/uuid use ``final``?\n###################################\n\nYou might notice that many of the concrete classes returned in ramsey/uuid are marked as ``final``. There are specific\nreasons for this choice, and I will offer a few solutions for those looking to extend or mock the classes for testing\npurposes.\n\nBut Why?\n--------\n\n.. raw:: html\n\n    <div style=\"width:100%;height:0;padding-bottom:56%;position:relative;\">\n        <iframe src=\"https://giphy.com/embed/eauCbbW6MvqKI\" width=\"100%\" height=\"100%\" style=\"position:absolute\" frameBorder=\"0\" class=\"giphy-embed\" allowFullScreen></iframe>\n    </div>\n    <p><a href=\"https://giphy.com/gifs/eauCbbW6MvqKI\">via GIPHY</a></p>\n\nFirst, let's take a look at why ramsey/uuid uses ``final``.\n\nUUIDs are defined by a set of rules --- published as `RFC 9562`_ (formerly `RFC 4122`_) --- and those rules shouldn't\nchange. If they do, then it's no longer a UUID --- at least not as defined by `RFC 9562`_.\n\nAs an example, let's think about :php:class:`Rfc4122\\\\UuidV1 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1>`. If our application wants\nto do something special with this type, it might use the ``instanceof`` operator to check that a variable is a UuidV1,\nor it might use a type hint on a method argument. If a third-party library passes a UUID object to us that extends\nUuidV1 but overrides some very important internal logic, then we may no longer have a version 1 UUID. Perhaps we can all\nbe adults and play nicely, but ramsey/uuid cannot make any guarantees for any subclasses of UuidV1.\n\nHowever, ramsey/uuid *can* make guarantees about classes that implement :php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>`\nor :php:interface:`Rfc4122\\\\UuidInterface <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface>`.\n\nSo, if we're working with an instance of a class that is marked ``final``, we can guarantee that the rules for the\ncreation of that object will not change, even if a third-party library passes us an instance of the same class.\n\nThis is the reason why ramsey/uuid specifies certain :ref:`argument and return types <reference.types>` that are marked\n``final``. Since these are ``final``, ramsey/uuid is able to guarantee the type of data these value objects contain.\n:php:class:`Type\\\\Integer <Ramsey\\\\Uuid\\\\Type\\\\Integer>` should never contain any characters other than numeral digits,\nand :php:class:`Type\\\\Hexadecimal <Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>` should never contain any characters other than\nhexadecimal digits. If other libraries could extend these and return them from UUID instances, then ramsey/uuid cannot\nguarantee their values.\n\nThis is very similar to using strict types with ``int``, ``float``, or ``bool``. These types cannot change, so think of\nfinal classes in ramsey/uuid as types that cannot change.\n\nOverriding Behavior\n-------------------\n\nYou may override the behavior of ramsey/uuid as much as you want. Despite the use of ``final``, the library is very\nflexible. Take a look at the myriad opportunities to change how the library works:\n\n* :ref:`rfc4122.version1.random`\n* :ref:`customize.timestamp-first-comb-codec`\n* :ref:`customize.factory`\n* :ref:`And more... <customize>`\n\nramsey/uuid is able to provide this flexibility through the use of `interfaces`_, `factories`_, and `dependency injection`_.\n\nAt the same time, ramsey/uuid is able to guarantee that neither a :php:class:`UuidV1 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1>`\nnor a :php:class:`UuidV4 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4>` nor an :php:class:`Integer <Ramsey\\\\Uuid\\\\Type\\\\Integer>` nor\na :php:class:`Time <Ramsey\\\\Uuid\\\\Type\\\\Time>`, etc. will ever change because of `downstream`_ code.\n\nUUIDs have specific rules that make them practically unique. ramsey/uuid ensures that other code cannot change this\nexpectation while allowing your code and third-party libraries to change how UUIDs are generated and to return different\ntypes of UUIDs not specified by `RFC 9562`_.\n\nTesting With UUIDs\n------------------\n\nSometimes, the use of ``final`` can throw a wrench in our ability to write tests, but it doesn't have to be that way. To\nlearn a few techniques for using ramsey/uuid instances in your tests, take a look at :ref:`testing`.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _interfaces: https://www.php.net/interfaces\n.. _factories: https://en.wikipedia.org/wiki/Factory_%28object-oriented_programming%29\n.. _dependency injection: https://en.wikipedia.org/wiki/Dependency_injection\n.. _downstream: https://en.wikipedia.org/wiki/Downstream_(software_development)\n"
  },
  {
    "path": "docs/index.rst",
    "content": ".. _index:\n\n======================\nramsey/uuid User Guide\n======================\n\nFor `ramsey/uuid <https://github.com/ramsey/uuid>`_ |version|. Updated on |today|.\n\nContents\n--------\n\n.. toctree::\n    :maxdepth: 2\n    :includehidden:\n\n    introduction\n    quickstart\n    rfc4122\n    nonstandard\n    database\n    customize\n    testing\n    upgrading\n    FAQs <faq>\n    reference\n    copyright\n\nIndices and Tables\n------------------\n\n* :ref:`genindex`\n* :ref:`search`\n"
  },
  {
    "path": "docs/introduction.rst",
    "content": ".. _introduction:\n\n============\nIntroduction\n============\n\nramsey/uuid is a PHP library for generating and working with `RFC 9562`_ (formerly `RFC 4122`_) version 1, 2, 3, 4, 5,\n6, 7, and 8 universally unique identifiers (UUID). ramsey/uuid also supports optional and non-standard features, such as\nGUIDs and other approaches for encoding/decoding UUIDs.\n\nWhat Is a UUID?\n###############\n\nA universally unique identifier, or UUID, is a 128-bit unsigned integer, usually represented as a hexadecimal string\nsplit into five groups with dashes. The most widely-known and used types of UUIDs are defined by `RFC 9562`_ (formerly\n`RFC 4122`_).\n\nA UUID, when encoded in hexadecimal string format, looks like:\n\n.. code-block:: text\n\n    ebb5c735-0308-4e3c-9aea-8a270aebfe15\n\nThe probability of duplicating a UUID is close to zero, so they are a great choice for generating unique identifiers in\ndistributed systems.\n\nUUIDs can also be stored in binary format, as a string of 16 bytes.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/nonstandard/guid.rst",
    "content": ".. _nonstandard.guid:\n\n===================================\nGlobally Unique Identifiers (GUIDs)\n===================================\n\n.. tip::\n\n    Using these techniques to work with GUIDs is useful if you're working with identifiers that have been stored in GUID\n    byte order. For example, this is the case if working with the ``UNIQUEIDENTIFIER`` data type in Microsoft SQL Server.\n    This is a GUID, stored as a 16-byte binary string. If working directly with the bytes, you may use the GUID\n    functionality in ramsey/uuid to properly handle this data type.\n\nAccording to the Windows Dev Center article on `GUID structure`_, \"GUIDs are the Microsoft implementation of the\ndistributed computing environment (DCE) universally unique identifier.\" For all intents and purposes, a GUID string\nrepresentation is identical to that of an `RFC 9562`_ (formerly `RFC 4122`_) UUID. For historical reasons, *the byte\norder is not*.\n\nThe `.NET Framework documentation`_ explains:\n\n    Note that the order of bytes in the returned byte array is different from the string representation of a Guid value.\n    The order of the beginning four-byte group and the next two two-byte groups is reversed, whereas the order of the\n    last two-byte group and the closing six-byte group is the same.\n\nThis is best explained by example.\n\n.. code-block:: php\n    :caption: Decoding a GUID from byte representation\n    :name: nonstandard.guid.decode-bytes-example\n\n    use Ramsey\\Uuid\\FeatureSet;\n    use Ramsey\\Uuid\\UuidFactory;\n\n    // The bytes of a GUID previously stored in some datastore.\n    $guidBytes = hex2bin('0eab93fc9ec9584b975e9c5e68c53624');\n\n    $useGuids = true;\n    $featureSet = new FeatureSet($useGuids);\n    $factory = new UuidFactory($featureSet);\n\n    $guid = $factory->fromBytes($guidBytes);\n\n    printf(\n        \"Class: %s\\nGUID: %s\\nVersion: %d\\nBytes: %s\\n\",\n        get_class($guid),\n        $guid->toString(),\n        $guid->getFields()->getVersion(),\n        bin2hex($guid->getBytes())\n    );\n\nThis transforms the bytes of a GUID, as represented by ``$guidBytes``, into a :php:class:`Ramsey\\\\Uuid\\\\Guid\\\\Guid`\ninstance and prints out some details about it. It looks something like this:\n\n.. code-block:: text\n\n    Class: Ramsey\\Uuid\\Guid\\Guid\n    GUID: fc93ab0e-c99e-4b58-975e-9c5e68c53624\n    Version: 4\n    Bytes: 0eab93fc9ec9584b975e9c5e68c53624\n\nNote the difference between the string GUID and the bytes. The bytes are arranged like this:\n\n.. code-block:: text\n\n    0e ab 93 fc 9e c9 58 4b 97 5e 9c 5e 68 c5 36 24\n\nIn an `RFC 9562`_ (formerly `RFC 4122`_) UUID, the bytes are stored in the same order as you see presented in the string\nrepresentation. This is often called *network byte order*, or *big-endian* order. In a GUID, the order of the bytes are\nreversed in each grouping for the first 64 bits and stored in *little-endian* order. The remaining 64 bits are stored in\nnetwork byte order. See `Endianness <#nonstandard-guid-endianness>`_ to learn more.\n\n.. caution::\n\n    The bytes themselves do not indicate their order. If you decode GUID bytes as a UUID or UUID bytes as a GUID, you\n    will get the wrong values. However, you can always create a GUID or UUID from the same string value; the bytes for\n    each will be in a different order, even though the string is the same.\n\n    The key is to know ahead of time in what order the bytes are stored. Then, you will be able to decode them using the\n    correct approach.\n\nConverting GUIDs to UUIDs\n#########################\n\nContinuing from the example, :ref:`nonstandard.guid.decode-bytes-example`, we can take the GUID string representation\nand convert it into a standard UUID.\n\n.. code-block:: php\n    :caption: Convert a GUID to a UUID\n    :name: nonstandard.guid.convert-example\n\n    $uuid = Uuid::fromString($guid->toString());\n\n    printf(\n        \"Class: %s\\nUUID: %s\\nVersion: %d\\nBytes: %s\\n\",\n        get_class($uuid),\n        $uuid->toString(),\n        $uuid->getFields()->getVersion(),\n        bin2hex($uuid->getBytes())\n    );\n\nBecause the GUID was a version 4, random UUID, this creates an instance of :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4`\nfrom the GUID string and prints out a few details about it. It looks something like this:\n\n.. code-block:: text\n\n    Class: Ramsey\\Uuid\\Rfc4122\\UuidV4\n    UUID: fc93ab0e-c99e-4b58-975e-9c5e68c53624\n    Version: 4\n    Bytes: fc93ab0ec99e4b58975e9c5e68c53624\n\nNote how the UUID string is identical to the GUID string. However, the byte order is different, since they are in\nbig-endian order. The bytes are now arranged like this:\n\n.. code-block:: text\n\n    fc 93 ab 0e c9 9e 4b 58 97 5e 9c 5e 68 c5 36 24\n\n.. admonition:: Endianness\n    :name: nonstandard.guid.endianness\n\n    Big-endian and little-endian refer to the ordering of bytes in a multi-byte number. Big-endian order places the most\n    significant byte first, followed by the other bytes in descending order. Little-endian order places the least\n    significant byte first, followed by the other bytes in ascending order.\n\n    Take the hexadecimal number ``0x1234``, for example. In big-endian order, the bytes are stored as ``12 34``, and in\n    little-endian order, they are stored as ``34 12``. In either case, the number is still ``0x1234``.\n\n    Networking protocols usually use big-endian ordering, while computer processor architectures often use little-endian\n    ordering.\n\n    The terms originated in Jonathan Swift's *Gulliver's Travels*, where the Lilliputians argue over which end of a\n    hard-boiled egg is the best end to crack.\n\n.. _GUID structure: https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _.NET Framework documentation: https://learn.microsoft.com/en-us/dotnet/api/system.guid.tobytearray\n"
  },
  {
    "path": "docs/nonstandard/other.rst",
    "content": ".. _nonstandard.other:\n\n=======================\nOther Nonstandard UUIDs\n=======================\n\nSometimes, you might encounter a string that looks like a UUID but doesn't follow the `RFC 9562`_ (formerly `RFC 4122`_)\nspecification. Take this string, for example:\n\n.. code-block:: text\n\n    d95959bc-2ff5-43eb-fccd-14883ba8f174\n\nAt a glance, this looks like a valid UUID, but the variant bits don't match `RFC 9562`_ (formerly `RFC 4122`_). Instead\nof throwing a validation exception, ramsey/uuid will assume this is a UUID, since it fits the format and has 128 bits,\nbut it will represent it as a :php:class:`Ramsey\\\\Uuid\\\\Nonstandard\\\\Uuid`.\n\n.. code-block:: php\n    :caption: Create an instance of :php:class:`Ramsey\\\\Uuid\\\\Nonstandard\\\\Uuid` from a non-RFC 9562 UUID\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::fromString('d95959bc-2ff5-43eb-fccd-14883ba8f174');\n\n    printf(\n        \"Class: %s\\nUUID: %s\\nVersion: %d\\nVariant: %s\\n\",\n        get_class($uuid),\n        $uuid->toString(),\n        $uuid->getFields()->getVersion(),\n        $uuid->getFields()->getVariant()\n    );\n\nThis will create a :php:class:`Ramsey\\\\Uuid\\\\Nonstandard\\\\Uuid` from the given string and print out a few details about\nit. It will look something like this:\n\n.. code-block:: text\n\n    Class: Ramsey\\Uuid\\Nonstandard\\Uuid\n    UUID: d95959bc-2ff5-43eb-fccd-14883ba8f174\n    Version: 0\n    Variant: 7\n\nNote that the version is 0. Since the variant is 7, and there is no formal specification for this variant of UUID,\nramsey/uuid has no way of knowing what type of UUID this is.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/nonstandard/version6.rst",
    "content": ".. _nonstandard.version6:\n\n===================================\nVersion 6: Reordered Gregorian Time\n===================================\n\n.. attention::\n\n    This documentation has moved to :ref:`RFC 9562 UUIDs: Version 6: Reordered\n    Gregorian Time <rfc4122.version6>`.\n\n    The :php:class:`Ramsey\\\\Uuid\\\\Nonstandard\\\\UuidV6` class is deprecated in\n    favor of :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV6`.\n"
  },
  {
    "path": "docs/nonstandard.rst",
    "content": ".. _nonstandard:\n\n=================\nNonstandard UUIDs\n=================\n\n.. toctree::\n    :titlesonly:\n    :hidden:\n\n    nonstandard/version6\n    nonstandard/guid\n    nonstandard/other\n\nOutside of `RFC 9562`_ (formerly `RFC 4122`_), other types of UUIDs are in-use, following rules of their own. Some of\nthese are on their way to becoming accepted standards, while others have historical reasons for remaining valid today.\nStill, others are completely random and do not follow any rules.\n\nFor these cases, ramsey/uuid provides a special functionality to handle these alternate, nonstandard forms.\n\nGlobally Unique Identifiers (GUIDs)\n    A globally unique identifier, or GUID, is often used as a synonym for UUID. A key difference is the order of the\n    bytes. Any `RFC 9562`_ version UUID may be represented as a GUID. For more details, see :ref:`nonstandard.guid`.\n\nOther Nonstandard UUIDs\n    Sometimes, UUID string or byte representations don't follow `RFC 9562`_. Rather than reject these identifiers,\n    ramsey/uuid returns them with the special Nonstandard\\\\Uuid instance type. For more details, see\n    :ref:`nonstandard.other`.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/quickstart.rst",
    "content": ".. _quickstart:\n\n===============\nGetting Started\n===============\n\nRequirements\n############\n\nramsey/uuid |version| requires the following:\n\n* PHP 8.0+\n* `ext-json <https://www.php.net/manual/en/book.json.php>`_\n\nThe JSON extension is normally enabled by default, but it is possible to disable it. Other required extensions include\n`PCRE <https://www.php.net/manual/en/book.pcre.php>`_ and `SPL <https://www.php.net/manual/en/book.spl.php>`_. These\nstandard extensions cannot be disabled without patching PHP's build system and/or C sources.\n\nramsey/uuid recommends installing/enabling the following extensions. While not required, these extensions improve the\nperformance of ramsey/uuid.\n\n* `ext-gmp <https://www.php.net/manual/en/book.gmp.php>`_\n* `ext-bcmath <https://www.php.net/manual/en/book.bc.php>`_\n\nInstall With Composer\n#####################\n\nThe only supported installation method for ramsey/uuid is `Composer <https://getcomposer.org>`_. Use the following\ncommand to add ramsey/uuid to your project dependencies:\n\n.. code-block:: bash\n\n    composer require ramsey/uuid\n\nUsing ramsey/uuid\n#################\n\nAfter installing ramsey/uuid, the quickest way to get up-and-running is to use the static generation methods.\n\n.. code-block:: php\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid4();\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion()\n    );\n\nThis will return an instance of :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4`.\n\n.. tip::\n    .. rubric:: Use the Interfaces\n\n    Feel free to use ``instanceof`` to check the specific instance types of UUIDs. However, when using type hints, it's\n    best to use the interfaces.\n\n    The most lenient interface is :php:interface:`Ramsey\\\\Uuid\\\\UuidInterface`, while\n    :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface` ensures the UUIDs you're using conform to the `RFC 9562`_\n    (formerly `RFC 4122`_) standard. If you're not sure which one to use, start with the stricter\n    :php:interface:`Rfc4122\\\\UuidInterface <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface>`.\n\nramsey/uuid provides a number of helpful static methods that help you work with and generate most types of UUIDs,\nwithout any special customization of the library.\n\n.. list-table::\n    :widths: 25 75\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - Description\n    * - :php:meth:`Uuid::uuid1() <Ramsey\\\\Uuid\\\\Uuid::uuid1>`\n      - This generates a :ref:`rfc4122.version1` UUID.\n    * - :php:meth:`Uuid::uuid2() <Ramsey\\\\Uuid\\\\Uuid::uuid2>`\n      - This generates a :ref:`rfc4122.version2` UUID.\n    * - :php:meth:`Uuid::uuid3() <Ramsey\\\\Uuid\\\\Uuid::uuid3>`\n      - This generates a :ref:`rfc4122.version3` UUID.\n    * - :php:meth:`Uuid::uuid4() <Ramsey\\\\Uuid\\\\Uuid::uuid4>`\n      - This generates a :ref:`rfc4122.version4` UUID.\n    * - :php:meth:`Uuid::uuid5() <Ramsey\\\\Uuid\\\\Uuid::uuid5>`\n      - This generates a :ref:`rfc4122.version5` UUID.\n    * - :php:meth:`Uuid::uuid6() <Ramsey\\\\Uuid\\\\Uuid::uuid6>`\n      - This generates a :ref:`rfc4122.version6` UUID.\n    * - :php:meth:`Uuid::uuid7() <Ramsey\\\\Uuid\\\\Uuid::uuid7>`\n      - This generates a :ref:`rfc4122.version7` UUID.\n    * - :php:meth:`Uuid::uuid8() <Ramsey\\\\Uuid\\\\Uuid::uuid8>`\n      - This generates a :ref:`rfc4122.version8` UUID.\n    * - :php:meth:`Uuid::isValid() <Ramsey\\\\Uuid\\\\Uuid::isValid>`\n      - Checks whether a string is a valid UUID.\n    * - :php:meth:`Uuid::fromString() <Ramsey\\\\Uuid\\\\Uuid::fromString>`\n      - Creates a UUID instance from a string UUID.\n    * - :php:meth:`Uuid::fromBytes() <Ramsey\\\\Uuid\\\\Uuid::fromBytes>`\n      - Creates a UUID instance from a 16-byte string.\n    * - :php:meth:`Uuid::fromInteger() <Ramsey\\\\Uuid\\\\Uuid::fromInteger>`\n      - Creates a UUID instance from a string integer.\n    * - :php:meth:`Uuid::fromDateTime() <Ramsey\\\\Uuid\\\\Uuid::fromDateTime>`\n      - Creates a version 1 UUID instance from a PHP `DateTimeInterface`_.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _DateTimeInterface: https://www.php.net/datetimeinterface\n"
  },
  {
    "path": "docs/reference/calculators.rst",
    "content": ".. _reference.calculators:\n\n===========\nCalculators\n===========\n\n.. php:namespace:: Ramsey\\Uuid\\Math\n\n.. php:interface:: CalculatorInterface\n\n    Provides functionality for performing mathematical calculations.\n\n    .. php:method:: add($augend, ...$addends)\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface $augend: The first addend (the integer being added to)\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface ...$addends: The additional integers to a add to the augend\n        :returns: The sum of all the parameters\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\NumberInterface\n\n    .. php:method:: subtract($minuend, ...$subtrahends)\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface $minuend: The integer being subtracted from\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface ...$subtrahends: The integers to subtract from the minuend\n        :returns: The difference after subtracting all parameters\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\NumberInterface\n\n    .. php:method:: multiply($multiplicand, ...$multipliers)\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface $multiplicand: The integer to be multiplied\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface ...$multipliers: The factors by which to multiply the multiplicand\n        :returns: The product of multiplying all the provided parameters\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\NumberInterface\n\n    .. php:method:: divide($roundingMode, $scale, $dividend, ...$divisors)\n\n        :param int $roundingMode: The strategy for rounding the quotient; one of the :php:class:`Ramsey\\\\Uuid\\\\Math\\\\RoundingMode` constants\n        :param int $scale: The scale to use for the operation\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface $dividend: The integer to be divided\n        :param Ramsey\\\\Uuid\\\\Type\\\\NumberInterface ...$divisors: The integers to divide ``$dividend`` by, in the order in which the division operations should take place (left-to-right)\n        :returns: The quotient of dividing the provided parameters left-to-right\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\NumberInterface\n\n\n    .. php:method:: fromBase($value, $base)\n\n        Converts a value from an arbitrary base to a base-10 integer value.\n\n        :param string $value: The value to convert\n        :param int $base: The base to convert from (i.e., 2, 16, 32, etc.)\n        :returns: The base-10 integer value of the converted value\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Integer\n\n    .. php:method:: toBase($value, $base)\n\n        Converts a base-10 integer value to an arbitrary base.\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\Integer $value: The integer value to convert\n        :param int $base: The base to convert to (i.e., 2, 16, 32, etc.)\n        :returns: The value represented in the specified base\n        :returntype: ``string``\n\n    .. php:method:: toHexadecimal($value)\n\n        Converts an Integer instance to a Hexadecimal instance.\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\Integer $value: The Integer to convert to Hexadecimal\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: toInteger($value)\n\n        Converts a Hexadecimal instance to an Integer instance.\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal $value: The Hexadecimal to convert to Integer\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Integer\n\n\n.. php:class:: RoundingMode\n\n    .. php:const:: UNNECESSARY\n\n        Asserts that the requested operation has an exact result, hence no rounding is necessary.\n\n    .. php:const:: UP\n\n        Rounds away from zero.\n\n        Always increments the digit prior to a nonzero discarded fraction. Note that this rounding mode never decreases\n        the magnitude of the calculated value.\n\n    .. php:const:: DOWN\n\n        Rounds towards zero.\n\n        Never increments the digit prior to a discarded fraction (i.e., truncates). Note that this rounding mode never\n        increases the magnitude of the calculated value.\n\n    .. php:const:: CEILING\n\n        Rounds towards positive infinity.\n\n        If the result is positive, behaves as for :php:const:`UP <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::UP>`; if negative,\n        behaves as for :php:const:`DOWN <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::DOWN>`. Note that this rounding mode never\n        decreases the calculated value.\n\n    .. php:const:: FLOOR\n\n        Rounds towards negative infinity.\n\n        If the result is positive, behave as for :php:const:`DOWN <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::DOWN>`; if negative,\n        behave as for :php:const:`UP <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::UP>`. Note that this rounding mode never\n        increases the calculated value.\n\n    .. php:const:: HALF_UP\n\n        Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round up.\n\n        Behaves as for :php:const:`UP <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::UP>` if the discarded fraction is >= 0.5;\n        otherwise, behaves as for :php:const:`DOWN <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::DOWN>`. Note that this is the\n        rounding mode commonly taught at school.\n\n    .. php:const:: HALF_DOWN\n\n        Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round down.\n\n        Behaves as for :php:const:`UP <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::UP>` if the discarded fraction is > 0.5;\n        otherwise, behaves as for :php:const:`DOWN <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::DOWN>`.\n\n    .. php:const:: HALF_CEILING\n\n        Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round towards positive\n        infinity.\n\n        If the result is positive, behaves as for :php:const:`HALF_UP <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::HALF_UP>`; if\n        negative, behaves as for :php:const:`HALF_DOWN <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::HALF_DOWN>`.\n\n    .. php:const:: HALF_FLOOR\n\n        Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round towards negative\n        infinity.\n\n        If the result is positive, behaves as for :php:const:`HALF_DOWN <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::HALF_DOWN>`;\n        if negative, behaves as for :php:const:`HALF_UP <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::HALF_UP>`.\n\n    .. php:const:: HALF_EVEN\n\n        Rounds towards the \"nearest neighbor\" unless both neighbors are equidistant, in which case rounds towards the\n        even neighbor.\n\n        Behaves as for :php:const:`HALF_UP <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::HALF_UP>` if the digit to the left of the\n        discarded fraction is odd; behaves as for :php:const:`HALF_DOWN <Ramsey\\\\Uuid\\\\Math\\\\RoundingMode::HALF_DOWN>`\n        if it's even.\n\n        Note that this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a\n        sequence of calculations. It is sometimes known as \"Banker's rounding\", and is chiefly used in the USA.\n"
  },
  {
    "path": "docs/reference/exceptions.rst",
    "content": ".. _reference.exceptions:\n\n==========\nExceptions\n==========\n\nAll exceptions in the :php:ns:`Ramsey\\\\Uuid` namespace implement :php:interface:`Ramsey\\\\Uuid\\\\Exception\\\\UuidExceptionInterface`.\nThis provides a base type you may use to catch any and all exceptions that originate from this library.\n\n.. php:namespace:: Ramsey\\Uuid\\Exception\n\n.. php:interface:: UuidExceptionInterface\n\n    This is the interface all exceptions in ramsey/uuid must implement.\n\n.. php:exception:: BuilderNotFoundException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate that no suitable UUID builder could be found.\n\n.. php:exception:: DateTimeException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate that the PHP DateTime extension encountered an exception or error.\n\n.. php:exception:: DceSecurityException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate an exception occurred while dealing with DCE Security (version 2) UUIDs\n\n.. php:exception:: InvalidArgumentException\n\n    Extends `InvalidArgumentException <https://www.php.net/invalidargumentexception>`_.\n\n    Thrown to indicate that the argument received is not valid.\n\n.. php:exception:: InvalidBytesException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate that the bytes being operated on are invalid in some way.\n\n.. php:exception:: InvalidUuidStringException\n\n    Extends :php:exc:`Ramsey\\\\Uuid\\\\Exception\\\\InvalidArgumentException`.\n\n    Thrown to indicate that the string received is not a valid UUID.\n\n.. php:exception:: NameException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate that an error occurred while attempting to hash a namespace and name\n\n.. php:exception:: NodeException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate that attempting to fetch or create a node ID encountered an error.\n\n.. php:exception:: RandomSourceException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate that the source of random data encountered an error.\n\n.. php:exception:: TimeSourceException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate that the source of time encountered an error.\n\n.. php:exception:: UnableToBuildUuidException\n\n    Extends `RuntimeException <https://www.php.net/runtimeexception>`_.\n\n    Thrown to indicate a builder is unable to build a UUID.\n\n.. php:exception:: UnsupportedOperationException\n\n    Extends `LogicException <https://www.php.net/logicexception>`_.\n\n    Thrown to indicate that the requested operation is not supported.\n"
  },
  {
    "path": "docs/reference/fields-fieldsinterface.rst",
    "content": ".. _reference.fields.fieldsinterface:\n\n========================\nFields\\\\FieldsInterface\n========================\n\n.. php:namespace:: Ramsey\\Uuid\\Fields\n\n.. php:interface:: FieldsInterface\n\n    Represents the fields of a UUID.\n\n    .. php:method:: getBytes()\n\n        :returns: The bytes that comprise these fields.\n        :returntype: ``string``\n"
  },
  {
    "path": "docs/reference/guid-fields.rst",
    "content": ".. _reference.guid.fields:\n\n============\nGuid\\\\Fields\n============\n\n.. php:namespace:: Ramsey\\Uuid\\Guid\n\n.. php:class:: Fields\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface`.\n\n    Guid\\Fields represents the fields of a GUID.\n"
  },
  {
    "path": "docs/reference/guid-guid.rst",
    "content": ".. _reference.guid.guid:\n\n==========\nGuid\\\\Guid\n==========\n\n.. php:namespace:: Ramsey\\Uuid\\Guid\n\n.. php:class:: Guid\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\UuidInterface`.\n\n    Guid represents a :ref:`nonstandard.guid`. In addition to providing the methods defined on the interface, this class\n    additionally provides the following methods.\n\n    .. php:method:: getFields()\n\n        :returns: The fields that comprise this GUID.\n        :returntype: Ramsey\\\\Uuid\\\\Guid\\\\Fields\n"
  },
  {
    "path": "docs/reference/helper.rst",
    "content": ".. _reference.helper:\n\n================\nHelper Functions\n================\n\nramsey/uuid additionally provides the following helper functions, which return only the string standard representation\nof a UUID.\n\n.. php:function:: Ramsey\\Uuid\\v1([$node[, $clockSeq]])\n\n    Generates a string standard representation of a version 1, Gregorian time UUID.\n\n    :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n    :param int|null $clockSeq: An optional clock sequence to use\n    :returns: A string standard representation of a version 1 UUID\n    :returntype: string\n\n.. php:function:: Ramsey\\Uuid\\v2($localDomain[, $localIdentifier[, $node[, $clockSeq]]])\n\n    Generates a string standard representation of a version 2, DCE Security UUID.\n\n    :param int $localDomain: The local domain to use (one of ``Uuid::DCE_DOMAIN_PERSON``, ``Uuid::DCE_DOMAIN_GROUP``, or ``Uuid::DCE_DOMAIN_ORG``)\n    :param Ramsey\\\\Uuid\\\\Type\\\\Integer|null $localIdentifier: A local identifier for the domain (defaults to system UID or GID for *person* or *group*)\n    :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n    :param int|null $clockSeq: An optional clock sequence to use\n    :returns: A string standard representation of a version 2 UUID\n    :returntype: string\n\n.. php:function:: Ramsey\\Uuid\\v3($ns, $name)\n\n    Generates a string standard representation of a version 3, name-based (MD5) UUID.\n\n    :param Ramsey\\\\Uuid\\\\UuidInterface|string $ns: The namespace for this identifier\n    :param string $name: The name from which to generate an identifier\n    :returns: A string standard representation of a version 3 UUID\n    :returntype: string\n\n.. php:function:: Ramsey\\Uuid\\v4()\n\n    Generates a string standard representation of a version 4, random UUID.\n\n    :returns: A string standard representation of a version 4 UUID\n    :returntype: string\n\n.. php:function:: Ramsey\\Uuid\\v5($ns, $name)\n\n    Generates a string standard representation of a version 5, name-based (SHA-1) UUID.\n\n    :param Ramsey\\\\Uuid\\\\UuidInterface|string $ns: The namespace for this identifier\n    :param string $name: The name from which to generate an identifier\n    :returns: A string standard representation of a version 5 UUID\n    :returntype: string\n\n.. php:function:: Ramsey\\Uuid\\v6([$node[, $clockSeq]])\n\n    Generates a string standard representation of a version 6, reordered Gregorian time UUID.\n\n    :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n    :param int|null $clockSeq: An optional clock sequence to use\n    :returns: A string standard representation of a version 6 UUID\n    :returntype: string\n\n.. php:function:: Ramsey\\Uuid\\v7([$dateTime])\n\n    Generates a string standard representation of a version 7, Unix Epoch time UUID.\n\n    :param \\\\DatetimeInterface|null $node: An optional date/time from which to create the version 7 UUID. If not\n        provided, the UUID is generated using the current date/time\n    :returns: A string standard representation of a version 7 UUID\n    :returntype: string\n\n.. php:function:: Ramsey\\Uuid\\v8($bytes)\n\n    Generates a string standard representation of a version 8, implementation-specific, custom format UUID.\n\n    :param string $bytes: A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of\n                          information. Be aware, however, bits 48 through 51 will be replaced with the UUID version\n                          field, and bits 64 and 65 will be replaced with the UUID variant. You MUST NOT rely on\n                          these bits for your application needs.\n    :returns: A string standard representation of a version 8 UUID\n    :returntype: string\n"
  },
  {
    "path": "docs/reference/name-based-namespaces.rst",
    "content": ".. _reference.name-based-namespaces:\n\n=====================\nPredefined Namespaces\n=====================\n\n`RFC 9562`_ (formerly `RFC 4122`_) defines a handful of UUIDs to use with \"for some potentially interesting name spaces.\"\n\n.. list-table::\n    :widths: 30 70\n    :align: center\n    :header-rows: 1\n\n    * - Constant\n      - Description\n    * - :php:const:`Uuid::NAMESPACE_DNS <Ramsey\\\\Uuid\\\\Uuid::NAMESPACE_DNS>`\n      - The name string is a fully-qualified domain name.\n    * - :php:const:`Uuid::NAMESPACE_URL <Ramsey\\\\Uuid\\\\Uuid::NAMESPACE_URL>`\n      - The name string is a URL.\n    * - :php:const:`Uuid::NAMESPACE_OID <Ramsey\\\\Uuid\\\\Uuid::NAMESPACE_OID>`\n      - The name string is an `ISO object identifier (OID)`_.\n    * - :php:const:`Uuid::NAMESPACE_X500 <Ramsey\\\\Uuid\\\\Uuid::NAMESPACE_X500>`\n      - The name string is an `X.500`_ `DN`_ in `DER`_ or a text output format.\n\n\n.. _RFC 4122: https://tools.ietf.org/html/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _ISO object identifier (OID): http://www.oid-info.com\n.. _X.500: https://en.wikipedia.org/wiki/X.500\n.. _DN: https://en.wikipedia.org/wiki/Distinguished_Name\n.. _DER: https://www.itu.int/rec/T-REC-X.690/\n"
  },
  {
    "path": "docs/reference/nonstandard-fields.rst",
    "content": ".. _reference.nonstandard.fields:\n\n===================\nNonstandard\\\\Fields\n===================\n\n.. php:namespace:: Ramsey\\Uuid\\Nonstandard\n\n.. php:class:: Fields\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface`.\n\n    Nonstandard\\\\Fields represents the fields of a nonstandard UUID.\n"
  },
  {
    "path": "docs/reference/nonstandard-uuid.rst",
    "content": ".. _reference.nonstandard.uuid:\n\n=================\nNonstandard\\\\Uuid\n=================\n\n.. php:namespace:: Ramsey\\Uuid\\Nonstandard\n\n.. php:class:: Uuid\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\UuidInterface`.\n\n    Nonstandard\\\\Uuid represents :ref:`nonstandard.other`. In addition to providing the methods defined on the interface,\n    this class additionally provides the following methods.\n\n    .. php:method:: getFields()\n\n        :returns: The fields that comprise this UUID\n        :returntype: Ramsey\\\\Uuid\\\\Nonstandard\\\\Fields\n"
  },
  {
    "path": "docs/reference/nonstandard-uuidv6.rst",
    "content": ".. _reference.nonstandard.uuidv6:\n\n===================\nNonstandard\\\\UuidV6\n===================\n\n.. php:namespace:: Ramsey\\Uuid\\Nonstandard\n\n.. php:class:: UuidV6\n\n    .. attention::\n\n        :php:class:`Ramsey\\\\Uuid\\\\Nonstandard\\\\UuidV6` is deprecated in favor of :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV6`.\n        Please migrate any code using ``Nonstandard\\UuidV6`` to ``Rfc4122\\UuidV6``.\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV6 represents a :ref:`version 6, reordered Gregorian time UUID <nonstandard.version6>`. In addition to providing\n    the methods defined on the interface, this class additionally provides the following methods.\n\n    .. php:method:: getDateTime()\n\n        :returns: A date object representing the timestamp associated with the UUID\n        :returntype: ``\\DateTimeInterface``\n\n    .. php:method:: toUuidV1()\n\n        :returns: A version 1 UUID, converted from this version 6 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1\n\n    .. php:staticmethod:: fromUuidV1()\n\n        :param Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1 $uuidV1: A version 1 UUID\n        :returns: A version 6 UUID, converted from the given version 1 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV6\n"
  },
  {
    "path": "docs/reference/rfc4122-fieldsinterface.rst",
    "content": ".. _reference.rfc4122.fieldsinterface:\n\n========================\nRfc4122\\\\FieldsInterface\n========================\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:interface:: FieldsInterface\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Fields\\\\FieldsInterface`.\n\n    Rfc4122\\\\FieldsInterface represents the fields of an `RFC 9562`_ (formerly `RFC 4122`_) UUID. In addition to the\n    methods defined on the interface, this class additionally defines the following methods.\n\n    .. php:method:: getClockSeq()\n\n        :returns: The full 16-bit clock sequence, with the variant bits (two most significant bits) masked out.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getClockSeqHiAndReserved()\n\n        :returns: The high field of the clock sequence multiplexed with the variant.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getClockSeqLow()\n\n        :returns: The low field of the clock sequence.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getNode()\n\n        :returns: The node field.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getTimeHiAndVersion()\n\n        :returns: The high field of the timestamp multiplexed with the version.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getTimeLow()\n\n        :returns: The low field of the timestamp.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getTimeMid()\n\n        :returns: The middle field of the timestamp.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getTimestamp()\n\n        :returns: The full 60-bit timestamp, without the version.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getVariant()\n\n        Returns the variant, which, for `RFC 9562`_ (formerly `RFC 4122`_) variant UUIDs, should always be the value ``2``.\n\n        :returns: The UUID variant.\n        :returntype: ``int``\n\n    .. php:method:: getVersion()\n\n        :returns: The UUID version.\n        :returntype: ``int``\n\n    .. php:method:: isNil()\n\n        A *nil* UUID is a special type of UUID with all 128 bits set to zero. Its string standard representation is\n        always ``00000000-0000-0000-0000-000000000000``.\n\n        :returns: True if this UUID represents a nil UUID.\n        :returntype: ``bool``\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidinterface.rst",
    "content": ".. _reference.rfc4122.uuidinterface:\n\n======================\nRfc4122\\\\UuidInterface\n======================\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:interface:: UuidInterface\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\UuidInterface`.\n\n    Rfc4122\\\\UuidInterface represents an `RFC 9562`_ (formerly `RFC 4122`_) UUID. In addition to the methods defined on\n    the interface, this interface additionally defines the following methods.\n\n    .. php:method:: getFields()\n\n        :returns: The fields that comprise this UUID.\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv1.rst",
    "content": ".. _reference.rfc4122.uuidv1:\n\n===============\nRfc4122\\\\UuidV1\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV1\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV1 represents a :ref:`version 1, Gregorian time UUID <rfc4122.version1>`. In addition to providing the methods\n    defined on the interface, this class additionally provides the following methods.\n\n    .. php:method:: getDateTime()\n\n        :returns: A date object representing the timestamp associated with the UUID.\n        :returntype: ``\\DateTimeInterface``\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv2.rst",
    "content": ".. _reference.rfc4122.uuidv2:\n\n===============\nRfc4122\\\\UuidV2\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV2\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV2 represents a :ref:`version 2, DCE Security UUID <rfc4122.version2>`. In addition to providing the methods\n    defined on the interface, this class additionally provides the following methods.\n\n    .. php:method:: getDateTime()\n\n        Returns a `DateTimeInterface <https://www.php.net/datetimeinterface>`_ instance representing the timestamp\n        associated with the UUID\n\n        .. caution::\n\n            It is important to note that version 2 UUIDs suffer from some loss of timestamp precision. See\n            :ref:`rfc4122.version2.timestamp-problems` to learn more.\n\n        :returns: A date object representing the timestamp associated with the UUID\n        :returntype: ``\\DateTimeInterface``\n\n    .. php:method:: getLocalDomain()\n\n        :returns: The local domain identifier for this UUID, which is one of :php:const:`Ramsey\\\\Uuid\\\\Uuid::DCE_DOMAIN_PERSON`,\n                  :php:const:`Ramsey\\\\Uuid\\\\Uuid::DCE_DOMAIN_GROUP`, or :php:const:`Ramsey\\\\Uuid\\\\Uuid::DCE_DOMAIN_ORG`\n        :returntype: ``int``\n\n    .. php:method:: getLocalDomainName()\n\n        :returns: A string name associated with the local domain identifier (one of \"person,\" \"group,\" or \"org\")\n        :returntype: ``string``\n\n    .. php:method:: getLocalIdentifier()\n\n        :returns: The local identifier used when creating this UUID\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Integer\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv3.rst",
    "content": ".. _reference.rfc4122.uuidv3:\n\n===============\nRfc4122\\\\UuidV3\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV3\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV3 represents a :ref:`version 3, name-based (MD5 hashed) UUID <rfc4122.version3>`.\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv4.rst",
    "content": ".. _reference.rfc4122.uuidv4:\n\n===============\nRfc4122\\\\UuidV4\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV4\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV4 represents a :ref:`version 4, random UUID <rfc4122.version4>`.\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv5.rst",
    "content": ".. _reference.rfc4122.uuidv5:\n\n===============\nRfc4122\\\\UuidV5\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV5\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV5 represents a :ref:`version 5, name-based (SHA-1 hashed) UUID <rfc4122.version5>`.\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv6.rst",
    "content": ".. _reference.rfc4122.uuidv6:\n\n===============\nRfc4122\\\\UuidV6\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV6\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV6 represents a :ref:`version 6, reordered Gregorian time UUID <rfc4122.version6>`. In addition to providing the\n    methods defined on the interface, this class additionally provides the following methods.\n\n    .. php:method:: getDateTime()\n\n        :returns: A date object representing the timestamp associated with the UUID\n        :returntype: ``\\DateTimeInterface``\n\n    .. php:method:: toUuidV1()\n\n        :returns: A version 1 UUID, converted from this version 6 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1\n\n    .. php:staticmethod:: fromUuidV1()\n\n        :param Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1 $uuidV1: A version 1 UUID\n        :returns: A version 6 UUID, converted from the given version 1 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV6\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv7.rst",
    "content": ".. _reference.rfc4122.uuidv7:\n\n===============\nRfc4122\\\\UuidV7\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV7\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV7 represents a :ref:`version 7, Unix Epoch time UUID <rfc4122.version7>`. In addition to providing the methods\n    defined on the interface, this class additionally provides the following methods.\n\n    .. php:method:: getDateTime()\n\n        :returns: A date object representing the timestamp associated with the UUID.\n        :returntype: ``\\DateTimeInterface``\n"
  },
  {
    "path": "docs/reference/rfc4122-uuidv8.rst",
    "content": ".. _reference.rfc4122.uuidv8:\n\n===============\nRfc4122\\\\UuidV8\n===============\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: UuidV8\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface`.\n\n    UuidV8 represents a :ref:`version 8, implementation-specific, custom format UUID <rfc4122.version8>`.\n"
  },
  {
    "path": "docs/reference/types.rst",
    "content": ".. _reference.types:\n\n=====\nTypes\n=====\n\n.. php:namespace:: Ramsey\\Uuid\\Type\n\n.. php:class:: TypeInterface\n\n    Implements `JsonSerializable <https://www.php.net/jsonserializable>`_ and `Serializable <https://www.php.net/serializable>`_.\n\n    TypeInterface ensures consistency in typed values returned by ramsey/uuid.\n\n    .. php:method:: toString()\n\n        :returntype: ``string``\n\n    .. php:method:: __toString()\n\n        :returntype: ``string``\n\n.. php:class:: NumberInterface\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Type\\\\TypeInterface`.\n\n    NumberInterface ensures consistency in numeric values returned by ramsey/uuid.\n\n    .. php:method:: isNegative()\n\n        :returns: True if this number is less than zero, false otherwise.\n        :returntype: ``bool``\n\n.. php:class:: Decimal\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Type\\\\NumberInterface`.\n\n    A value object representing a decimal, for type-safety purposes, to ensure that decimals returned from ramsey/uuid\n    methods as strings are truly decimals and not some other kind of string.\n\n    To support values as true decimals and not as floats or doubles, we store the decimals as strings.\n\n.. php:class:: Hexadecimal\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Type\\\\TypeInterface`.\n\n    A value object representing a hexadecimal number, for type-safety purposes, to ensure that hexadecimal numbers\n    returned from ramsey/uuid methods as strings are truly hexadecimal and not some other kind of string.\n\n.. php:class:: Integer\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Type\\\\NumberInterface`.\n\n    A value object representing an integer, for type-safety purposes, to ensure that integers returned from ramsey/uuid\n    methods as strings are truly integers and not some other kind of string.\n\n    To support large integers beyond ``PHP_INT_MAX`` and ``PHP_INT_MIN`` on both 64-bit and 32-bit systems, we store the\n    integers as strings.\n\n.. php:class:: Time\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Type\\\\TypeInterface`.\n\n    A value object representing a timestamp, for type-safety purposes, to ensure that timestamps used by ramsey/uuid are\n    truly timestamp integers and not some other kind of string or integer.\n\n    .. php:method:: getSeconds()\n\n        :returntype: :php:class:`Ramsey\\\\Uuid\\\\Type\\\\Integer`\n\n    .. php:method:: getMicroseconds()\n\n        :returntype: :php:class:`Ramsey\\\\Uuid\\\\Type\\\\Integer`\n"
  },
  {
    "path": "docs/reference/uuid.rst",
    "content": ".. _reference.uuid:\n\n====\nUuid\n====\n\nRamsey\\\\Uuid\\\\Uuid provides static methods for the most common functionality for generating and working with UUIDs. It\nalso provides constants used throughout the ramsey/uuid library.\n\n.. php:namespace:: Ramsey\\Uuid\n\n.. php:class:: Uuid\n\n    .. php:const:: UUID_TYPE_TIME\n\n        :ref:`rfc4122.version1` UUID.\n\n    .. php:const:: UUID_TYPE_DCE_SECURITY\n\n        :ref:`rfc4122.version2` UUID.\n\n    .. php:const:: UUID_TYPE_HASH_MD5\n\n        :ref:`rfc4122.version3` UUID.\n\n    .. php:const:: UUID_TYPE_RANDOM\n\n        :ref:`rfc4122.version4` UUID.\n\n    .. php:const:: UUID_TYPE_HASH_SHA1\n\n        :ref:`rfc4122.version5` UUID.\n\n    .. php:const:: UUID_TYPE_REORDERED_TIME\n\n        :ref:`rfc4122.version6` UUID.\n\n    .. php:const:: UUID_TYPE_PEABODY\n\n        *Deprecated.* Use :php:const:`Uuid::UUID_TYPE_REORDERED_TIME` instead.\n\n    .. php:const:: UUID_TYPE_UNIX_TIME\n\n        :ref:`rfc4122.version7` UUID.\n\n    .. php:const:: UUID_TYPE_CUSTOM\n\n        :ref:`rfc4122.version8` UUID.\n\n    .. php:const:: NAMESPACE_DNS\n\n        The name string is a fully-qualified domain name.\n\n    .. php:const:: NAMESPACE_URL\n\n        The name string is a URL.\n\n    .. php:const:: NAMESPACE_OID\n\n        The name string is an `ISO object identifier (OID)`_.\n\n    .. php:const:: NAMESPACE_X500\n\n        The name string is an `X.500`_ `DN`_ in `DER`_ or a text output format.\n\n    .. php:const:: NIL\n\n        The nil UUID is a special form of UUID that is specified to have all 128 bits set to zero.\n\n    .. php:const:: DCE_DOMAIN_PERSON\n\n        DCE Security principal (person) domain.\n\n    .. php:const:: DCE_DOMAIN_GROUP\n\n        DCE Security group domain.\n\n    .. php:const:: DCE_DOMAIN_ORG\n\n        DCE Security organization domain.\n\n    .. php:const:: RESERVED_NCS\n\n        Variant identifier: reserved, NCS backward compatibility.\n\n    .. php:const:: RFC_4122\n\n        An alias for :php:const:`Uuid::RFC_9562`.\n\n    .. php:const:: RFC_9562\n\n        Variant identifier: the UUID layout specified in `RFC 9562`_ (formerly `RFC 4122`_).\n\n    .. php:const:: RESERVED_MICROSOFT\n\n        Variant identifier: reserved, Microsoft Corporation backward compatibility.\n\n    .. php:const:: RESERVED_FUTURE\n\n        Variant identifier: reserved for future definition.\n\n    .. php:staticmethod:: uuid1([$node[, $clockSeq]])\n\n        Generates a version 1, Gregorian time UUID. See :ref:`rfc4122.version1`.\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 1 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1\n\n    .. php:staticmethod:: uuid2($localDomain[, $localIdentifier[, $node[, $clockSeq]]])\n\n        Generates a version 2, DCE Security UUID. See :ref:`rfc4122.version2`.\n\n        :param int $localDomain: The local domain to use (one of :php:const:`Uuid::DCE_DOMAIN_PERSON`, :php:const:`Uuid::DCE_DOMAIN_GROUP`, or :php:const:`Uuid::DCE_DOMAIN_ORG`)\n        :param Ramsey\\\\Uuid\\\\Type\\\\Integer|null $localIdentifier: A local identifier for the domain (defaults to system UID or GID for *person* or *group*)\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 2 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV2\n\n    .. php:staticmethod:: uuid3($ns, $name)\n\n        Generates a version 3, name-based (MD5) UUID. See :ref:`rfc4122.version3`.\n\n        :param Ramsey\\\\Uuid\\\\UuidInterface|string $ns: The namespace for this identifier\n        :param string $name: The name from which to generate an identifier\n        :returns: A version 3 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV3\n\n    .. php:staticmethod:: uuid4()\n\n        Generates a version 4, random UUID. See :ref:`rfc4122.version4`.\n\n        :returns: A version 4 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4\n\n    .. php:staticmethod:: uuid5($ns, $name)\n\n        Generates a version 5, name-based (SHA-1) UUID. See :ref:`rfc4122.version5`.\n\n        :param Ramsey\\\\Uuid\\\\UuidInterface|string $ns: The namespace for this identifier\n        :param string $name: The name from which to generate an identifier\n        :returns: A version 5 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV5\n\n    .. php:staticmethod:: uuid6([$node[, $clockSeq]])\n\n        Generates a version 6, reordered Gregorian time UUID. See :ref:`rfc4122.version6`.\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 6 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV6\n\n    .. php:staticmethod:: uuid7([$dateTime])\n\n        Generates a version 7, Unix Epoch time UUID. See :ref:`rfc4122.version7`.\n\n        :param DateTimeInterface|null $dateTime: The date from which to create the UUID instance\n        :returns: A version 7 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV7\n\n    .. php:staticmethod:: uuid8($bytes)\n\n        Generates a version 8, implementation-specific, custom format UUID. See :ref:`rfc4122.version8`.\n\n        :param string $bytes: A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of\n                              information. Be aware, however, bits 48 through 51 will be replaced with the UUID version\n                              field, and bits 64 and 65 will be replaced with the UUID variant. You MUST NOT rely on\n                              these bits for your application needs.\n        :returns: A version 8 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV8\n\n    .. php:staticmethod:: fromString($uuid)\n\n        Creates an instance of UuidInterface from the string standard representation.\n\n        :param string $uuid: The string standard representation of a UUID\n        :returntype: Ramsey\\\\Uuid\\\\UuidInterface\n\n    .. php:staticmethod:: fromBytes($bytes)\n\n        Creates an instance of UuidInterface from a 16-byte string.\n\n        :param string $bytes: A 16-byte binary string representation of a UUID\n        :returntype: Ramsey\\\\Uuid\\\\UuidInterface\n\n    .. php:staticmethod:: fromInteger($integer)\n\n        Creates an instance of UuidInterface from a 128-bit string integer.\n\n        :param string $integer: A 128-bit string integer representation of a UUID\n        :returntype: Ramsey\\\\Uuid\\\\UuidInterface\n\n    .. php:staticmethod:: fromDateTime($dateTime[, $node[, $clockSeq]])\n\n        Creates a version 1 UUID instance from a `DateTimeInterface <https://www.php.net/datetimeinterface>`_ instance.\n\n        :param DateTimeInterface $dateTime: The date from which to create the UUID instance\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 1 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1\n\n    .. php:staticmethod:: isValid($uuid)\n\n        Validates the string standard representation of a UUID.\n\n        :param string $uuid: The string standard representation of a UUID\n        :returntype: ``bool``\n\n    .. php:staticmethod:: setFactory($factory)\n\n        Sets the factory used to create UUIDs.\n\n        :param Ramsey\\\\Uuid\\\\UuidFactoryInterface $factory: A UUID factory to use for all UUID generation\n        :returntype: void\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _ISO object identifier (OID): http://www.oid-info.com\n.. _X.500: https://en.wikipedia.org/wiki/X.500\n.. _DN: https://en.wikipedia.org/wiki/Distinguished_Name\n.. _DER: https://www.itu.int/rec/T-REC-X.690/\n"
  },
  {
    "path": "docs/reference/uuidfactoryinterface.rst",
    "content": ".. _reference.uuidfactoryinterface:\n\n====================\nUuidFactoryInterface\n====================\n\n.. php:namespace:: Ramsey\\Uuid\n\n.. php:interface:: UuidFactoryInterface\n\n    Represents a UUID factory.\n\n    .. php:method:: getValidator()\n\n        :returntype: Ramsey\\\\Uuid\\\\Validator\\\\ValidatorInterface\n\n    .. php:method:: uuid1([$node[, $clockSeq]])\n\n        Generates a version 1, Gregorian time UUID. See :ref:`rfc4122.version1`.\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 1 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1\n\n    .. php:method:: uuid2($localDomain[, $localIdentifier[, $node[, $clockSeq]]])\n\n        Generates a version 2, DCE Security UUID. See :ref:`rfc4122.version2`.\n\n        :param int $localDomain: The local domain to use (one of :php:const:`Uuid::DCE_DOMAIN_PERSON`, :php:const:`Uuid::DCE_DOMAIN_GROUP`, or :php:const:`Uuid::DCE_DOMAIN_ORG`)\n        :param Ramsey\\\\Uuid\\\\Type\\\\Integer|null $localIdentifier: A local identifier for the domain (defaults to system UID or GID for *person* or *group*)\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 2 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV2\n\n    .. php:method:: uuid3($ns, $name)\n\n        Generates a version 3, name-based (MD5) UUID. See :ref:`rfc4122.version3`.\n\n        :param Ramsey\\\\Uuid\\\\UuidInterface|string $ns: The namespace for this identifier\n        :param string $name: The name from which to generate an identifier\n        :returns: A version 3 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV3\n\n    .. php:method:: uuid4()\n\n        Generates a version 4, random UUID. See :ref:`rfc4122.version4`.\n\n        :returns: A version 4 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4\n\n    .. php:method:: uuid5($ns, $name)\n\n        Generates a version 5, name-based (SHA-1) UUID. See :ref:`rfc4122.version5`.\n\n        :param Ramsey\\\\Uuid\\\\UuidInterface|string $ns: The namespace for this identifier\n        :param string $name: The name from which to generate an identifier\n        :returns: A version 5 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV5\n\n    .. php:method:: uuid6([$node[, $clockSeq]])\n\n        Generates a version 6, reordered Gregorian time UUID. See :ref:`rfc4122.version6`.\n\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 6 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV6\n\n    .. php:method:: fromString($uuid)\n\n        Creates an instance of UuidInterface from the string standard representation.\n\n        :param string $uuid: The string standard representation of a UUID\n        :returntype: Ramsey\\\\Uuid\\\\UuidInterface\n\n    .. php:method:: fromBytes($bytes)\n\n        Creates an instance of UuidInterface from a 16-byte string.\n\n        :param string $bytes: A 16-byte binary string representation of a UUID\n        :returntype: Ramsey\\\\Uuid\\\\UuidInterface\n\n    .. php:method:: fromInteger($integer)\n\n        Creates an instance of UuidInterface from a 128-bit string integer.\n\n        :param string $integer: A 128-bit string integer representation of a UUID\n        :returntype: Ramsey\\\\Uuid\\\\UuidInterface\n\n    .. php:method:: fromDateTime($dateTime[, $node[, $clockSeq]])\n\n        Creates a version 1 UUID instance from a `DateTimeInterface <https://www.php.net/datetimeinterface>`_ instance.\n\n        :param DateTimeInterface $dateTime: The date from which to create the UUID instance\n        :param Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal|null $node: An optional hexadecimal node to use\n        :param int|null $clockSeq: An optional clock sequence to use\n        :returns: A version 1 UUID\n        :returntype: Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1\n"
  },
  {
    "path": "docs/reference/uuidinterface.rst",
    "content": ".. _reference.uuidinterface:\n\n=============\nUuidInterface\n=============\n\n.. php:namespace:: Ramsey\\Uuid\n\n.. php:interface:: UuidInterface\n\n    Represents a UUID.\n\n    .. php:method:: compareTo($other)\n\n        :param Ramsey\\\\Uuid\\\\UuidInterface $other: The UUID to compare\n        :returns: Returns ``-1``, ``0``, or ``1`` if the UUID is less than, equal to, or greater than the other UUID.\n        :returntype: ``int``\n\n    .. php:method:: equals($other)\n\n        :param object|null $other: An object to test for equality with this UUID.\n        :returns: Returns true if the UUID is equal to the provided object.\n        :returntype: ``bool``\n\n    .. php:method:: getBytes()\n\n        :returns: A binary string representation of the UUID.\n        :returntype: ``string``\n\n    .. php:method:: getFields()\n\n        :returns: The fields that comprise this UUID.\n        :returntype: Ramsey\\\\Uuid\\\\Fields\\\\FieldsInterface\n\n    .. php:method:: getHex()\n\n        :returns: The hexadecimal representation of the UUID.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal\n\n    .. php:method:: getInteger()\n\n        :returns: The integer representation of the UUID.\n        :returntype: Ramsey\\\\Uuid\\\\Type\\\\Integer\n\n    .. php:method:: getUrn()\n\n        :returns: The string standard representation of the UUID as a `URN`_.\n        :returntype: ``string``\n\n    .. php:method:: toString()\n\n        :returns: The string standard representation of the UUID.\n        :returntype: ``string``\n\n    .. php:method:: __toString()\n\n        :returns: The string standard representation of the UUID.\n        :returntype: ``string``\n\n.. _URN: https://www.rfc-editor.org/rfc/rfc8141\n"
  },
  {
    "path": "docs/reference/validators.rst",
    "content": ".. _reference.validators:\n\n==========\nValidators\n==========\n\n.. php:namespace:: Ramsey\\Uuid\\Validator\n\n.. php:interface:: ValidatorInterface\n\n    .. php:method:: getPattern()\n\n        :returns: The regular expression pattern used by this validator\n        :returntype: ``string``\n\n    .. php:method:: validate($uuid)\n\n        :param string $uuid: The string to validate as a UUID\n        :returns: True if the provided string represents a UUID, false otherwise\n        :returntype: ``bool``\n\n.. php:class:: GenericValidator\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Validator\\\\ValidatorInterface`.\n\n    GenericValidator validates strings as UUIDs of any variant.\n\n.. php:namespace:: Ramsey\\Uuid\\Rfc4122\n\n.. php:class:: Validator\n\n    Implements :php:interface:`Ramsey\\\\Uuid\\\\Validator\\\\ValidatorInterface`.\n\n    Rfc4122\\\\Validator validates strings as UUIDs of the `RFC 9562`_ (formerly `RFC 4122`_) variant.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/reference.rst",
    "content": ".. _reference:\n\n=========\nReference\n=========\n\n.. toctree::\n    :titlesonly:\n\n    reference/uuid\n    reference/uuidinterface\n    reference/fields-fieldsinterface\n    reference/rfc4122-uuidinterface\n    reference/rfc4122-fieldsinterface\n    reference/rfc4122-uuidv1\n    reference/rfc4122-uuidv2\n    reference/rfc4122-uuidv3\n    reference/rfc4122-uuidv4\n    reference/rfc4122-uuidv5\n    reference/rfc4122-uuidv6\n    reference/rfc4122-uuidv7\n    reference/rfc4122-uuidv8\n    reference/guid-fields\n    reference/guid-guid\n    reference/nonstandard-fields\n    reference/nonstandard-uuid\n    reference/nonstandard-uuidv6\n    reference/uuidfactoryinterface\n    reference/types\n    reference/exceptions\n    reference/helper\n    reference/name-based-namespaces\n    reference/calculators\n    reference/validators\n"
  },
  {
    "path": "docs/requirements.txt",
    "content": "Sphinx==7.3.7\nsphinx-rtd-theme==2.0.0\nsphinxcontrib-phpdomain==0.11.1\n"
  },
  {
    "path": "docs/rfc4122/version1.rst",
    "content": ".. _rfc4122.version1:\n\n=========================\nVersion 1: Gregorian Time\n=========================\n\n.. attention::\n\n    If you need a time-based UUID, and you don't need the other features included in version 1 UUIDs, we recommend using\n    :ref:`version 7 UUIDs <rfc4122.version7>`.\n\nA version 1 UUID uses the current time, along with the MAC address (or *node*) for a network interface on the local\nmachine. This serves two purposes:\n\n1. You can know *when* the identifier was created.\n2. You can know *where* the identifier was created.\n\nIn a distributed system, these two pieces of information can be valuable. Not only is there no need for a central\nauthority to generate identifiers, but you can determine what nodes in your infrastructure created the UUIDs and at what\ntime.\n\n.. tip::\n\n    It is also possible to use a **randomly-generated node**, rather than a hardware address. This is useful for when\n    you don't want to leak machine information, while still using a UUID based on time. Keep reading to find out how.\n\nBy default, ramsey/uuid will attempt to look up a MAC address for the machine it is running on, using this value as the\nnode. If it cannot find a MAC address, it will generate a random node.\n\n.. code-block:: php\n    :caption: Generate a version 1, Gregorian time UUID\n    :name: rfc4122.version1.example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid1();\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\nDate: %s\\nNode: %s\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion(),\n        $uuid->getDateTime()->format('r'),\n        $uuid->getFields()->getNode()->toString()\n    );\n\nThis will generate a version 1 UUID and print out its string representation, the time the UUID was created, and the node\nused to create the UUID.\n\nIt will look something like this:\n\n.. code-block:: text\n\n    UUID: e22e1622-5c14-11ea-b2f3-0242ac130003\n    Version: 1\n    Date: Sun, 01 Mar 2020 23:32:15 +0000\n    Node: 0242ac130003\n\nYou may provide custom values for version 1 UUIDs, including node and clock sequence.\n\n.. code-block:: php\n    :caption: Provide custom node and clock sequence to create a version 1,\n              Gregorian time UUID\n    :name: rfc4122.version1.custom-example\n\n    use Ramsey\\Uuid\\Provider\\Node\\StaticNodeProvider;\n    use Ramsey\\Uuid\\Type\\Hexadecimal;\n    use Ramsey\\Uuid\\Uuid;\n\n    $nodeProvider = new StaticNodeProvider(new Hexadecimal('121212121212'));\n    $clockSequence = 16383;\n\n    $uuid = Uuid::uuid1($nodeProvider->getNode(), $clockSequence);\n\n.. tip::\n\n    Version 1 UUIDs generated in ramsey/uuid are instances of UuidV1. Check out the :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1`\n    API documentation to learn more about what you can do with a UuidV1 instance.\n\n.. _rfc4122.version1.custom:\n\nProviding a Custom Node\n#######################\n\nYou may override the default behavior by passing your own node value when generating a version 1 UUID.\n\nIn the :ref:`example above <rfc4122.version1.custom-example>`, we saw how to pass a custom node and clock sequence. An\ninteresting thing to note about the example is its use of StaticNodeProvider. Why didn't we pass in a\n:php:class:`Hexadecimal <Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>` value, instead?\n\nAccording to `RFC 9562, section 6.10`_, node values that do not identify the host --- in other words, our own custom\nnode value --- should set the unicast/multicast bit to one (1). This bit will never be set in IEEE 802 addresses\nobtained from network cards, so it helps to distinguish it from a hardware MAC address.\n\nThe StaticNodeProvider sets this bit for you. This is why we used it rather than providing a :php:class:`Hexadecimal\n<Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>` value directly.\n\nRecall from the example that the node value we set was ``121212121212``, but if you take a look at this value with\n``$uuid->getFields()->getNode()->toString()``, it becomes:\n\n.. code-block:: text\n\n    131212121212\n\nThat's a result of this bit being set by the StaticNodeProvider.\n\n.. _rfc4122.version1.random:\n\nGenerating a Random Node\n########################\n\nInstead of providing a custom node, you may also generate a random node each time you generate a version 1 UUID. The\nRandomNodeProvider may be used to generate a random node value, and like the StaticNodeProvider, it also sets the\nunicast/multicast bit for you.\n\n.. code-block:: php\n    :caption: Provide a random node value to create a version 1, Gregorian time UUID\n    :name: rfc4122.version1.random-example\n\n    use Ramsey\\Uuid\\Provider\\Node\\RandomNodeProvider;\n    use Ramsey\\Uuid\\Uuid;\n\n    $nodeProvider = new RandomNodeProvider();\n\n    $uuid = Uuid::uuid1($nodeProvider->getNode());\n\n.. _rfc4122.version1.clock:\n\nWhat's a Clock Sequence?\n########################\n\nThe clock sequence part of a version 1 UUID helps prevent collisions. Since this UUID is based on a timestamp and a\nmachine node value, it is possible for collisions to occur for multiple UUIDs generated within the same microsecond on\nthe same machine.\n\nThe clock sequence is the solution to this problem.\n\nThe clock sequence is a 14-bit number --- this supports values from 0 to 16,383 --- which means it should be possible to\ngenerate up to 16,384 UUIDs per microsecond with the same node value, before hitting a collision.\n\n.. caution::\n\n    ramsey/uuid does not use *stable storage* for clock sequence values. Instead, all clock sequences are\n    randomly-generated. If you are generating a lot of version 1 UUIDs every microsecond, it is possible to hit\n    collisions because of the random values. If this is the case, you should use your own mechanism for generating clock\n    sequence values, to ensure against randomly-generated duplicates.\n\n    See `section 6.3 of RFC 9562`_, for more information.\n\n.. _rfc4122.version1.privacy:\n\nPrivacy Concerns\n################\n\nAs discussed earlier in this section, version 1 UUIDs use a MAC address from a local hardware network interface. This\nmeans it is possible to uniquely identify the machine on which a version 1 UUID was created.\n\nIf the value provided by the timestamp of a version 1 UUID is important to you, but you do not wish to expose the\ninterface address of any of your local machines, see :ref:`rfc4122.version1.random` or :ref:`rfc4122.version1.custom`.\n\nIf you do not need an identifier with a timestamp value embedded in it, see :ref:`rfc4122.version4` to learn about\nrandom UUIDs.\n\n.. _RFC 9562, section 6.10: https://www.rfc-editor.org/rfc/rfc9562#section-6.10\n.. _section 6.3 of RFC 9562: https://www.rfc-editor.org/rfc/rfc9562#section-6.3\n"
  },
  {
    "path": "docs/rfc4122/version2.rst",
    "content": ".. _rfc4122.version2:\n\n=======================\nVersion 2: DCE Security\n=======================\n\n.. tip::\n\n    DCE Security UUIDs are so-called because they were defined as part of the \"Authentication and Security Services\" for\n    the `Distributed Computing Environment`_ (DCE) in the early 1990s.\n\n    Version 2 UUIDs are not widely used. See :ref:`rfc4122.version2.problems` before deciding whether to use them.\n\nLike a :ref:`version 1 UUID <rfc4122.version1>`, a version 2 UUID uses the current time, along with the MAC address (or\n*node*) for a network interface on the local machine. Additionally, a version 2 UUID replaces the low part of the time\nfield with a local identifier such as the user ID or group ID of the local account that created the UUID. This serves\nthree purposes:\n\n1. You can know *when* the identifier was created (see :ref:`rfc4122.version2.timestamp-problems`).\n2. You can know *where* the identifier was created.\n3. You can know *who* created the identifier.\n\nIn a distributed system, these three pieces of information can be valuable. Not only is there no need for a central\nauthority to generate identifiers, but you can determine what nodes in your infrastructure created the UUIDs, at what\ntime they were created, and the account on the machine that created them.\n\nBy default, ramsey/uuid will attempt to look up a MAC address for the machine it is running on, using this value as the\nnode. If it cannot find a MAC address, it will generate a random node.\n\n.. code-block:: php\n    :caption: Use a domain to generate a version 2, DCE Security UUID\n    :name: rfc4122.version2.example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid2(Uuid::DCE_DOMAIN_PERSON);\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\nDate: %s\\nNode: %s\\nDomain: %s\\nID: %s\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion(),\n        $uuid->getDateTime()->format('r'),\n        $uuid->getFields()->getNode()->toString(),\n        $uuid->getLocalDomainName(),\n        $uuid->getLocalIdentifier()->toString()\n    );\n\nThis will generate a version 2 UUID and print out its string representation, the time the UUID was created, and the node\nused to create it, as well as the name of the local domain specified and the local domain identifier (in this case, a\n`POSIX`_ UID, automatically obtained from the local machine).\n\nIt will look something like this:\n\n.. code-block:: text\n\n    UUID: 000001f5-5e9a-21ea-9e00-0242ac130003\n    Version: 2\n    Date: Thu, 05 Mar 2020 04:30:10 +0000\n    Node: 0242ac130003\n    Domain: person\n    ID: 501\n\nJust as with version 1 UUIDs, you may provide custom values for version 2 UUIDs, including local identifier, node, and\nclock sequence.\n\n.. code-block:: php\n    :caption: Provide custom identifier, node, and clock sequence to create a\n              version 2, DCE Security UUID\n    :name: rfc4122.version2.custom-example\n\n    use Ramsey\\Uuid\\Provider\\Node\\StaticNodeProvider;\n    use Ramsey\\Uuid\\Type\\Hexadecimal;\n    use Ramsey\\Uuid\\Type\\Integer;\n    use Ramsey\\Uuid\\Uuid;\n\n    $localId = new Integer(1001);\n    $nodeProvider = new StaticNodeProvider(new Hexadecimal('121212121212'));\n    $clockSequence = 63;\n\n    $uuid = Uuid::uuid2(\n        Uuid::DCE_DOMAIN_ORG,\n        $localId,\n        $nodeProvider->getNode(),\n        $clockSequence\n    );\n\n.. tip::\n\n    Version 2 UUIDs generated in ramsey/uuid are instances of UuidV2. Check out the :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV2`\n    API documentation to learn more about what you can do with a UuidV2 instance.\n\n.. _rfc4122.version2.domains:\n\nDomains\n#######\n\nThe *domain* value tells what the local identifier represents.\n\nIf using the *person* or *group* domains, ramsey/uuid will attempt to look up these values from the local machine. On\n`POSIX`_ systems, it will use ``id -u`` and ``id -g``, respectively. On Windows, it will use ``whoami`` and ``wmic``.\n\nThe *org* domain is site-defined. Its intent is to identify the organization that generated the UUID, but since this can\nhave different meanings for different companies and projects, you get to define its value.\n\n.. list-table:: DCE Security Domains\n    :widths: 30 70\n    :align: center\n    :header-rows: 1\n    :name: rfc4122.version2.table-domains\n\n    * - Constant\n      - Description\n    * - :php:const:`Uuid::DCE_DOMAIN_PERSON <Ramsey\\\\Uuid\\\\Uuid::DCE_DOMAIN_PERSON>`\n      - The local identifier refers to a *person* (e.g., UID).\n    * - :php:const:`Uuid::DCE_DOMAIN_GROUP <Ramsey\\\\Uuid\\\\Uuid::DCE_DOMAIN_GROUP>`\n      - The local identifier refers to a *group* (e.g., GID).\n    * - :php:const:`Uuid::DCE_DOMAIN_ORG <Ramsey\\\\Uuid\\\\Uuid::DCE_DOMAIN_ORG>`\n      - The local identifier refers to an *organization* (this is site-defined).\n\n.. note::\n\n    According to section 5.2.1.1 of `DCE 1.1: Authentication and Security Services <https://publications.opengroup.org/c311>`_,\n    the domain \"can potentially hold values outside the range [0, 2\\ :sup:`8` -- 1]; however, the only values currently\n    registered are in the range [0, 2].\"\n\n    As a result, ramsey/uuid supports only the *person*, *group*, and *org* domains.\n\n.. _rfc4122.version2.nodes:\n\nCustom and Random Nodes\n#######################\n\nIn the :ref:`example above <rfc4122.version2.custom-example>`, we provided a custom node when generating a version 2\nUUID. You may also generate random node values.\n\nTo learn more, see the :ref:`rfc4122.version1.custom` and :ref:`rfc4122.version1.random` sections under\n:ref:`rfc4122.version1`.\n\n.. _rfc4122.version2.clock:\n\nClock Sequence\n##############\n\nIn a version 2 UUID, the clock sequence serves the same purpose as in a version 1 UUID. See :ref:`rfc4122.version1.clock`\nto learn more.\n\n.. warning::\n\n    The clock sequence in a version 2 UUID is a 6-bit number. It supports values from 0 to 63. This is different from\n    the 14-bit number used by version 1 UUIDs.\n\n    See :ref:`rfc4122.version2.uniqueness-problems` to understand how this affects version 2 UUIDs.\n\n.. _rfc4122.version2.problems:\n\nProblems With Version 2 UUIDs\n#############################\n\nVersion 2 UUIDs can be useful for the data they contain. However, there are trade-offs in choosing to use them.\n\n.. _rfc4122.version2.privacy-problems:\n\nPrivacy\n-------\n\nUnless using a randomly-generated node, version 2 UUIDs use the MAC address for a local hardware interface as the node\nvalue. In addition, they use a local identifier --- usually an account or group ID. Some may consider the use of these\nidentifying features a breach of privacy. The use of a timestamp further complicates the issue, since these UUIDs could\nbe used to identify a user account on a specific machine at a specific time.\n\nIf you don't need an identifier with a local identifier and timestamp value embedded in it, see :ref:`rfc4122.version4`\nto learn about random UUIDs.\n\n.. _rfc4122.version2.uniqueness-problems:\n\nLimited Uniqueness\n------------------\n\nWith the inclusion of the local identifier and domain comes a serious limitation in the number of unique UUIDs that may\nbe created. This is because:\n\n1. The local identifier replaces the lower 32 bits of the timestamp.\n2. The domain replaces the lower 8 bits of the clock sequence.\n\nAs a result, the timestamp advances --- the clock *ticks* --- only once every 429.49 seconds (about 7 minutes). This\nmeans the clock sequence is important to ensure uniqueness, but since the clock sequence is only 6 bits, compared to 14\nbits for version 1 UUIDs, **only 64 unique UUIDs per combination of node, domain, and identifier may be generated per\n7-minute tick of the clock**.\n\nYou can overcome this lack of uniqueness by using a :ref:`random node <rfc4122.version2.nodes>`, which provides 47 bits\nof randomness to the UUID --- after setting the unicast/multicast bit (see discussion on :ref:`rfc4122.version1.custom`)\n--- increasing the number of UUIDs per 7-minute clock tick to 2\\ :sup:`53` (or 9,007,199,254,740,992), at the expense of\nremaining locally unique.\n\n.. note::\n\n    This lack of uniqueness did not present a problem for DCE, since:\n\n        [T]he security architecture of DCE depends upon the uniqueness of security-version UUIDs *only within the\n        context of a cell*; that is, only within the context of the local [Registration Service's] (persistent)\n        datastore, and that degree of uniqueness can be guaranteed by the RS itself (namely, the RS maintains state in\n        its datastore, in the sense that it can always check that every UUID it maintains is different from all other\n        UUIDs it maintains). In other words, while security-version UUIDs are (like all UUIDs) specified to be \"globally\n        unique in space and time\", security is not compromised if they are merely \"locally unique per cell\".\n\n        -- `DCE 1.1: Authentication and Security Services, section 5.2.1.1 <https://publications.opengroup.org/c311>`_\n\n.. _rfc4122.version2.timestamp-problems:\n\nLossy Timestamps\n----------------\n\nVersion 2 UUIDs are generated in the same way as version 1 UUIDs, but the low part of the timestamp (the ``time_low``\nfield) is replaced by a 32-bit integer that represents a local identifier. Because of this, not only do version 2 UUIDs\nhave :ref:`limited uniqueness <rfc4122.version2.uniqueness-problems>`, but they also lack time precision.\n\nWhen reconstructing the timestamp to return a `DateTimeInterface`_ instance from :php:meth:`UuidV2::getDateTime()\n<Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV2::getDateTime>`, we replace the 32 lower bits of the timestamp with zeros, since the local\nidentifier should not be part of the timestamp. This results in a loss of precision, causing the timestamp to be off by\na range of 0 to 429.4967295 seconds (or 7 minutes, 9 seconds, and 496,730 microseconds).\n\nWhen using version 2 UUIDs, treat the timestamp as an approximation. At worst, it could be off by about 7 minutes.\n\n.. hint::\n\n    If the value 429.4967295 looks familiar, it's because it directly corresponds to 2\\ :sup:`32` -- 1, or ``0xffffffff``.\n    The local identifier is 32-bits, and we have set each of these bits to 0, so the maximum range of timestamp drift is\n    ``0x00000000`` to ``0xffffffff`` (counted in 100-nanosecond intervals).\n\n.. _Distributed Computing Environment: https://en.wikipedia.org/wiki/Distributed_Computing_Environment\n.. _POSIX: https://en.wikipedia.org/wiki/POSIX\n.. _DateTimeInterface: https://www.php.net/datetimeinterface\n"
  },
  {
    "path": "docs/rfc4122/version3.rst",
    "content": ".. _rfc4122.version3:\n\n===========================\nVersion 3: Name-based (MD5)\n===========================\n\n.. attention::\n\n    `RFC 9562`_ states, \"Where possible, UUIDv5 SHOULD be used in lieu of UUIDv3.\" Unless you have a specific use-case\n    for version 3 UUIDs, use :ref:`version 5 UUIDs <rfc4122.version5>`.\n\n.. note::\n\n    To learn about name-based UUIDs, read the section :ref:`rfc4122.version5`. Version 3 UUIDs behave exactly the same\n    as :ref:`version 5 UUIDs <rfc4122.version5>`. The only difference is the hashing algorithm used to generate the UUID.\n\n    Version 3 UUIDs use `MD5`_ as the hashing algorithm for combining the namespace and the name.\n\nDue to the use of a different hashing algorithm, version 3 UUIDs generated with any given namespace and name will differ\nfrom version 5 UUIDs generated using the same namespace and name.\n\nAs an example, let's take a look at generating a version 3 UUID using the same namespace and name used in\n\":ref:`rfc4122.version5.url-example`.\"\n\n.. code-block:: php\n    :caption: Generate a version 3, name-based UUID for a URL\n    :name: rfc4122.version3.url-example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'https://www.php.net');\n\nEven though the namespace and name are the same, the version 3 UUID generated will always be\n``3f703955-aaba-3e70-a3cb-baff6aa3b28f``.\n\nLikewise, we can use the custom namespace we created in \":ref:`rfc4122.version5.create-namespace`\" to generate a version\n3 UUID, but the result will be different from the version 5 UUID with the same custom namespace and name.\n\n.. code-block:: php\n    :caption: Use a custom namespace to create version 3, name-based UUIDs\n    :name: rfc4122.version3.custom-example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    const WIDGET_NAMESPACE = '4bdbe8ec-5cb5-11ea-bc55-0242ac130003';\n\n    $uuid = Uuid::uuid3(WIDGET_NAMESPACE, 'widget/1234567890');\n\nWith this custom namespace, the version 3 UUID for the name \"widget/1234567890\" will always be\n``53564aa3-4154-3ca5-ac90-dba59dc7d3cb``.\n\n.. tip::\n\n    Version 3 UUIDs generated in ramsey/uuid are instances of UuidV3. Check out the\n    :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV3` API documentation to learn more about what you can do with a UuidV3\n    instance.\n\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _MD5: https://en.wikipedia.org/wiki/MD5\n"
  },
  {
    "path": "docs/rfc4122/version4.rst",
    "content": ".. _rfc4122.version4:\n\n=================\nVersion 4: Random\n=================\n\nVersion 4 UUIDs are perhaps the most popular form of UUID. They are randomly-generated and do not contain any\ninformation about the time they are created or the machine that generated them. If you don't care about this information,\nthen a version 4 UUID might be perfect for your needs.\n\n.. code-block:: php\n    :caption: Generate a version 4, random UUID\n    :name: rfc4122.version4.example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid4();\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion()\n    );\n\nThis will generate a version 4 UUID and print out its string representation. It will look something like this:\n\n.. code-block:: text\n\n    UUID: 1ee9aa1b-6510-4105-92b9-7171bb2f3089\n    Version: 4\n\n.. tip::\n\n    Version 4 UUIDs generated in ramsey/uuid are instances of UuidV4. Check out the\n    :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4` API documentation to learn more about what you can do with a UuidV4\n    instance.\n"
  },
  {
    "path": "docs/rfc4122/version5.rst",
    "content": ".. _rfc4122.version5:\n\n=============================\nVersion 5: Name-based (SHA-1)\n=============================\n\n.. danger::\n\n    Since :ref:`version 3 <rfc4122.version3>` and version 5 UUIDs essentially use a *salt* (the namespace) to hash data,\n    it may be tempting to use them to hash passwords. **DO NOT do this under any circumstances!** You should not store\n    any sensitive information in a version 3 or version 5 UUID, since `MD5 and SHA-1 are insecure and have known attacks\n    demonstrated against them <https://en.wikipedia.org/wiki/Hash_function_security_summary>`_.\n\n    *Use these types of UUIDs as identifiers only.*\n\nThe first thing that comes to mind with most people think of a UUID is a *random* identifier, but name-based UUIDs\naren't random at all. In fact, they're deterministic. For any given identical namespace and name, you will always\ngenerate the same UUID.\n\nName-based UUIDs are useful when you need an identifier that's based on something's *name* --- think *identity* --- and\nwill always be the same no matter where or when it is created.\n\nFor example, let's say I want to create an identifier for a URL. I could use a :ref:`version 1 <rfc4122.version1>` or\n:ref:`version 4 <rfc4122.version4>` UUID to create an identifier for the URL, but what if I'm working with a distributed\nsystem, and I want to ensure that every client in this system can always generate the same identifier for any given URL?\n\nThis is where a name-based UUID comes in handy.\n\nName-based UUIDs combine a namespace with a name. This way, the UUIDs are unique to the namespace they're created in.\n`RFC 9562`_ defines some :ref:`predefined namespaces <reference.name-based-namespaces>`, one of which is for URLs.\n\n.. note::\n\n    Version 5 UUIDs use `SHA-1`_ as the hashing algorithm for combining the namespace and the name.\n\n.. code-block:: php\n    :caption: Generate a version 5, name-based UUID for a URL\n    :name: rfc4122.version5.url-example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'https://www.php.net');\n\nThe UUID generated will always be the same, as long as the namespace and name are the same. The version 5 UUID for\n\"https://www.php.net\" in the URL namespace will always be ``a8f6ae40-d8a7-58f0-be05-a22f94eca9ec``. See for yourself.\nRun the code above, and you'll see it always generates the same UUID.\n\n.. tip::\n\n    Version 5 UUIDs generated in ramsey/uuid are instances of UuidV5. Check out the\n    :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV5` API documentation to learn more about what you can do with a UuidV5\n    instance.\n\n.. _rfc4122.version5.custom-namespaces:\n\nCustom Namespaces\n#################\n\nIf you're working with name-based UUIDs for names that don't fit into any of the :ref:`predefined namespaces\n<reference.name-based-namespaces>`, or you don't want to use any of the predefined namespaces, you can create your own\nnamespace.\n\nThe best way to do this is to generate a :ref:`version 1 <rfc4122.version1>` or :ref:`version 4 <rfc4122.version4>` UUID\nand save this UUID as your namespace.\n\n.. code-block:: php\n    :caption: Generate a custom namespace UUID\n    :name: rfc4122.version5.create-namespace\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid1();\n\n    printf(\"My namespace UUID is %s\\n\", $uuid->toString());\n\nThis will generate a version 1, Gregorian time UUID, which we'll store to a constant so we can reuse it as our own\ncustom namespace.\n\n.. code-block:: php\n    :caption: Use a custom namespace to create version 5, name-based UUIDs\n    :name: rfc4122.version5.custom-example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    const WIDGET_NAMESPACE = '4bdbe8ec-5cb5-11ea-bc55-0242ac130003';\n\n    $uuid = Uuid::uuid5(WIDGET_NAMESPACE, 'widget/1234567890');\n\nWith this custom namespace, the version 5 UUID for the name \"widget/1234567890\" will always be\n``a35477ae-bfb1-5f2e-b5a4-4711594d855f``.\n\nWe can publish this namespace, allowing others to use it to generate identifiers for widgets. When two or more systems\ntry to reference the same widget, they'll end up generating the same identifier for it, which is exactly what we want.\n\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n.. _SHA-1: https://en.wikipedia.org/wiki/SHA-1\n"
  },
  {
    "path": "docs/rfc4122/version6.rst",
    "content": ".. _rfc4122.version6:\n\n===================================\nVersion 6: Reordered Gregorian Time\n===================================\n\n.. attention::\n\n    If you need a time-based UUID, and you don't need the other features included in version 6 UUIDs, we recommend using\n    :ref:`version 7 UUIDs <rfc4122.version7>`.\n\nVersion 6 UUIDs solve `two problems that have long existed`_ with the use of :ref:`version 1 <rfc4122.version1>` UUIDs:\n\n1. Scattered database records\n2. Inability to sort by an identifier in a meaningful way (i.e., insert order)\n\nTo overcome these issues, we need the ability to generate UUIDs that are *monotonically increasing* while still\nproviding all the benefits of version 1 UUIDs.\n\nVersion 6 UUIDs do this by storing the time in standard byte order, instead of breaking it up and rearranging the time\nbytes, according to the `RFC 9562`_ (formerly `RFC 4122`_) definition for version 1 UUIDs. All other fields remain the\nsame.\n\nIn all other ways, version 6 UUIDs function like version 1 UUIDs.\n\n.. tip::\n\n    Prior to version 4.0.0, ramsey/uuid provided a solution for this with the :ref:`ordered-time codec\n    <customize.ordered-time-codec>`. The ordered-time codec is now deprecated and will be removed in ramsey/uuid 5.0.0.\n    However, you may replace UUIDs generated using the ordered-time codec with version 6 UUIDs. Keep reading to find out\n    how.\n\n.. code-block:: php\n    :caption: Generate a version 6, reordered Gregorian time UUID\n    :name: rfc4122.version6.example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid6();\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\nDate: %s\\nNode: %s\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion(),\n        $uuid->getDateTime()->format('r'),\n        $uuid->getFields()->getNode()->toString()\n    );\n\nThis will generate a version 6 UUID and print out its string representation, the time the UUID was created, and the node\nused to create the UUID.\n\nIt will look something like this:\n\n.. code-block:: text\n\n    UUID: 1ea60f56-b67b-61fc-829a-0242ac130003\n    Version: 6\n    Date: Sun, 08 Mar 2020 04:29:37 +0000\n    Node: 0242ac130003\n\nYou may provide custom values for version 6 UUIDs, including node and clock sequence.\n\n.. code-block:: php\n    :caption: Provide custom node and clock sequence to create a version 6, reordered Gregorian time UUID\n    :name: rfc4122.version6.custom-example\n\n    use Ramsey\\Uuid\\Provider\\Node\\StaticNodeProvider;\n    use Ramsey\\Uuid\\Type\\Hexadecimal;\n    use Ramsey\\Uuid\\Uuid;\n\n    $nodeProvider = new StaticNodeProvider(new Hexadecimal('121212121212'));\n    $clockSequence = 16383;\n\n    $uuid = Uuid::uuid6($nodeProvider->getNode(), $clockSequence);\n\n.. tip::\n\n    Version 6 UUIDs generated in ramsey/uuid are instances of UuidV6. Check out the\n    :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV6` API documentation to learn more about what you can do with a UuidV6\n    instance.\n\n.. _rfc4122.version6.nodes:\n\nCustom and Random Nodes\n#######################\n\nIn the :ref:`example above <rfc4122.version6.custom-example>`, we provided a custom node when generating a version 6\nUUID. You may also generate random node values.\n\nTo learn more, see the :ref:`rfc4122.version1.custom` and :ref:`rfc4122.version1.random` sections under\n:ref:`rfc4122.version1`.\n\n.. _rfc4122.version6.clock:\n\nClock Sequence\n##############\n\nIn a version 6 UUID, the clock sequence serves the same purpose as in a version 1 UUID. See :ref:`rfc4122.version1.clock`\nto learn more.\n\n.. _rfc4122.version6.version1-conversion:\n\nVersion 1-to-6 Conversion\n#########################\n\nIt is possible to convert back-and-forth between version 6 and version 1 UUIDs.\n\n.. code-block:: php\n    :caption: Convert a version 1 UUID to a version 6 UUID\n    :name: rfc4122.version6.convert-version1-example\n\n    use Ramsey\\Uuid\\Rfc4122\\UuidV1;\n    use Ramsey\\Uuid\\Rfc4122\\UuidV6;\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid1 = Uuid::fromString('3960c5d8-60f8-11ea-bc55-0242ac130003');\n\n    if ($uuid1 instanceof UuidV1) {\n        $uuid6 = UuidV6::fromUuidV1($uuid1);\n    }\n\n.. code-block:: php\n    :caption: Convert a version 6 UUID to a version 1 UUID\n    :name: rfc4122.version6.convert-version6-example\n\n    use Ramsey\\Uuid\\Rfc4122\\UuidV6;\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid6 = Uuid::fromString('1ea60f83-960c-65d8-bc55-0242ac130003');\n\n    if ($uuid6 instanceof UuidV6) {\n        $uuid1 = $uuid6->toUuidV1();\n    }\n\n.. _rfc4122.version6.ordered-time-conversion:\n\nOrdered-time to Version 6 Conversion\n####################################\n\nYou may convert UUIDs previously generated and stored using the :ref:`ordered-time codec <customize.ordered-time-codec>`\ninto version 6 UUIDs.\n\n.. caution::\n\n    If you perform this conversion, the bytes and string representation of your UUIDs will change. This will break any\n    software that expects your identifiers to be fixed.\n\n.. code-block:: php\n    :caption: Convert an ordered-time codec encoded UUID to a version 6 UUID\n    :name: rfc4122.version6.convert-ordered-time-example\n\n    use Ramsey\\Uuid\\Codec\\OrderedTimeCodec;\n    use Ramsey\\Uuid\\Rfc4122\\UuidV1;\n    use Ramsey\\Uuid\\Rfc4122\\UuidV6;\n    use Ramsey\\Uuid\\UuidFactory;\n\n    // The bytes of a version 1 UUID previously stored in some datastore\n    // after encoding to bytes with the OrderedTimeCodec.\n    $bytes = hex2bin('11ea60faf17c8af6ad23acde48001122');\n\n    $factory = new UuidFactory();\n    $codec = new OrderedTimeCodec($factory->getUuidBuilder());\n\n    $factory->setCodec($codec);\n\n    $orderedTimeUuid = $factory->fromBytes($bytes);\n\n    if ($orderedTimeUuid instanceof UuidV1) {\n        $uuid6 = UuidV6::fromUuidV1($orderedTimeUuid);\n    }\n\n.. _rfc4122.version6.privacy:\n\nPrivacy Concerns\n################\n\nLike :ref:`version 1 UUIDs <rfc4122.version1>`, version 6 UUIDs use a MAC address from a local hardware network\ninterface. This means it is possible to uniquely identify the machine on which a version 6 UUID was created.\n\nIf the value provided by the timestamp of a version 6 UUID is important to you, but you do not wish to expose the\ninterface address of any of your local machines, see :ref:`rfc4122.version6.nodes`.\n\nIf you do not need an identifier with a node value embedded in it, but you still need the benefit of a monotonically\nincreasing unique identifier, see :ref:`rfc4122.version7`.\n\n.. _two problems that have long existed: https://www.percona.com/blog/store-uuid-optimized-way/\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/rfc4122/version7.rst",
    "content": ".. _rfc4122.version7:\n\n==========================\nVersion 7: Unix Epoch Time\n==========================\n\n.. admonition:: ULIDs and Version 7 UUIDs\n    :class: hint\n\n    Version 7 UUIDs are binary-compatible with `ULIDs`_ (universally unique lexicographically-sortable identifiers).\n\n    Both use a 48-bit timestamp in milliseconds since the Unix Epoch, filling the rest with random data. Version 7 UUIDs\n    then add the version and variant bits required by the UUID specification, which reduces the randomness from 80 bits\n    to 74. Otherwise, they are identical.\n\n    You may even convert a version 7 UUID to a ULID. :ref:`See below for an example. <rfc4122.version7.ulid>`\n\nVersion 7 UUIDs solve `two problems that have long existed`_ with the use of :ref:`version 1 <rfc4122.version1>` UUIDs:\n\n1. Scattered database records\n2. Inability to sort by an identifier in a meaningful way (i.e., insert order)\n\nTo overcome these issues, we need the ability to generate UUIDs that are *monotonically increasing*.\n\n:ref:`Version 6 UUIDs <rfc4122.version6>` provide an excellent solution for those who need monotonically increasing,\nsortable UUIDs with the features of version 1 UUIDs (MAC address and clock sequence), but if those features aren't\nnecessary for your application, using a version 6 UUID might be overkill.\n\nVersion 7 UUIDs combine random data (like version 4 UUIDs) with a timestamp (in milliseconds since the Unix Epoch, i.e.,\n1970-01-01 00:00:00 UTC) to create a monotonically increasing, sortable UUID that doesn't have any privacy concerns,\nsince it doesn't include a MAC address.\n\nFor this reason, implementations should use version 7 UUIDs over versions 1 and 6, if possible.\n\n.. code-block:: php\n    :caption: Generate a version 7, Unix Epoch time UUID\n    :name: rfc4122.version7.example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid7();\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\nDate: %s\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion(),\n        $uuid->getDateTime()->format('r'),\n    );\n\nThis will generate a version 7 UUID and print out its string representation and the time it was created.\n\nIt will look something like this:\n\n.. code-block:: text\n\n    UUID: 01833ce0-3486-7bfd-84a1-ad157cf64005\n    Version: 7\n    Date: Wed, 14 Sep 2022 16:41:10 +0000\n\nTo use an existing date and time to generate a version 7 UUID, you may pass a ``\\DateTimeInterface`` instance to the\n``uuid7()`` method.\n\n.. code-block:: php\n    :caption: Generate a version 7 UUID from an existing date and time\n    :name: rfc4122.version7.example-datetime\n\n    use DateTimeImmutable;\n    use Ramsey\\Uuid\\Uuid;\n\n    $dateTime = new DateTimeImmutable('@281474976710.655');\n    $uuid = Uuid::uuid7($dateTime);\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\nDate: %s\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion(),\n        $uuid->getDateTime()->format('r'),\n    );\n\nWhich will print something like this:\n\n.. code-block:: text\n\n    UUID: ffffffff-ffff-7964-a8f6-001336ac20cb\n    Version: 7\n    Date: Tue, 02 Aug 10889 05:31:50 +0000\n\n.. tip::\n\n    Version 7 UUIDs generated in ramsey/uuid are instances of UuidV7. Check out the\n    :php:class:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV7` API documentation to learn more about what you can do with a UuidV7\n    instance.\n\n.. _rfc4122.version7.ulid:\n\nConvert a Version 7 UUID to a ULID\n##################################\n\nAs mentioned in the callout above, version 7 UUIDs are binary-compatible with `ULIDs`_. This means you can encode a\nversion 7 UUID using `Crockford's Base 32 algorithm`_ and it will be a valid ULID, timestamp and all.\n\nUsing the third-party library `tuupola/base32`_, here's how we can encode a version 7 UUID as a ULID. Note that there's\na little bit of work to perform the conversion, since you're working with different bases.\n\n.. code-block:: php\n    :caption: Encode a version 7, Unix Epoch time UUID as a ULID\n    :name: rfc4122.version7.example-ulid\n\n    use Ramsey\\Uuid\\Uuid;\n    use Tuupola\\Base32;\n\n    $crockford = new Base32([\n        'characters' => Base32::CROCKFORD,\n        'padding' => false,\n        'crockford' => true,\n    ]);\n\n    $uuid = Uuid::uuid7();\n\n    // First, we must pad the 16-byte string to 20 bytes\n    // for proper conversion without data loss.\n    $bytes = str_pad($uuid->getBytes(), 20, \"\\x00\", STR_PAD_LEFT);\n\n    // Use Crockford's Base 32 encoding algorithm.\n    $encoded = $crockford->encode($bytes);\n\n    // That 20-byte string was encoded to 32 characters to avoid loss\n    // of data. We must strip off the first 6 characters--which are\n    // all zeros--to get a valid 26-character ULID string.\n    $ulid = substr($encoded, 6);\n\n    printf(\"ULID: %s\\n\", $ulid);\n\nThis will print something like this:\n\n.. code-block:: text\n\n    ULID: 01GCZ05N3JFRKBRWKNGCQZGP44\n\n.. caution::\n\n    Be aware that all version 7 UUIDs may be converted to ULIDs but not all ULIDs may be converted to UUIDs.\n\n    For that matter, all UUIDs of any version may be encoded as ULIDs, but they will not be monotonically increasing and\n    sortable unless they are version 7 UUIDs. You will also not be able to extract a meaningful timestamp from the ULID,\n    unless it was converted from a version 7 UUID.\n\n.. _ULIDs: https://github.com/ulid/spec\n.. _two problems that have long existed: https://www.percona.com/blog/store-uuid-optimized-way/\n.. _Crockford's Base 32 algorithm: https://www.crockford.com/base32.html\n.. _tuupola/base32: https://packagist.org/packages/tuupola/base32\n"
  },
  {
    "path": "docs/rfc4122/version8.rst",
    "content": ".. _rfc4122.version8:\n\n========================\nVersion 8: Custom Format\n========================\n\nVersion 8 UUIDs allow applications to create custom UUIDs in an RFC-compatible way. The only requirement is the version\nand variant bits must be set according to the UUID specification. The bytes provided may contain any value according to\nyour application's needs. Be aware, however, that other applications may not understand the semantics of the value.\n\n.. warning::\n\n    The bytes should be a 16-byte octet string, an open blob of data that you may fill with 128 bits of information.\n    However, bits 48 through 51 will be replaced with the UUID version field, and bits 64 and 65 will be replaced with\n    the UUID variant. You must not rely on these bits for your application needs.\n\n.. code-block:: php\n    :caption: Generate a version 8, custom UUID\n    :name: rfc4122.version8.example\n\n    use Ramsey\\Uuid\\Uuid;\n\n    $uuid = Uuid::uuid8(\"\\x00\\x11\\x22\\x33\\x44\\x55\\x66\\x77\\x88\\x99\\xaa\\xbb\\xcc\\xdd\\xee\\xff\");\n\n    printf(\n        \"UUID: %s\\nVersion: %d\\n\",\n        $uuid->toString(),\n        $uuid->getFields()->getVersion()\n    );\n\nThis will generate a version 8 UUID and print out its string representation. It will look something like this:\n\n.. code-block:: text\n\n    UUID: 00112233-4455-8677-8899-aabbccddeeff\n    Version: 8\n"
  },
  {
    "path": "docs/rfc4122.rst",
    "content": ".. _rfc4122:\n\n==================================\nRFC 9562 (formerly RFC 4122) UUIDs\n==================================\n\n.. toctree::\n    :titlesonly:\n    :hidden:\n\n    rfc4122/version1\n    rfc4122/version2\n    rfc4122/version3\n    rfc4122/version4\n    rfc4122/version5\n    rfc4122/version6\n    rfc4122/version7\n    rfc4122/version8\n\n`RFC 9562`_ (formerly `RFC 4122`_) defines eight versions of UUIDs. Each version has different generation algorithms and\nproperties. Which one you choose depends on your use-case. You can find out more about their applications on the\nspecific page for that version.\n\nVersion 1: Gregorian Time\n    This version of UUID combines a timestamp, node value (in the form of a MAC address from the local computer's\n    network interface), and a clock sequence to ensure uniqueness. For more details, see :doc:`rfc4122/version1`.\n\nVersion 2: DCE Security\n    This version of UUID is the same as Version 1, except the ``clock_seq_low`` field is replaced with a *local domain*\n    and the ``time_low`` field is replaced with a *local identifier*. For more details, see :doc:`rfc4122/version2`.\n\nVersion 3: Name-based (MD5)\n    This version of UUID hashes together a namespace and a name to create a deterministic UUID. The hashing algorithm\n    used is MD5. For more details, see :doc:`rfc4122/version3`.\n\nVersion 4: Random\n    This version creates a UUID using truly-random or pseudo-random numbers. For more details, see :doc:`rfc4122/version4`.\n\nVersion 5: Named-based (SHA-1)\n    This version of UUID hashes together a namespace and a name to create a deterministic UUID. The hashing algorithm\n    used is SHA-1. For more details, see :doc:`rfc4122/version5`.\n\nVersion 6: Reordered Gregorian Time\n    This version of UUID combines the features of a :ref:`version 1 UUID <rfc4122.version1>` with a *monotonically\n    increasing* UUID. For more details, see :ref:`rfc4122.version6`.\n\nVersion 7: Unix Epoch Time\n    This version of UUID combines a timestamp--based on milliseconds elapsed since the Unix Epoch--and random bytes to\n    create a monotonically increasing, sortable UUID without the privacy and entropy concerns associated with version 1\n    and version 6 UUIDs. For more details, see :ref:`rfc4122.version7`.\n\nVersion 8: Implementation-Specific, Custom Format\n    This version of UUID allows applications to generate custom identifiers in an RFC-compatible format. For more\n    details, see :doc:`rfc4122/version8`.\n\n.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122\n.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562\n"
  },
  {
    "path": "docs/testing.rst",
    "content": ".. _testing:\n\n==================\nTesting With UUIDs\n==================\n\nOne problem with the use of ``final`` is the inability to create a `mock object`_ to use in tests. However, the\nfollowing techniques should help with testing.\n\n.. tip::\n\n    To learn why ramsey/uuid uses ``final``, take a look at :ref:`faq.final`.\n\n.. _testing.inject:\n\nInject a UUID of a Specific Type\n--------------------------------\n\nLet's say we have a method that uses a type hint for :php:class:`UuidV1 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1>`.\n\n.. code-block:: php\n\n    public function tellTime(UuidV1 $uuid): string\n    {\n        return $uuid->getDateTime()->format('Y-m-d H:i:s');\n    }\n\nSince this method uses UuidV1 as the type hint, we're not able to pass another object that implements UuidInterface, and\nwe cannot extend or mock UuidV1, so how do we test this?\n\nOne way is to use :php:meth:`Uuid::uuid1() <Ramsey\\\\Uuid\\\\Uuid::uuid1>` to create a regular UuidV1 instance and pass it.\n\n.. code-block:: php\n\n    public function testTellTime(): void\n    {\n        $uuid = Uuid::uuid1();\n        $myObj = new MyClass();\n\n        $this->assertIsString($myObj->tellTime($uuid));\n    }\n\nThis might satisfy our testing needs if we only want to assert that the method returns a string. If we want to test for\na specific string, we can do that, too, by generating a UUID ahead of time and using it as a known value.\n\n.. code-block:: php\n\n    public function testTellTime(): void\n    {\n        // We generated this version 1 UUID ahead of time and know the\n        // exact date and time it contains, so we can use it to test the\n        // return value of our method.\n        $uuid = Uuid::fromString('177ef0d8-6630-11ea-b69a-0242ac130003');\n        $myObj = new MyClass();\n\n        $this->assertSame('2020-03-14 20:12:12', $myObj->tellTime($uuid));\n    }\n\n.. note::\n\n    These examples assume the use of `PHPUnit`_ for tests. The concepts will work no matter what testing framework you use.\n\n.. _testing.static:\n\nReturning Specific UUIDs From a Static Method\n---------------------------------------------\n\nSometimes, rather than pass UUIDs as method arguments, we might call the static methods on the Uuid class from inside\nthe method we want to test. This can be tricky to test.\n\n.. code-block:: php\n\n    public function tellTime(): string\n    {\n        $uuid = Uuid::uuid1();\n\n        return $uuid->getDateTime()->format('Y-m-d H:i:s');\n    }\n\nWe can call this in a test and assert that it returns a string, but we can't return a specific UUID value from the\nstatic method call --- or can we?\n\nWe can do this by :ref:`overriding the default factory <customize.factory>`.\n\nFirst, we create our own factory class for testing. In this example, we extend UuidFactory, but you may create your own\nseparate factory class for testing, as long as you implement :php:interface:`Ramsey\\\\Uuid\\\\UuidFactoryInterface`.\n\n.. code-block:: php\n\n    namespace MyPackage;\n\n    use Ramsey\\Uuid\\UuidFactory;\n    use Ramsey\\Uuid\\UuidInterface;\n\n    class MyTestUuidFactory extends UuidFactory\n    {\n        public $uuid1;\n\n        public function uuid1($node = null, ?int $clockSeq = null): UuidInterface\n        {\n            return $this->uuid1;\n        }\n    }\n\nNow, from our tests, we can replace the default factory with our new factory, and we can even change the value returned\nby the :php:meth:`uuid1() <Ramsey\\\\Uuid\\\\UuidFactoryInterface::uuid1>` method for our tests.\n\n.. code-block:: php\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testTellTime(): void\n    {\n        $factory = new MyTestUuidFactory();\n        Uuid::setFactory($factory);\n\n        $myObj = new MyClass();\n\n        $factory->uuid1 = Uuid::fromString('177ef0d8-6630-11ea-b69a-0242ac130003');\n        $this->assertSame('2020-03-14 20:12:12', $myObj->tellTime());\n\n        $factory->uuid1 = Uuid::fromString('13814000-1dd2-11b2-9669-00007ffffffe');\n        $this->assertSame('1970-01-01 00:00:00', $myObj->tellTime());\n    }\n\n.. attention::\n\n    The factory is a static property on the Uuid class. By replacing it like this, all uses of the Uuid class after this\n    point will continue to use the new factory. This is why we must run the test in a separate process. Otherwise, this\n    could cause other tests to fail.\n\n    Running tests in separate processes can significantly slow down your tests, so try to use this technique sparingly,\n    and if possible, pass your dependencies to your objects, rather than creating (or fetching them) from within. This\n    makes testing easier.\n\n\n.. _testing.mock:\n\nMocking UuidInterface\n---------------------\n\nAnother technique for testing with UUIDs is to mock :php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>`.\n\nConsider a method that accepts a UuidInterface.\n\n.. code-block:: php\n\n    public function tellTime(UuidInterface $uuid): string\n    {\n        return $uuid->getDateTime()->format('Y-m-d H:i:s');\n    }\n\nWe can mock UuidInterface, passing that mocked value into this method. Then, we can make assertions about what methods\nwere called on the mock object. In the following example test, we don't care whether the return value matches an actual\ndate format. What we care about is that the methods on the UuidInterface object were called.\n\n.. code-block:: php\n\n    public function testTellTime(): void\n    {\n        $dateTime = Mockery::mock(DateTime::class);\n        $dateTime->expects()->format('Y-m-d H:i:s')->andReturn('a test date');\n\n        $uuid = Mockery::mock(UuidInterface::class, [\n            'getDateTime' => $dateTime,\n        ]);\n\n        $myObj = new MyClass();\n\n        $this->assertSame('a test date', $myObj->tellTime($uuid));\n    }\n\n.. note::\n\n    One of my favorite mocking libraries is `Mockery`_, so that's what I use in these examples. However, other mocking\n    libraries exist, and PHPUnit provides built-in mocking capabilities.\n\n.. _mock object: https://en.wikipedia.org/wiki/Mock_object\n.. _PHPUnit: https://phpunit.de\n.. _Mockery: https://github.com/mockery/mockery\n"
  },
  {
    "path": "docs/upgrading/2-to-3.rst",
    "content": ".. _upgrading.2-to-3:\n\n==============\nVersion 2 to 3\n==============\n\nWhile we have made significant internal changes to the library, we have made every effort to ensure a seamless upgrade\npath from the 2.x series of this library to 3.x.\n\nOne major breaking change is the transition from the ``Rhumsaa`` root namespace to ``Ramsey``. In most cases, all you\nwill need is to change the namespace to ``Ramsey`` in your code, and everything will \"just work.\"\n\n.. note::\n\n    For more details on the namespace change, including reasons for the change, read the blog post \"`Introducing\n    ramsey/uuid <https://benramsey.com/blog/2016/04/ramsey-uuid/>`_\".\n\nHere are full details on the breaking changes to the public API of this library:\n\n1. All namespace references of ``Rhumsaa`` have changed to ``Ramsey``. Simply change the namespace to ``Ramsey`` in your\n   code and everything should work.\n2. The console application has moved to `ramsey/uuid-console <https://packagist.org/packages/ramsey/uuid-console>`_. If\n   using the console functionality, use Composer to require ``ramsey/uuid-console``.\n3. The Doctrine field type mapping has moved to `ramsey/uuid-doctrine <https://packagist.org/packages/ramsey/uuid-doctrine>`_.\n   If using the Doctrine functionality, use Composer to require ``ramsey/uuid-doctrine``.\n"
  },
  {
    "path": "docs/upgrading/3-to-4.rst",
    "content": ".. _upgrading.3-to-4:\n\n==============\nVersion 3 to 4\n==============\n\nI've made great efforts to ensure that the upgrade experience for most will be seamless and uneventful. However, no\nmatter the degree to which you use ramsey/uuid (customized or unchanged), there are a number of things to be aware of as\nyou upgrade your code to use version 4.\n\n.. tip::\n\n    These are the changes that are most likely to affect you. For a full list of changes, take a look at the `4.0.0 changelog`_.\n\n.. _upgrading.3-to-4.new:\n\nWhat's New?\n###########\n\nThere are a lot of new features in ramsey/uuid! Here are a few of them:\n\n* Support :ref:`version 6 UUIDs <nonstandard.version6>`.\n* Support :ref:`version 2 (DCE Security) UUIDs <rfc4122.version2>`.\n* Add classes to represent each version of RFC 4122 UUID. When generating new UUIDs or creating UUIDs from existing\n  strings, bytes, or integers, if the UUID is an RFC 4122 variant, one of these instances will be returned:\n\n  * :php:class:`Rfc4122\\\\UuidV1 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1>`\n  * :php:class:`Rfc4122\\\\UuidV2 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV2>`\n  * :php:class:`Rfc4122\\\\UuidV3 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV3>`\n  * :php:class:`Rfc4122\\\\UuidV4 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4>`\n  * :php:class:`Rfc4122\\\\UuidV5 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV5>`\n  * :php:class:`Rfc4122\\\\NilUuid <Ramsey\\\\Uuid\\\\Rfc4122\\\\NilUuid>`\n\n* Add classes to represent version 6 UUIDs, GUIDs, and nonstandard (non-RFC 4122 variants) UUIDs:\n\n  * :php:class:`Nonstandard\\\\UuidV6 <Ramsey\\\\Uuid\\\\Nonstandard\\\\UuidV6>`\n  * :php:class:`Nonstandard\\\\Uuid <Ramsey\\\\Uuid\\\\Nonstandard\\\\Uuid>`\n  * :php:class:`Guid\\\\Guid <Ramsey\\\\Uuid\\\\Guid\\\\Guid>`\n\n* Add :php:meth:`Uuid::fromDateTime() <Ramsey\\\\Uuid\\\\Uuid::fromDateTime>` to create version 1 UUIDs from instances of\n  DateTimeInterface.\n\n.. _upgrading.3-to-4.changed:\n\nWhat's Changed?\n###############\n\n.. attention::\n\n    ramsey/uuid version 4 requires PHP 7.2 or later.\n\nQuite a bit has changed, but much remains familiar. Unless you've changed the behavior of ramsey/uuid through custom\ncodecs, providers, generators, etc., the standard functionality and API found in version 3 will not differ much.\n\n.. rubric:: Here are the highlights:\n\n* ramsey/uuid now works on 32-bit and 64-bit systems, with no degradation in functionality! All Degraded\\* classes are\n  deprecated and no longer used; they'll go away in ramsey/uuid version 5.\n* Pay attention to the :ref:`return types for the static methods <upgrading.3-to-4.static-methods>` on the\n  :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>` class. They've changed slightly, but this won't affect you if your type hints\n  use :php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>`.\n* The :ref:`return types for three methods <upgrading.3-to-4.return-types>` defined on :php:interface:`UuidInterface\n  <Ramsey\\\\Uuid\\\\UuidInterface>` have changed, breaking backwards compatibility. **Take note and update your code.**\n* :ref:`There are a number of deprecations. <upgrading.3-to-4.deprecations>` These shouldn't affect you now, but please\n  take a look at the recommendations and update your code soon. These will go away in ramsey/uuid version 5.\n* ramsey/uuid now :ref:`throws custom exceptions for everything <reference.exceptions>`. The exception\n  UnsatisfiedDependencyException no longer exists.\n* If you customize ramsey/uuid at all by implementing the interfaces, take a look at the :ref:`interface\n  <upgrading.3-to-4.interfaces>` and :ref:`constructor <upgrading.3-to-4.constructors>` changes and update your code.\n\n.. tip::\n\n    If you maintain a public project that uses ramsey/uuid version 3 and you find that **your code does not require any\n    changes to upgrade** to version 4, consider using the following version constraint in your project's ``composer.json``\n    file:\n\n    .. code-block:: bash\n\n        composer require ramsey/uuid:\"^3 || ^4\"\n\n    This will allow any `downstream users`_ of your project who aren't ready to upgrade to version 4 the ability to\n    continue using your project while deciding on an appropriate upgrade schedule.\n\n    If your downstream users do not specify ramsey/uuid as a dependency, and they use functionality specific to version\n    3, they may need to update their own Composer dependencies to use ramsey/uuid ``^3`` to avoid using version 4.\n\n.. _upgrading.3-to-4.static-methods:\n\nUuid Static Methods\n###################\n\nAll the static methods on the :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>` class continue to work as they did in version 3,\nwith this slight change: **they now return more-specific types**, all of which implement the new interface\n:php:interface:`Rfc4122\\\\UuidInterface <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface>`, which implements the familiar interface\n:php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>`.\n\nIf your type hints are for :php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>`, then you should not require any\nchanges.\n\n.. list-table:: Return types for Uuid static methods\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - 3.x Returned\n      - 4.x Returns\n    * - :php:meth:`Uuid::uuid1() <Ramsey\\\\Uuid\\\\Uuid::uuid1>`\n      - :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>`\n      - :php:class:`Rfc4122\\\\UuidV1 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1>`\n    * - :php:meth:`Uuid::uuid3() <Ramsey\\\\Uuid\\\\Uuid::uuid3>`\n      - :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>`\n      - :php:class:`Rfc4122\\\\UuidV3 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV3>`\n    * - :php:meth:`Uuid::uuid4() <Ramsey\\\\Uuid\\\\Uuid::uuid4>`\n      - :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>`\n      - :php:class:`Rfc4122\\\\UuidV4 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4>`\n    * - :php:meth:`Uuid::uuid5() <Ramsey\\\\Uuid\\\\Uuid::uuid5>`\n      - :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>`\n      - :php:class:`Rfc4122\\\\UuidV5 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV5>`\n\n:php:meth:`Uuid::fromString() <Ramsey\\\\Uuid\\\\Uuid::fromString>`, :php:meth:`Uuid::fromBytes() <Ramsey\\\\Uuid\\\\Uuid::fromBytes>`,\nand :php:meth:`Uuid::fromInteger() <Ramsey\\\\Uuid\\\\Uuid::fromInteger>` all return an appropriate more-specific type,\nbased on the input value. If the input value is a version 1 UUID, for example, the return type will be an\n:php:class:`Rfc4122\\\\UuidV1 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1>`. If the input looks like a UUID or is a 128-bit number, but\nit doesn't validate as an RFC 4122 UUID, the return type will be a :php:class:`Nonstandard\\\\Uuid\n<Ramsey\\\\Uuid\\\\Nonstandard\\\\Uuid>`. These return types implement :php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>`.\nIf using this as a type hint, you shouldn't need to make any changes.\n\n.. _upgrading.3-to-4.return-types:\n\nChanged Return Types\n####################\n\nThe following :php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>` method return types have changed in version 4\nand you will need to update your code, if you use these methods.\n\n.. list-table:: Changed UuidInterface method return types\n    :widths: 40 30 30\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - 3.x Returned\n      - 4.x Returns\n    * - :php:meth:`UuidInterface::getFields() <Ramsey\\\\Uuid\\\\UuidInterface::getFields>`\n      - ``array``\n      - :php:class:`Rfc4122\\\\FieldsInterface <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface>`\n    * - :php:meth:`UuidInterface::getHex() <Ramsey\\\\Uuid\\\\UuidInterface::getHex>`\n      - ``string``\n      - :php:class:`Type\\\\Hexadecimal <Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>`\n    * - :php:meth:`UuidInterface::getInteger() <Ramsey\\\\Uuid\\\\UuidInterface::getInteger>`\n      - ``mixed`` [#f1]_\n      - :php:class:`Type\\\\Integer <Ramsey\\\\Uuid\\\\Type\\\\Integer>`\n\nIn version 3, the following :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>` methods return ``int``, ``string``, or\nMoontoast\\\\Math\\\\BigNumber, depending on the environment. In version 4, they all return numeric ``string`` values for\nthe sake of consistency. These methods :ref:`are also deprecated <upgrading.3-to-4.deprecations.uuid>` and will be\nremoved in version 5.\n\n* ``getClockSeqHiAndReserved()``\n* ``getClockSeqLow()``\n* ``getClockSequence()``\n* ``getLeastSignificantBits()``\n* ``getMostSignificantBits()``\n* ``getNode()``\n* ``getTimeHiAndVersion()``\n* ``getTimeLow()``\n* ``getTimeMid()``\n* ``getTimestamp()``\n\n.. _upgrading.3-to-4.deprecations:\n\nDeprecations\n############\n\n.. _upgrading.3-to-4.deprecations.uuidinterface:\n\nUuidInterface\n-------------\n\nThe following :php:interface:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>` methods are deprecated, but upgrading to\nversion 4 should not cause any problems if using these methods. You are encouraged to update your code according to the\nrecommendations, though, since these methods will go away in version 5.\n\n.. list-table:: Deprecated UuidInterface methods\n    :widths: 30 70\n    :align: center\n    :header-rows: 1\n\n    * - Deprecated Method\n      - Update To\n    * - ``getDateTime()``\n      - Use ``getDateTime()`` on :php:meth:`UuidV1\n        <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1::getDateTime>`, :php:meth:`UuidV2\n        <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV2::getDateTime>`, or :php:meth:`UuidV6\n        <Ramsey\\\\Uuid\\\\Nonstandard\\\\UuidV6::getDateTime>`\n    * - ``getClockSeqHiAndReservedHex()``\n      - :php:meth:`getFields()->getClockSeqHiAndReserved()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getClockSeqHiAndReserved>`\n    * - ``getClockSeqLowHex()``\n      - :php:meth:`getFields()->getClockSeqLow()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getClockSeqLow>`\n    * - ``getClockSequenceHex()``\n      - :php:meth:`getFields()->getClockSeq()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getClockSeq>`\n    * - ``getFieldsHex()``\n      - :php:meth:`getFields() <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface::getFields>` [#f2]_\n    * - ``getLeastSignificantBitsHex()``\n      - ``substr($uuid->getHex()->toString(), 0, 16)``\n    * - ``getMostSignificantBitsHex()``\n      - ``substr($uuid->getHex()->toString(), 16)``\n    * - ``getNodeHex()``\n      - :php:meth:`getFields()->getNode()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getNode>`\n    * - ``getNumberConverter()``\n      - This method has no replacement; plan accordingly.\n    * - ``getTimeHiAndVersionHex()``\n      - :php:meth:`getFields()->getTimeHiAndVersion()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getTimeHiAndVersion>`\n    * - ``getTimeLowHex()``\n      - :php:meth:`getFields()->getTimeLow()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getTimeLow>`\n    * - ``getTimeMidHex()``\n      - :php:meth:`getFields()->getTimeMid()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getTimeMid>`\n    * - ``getTimestampHex()``\n      - :php:meth:`getFields()->getTimestamp()->toString() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getTimestamp>`\n    * - ``getUrn()``\n      - :php:meth:`Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface::getUrn`\n    * - ``getVariant()``\n      - :php:meth:`getFields()->getVariant() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getVariant>`\n    * - ``getVersion()``\n      - :php:meth:`getFields()->getVersion() <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface::getVersion>`\n\n.. _upgrading.3-to-4.deprecations.uuid:\n\nUuid\n----\n\n:php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>` as an instantiable class is deprecated. In ramsey/uuid version 5, its constructor\nwill be ``private``, and the class will be ``final``. For more information, see :ref:`faq.final`\n\n.. note::\n\n    :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>` is being replaced by more-specific concrete classes, such as:\n\n    * :php:class:`Rfc4122\\\\UuidV1 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV1>`\n    * :php:class:`Rfc4122\\\\UuidV3 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV3>`\n    * :php:class:`Rfc4122\\\\UuidV4 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV4>`\n    * :php:class:`Rfc4122\\\\UuidV5 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV5>`\n    * :php:class:`Nonstandard\\\\Uuid <Ramsey\\\\Uuid\\\\Nonstandard\\\\Uuid>`\n\n    However, the :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>` class isn't going away. It will still hold common constants and\n    static methods.\n\n* ``Uuid::UUID_TYPE_IDENTIFIER`` is deprecated. Use ``Uuid::UUID_TYPE_DCE_SECURITY`` instead.\n* ``Uuid::VALID_PATTERN`` is deprecated. Use the following instead:\n\n    .. code-block:: php\n\n        use Ramsey\\Uuid\\Validator\\GenericValidator;\n        use Ramsey\\Uuid\\Rfc4122\\Validator as Rfc4122Validator;\n\n        $genericPattern = (new GenericValidator())->getPattern();\n        $rfc4122Pattern = (new Rfc4122Validator())->getPattern();\n\nThe following :php:class:`Uuid <Ramsey\\\\Uuid\\\\Uuid>` methods are deprecated. If using these methods, you shouldn't have\nany problems on version 4, but you are encouraged to update your code, since they will go away in version 5.\n\n* ``getClockSeqHiAndReserved()``\n* ``getClockSeqLow()``\n* ``getClockSequence()``\n* ``getLeastSignificantBits()``\n* ``getMostSignificantBits()``\n* ``getNode()``\n* ``getTimeHiAndVersion()``\n* ``getTimeLow()``\n* ``getTimeMid()``\n* ``getTimestamp()``\n\n.. hint::\n\n    There are no direct replacements for these methods. In ramsey/uuid version 3, they returned ``int`` or\n    Moontoast\\\\Math\\\\BigNumber values, depending on the environment. To update your code, you should use the recommended\n    alternates listed in :ref:`Deprecations: UuidInterface <upgrading.3-to-4.deprecations.uuidinterface>`, combined with\n    the arbitrary-precision mathematics library of your choice (e.g., `brick/math`_, `gmp`_, `bcmath`_, etc.).\n\n    .. code-block:: php\n        :caption: Using brick/math to convert a node to a string integer\n\n        use Brick\\Math\\BigInteger;\n\n        $node = BigInteger::fromBase($uuid->getFields()->getNode()->toString(), 16);\n\n.. _upgrading.3-to-4.interfaces:\n\nInterface Changes\n#################\n\nFor those who customize ramsey/uuid by implementing the interfaces provided, there are a few breaking changes to note.\n\n.. hint::\n\n    Most existing methods on interfaces have type hints added to them. If you implement any interfaces, please be aware\n    of this and update your classes.\n\nUuidInterface\n-------------\n\n.. list-table::\n    :widths: 25 75\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - Description\n    * - :php:meth:`__toString() <Ramsey\\\\Uuid\\\\UuidInterface::__toString>`\n      - New method; returns ``string``\n    * - :php:meth:`getDateTime() <Ramsey\\\\Uuid\\\\UuidInterface::getDateTime>`\n      - Deprecated; now returns `DateTimeInterface`_\n    * - :php:meth:`getFields() <Ramsey\\\\Uuid\\\\UuidInterface::getFields>`\n      - Used to return ``array``; now returns :php:class:`Rfc4122\\\\FieldsInterface <Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface>`\n    * - :php:meth:`getHex() <Ramsey\\\\Uuid\\\\UuidInterface::getHex>`\n      - Used to return ``string``; now returns :php:class:`Type\\\\Hexadecimal <Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>`\n    * - :php:meth:`getInteger() <Ramsey\\\\Uuid\\\\UuidInterface::getInteger>`\n      - New method; returns :php:class:`Type\\\\Integer <Ramsey\\\\Uuid\\\\Type\\\\Integer>`\n\nUuidFactoryInterface\n--------------------\n\n.. list-table::\n    :widths: 25 75\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - Description\n    * - :php:meth:`uuid2() <Ramsey\\\\Uuid\\\\UuidFactoryInterface::uuid2>`\n      - New method; returns :php:class:`Rfc4122\\\\UuidV2 <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidV2>`\n    * - :php:meth:`uuid6() <Ramsey\\\\Uuid\\\\UuidFactoryInterface::uuid6>`\n      - New method; returns :php:class:`Nonstandard\\\\UuidV6 <Ramsey\\\\Uuid\\\\Nonstandard\\\\UuidV6>`\n    * - :php:meth:`fromDateTime() <Ramsey\\\\Uuid\\\\UuidFactoryInterface::fromDateTime>`\n      - New method; returns :php:class:`UuidInterface <Ramsey\\\\Uuid\\\\UuidInterface>`\n    * - :php:meth:`fromInteger() <Ramsey\\\\Uuid\\\\UuidFactoryInterface::fromInteger>`\n      - Changed to accept only strings\n    * - :php:meth:`getValidator() <Ramsey\\\\Uuid\\\\UuidFactoryInterface::getValidator>`\n      - New method; returns :php:class:`UuidInterface <Ramsey\\\\Uuid\\\\Validator\\\\ValidatorInterface>`\n\nBuilder\\\\UuidBuilderInterface\n-----------------------------\n\n.. list-table::\n    :widths: 25 75\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - Description\n    * - ``build()``\n      - The second parameter used to accept ``array $fields``; now accepts ``string $bytes``\n\nConverter\\\\TimeConverterInterface\n---------------------------------\n\n.. list-table::\n    :widths: 25 75\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - Description\n    * - ``calculateTime()``\n      - Used to return ``string[]``; now returns :php:class:`Type\\\\Hexadecimal <Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>`\n    * - ``convertTime()``\n      - New method; returns :php:class:`Type\\\\Time <Ramsey\\\\Uuid\\\\Type\\\\Time>`\n\nProvider\\\\TimeProviderInterface\n---------------------------------\n\n.. list-table::\n    :widths: 25 75\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - Description\n    * - ``currentTime()``\n      - Method removed from interface; use ``getTime()`` instead\n    * - ``getTime()``\n      - New method; returns :php:class:`Type\\\\Time <Ramsey\\\\Uuid\\\\Type\\\\Time>`\n\nProvider\\\\NodeProviderInterface\n---------------------------------\n\n.. list-table::\n    :widths: 25 75\n    :align: center\n    :header-rows: 1\n\n    * - Method\n      - Description\n    * - ``getNode()``\n      - Used to return ``string|false|null``; now returns :php:class:`Type\\\\Hexadecimal <Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>`\n\n\n.. _upgrading.3-to-4.constructors:\n\nConstructor Changes\n###################\n\nThere are a handful of constructor changes that might affect your use of ramsey/uuid, especially if you customize the\nlibrary.\n\nUuid\n----\n\nThe constructor for :php:class:`Ramsey\\\\Uuid\\\\Uuid` is deprecated. However, there are a few changes to it that might\naffect your use of this class.\n\nThe first constructor parameter used to be ``array $fields`` and is now :php:interface:`Rfc4122\\\\FieldsInterface $fields\n<Ramsey\\\\Uuid\\\\Rfc4122\\\\FieldsInterface>`.\n\n``Converter\\TimeConverterInterface $timeConverter`` is required as a new fourth parameter.\n\nBuilder\\\\DefaultUuidBuilder\n---------------------------\n\nWhile Builder\\\\DefaultUuidBuilder is deprecated, it now inherits from Rfc4122\\\\UuidBuilder, which requires\n``Converter\\TimeConverterInterface $timeConverter`` as its second constructor argument.\n\nProvider\\\\Node\\\\FallbackNodeProvider\n------------------------------------\n\nProvider\\\\Node\\\\FallbackNodeProvider now requires ``iterable<Ramsey\\Uuid\\Provider\\NodeProviderInterface>`` as its\nconstructor parameter.\n\n.. code-block::\n\n    use MyPackage\\MyCustomNodeProvider;\n    use Ramsey\\Uuid\\Provider\\Node\\FallbackNodeProvider;\n    use Ramsey\\Uuid\\Provider\\Node\\RandomNodeProvider;\n    use Ramsey\\Uuid\\Provider\\Node\\SystemNodeProvider;\n\n    $nodeProviders = [];\n    $nodeProviders[] = new MyCustomNodeProvider();\n    $nodeProviders[] = new SystemNodeProvider();\n    $nodeProviders[] = new RandomNodeProvider();\n\n    $provider = new FallbackNodeProvider($nodeProviders);\n\nProvider\\\\Time\\\\FixedTimeProvider\n---------------------------------\n\nThe constructor for Provider\\\\Time\\\\FixedTimeProvider no longer accepts an array. It accepts\n:php:class:`Type\\\\Time <Ramsey\\\\Uuid\\\\Type\\\\Time>` instances.\n\n-------------------------------------------------------------------------------\n\n.. rubric:: Footnotes\n\n.. [#f1] This ``mixed`` return type could have been an ``int``, ``string``, or Moontoast\\\\Math\\\\BigNumber. In version 4,\n    ramsey/uuid cleans this up for the sake of consistency.\n\n.. [#f2] The :php:meth:`getFields() <Ramsey\\\\Uuid\\\\Rfc4122\\\\UuidInterface::getFields>` method returns a\n    :php:class:`Type\\\\Hexadecimal <Ramsey\\\\Uuid\\\\Type\\\\Hexadecimal>` instance; you will need to construct an array if\n    you wish to match the return value of the deprecated ``getFieldsHex()`` method.\n\n.. _downstream users: https://en.wikipedia.org/wiki/Downstream_(software_development)\n.. _version 6 UUIDs: http://gh.peabody.io/uuidv6/\n.. _4.0.0 changelog: https://github.com/ramsey/uuid/releases/tag/4.0.0\n.. _brick/math: https://github.com/brick/math\n.. _gmp: https://www.php.net/gmp\n.. _bcmath: https://www.php.net/bcmath\n.. _DateTimeInterface: https://www.php.net/datetimeinterface\n"
  },
  {
    "path": "docs/upgrading.rst",
    "content": ".. _upgrading:\n\n=====================\nUpgrading ramsey/uuid\n=====================\n\n.. toctree::\n    :titlesonly:\n\n    upgrading/3-to-4\n    upgrading/2-to-3\n"
  },
  {
    "path": "phpbench.json",
    "content": "{\n    \"runner.bootstrap\": \"vendor/autoload.php\",\n    \"runner.path\": \"tests/benchmark\",\n    \"runner.retry_threshold\": 5,\n    \"report.generators\": {\n        \"report\": {\n            \"extends\": \"aggregate\"\n        }\n    }\n}\n"
  },
  {
    "path": "phpcs.xml.dist",
    "content": "<?xml version=\"1.0\"?>\n<ruleset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"vendor/squizlabs/php_codesniffer/phpcs.xsd\" name=\"Ramsey\">\n\n    <arg name=\"extensions\" value=\"php\"/>\n    <arg name=\"colors\"/>\n    <arg value=\"sp\"/>\n\n    <file>./src</file>\n    <file>./tests</file>\n\n    <description>A common coding standard for Ramsey's PHP libraries.</description>\n\n    <!-- Rules -->\n    <rule ref=\"PSR12\">\n        <!-- Already checked with the sniff Squiz.WhiteSpace.SemicolonSpacing.Incorrect -->\n        <exclude name=\"PSR12.Files.DeclareStatement.SpaceFoundBeforeSemicolon\"/>\n    </rule>\n\n    <!-- Warn about TODOs and FIXMEs in code. -->\n    <rule ref=\"Generic.Commenting.Fixme\"/>\n    <rule ref=\"Generic.Commenting.Todo\"/>\n\n    <!-- Constants must be all uppercase. -->\n    <rule ref=\"Generic.NamingConventions.UpperCaseConstantName\"/>\n\n    <!-- Disallow 'else if' in favor of 'elseif' (increase PSR12 severity level from warning to error) -->\n    <rule ref=\"PSR2.ControlStructures.ElseIfDeclaration.NotAllowed\">\n        <type>error</type>\n    </rule>\n\n    <!-- Forbid comments starting with # -->\n    <rule ref=\"PEAR.Commenting.InlineComment\"/>\n\n    <!-- Force array element indentation with one tab stop -->\n    <rule ref=\"Generic.Arrays.ArrayIndent\"/>\n\n    <!-- Forbid 'array(...)' -->\n    <rule ref=\"Generic.Arrays.DisallowLongArraySyntax\"/>\n\n    <!-- Forbid empty statements -->\n    <rule ref=\"Generic.CodeAnalysis.EmptyStatement\">\n        <!-- But allow empty catch -->\n        <exclude name=\"Generic.CodeAnalysis.EmptyStatement.DetectedCatch\"/>\n    </rule>\n\n    <!-- Forbid final methods in final classes -->\n    <rule ref=\"Generic.CodeAnalysis.UnnecessaryFinalModifier\"/>\n\n    <!-- Force whitespace after a type cast -->\n    <rule ref=\"Generic.Formatting.SpaceAfterCast\"/>\n\n    <!-- Forbid PHP 4 constructors -->\n    <rule ref=\"Generic.NamingConventions.ConstructorName\"/>\n\n    <!-- Forbid any content before opening tag -->\n    <rule ref=\"Generic.PHP.CharacterBeforePHPOpeningTag\"/>\n\n    <!-- Forbid backtick operator -->\n    <rule ref=\"Generic.PHP.BacktickOperator\"/>\n\n    <!-- Forbid 'php_sapi_name()' function, use PHP_SAPI -->\n    <rule ref=\"Generic.PHP.SAPIUsage\"/>\n\n    <!-- Forbid deprecated functions -->\n    <rule ref=\"Generic.PHP.DeprecatedFunctions\"/>\n\n    <!-- Allow comments to run longer than 120 characters -->\n    <rule ref=\"Generic.Files.LineLength\">\n        <properties>\n            <property name=\"ignoreComments\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid a bunch of functions -->\n    <rule ref=\"Generic.PHP.ForbiddenFunctions\">\n        <properties>\n            <property name=\"forbiddenFunctions\" type=\"array\">\n                <!-- Forbid 'empty()'; use more strict comparison instead -->\n                <element key=\"empty\" value=\"null\"/>\n                <!-- Forbid some alias functions for scalars -->\n                <element key=\"doubleval\" value=\"floatval\"/>\n                <element key=\"is_double\" value=\"is_float\"/>\n                <element key=\"is_integer\" value=\"is_int\"/>\n                <element key=\"is_long\" value=\"is_int\"/>\n                <element key=\"is_real\" value=\"is_float\"/>\n                <!-- Forbid remaining debug functions in the code -->\n                <element key=\"d\" value=\"null\"/>\n                <element key=\"dd\" value=\"null\"/>\n                <element key=\"dump\" value=\"null\"/>\n                <element key=\"dump_d\" value=\"null\"/>\n                <element key=\"var_dump\" value=\"null\"/>\n            </property>\n        </properties>\n    </rule>\n\n    <!-- Forbid goto instruction -->\n    <rule ref=\"Generic.PHP.DiscourageGoto\"/>\n\n    <!-- Forbid merge conflict artifacts left in files -->\n    <rule ref=\"Generic.VersionControl.GitMergeConflict\"/>\n\n    <!-- Require comma after last element in multi-line array -->\n    <rule ref=\"SlevomatCodingStandard.Arrays.TrailingArrayComma\"/>\n\n    <!-- Rules for single-line arrays. -->\n    <rule ref=\"SlevomatCodingStandard.Arrays.SingleLineArrayWhitespace\"/>\n\n    <!-- Require presence of constant visibility -->\n    <rule ref=\"SlevomatCodingStandard.Classes.ClassConstantVisibility\">\n        <properties>\n            <property name=\"fixable\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid empty lines around type declarations -->\n    <rule ref=\"SlevomatCodingStandard.Classes.EmptyLinesAroundClassBraces\">\n        <properties>\n            <property name=\"linesCountAfterOpeningBrace\" value=\"0\"/>\n            <property name=\"linesCountBeforeClosingBrace\" value=\"0\"/>\n        </properties>\n        <!-- Already checked with the sniff PSR2.Classes.ClassDeclaration.CloseBraceAfterBody -->\n        <exclude name=\"SlevomatCodingStandard.Classes.EmptyLinesAroundClassBraces.IncorrectEmptyLinesBeforeClosingBrace\"/>\n    </rule>\n\n    <!-- Require usage of ::class instead of __CLASS__, get_class(), get_class($this), get_called_class() and get_parent_class() -->\n    <rule ref=\"SlevomatCodingStandard.Classes.ModernClassNameReference\"/>\n\n    <!-- Forbid uses of multiple traits separated by comma -->\n    <rule ref=\"SlevomatCodingStandard.Classes.TraitUseDeclaration\"/>\n\n    <!-- Require no spaces before trait use, between trait uses and one space after trait uses -->\n    <rule ref=\"SlevomatCodingStandard.Classes.TraitUseSpacing\">\n        <properties>\n            <property name=\"linesCountAfterLastUse\" value=\"1\"/>\n            <property name=\"linesCountAfterLastUseWhenLastInClass\" value=\"0\"/>\n            <property name=\"linesCountBeforeFirstUse\" value=\"0\"/>\n            <property name=\"linesCountBetweenUses\" value=\"0\"/>\n        </properties>\n    </rule>\n\n    <rule ref=\"SlevomatCodingStandard.Commenting.DocCommentSpacing\">\n        <properties>\n            <property name=\"linesCountBeforeFirstContent\" value=\"0\"/>\n            <property name=\"linesCountAfterLastContent\" value=\"0\"/>\n            <property name=\"linesCountBetweenDescriptionAndAnnotations\" value=\"1\"/>\n            <property name=\"linesCountBetweenAnnotationsGroups\" value=\"1\"/>\n            <property name=\"annotationsGroups\" type=\"array\">\n                <element value=\"@internal,@deprecated,\"/>\n                <element value=\"@link,@see,@uses,\"/>\n                <element value=\"@param\"/>\n                <element value=\"@return\"/>\n                <element value=\"@throws\"/>\n            </property>\n        </properties>\n    </rule>\n\n    <!-- Forbid useless annotations -->\n    <rule ref=\"SlevomatCodingStandard.Commenting.ForbiddenAnnotations\">\n        <properties>\n            <property name=\"forbiddenAnnotations\" type=\"array\">\n                <element value=\"@api\"/>\n                <element value=\"@author\"/>\n                <element value=\"@category\"/>\n                <element value=\"@created\"/>\n                <element value=\"@package\"/>\n                <element value=\"@since\"/>\n                <element value=\"@subpackage\"/>\n                <element value=\"@version\"/>\n            </property>\n        </properties>\n    </rule>\n\n    <!-- Forbid empty comments -->\n    <rule ref=\"SlevomatCodingStandard.Commenting.EmptyComment\"/>\n\n    <!-- Report invalid format of inline phpDocs with @var -->\n    <rule ref=\"SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration\">\n        <properties>\n            <property name=\"allowDocCommentAboveReturn\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Report use of the useless @inheritDoc annotation -->\n    <rule ref=\"SlevomatCodingStandard.Commenting.UselessInheritDocComment\"/>\n\n    <!-- Require consistent spacing for control structures (add a line break) -->\n    <rule ref=\"SlevomatCodingStandard.ControlStructures.JumpStatementsSpacing\">\n        <properties>\n            <property name=\"jumpStatements\" type=\"array\">\n                <element value=\"break\"/>\n                <element value=\"continue\"/>\n                <element value=\"return\"/>\n                <element value=\"throw\"/>\n            </property>\n        </properties>\n    </rule>\n\n    <!-- Forbid fancy yoda conditions -->\n    <rule ref=\"SlevomatCodingStandard.ControlStructures.DisallowYodaComparison\"/>\n\n    <!-- Require language constructs without parentheses -->\n    <rule ref=\"SlevomatCodingStandard.ControlStructures.LanguageConstructWithParentheses\"/>\n\n    <!-- Require new instances with parentheses -->\n    <rule ref=\"SlevomatCodingStandard.ControlStructures.NewWithParentheses\"/>\n\n    <!-- Require usage of null coalesce operator when possible -->\n    <rule ref=\"SlevomatCodingStandard.ControlStructures.RequireNullCoalesceOperator\"/>\n\n    <!-- Forbid usage of conditions when a simple return can be used -->\n    <rule ref=\"SlevomatCodingStandard.ControlStructures.UselessIfConditionWithReturn\"/>\n\n    <!-- Forbid usage of boolean-only ternary operator usage (e.g. $foo ? true : false) -->\n    <rule ref=\"SlevomatCodingStandard.ControlStructures.UselessTernaryOperator\"/>\n\n    <!-- Forbid useless unreachable catch blocks -->\n    <rule ref=\"SlevomatCodingStandard.Exceptions.DeadCatch\"/>\n\n    <!-- Require using Throwable instead of Exception -->\n    <rule ref=\"SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly\"/>\n\n    <!-- Forbid unused variables passed to closures via 'use' -->\n    <rule ref=\"SlevomatCodingStandard.Functions.UnusedInheritedVariablePassedToClosure\"/>\n\n    <!-- Require use statements to be alphabetically sorted -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses\">\n        <properties>\n            <property name=\"psr12Compatible\" value=\"true\"/>\n            <property name=\"caseSensitive\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid fancy group uses -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.DisallowGroupUse\"/>\n\n    <!-- Forbid multiple use statements on same line -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.MultipleUsesPerLine\"/>\n\n    <!-- Forbid using absolute class name references (except global ones) -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly\">\n        <properties>\n            <property name=\"allowFallbackGlobalConstants\" value=\"false\"/>\n            <property name=\"allowFallbackGlobalFunctions\" value=\"true\"/>\n            <property name=\"allowFullyQualifiedGlobalClasses\" value=\"false\"/>\n            <property name=\"allowFullyQualifiedGlobalConstants\" value=\"false\"/>\n            <property name=\"allowFullyQualifiedGlobalFunctions\" value=\"false\"/>\n            <property name=\"allowFullyQualifiedNameForCollidingClasses\" value=\"true\"/>\n            <property name=\"allowFullyQualifiedNameForCollidingConstants\" value=\"true\"/>\n            <property name=\"allowFullyQualifiedNameForCollidingFunctions\" value=\"true\"/>\n            <property name=\"allowPartialUses\" value=\"true\"/>\n            <property name=\"searchAnnotations\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid unused use statements -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.UnusedUses\">\n        <properties>\n            <property name=\"searchAnnotations\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid useless alias for classes, constants and functions -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.UselessAlias\"/>\n\n    <!-- Forbid superfluous leading backslash in use statements -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.UseDoesNotStartWithBackslash\"/>\n\n    <!-- Forbid useless uses of the same namespace -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.UseFromSameNamespace\"/>\n\n    <!-- Require one space after the namespace, and no space before the semicolon -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.NamespaceDeclaration\"/>\n\n    <!-- Require only one namespace in a file -->\n    <rule ref=\"SlevomatCodingStandard.Namespaces.RequireOneNamespaceInFile\"/>\n\n    <!-- Forbid weak comparisons -->\n    <rule ref=\"SlevomatCodingStandard.Operators.DisallowEqualOperators\"/>\n\n    <!-- Require NOWDOC if string interpolation not used -->\n    <rule ref=\"SlevomatCodingStandard.PHP.RequireNowdoc\"/>\n\n    <!-- Forbid 'list(...)' syntax -->\n    <rule ref=\"SlevomatCodingStandard.PHP.ShortList\"/>\n\n    <!-- Forbid use of longhand cast operators -->\n    <rule ref=\"SlevomatCodingStandard.PHP.TypeCast\"/>\n\n    <!-- Forbid useless parentheses -->\n    <rule ref=\"SlevomatCodingStandard.PHP.UselessParentheses\"/>\n\n    <!-- Forbid useless semicolon `;` -->\n    <rule ref=\"SlevomatCodingStandard.PHP.UselessSemicolon\"/>\n\n    <!-- There must be no space after the spread operator. -->\n    <rule ref=\"SlevomatCodingStandard.Operators.SpreadOperatorSpacing\">\n        <properties>\n            <property name=\"spacesCountAfterOperator\" value=\"0\"/>\n        </properties>\n    </rule>\n\n    <!-- Require 0 spaces after the reference '&' operator -->\n    <rule ref=\"SlevomatCodingStandard.PHP.ReferenceSpacing\">\n        <properties>\n            <property name=\"spacesCountAfterReference\" value=\"0\"/>\n        </properties>\n    </rule>\n\n    <!-- Require presence of declare(strict_types=1) -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.DeclareStrictTypes\">\n        <!-- Ignore whitespace requirements for lines occurring before declare(strict_types=1).\n             In general, we have two lines before this statement, one before the\n             file header comment and one after. The sniff does not count any\n             newlines from the comment block. However, in tests, we don't use\n             file header comments, so we have only one line before this\n             statement. This causes problems, so we just ignore this error. -->\n        <exclude name=\"SlevomatCodingStandard.TypeHints.DeclareStrictTypes.IncorrectWhitespaceBeforeDeclare\"/>\n        <properties>\n            <property name=\"linesCountAfterDeclare\" value=\"1\"/>\n            <property name=\"spacesCountAroundEqualsSign\" value=\"0\"/>\n        </properties>\n    </rule>\n\n    <!-- Require use of short versions of scalar types (i.e. int instead of integer) -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.LongTypeHints\"/>\n\n    <!-- Require the 'null' type hint to be in the last position of annotations -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.NullTypeHintOnLastPosition\"/>\n\n    <!-- Require ? when default value is null -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.NullableTypeForNullDefaultValue\"/>\n\n    <!-- Require one space between typehint and variable, require no space between nullability sign and typehint -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing\"/>\n\n    <!-- Require types to be written as natively if possible;\n         require iterable types to specify phpDoc with their content;\n         forbid useless/duplicated information in phpDoc -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.ParameterTypeHint\">\n        <properties>\n            <property name=\"enableObjectTypeHint\" value=\"true\"/>\n        </properties>\n\n        <!-- We don't want to check for this just yet. -->\n        <exclude name=\"SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint\"/>\n    </rule>\n    <rule ref=\"SlevomatCodingStandard.TypeHints.PropertyTypeHint\">\n        <properties>\n            <property name=\"enableNativeTypeHint\" value=\"false\"/>\n        </properties>\n    </rule>\n    <rule ref=\"SlevomatCodingStandard.TypeHints.ReturnTypeHint\">\n        <properties>\n            <property name=\"enableObjectTypeHint\" value=\"true\"/>\n        </properties>\n\n        <!-- some native type hints cannot be added, because declaring them on pre-existing interfaces leads\n             to a major downstream BC break -->\n        <exclude name=\"SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint\"/>\n    </rule>\n\n    <rule ref=\"SlevomatCodingStandard.Commenting.UselessFunctionDocComment\"/>\n\n    <!-- Require the return type hint to have one space (i.e. function foo(): ?int) -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing\"/>\n\n    <!-- For arrow functions, require 1 space after the keyword and before/after the arrow -->\n    <rule ref=\"SlevomatCodingStandard.Functions.ArrowFunctionDeclaration\"/>\n\n    <!-- Forbid useless @var for constants -->\n    <rule ref=\"SlevomatCodingStandard.TypeHints.UselessConstantTypeHint\"/>\n\n    <!-- Disallow use of super-global variables -->\n    <rule ref=\"SlevomatCodingStandard.Variables.DisallowSuperGlobalVariable\"/>\n\n    <!-- Clean up unnecessary variables -->\n    <rule ref=\"SlevomatCodingStandard.Variables.UselessVariable\"/>\n    <rule ref=\"SlevomatCodingStandard.Variables.UnusedVariable\"/>\n\n    <!-- Forbid spaces around square brackets -->\n    <rule ref=\"Squiz.Arrays.ArrayBracketSpacing\"/>\n\n    <!-- Forbid class being in a file with different name -->\n    <rule ref=\"Squiz.Classes.ClassFileName\"/>\n\n    <!-- Force 'self::' for self-reference, force lower-case self, forbid spaces around '::' -->\n    <rule ref=\"Squiz.Classes.SelfMemberReference\"/>\n\n    <!-- Forbid 'AND' and 'OR', require '&&' and '||' -->\n    <rule ref=\"Squiz.Operators.ValidLogicalOperators\"/>\n\n    <!-- Forbid global functions -->\n    <rule ref=\"Squiz.Functions.GlobalFunction\"/>\n\n    <!-- Forbid 'global' -->\n    <rule ref=\"Squiz.PHP.GlobalKeyword\"/>\n\n    <!-- Forbid functions inside functions -->\n    <rule ref=\"Squiz.PHP.InnerFunctions\"/>\n\n    <!-- Require PHP function calls in lowercase -->\n    <rule ref=\"Squiz.PHP.LowercasePHPFunctions\"/>\n\n    <!-- Forbid dead code -->\n    <rule ref=\"Squiz.PHP.NonExecutableCode\"/>\n\n    <!-- Forbid `$this` inside static function -->\n    <rule ref=\"Squiz.Scope.StaticThisUsage\"/>\n\n    <!-- Force whitespace before and after concatenation -->\n    <rule ref=\"Squiz.Strings.ConcatenationSpacing\">\n        <properties>\n            <property name=\"spacing\" value=\"1\"/>\n            <property name=\"ignoreNewlines\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid blank line after function opening brace -->\n    <rule ref=\"Squiz.WhiteSpace.FunctionOpeningBraceSpace\"/>\n\n    <!-- Require 1 line before and after function, except at the top and bottom -->\n    <rule ref=\"Squiz.WhiteSpace.FunctionSpacing\">\n        <properties>\n            <property name=\"spacing\" value=\"1\"/>\n            <property name=\"spacingBeforeFirst\" value=\"0\"/>\n            <property name=\"spacingAfterLast\" value=\"0\"/>\n        </properties>\n    </rule>\n\n    <!-- Require space after language constructs -->\n    <rule ref=\"Generic.WhiteSpace.LanguageConstructSpacing\"/>\n\n    <!-- Require space around logical operators -->\n    <rule ref=\"Squiz.WhiteSpace.LogicalOperatorSpacing\"/>\n\n    <rule ref=\"SlevomatCodingStandard.TypeHints.DNFTypeHintFormat\">\n        <properties>\n            <property name=\"withSpacesAroundOperators\" value=\"yes\"/>\n            <property name=\"nullPosition\" value=\"last\"/>\n            <property name=\"shortNullable\" value=\"yes\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid spaces around '->' operator -->\n    <rule ref=\"Squiz.WhiteSpace.ObjectOperatorSpacing\">\n        <properties>\n            <property name=\"ignoreNewlines\" value=\"true\"/>\n        </properties>\n    </rule>\n\n    <!-- Forbid spaces before semicolon ';' -->\n    <rule ref=\"Squiz.WhiteSpace.SemicolonSpacing\"/>\n\n    <!-- Forbid superfluous whitespaces -->\n    <rule ref=\"Squiz.WhiteSpace.SuperfluousWhitespace\">\n        <properties>\n            <!-- turned on by PSR12 -> turning back off -->\n            <property name=\"ignoreBlankLines\" value=\"false\"/>\n        </properties>\n    </rule>\n    <rule ref=\"Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines\">\n        <!-- turned off by PSR12 -> turning back on -->\n        <severity>5</severity>\n    </rule>\n\n    <!-- Does not allow double quotes for plain strings but does allow them if they contain a variable. -->\n    <rule ref=\"Squiz.Strings.DoubleQuoteUsage.NotRequired\"/>\n\n    <!-- Force camelCase variables -->\n    <rule ref=\"Squiz.NamingConventions.ValidVariableName\">\n        <exclude name=\"Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore\"/>\n    </rule>\n\n    <!-- Checks duplicate spaces anywhere because there aren't sniffs for every part of code to check formatting. -->\n    <rule ref=\"SlevomatCodingStandard.Whitespaces.DuplicateSpaces\"/>\n\n</ruleset>\n"
  },
  {
    "path": "phpstan.neon.dist",
    "content": "parameters:\n    tmpDir: ./build/cache/phpstan\n    level: max\n    treatPhpDocTypesAsCertain: false\n    paths:\n        - ./src\n        - ./tests\n    bootstrapFiles:\n        - ./tests/static-analysis/stubs.php\n    excludePaths:\n        analyse:\n            - ./tests/ExpectedBehaviorTest.php\n            - ./tests/static-analysis/stubs.php\n    ignoreErrors:\n        -\n            identifier: method.resultUnused\n            path: tests/*\n        -\n            identifier: staticMethod.resultUnused\n            path: tests/*\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"./vendor/phpunit/phpunit/phpunit.xsd\"\n         bootstrap=\"./tests/bootstrap.php\"\n         cacheResultFile=\"./build/cache/phpunit.result.cache\"\n         colors=\"true\"\n         verbose=\"true\">\n\n    <testsuites>\n        <testsuite name=\"unit-tests\">\n            <directory>./tests</directory>\n        </testsuite>\n    </testsuites>\n\n    <coverage processUncoveredFiles=\"true\">\n        <include>\n            <directory suffix=\".php\">./src</directory>\n        </include>\n    </coverage>\n\n    <php>\n        <!-- E_ALL & ~E_DEPRECATED -->\n        <ini name=\"error_reporting\" value=\"24575\"/>\n    </php>\n\n</phpunit>\n"
  },
  {
    "path": "resources/vagrant/.gitignore",
    "content": ".vagrant/\n"
  },
  {
    "path": "resources/vagrant/README.md",
    "content": "# Running Tests With Vagrant\n\nTo run tests using these instructions, you will first need to install\n[Vagrant](https://www.vagrantup.com). You should be able to use\n[VirtualBox](https://www.virtualbox.org) with each environment. Other providers,\nsuch as VMWare and Hyper-V, may be available, depending on the box used.\n\n* [Run tests on Linux](linux/README.md)\n* [Run tests on FreeBSD](freebsd/README.md)\n* [Run tests on Windows](windows/README.md)\n"
  },
  {
    "path": "resources/vagrant/freebsd/README.md",
    "content": "# Run tests on FreeBSD\n\n``` bash\ncd /path/to/uuid/resources/vagrant/freebsd\nvagrant up\nvagrant ssh\n```\n\nOnce inside the VM:\n\n``` bash\ncd uuid/\ncomposer install\ncomposer run-script --timeout=0 test\n```\n"
  },
  {
    "path": "resources/vagrant/freebsd/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n$script = <<-SCRIPT\npkg update\npkg install -y \\\n  php74 \\\n  php74-bcmath \\\n  php74-composer \\\n  php74-dom \\\n  php74-gmp \\\n  php74-json \\\n  php74-pecl-libsodium \\\n  php74-pecl-uuid \\\n  php74-pecl-xdebug \\\n  php74-simplexml \\\n  php74-tokenizer \\\n  php74-xml \\\n  php74-xmlreader \\\n  php74-xmlwriter \\\n  php74-zip \\\n  unzip\nSCRIPT\n\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"freebsd/FreeBSD-12.1-RELEASE\"\n  config.vm.box_version = \"2019.11.01\"\n  config.vm.provision \"shell\", inline: $script\n  config.vm.synced_folder \"../../../\", \"/home/vagrant/uuid\", type: \"rsync\"\n  config.ssh.shell = \"sh\"\n\n  config.vm.provider \"virtualbox\" do |v|\n    v.name = \"ramsey-uuid-freebsd\"\n  end\nend\n"
  },
  {
    "path": "resources/vagrant/linux/README.md",
    "content": "# Run tests on Linux\n\n``` bash\ncd /path/to/uuid/resources/vagrant/linux\nvagrant up\nvagrant ssh\n```\n\nOnce inside the VM:\n\n``` bash\ncd uuid/\ncomposer install\ncomposer run-script --timeout=0 test\n```\n"
  },
  {
    "path": "resources/vagrant/linux/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n$script = <<-SCRIPT\napt-get update\napt-get install -y \\\n  composer \\\n  php-bcmath \\\n  php-cli \\\n  php-gmp \\\n  php-json \\\n  php-uuid \\\n  php-xdebug \\\n  php-xml \\\n  php-zip \\\n  unzip\nSCRIPT\n\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"ubuntu/eoan64\"\n  config.vm.provision \"shell\", inline: $script\n  config.vm.synced_folder \"../../../\", \"/home/vagrant/uuid\", type: \"rsync\"\n\n  config.vm.provider \"virtualbox\" do |v|\n    v.name = \"ramsey-uuid-linux\"\n  end\nend\n"
  },
  {
    "path": "resources/vagrant/windows/README.md",
    "content": "# Run tests on Windows\n\n``` bash\ncd /path/to/uuid/resources/vagrant/windows\nvagrant up\nvagrant ssh\n```\n\nOnce inside the VM:\n\n``` bash\nrefreshenv\ncd uuid\ncomposer install\ncomposer run-script --timeout=0 test\n```\n"
  },
  {
    "path": "resources/vagrant/windows/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n$script = <<-SCRIPT\nchoco install composer php unzip --no-progress -y\nInvoke-WebRequest -Uri https://windows.php.net/downloads/pecl/releases/xdebug/2.9.1/php_xdebug-2.9.1-7.4-nts-vc15-x64.zip -UseBasicParsing -OutFile C:\\\\temp\\\\php_xdebug.zip\nunzip C:\\\\temp\\\\php_xdebug.zip -d C:\\\\temp\\\\php_xdebug\nmove C:\\\\temp\\\\php_xdebug\\\\php_xdebug.dll C:\\\\tools\\\\php74\\\\ext\\\\php_xdebug.dll\nAdd-Content C:\\\\tools\\\\php74\\\\php.ini \"`nextension=gmp\"\nAdd-Content C:\\\\tools\\\\php74\\\\php.ini \"`nextension=sodium\"\nAdd-Content C:\\\\tools\\\\php74\\\\php.ini \"`nzend_extension=xdebug\"\nSCRIPT\n\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"jborean93/WindowsServer2019\"\n  config.vm.provision \"shell\", inline: $script\n  config.vm.synced_folder \"../../../\", \"C:\\\\Users\\\\vagrant\\\\uuid\"\n\n  config.vm.provider \"virtualbox\" do |vb|\n    vb.name = \"ramsey-uuid-windows\"\n  end\nend\n"
  },
  {
    "path": "src/BinaryUtils.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\n/**\n * Provides binary math utilities\n */\nclass BinaryUtils\n{\n    /**\n     * Applies the variant field to the 16-bit clock sequence\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     *\n     * @param int $clockSeq The 16-bit clock sequence value before the variant is applied\n     *\n     * @return int The 16-bit clock sequence multiplexed with the UUID variant\n     *\n     * @pure\n     */\n    public static function applyVariant(int $clockSeq): int\n    {\n        return ($clockSeq & 0x3fff) | 0x8000;\n    }\n\n    /**\n     * Applies the version field to the 16-bit `time_hi_and_version` field\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     *\n     * @param int $timeHi The value of the 16-bit `time_hi_and_version` field before the version is applied\n     * @param int $version The version to apply to the `time_hi` field\n     *\n     * @return int The 16-bit time_hi field of the timestamp multiplexed with the UUID version number\n     *\n     * @pure\n     */\n    public static function applyVersion(int $timeHi, int $version): int\n    {\n        return ($timeHi & 0x0fff) | ($version << 12);\n    }\n}\n"
  },
  {
    "path": "src/Builder/BuilderCollection.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Builder;\n\nuse Ramsey\\Collection\\AbstractCollection;\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\PhpTimeConverter;\nuse Ramsey\\Uuid\\Guid\\GuidBuilder;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Nonstandard\\UuidBuilder as NonstandardUuidBuilder;\nuse Ramsey\\Uuid\\Rfc4122\\UuidBuilder as Rfc4122UuidBuilder;\nuse Traversable;\n\n/**\n * A collection of UuidBuilderInterface objects\n *\n * @deprecated this class has been deprecated and will be removed in 5.0.0. The use-case for this class comes from a\n *     pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced at runtime:\n *     that is no longer necessary, now that you can safely verify your code to be correct, and use more generic types\n *     like `iterable<T>` instead.\n *\n * @extends AbstractCollection<UuidBuilderInterface>\n */\nclass BuilderCollection extends AbstractCollection\n{\n    public function getType(): string\n    {\n        return UuidBuilderInterface::class;\n    }\n\n    public function getIterator(): Traversable\n    {\n        return parent::getIterator();\n    }\n\n    /**\n     * Re-constructs the object from its serialized form\n     *\n     * @param string $serialized The serialized PHP string to unserialize into a UuidInterface instance\n     */\n    public function unserialize($serialized): void\n    {\n        /** @var array<array-key, UuidBuilderInterface> $data */\n        $data = unserialize($serialized, [\n            'allowed_classes' => [\n                BrickMathCalculator::class,\n                GenericNumberConverter::class,\n                GenericTimeConverter::class,\n                GuidBuilder::class,\n                NonstandardUuidBuilder::class,\n                PhpTimeConverter::class,\n                Rfc4122UuidBuilder::class,\n            ],\n        ]);\n\n        $this->data = array_filter(\n            $data,\n            function ($unserialized): bool {\n                /** @phpstan-ignore instanceof.alwaysTrue */\n                return $unserialized instanceof UuidBuilderInterface;\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "src/Builder/DefaultUuidBuilder.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Builder;\n\nuse Ramsey\\Uuid\\Rfc4122\\UuidBuilder as Rfc4122UuidBuilder;\n\n/**\n * @deprecated Please transition to {@see Rfc4122UuidBuilder}.\n *\n * @immutable\n */\nclass DefaultUuidBuilder extends Rfc4122UuidBuilder\n{\n}\n"
  },
  {
    "path": "src/Builder/DegradedUuidBuilder.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Builder;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\Time\\DegradedTimeConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\DegradedUuid;\nuse Ramsey\\Uuid\\Rfc4122\\Fields as Rfc4122Fields;\nuse Ramsey\\Uuid\\UuidInterface;\n\n/**\n * @deprecated DegradedUuid instances are no longer necessary to support 32-bit systems. Please transition to {@see DefaultUuidBuilder}.\n *\n * @immutable\n */\nclass DegradedUuidBuilder implements UuidBuilderInterface\n{\n    private TimeConverterInterface $timeConverter;\n\n    /**\n     * @param NumberConverterInterface $numberConverter The number converter to use when constructing the DegradedUuid\n     * @param TimeConverterInterface|null $timeConverter The time converter to use for converting timestamps extracted\n     *     from a UUID to Unix timestamps\n     */\n    public function __construct(\n        private NumberConverterInterface $numberConverter,\n        ?TimeConverterInterface $timeConverter = null\n    ) {\n        $this->timeConverter = $timeConverter ?: new DegradedTimeConverter();\n    }\n\n    /**\n     * Builds and returns a DegradedUuid\n     *\n     * @param CodecInterface $codec The codec to use for building this DegradedUuid instance\n     * @param string $bytes The byte string from which to construct a UUID\n     *\n     * @return DegradedUuid The DegradedUuidBuild returns an instance of Ramsey\\Uuid\\DegradedUuid\n     *\n     * @phpstan-impure\n     */\n    public function build(CodecInterface $codec, string $bytes): UuidInterface\n    {\n        return new DegradedUuid(new Rfc4122Fields($bytes), $this->numberConverter, $codec, $this->timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Builder/FallbackBuilder.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Builder;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Exception\\BuilderNotFoundException;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\UuidInterface;\n\n/**\n * FallbackBuilder builds a UUID by stepping through a list of UUID builders until a UUID can be constructed without exceptions\n *\n * @immutable\n */\nclass FallbackBuilder implements UuidBuilderInterface\n{\n    /**\n     * @param iterable<UuidBuilderInterface> $builders An array of UUID builders\n     */\n    public function __construct(private iterable $builders)\n    {\n    }\n\n    /**\n     * Builds and returns a UuidInterface instance using the first builder that succeeds\n     *\n     * @param CodecInterface $codec The codec to use for building this instance\n     * @param string $bytes The byte string from which to construct a UUID\n     *\n     * @return UuidInterface an instance of a UUID object\n     *\n     * @pure\n     */\n    public function build(CodecInterface $codec, string $bytes): UuidInterface\n    {\n        $lastBuilderException = null;\n\n        foreach ($this->builders as $builder) {\n            try {\n                return $builder->build($codec, $bytes);\n            } catch (UnableToBuildUuidException $exception) {\n                $lastBuilderException = $exception;\n\n                continue;\n            }\n        }\n\n        throw new BuilderNotFoundException(\n            'Could not find a suitable builder for the provided codec and fields',\n            0,\n            $lastBuilderException,\n        );\n    }\n}\n"
  },
  {
    "path": "src/Builder/UuidBuilderInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Builder;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\UuidInterface;\n\n/**\n * A UUID builder builds instances of UuidInterface\n *\n * @immutable\n */\ninterface UuidBuilderInterface\n{\n    /**\n     * Builds and returns a UuidInterface\n     *\n     * @param CodecInterface $codec The codec to use for building this UuidInterface instance\n     * @param string $bytes The byte string from which to construct a UUID\n     *\n     * @return UuidInterface Implementations may choose to return more specific instances of UUIDs that implement UuidInterface\n     *\n     * @pure\n     */\n    public function build(CodecInterface $codec, string $bytes): UuidInterface;\n}\n"
  },
  {
    "path": "src/Codec/CodecInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Codec;\n\nuse Ramsey\\Uuid\\UuidInterface;\n\n/**\n * A codec encodes and decodes a UUID according to defined rules\n *\n * @immutable\n */\ninterface CodecInterface\n{\n    /**\n     * Returns a hexadecimal string representation of a UuidInterface\n     *\n     * @param UuidInterface $uuid The UUID for which to create a hexadecimal string representation\n     *\n     * @return non-empty-string Hexadecimal string representation of a UUID\n     *\n     * @pure\n     */\n    public function encode(UuidInterface $uuid): string;\n\n    /**\n     * Returns a binary string representation of a UuidInterface\n     *\n     * @param UuidInterface $uuid The UUID for which to create a binary string representation\n     *\n     * @return non-empty-string Binary string representation of a UUID\n     *\n     * @pure\n     */\n    public function encodeBinary(UuidInterface $uuid): string;\n\n    /**\n     * Returns a UuidInterface derived from a hexadecimal string representation\n     *\n     * @param string $encodedUuid The hexadecimal string representation to convert into a UuidInterface instance\n     *\n     * @return UuidInterface An instance of a UUID decoded from a hexadecimal string representation\n     *\n     * @pure\n     */\n    public function decode(string $encodedUuid): UuidInterface;\n\n    /**\n     * Returns a UuidInterface derived from a binary string representation\n     *\n     * @param string $bytes The binary string representation to convert into a UuidInterface instance\n     *\n     * @return UuidInterface An instance of a UUID decoded from a binary string representation\n     *\n     * @pure\n     */\n    public function decodeBytes(string $bytes): UuidInterface;\n}\n"
  },
  {
    "path": "src/Codec/GuidStringCodec.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Codec;\n\nuse Ramsey\\Uuid\\Guid\\Guid;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function bin2hex;\nuse function sprintf;\nuse function substr;\n\n/**\n * GuidStringCodec encodes and decodes globally unique identifiers (GUID)\n *\n * @see Guid\n *\n * @immutable\n */\nclass GuidStringCodec extends StringCodec\n{\n    public function encode(UuidInterface $uuid): string\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $hex = bin2hex($uuid->getFields()->getBytes());\n\n        /** @var non-empty-string */\n        return sprintf(\n            '%02s%02s%02s%02s-%02s%02s-%02s%02s-%04s-%012s',\n            substr($hex, 6, 2),\n            substr($hex, 4, 2),\n            substr($hex, 2, 2),\n            substr($hex, 0, 2),\n            substr($hex, 10, 2),\n            substr($hex, 8, 2),\n            substr($hex, 14, 2),\n            substr($hex, 12, 2),\n            substr($hex, 16, 4),\n            substr($hex, 20),\n        );\n    }\n\n    public function decode(string $encodedUuid): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $bytes = $this->getBytes($encodedUuid);\n\n        /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */\n        return $this->getBuilder()->build($this, $this->swapBytes($bytes));\n    }\n\n    public function decodeBytes(string $bytes): UuidInterface\n    {\n        // Call parent::decode() to preserve the correct byte order.\n        return parent::decode(bin2hex($bytes));\n    }\n\n    /**\n     * Swaps bytes according to the GUID rules\n     */\n    private function swapBytes(string $bytes): string\n    {\n        return $bytes[3] . $bytes[2] . $bytes[1] . $bytes[0]\n            . $bytes[5] . $bytes[4] . $bytes[7] . $bytes[6]\n            . substr($bytes, 8);\n    }\n}\n"
  },
  {
    "path": "src/Codec/OrderedTimeCodec.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Codec;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function strlen;\nuse function substr;\n\n/**\n * OrderedTimeCodec encodes and decodes a UUID, optimizing the byte order for more efficient storage\n *\n * For binary representations of version 1 UUID, this codec may be used to reorganize the time fields, making the UUID\n * closer to sequential when storing the bytes. According to Percona, this optimization can improve database INSERT and\n * SELECT statements using the UUID column as a key.\n *\n * The string representation of the UUID will remain unchanged. Only the binary representation is reordered.\n *\n * PLEASE NOTE: Binary representations of UUIDs encoded with this codec must be decoded with this codec. Decoding using\n * another codec can result in malformed UUIDs.\n *\n * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version6.html Version 6, reordered time-based UUIDs}.\n *\n * @link https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/ Storing UUID Values in MySQL\n *\n * @immutable\n */\nclass OrderedTimeCodec extends StringCodec\n{\n    /**\n     * Returns a binary string representation of a UUID, with the timestamp fields rearranged for optimized storage\n     *\n     * @return non-empty-string\n     */\n    public function encodeBinary(UuidInterface $uuid): string\n    {\n        if (\n            /** @phpstan-ignore possiblyImpure.methodCall */\n            !($uuid->getFields() instanceof Rfc4122FieldsInterface)\n            /** @phpstan-ignore possiblyImpure.methodCall */\n            || $uuid->getFields()->getVersion() !== Uuid::UUID_TYPE_TIME\n        ) {\n            throw new InvalidArgumentException('Expected version 1 (time-based) UUID');\n        }\n\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $bytes = $uuid->getFields()->getBytes();\n\n        return $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5]\n            . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3]\n            . substr($bytes, 8);\n    }\n\n    /**\n     * Returns a UuidInterface derived from an ordered-time binary string representation\n     *\n     * @throws InvalidArgumentException if $bytes is an invalid length\n     *\n     * @inheritDoc\n     */\n    public function decodeBytes(string $bytes): UuidInterface\n    {\n        if (strlen($bytes) !== 16) {\n            throw new InvalidArgumentException('$bytes string should contain 16 characters.');\n        }\n\n        // Rearrange the bytes to their original order.\n        $rearrangedBytes = $bytes[4] . $bytes[5] . $bytes[6] . $bytes[7]\n            . $bytes[2] . $bytes[3] . $bytes[0] . $bytes[1]\n            . substr($bytes, 8);\n\n        $uuid = parent::decodeBytes($rearrangedBytes);\n\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $fields = $uuid->getFields();\n\n        if (!$fields instanceof Rfc4122FieldsInterface || $fields->getVersion() !== Uuid::UUID_TYPE_TIME) {\n            throw new UnsupportedOperationException(\n                'Attempting to decode a non-time-based UUID using OrderedTimeCodec',\n            );\n        }\n\n        return $uuid;\n    }\n}\n"
  },
  {
    "path": "src/Codec/StringCodec.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Codec;\n\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Exception\\InvalidUuidStringException;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function bin2hex;\nuse function hex2bin;\nuse function implode;\nuse function sprintf;\nuse function str_replace;\nuse function strlen;\nuse function substr;\n\n/**\n * StringCodec encodes and decodes RFC 9562 (formerly RFC 4122) UUIDs\n *\n * @immutable\n */\nclass StringCodec implements CodecInterface\n{\n    /**\n     * Constructs a StringCodec\n     *\n     * @param UuidBuilderInterface $builder The builder to use when encoding UUIDs\n     */\n    public function __construct(private UuidBuilderInterface $builder)\n    {\n    }\n\n    public function encode(UuidInterface $uuid): string\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $hex = bin2hex($uuid->getFields()->getBytes());\n\n        /** @var non-empty-string */\n        return sprintf(\n            '%08s-%04s-%04s-%04s-%012s',\n            substr($hex, 0, 8),\n            substr($hex, 8, 4),\n            substr($hex, 12, 4),\n            substr($hex, 16, 4),\n            substr($hex, 20),\n        );\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function encodeBinary(UuidInterface $uuid): string\n    {\n        /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */\n        return $uuid->getFields()->getBytes();\n    }\n\n    /**\n     * @throws InvalidUuidStringException\n     *\n     * @inheritDoc\n     */\n    public function decode(string $encodedUuid): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return $this->builder->build($this, $this->getBytes($encodedUuid));\n    }\n\n    public function decodeBytes(string $bytes): UuidInterface\n    {\n        if (strlen($bytes) !== 16) {\n            throw new InvalidArgumentException('$bytes string should contain 16 characters.');\n        }\n\n        return $this->builder->build($this, $bytes);\n    }\n\n    /**\n     * Returns the UUID builder\n     */\n    protected function getBuilder(): UuidBuilderInterface\n    {\n        return $this->builder;\n    }\n\n    /**\n     * Returns a byte string of the UUID\n     */\n    protected function getBytes(string $encodedUuid): string\n    {\n        $parsedUuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}', '-'], '', $encodedUuid);\n\n        $components = [\n            substr($parsedUuid, 0, 8),\n            substr($parsedUuid, 8, 4),\n            substr($parsedUuid, 12, 4),\n            substr($parsedUuid, 16, 4),\n            substr($parsedUuid, 20),\n        ];\n\n        if (!Uuid::isValid(implode('-', $components))) {\n            throw new InvalidUuidStringException('Invalid UUID string: ' . $encodedUuid);\n        }\n\n        return (string) hex2bin($parsedUuid);\n    }\n}\n"
  },
  {
    "path": "src/Codec/TimestampFirstCombCodec.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Codec;\n\nuse Ramsey\\Uuid\\Exception\\InvalidUuidStringException;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function bin2hex;\nuse function sprintf;\nuse function substr;\nuse function substr_replace;\n\n/**\n * TimestampFirstCombCodec encodes and decodes COMBs, with the timestamp as the first 48 bits\n *\n * In contrast with the TimestampLastCombCodec, the TimestampFirstCombCodec adds the timestamp to the first 48 bits of\n * the COMB. To generate a timestamp-first COMB, set the TimestampFirstCombCodec as the codec, along with the\n * CombGenerator as the random generator.\n *\n * ```\n * $factory = new UuidFactory();\n *\n * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder()));\n *\n * $factory->setRandomGenerator(new CombGenerator(\n *     $factory->getRandomGenerator(),\n *     $factory->getNumberConverter(),\n * ));\n *\n * $timestampFirstComb = $factory->uuid4();\n * ```\n *\n * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version7.html Version 7, Unix Epoch Time UUIDs}.\n *\n * @link https://web.archive.org/web/20240118030355/https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys\n *\n * @immutable\n */\nclass TimestampFirstCombCodec extends StringCodec\n{\n    /**\n     * @return non-empty-string\n     */\n    public function encode(UuidInterface $uuid): string\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $bytes = $this->swapBytes($uuid->getFields()->getBytes());\n\n        return sprintf(\n            '%08s-%04s-%04s-%04s-%012s',\n            bin2hex(substr($bytes, 0, 4)),\n            bin2hex(substr($bytes, 4, 2)),\n            bin2hex(substr($bytes, 6, 2)),\n            bin2hex(substr($bytes, 8, 2)),\n            bin2hex(substr($bytes, 10))\n        );\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function encodeBinary(UuidInterface $uuid): string\n    {\n        /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */\n        return $this->swapBytes($uuid->getFields()->getBytes());\n    }\n\n    /**\n     * @throws InvalidUuidStringException\n     *\n     * @inheritDoc\n     */\n    public function decode(string $encodedUuid): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $bytes = $this->getBytes($encodedUuid);\n\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return $this->getBuilder()->build($this, $this->swapBytes($bytes));\n    }\n\n    public function decodeBytes(string $bytes): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return $this->getBuilder()->build($this, $this->swapBytes($bytes));\n    }\n\n    /**\n     * Swaps bytes according to the timestamp-first COMB rules\n     *\n     * @pure\n     */\n    private function swapBytes(string $bytes): string\n    {\n        $first48Bits = substr($bytes, 0, 6);\n        $last48Bits = substr($bytes, -6);\n\n        return substr_replace(substr_replace($bytes, $last48Bits, 0, 6), $first48Bits, -6);\n    }\n}\n"
  },
  {
    "path": "src/Codec/TimestampLastCombCodec.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Codec;\n\n/**\n * TimestampLastCombCodec encodes and decodes COMBs, with the timestamp as the last 48 bits\n *\n * The CombGenerator when used with the StringCodec (and, by proxy, the TimestampLastCombCodec) adds the timestamp to\n * the last 48 bits of the COMB. The TimestampLastCombCodec is provided for the sake of consistency. In practice, it is\n * identical to the standard StringCodec, but it may be used with the CombGenerator for additional context when reading\n * code.\n *\n * Consider the following code. By default, the codec used by UuidFactory is the StringCodec, but here, we explicitly\n * set the TimestampLastCombCodec. It is redundant, but it is clear that we intend this COMB to be generated with the\n * timestamp appearing at the end.\n *\n * ```\n * $factory = new UuidFactory();\n *\n * $factory->setCodec(new TimestampLastCombCodec($factory->getUuidBuilder()));\n *\n * $factory->setRandomGenerator(new CombGenerator(\n *     $factory->getRandomGenerator(),\n *     $factory->getNumberConverter(),\n * ));\n *\n * $timestampLastComb = $factory->uuid4();\n * ```\n *\n * @deprecated Please use {@see StringCodec} instead.\n *\n * @immutable\n */\nclass TimestampLastCombCodec extends StringCodec\n{\n}\n"
  },
  {
    "path": "src/Converter/Number/BigNumberConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Number;\n\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\n\n/**\n * Previously used to integrate moontoast/math as a bignum arithmetic library, BigNumberConverter is deprecated in favor\n * of GenericNumberConverter\n *\n * @deprecated Please transition to {@see GenericNumberConverter}.\n *\n * @immutable\n */\nclass BigNumberConverter implements NumberConverterInterface\n{\n    private NumberConverterInterface $converter;\n\n    public function __construct()\n    {\n        $this->converter = new GenericNumberConverter(new BrickMathCalculator());\n    }\n\n    /**\n     * @pure\n     */\n    public function fromHex(string $hex): string\n    {\n        return $this->converter->fromHex($hex);\n    }\n\n    /**\n     * @pure\n     */\n    public function toHex(string $number): string\n    {\n        return $this->converter->toHex($number);\n    }\n}\n"
  },
  {
    "path": "src/Converter/Number/DegradedNumberConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Number;\n\n/**\n * @deprecated DegradedNumberConverter is no longer necessary for converting numbers on 32-bit systems. Please\n *     transition to {@see GenericNumberConverter}.\n *\n * @immutable\n */\nclass DegradedNumberConverter extends BigNumberConverter\n{\n}\n"
  },
  {
    "path": "src/Converter/Number/GenericNumberConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Number;\n\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Math\\CalculatorInterface;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n\n/**\n * GenericNumberConverter uses the provided calculator to convert decimal numbers to and from hexadecimal values\n *\n * @immutable\n */\nclass GenericNumberConverter implements NumberConverterInterface\n{\n    public function __construct(private CalculatorInterface $calculator)\n    {\n    }\n\n    /**\n     * @pure\n     */\n    public function fromHex(string $hex): string\n    {\n        return $this->calculator->fromBase($hex, 16)->toString();\n    }\n\n    /**\n     * @pure\n     */\n    public function toHex(string $number): string\n    {\n        /** @phpstan-ignore return.type, possiblyImpure.new */\n        return $this->calculator->toBase(new IntegerObject($number), 16);\n    }\n}\n"
  },
  {
    "path": "src/Converter/NumberConverterInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter;\n\n/**\n * A number converter converts UUIDs from hexadecimal characters into representations of integers and vice versa\n *\n * @immutable\n */\ninterface NumberConverterInterface\n{\n    /**\n     * Converts a hexadecimal number into a string integer representation of the number\n     *\n     * The integer representation returned is a string representation of the integer to accommodate unsigned integers\n     * that are greater than `PHP_INT_MAX`.\n     *\n     * @param string $hex The hexadecimal string representation to convert\n     *\n     * @return numeric-string String representation of an integer\n     *\n     * @pure\n     */\n    public function fromHex(string $hex): string;\n\n    /**\n     * Converts a string integer representation into a hexadecimal string representation of the number\n     *\n     * @param string $number A string integer representation to convert; this must be a numeric string to accommodate\n     *     unsigned integers that are greater than `PHP_INT_MAX`.\n     *\n     * @return non-empty-string Hexadecimal string\n     *\n     * @pure\n     */\n    public function toHex(string $number): string;\n}\n"
  },
  {
    "path": "src/Converter/Time/BigNumberTimeConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Time;\n\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\n\n/**\n * Previously used to integrate moontoast/math as a bignum arithmetic library, BigNumberTimeConverter is deprecated in\n * favor of GenericTimeConverter\n *\n * @deprecated Please transition to {@see GenericTimeConverter}.\n *\n * @immutable\n */\nclass BigNumberTimeConverter implements TimeConverterInterface\n{\n    private TimeConverterInterface $converter;\n\n    public function __construct()\n    {\n        $this->converter = new GenericTimeConverter(new BrickMathCalculator());\n    }\n\n    public function calculateTime(string $seconds, string $microseconds): Hexadecimal\n    {\n        return $this->converter->calculateTime($seconds, $microseconds);\n    }\n\n    public function convertTime(Hexadecimal $uuidTimestamp): Time\n    {\n        return $this->converter->convertTime($uuidTimestamp);\n    }\n}\n"
  },
  {
    "path": "src/Converter/Time/DegradedTimeConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Time;\n\n/**\n * @deprecated DegradedTimeConverter is no longer necessary for converting time on 32-bit systems. Please transition to\n *     {@see GenericTimeConverter}.\n *\n * @immutable\n */\nclass DegradedTimeConverter extends BigNumberTimeConverter\n{\n}\n"
  },
  {
    "path": "src/Converter/Time/GenericTimeConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Time;\n\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Math\\CalculatorInterface;\nuse Ramsey\\Uuid\\Math\\RoundingMode;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\n\nuse function explode;\nuse function str_pad;\n\nuse const STR_PAD_LEFT;\n\n/**\n * GenericTimeConverter uses the provided calculator to calculate and convert time values\n *\n * @immutable\n */\nclass GenericTimeConverter implements TimeConverterInterface\n{\n    /**\n     * The number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix epoch.\n     */\n    private const GREGORIAN_TO_UNIX_INTERVALS = '122192928000000000';\n\n    /**\n     * The number of 100-nanosecond intervals in one second.\n     */\n    private const SECOND_INTERVALS = '10000000';\n\n    /**\n     * The number of 100-nanosecond intervals in one microsecond.\n     */\n    private const MICROSECOND_INTERVALS = '10';\n\n    public function __construct(private CalculatorInterface $calculator)\n    {\n    }\n\n    public function calculateTime(string $seconds, string $microseconds): Hexadecimal\n    {\n        /** @phpstan-ignore possiblyImpure.new */\n        $timestamp = new Time($seconds, $microseconds);\n\n        // Convert the seconds into a count of 100-nanosecond intervals.\n        $sec = $this->calculator->multiply(\n            $timestamp->getSeconds(),\n            new IntegerObject(self::SECOND_INTERVALS), /** @phpstan-ignore possiblyImpure.new */\n        );\n\n        // Convert the microseconds into a count of 100-nanosecond intervals.\n        $usec = $this->calculator->multiply(\n            $timestamp->getMicroseconds(),\n            new IntegerObject(self::MICROSECOND_INTERVALS), /** @phpstan-ignore possiblyImpure.new */\n        );\n\n        /**\n         * Combine the intervals of seconds and microseconds and add the count of 100-nanosecond intervals from the\n         * Gregorian calendar epoch to the Unix epoch. This gives us the correct count of 100-nanosecond intervals since\n         * the Gregorian calendar epoch for the given seconds and microseconds.\n         *\n         * @var IntegerObject $uuidTime\n         * @phpstan-ignore possiblyImpure.new\n         */\n        $uuidTime = $this->calculator->add($sec, $usec, new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS));\n\n        /**\n         * PHPStan considers CalculatorInterface::toHexadecimal, Hexadecimal:toString impure.\n         *\n         * @phpstan-ignore possiblyImpure.new\n         */\n        return new Hexadecimal(str_pad($this->calculator->toHexadecimal($uuidTime)->toString(), 16, '0', STR_PAD_LEFT));\n    }\n\n    public function convertTime(Hexadecimal $uuidTimestamp): Time\n    {\n        // From the total, subtract the number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix\n        // epoch. This gives us the number of 100-nanosecond intervals from the Unix epoch, which also includes the microtime.\n        $epochNanoseconds = $this->calculator->subtract(\n            $this->calculator->toInteger($uuidTimestamp),\n            new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS), /** @phpstan-ignore possiblyImpure.new */\n        );\n\n        // Convert the 100-nanosecond intervals into seconds and microseconds.\n        $unixTimestamp = $this->calculator->divide(\n            RoundingMode::HALF_UP,\n            6,\n            $epochNanoseconds,\n            new IntegerObject(self::SECOND_INTERVALS), /** @phpstan-ignore possiblyImpure.new */\n        );\n\n        $split = explode('.', (string) $unixTimestamp, 2);\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Time($split[0], $split[1] ?? 0);\n    }\n}\n"
  },
  {
    "path": "src/Converter/Time/PhpTimeConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Time;\n\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Math\\CalculatorInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\n\nuse function count;\nuse function dechex;\nuse function explode;\nuse function is_float;\nuse function is_int;\nuse function str_pad;\nuse function strlen;\nuse function substr;\n\nuse const STR_PAD_LEFT;\nuse const STR_PAD_RIGHT;\n\n/**\n * PhpTimeConverter uses built-in PHP functions and standard math operations available to the PHP programming language\n * to provide facilities for converting parts of time into representations that may be used in UUIDs\n *\n * @immutable\n */\nclass PhpTimeConverter implements TimeConverterInterface\n{\n    /**\n     * The number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix epoch.\n     */\n    private const GREGORIAN_TO_UNIX_INTERVALS = 0x01b21dd213814000;\n\n    /**\n     * The number of 100-nanosecond intervals in one second.\n     */\n    private const SECOND_INTERVALS = 10_000_000;\n\n    /**\n     * The number of 100-nanosecond intervals in one microsecond.\n     */\n    private const MICROSECOND_INTERVALS = 10;\n\n    private int $phpPrecision;\n    private CalculatorInterface $calculator;\n    private TimeConverterInterface $fallbackConverter;\n\n    public function __construct(\n        ?CalculatorInterface $calculator = null,\n        ?TimeConverterInterface $fallbackConverter = null,\n    ) {\n        if ($calculator === null) {\n            $calculator = new BrickMathCalculator();\n        }\n\n        if ($fallbackConverter === null) {\n            $fallbackConverter = new GenericTimeConverter($calculator);\n        }\n\n        $this->calculator = $calculator;\n        $this->fallbackConverter = $fallbackConverter;\n        $this->phpPrecision = (int) ini_get('precision');\n    }\n\n    public function calculateTime(string $seconds, string $microseconds): Hexadecimal\n    {\n        $seconds = new IntegerObject($seconds); /** @phpstan-ignore possiblyImpure.new */\n        $microseconds = new IntegerObject($microseconds); /** @phpstan-ignore possiblyImpure.new */\n\n        // Calculate the count of 100-nanosecond intervals since the Gregorian calendar epoch\n        // for the given seconds and microseconds.\n        $uuidTime = ((int) $seconds->toString() * self::SECOND_INTERVALS)\n            + ((int) $microseconds->toString() * self::MICROSECOND_INTERVALS)\n            + self::GREGORIAN_TO_UNIX_INTERVALS;\n\n        // Check to see whether we've overflowed the max/min integer size.\n        // If so, we will default to a different time converter.\n        // @phpstan-ignore function.alreadyNarrowedType (the integer value might have overflowed)\n        if (!is_int($uuidTime)) {\n            return $this->fallbackConverter->calculateTime(\n                $seconds->toString(),\n                $microseconds->toString(),\n            );\n        }\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Hexadecimal(\n            str_pad(dechex($uuidTime), 16, '0', STR_PAD_LEFT)\n        );\n    }\n\n    public function convertTime(Hexadecimal $uuidTimestamp): Time\n    {\n        $timestamp = $this->calculator->toInteger($uuidTimestamp);\n\n        // Convert the 100-nanosecond intervals into seconds and microseconds.\n        $splitTime = $this->splitTime(\n            ($timestamp->toString() - self::GREGORIAN_TO_UNIX_INTERVALS) / self::SECOND_INTERVALS,\n        );\n\n        if (count($splitTime) === 0) {\n            return $this->fallbackConverter->convertTime($uuidTimestamp);\n        }\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Time($splitTime['sec'], $splitTime['usec']);\n    }\n\n    /**\n     * @param float | int $time The time to split into seconds and microseconds\n     *\n     * @return string[]\n     *\n     * @pure\n     */\n    private function splitTime(float | int $time): array\n    {\n        $split = explode('.', (string) $time, 2);\n\n        // If the $time value is a float but $split only has 1 element, then the float math was rounded up to the next\n        // second, so we want to return an empty array to allow use of the fallback converter.\n        if (is_float($time) && count($split) === 1) {\n            return [];\n        }\n\n        if (count($split) === 1) {\n            return ['sec' => $split[0], 'usec' => '0'];\n        }\n\n        // If the microseconds are less than six characters AND the length of the number is greater than or equal to the\n        // PHP precision, then it's possible that we lost some precision for the microseconds. Return an empty array so\n        // that we can choose to use the fallback converter.\n        if (strlen($split[1]) < 6 && strlen((string) $time) >= $this->phpPrecision) {\n            return [];\n        }\n\n        $microseconds = $split[1];\n\n        // Ensure the microseconds are no longer than 6 digits. If they are,\n        // truncate the number to the first 6 digits and round up, if needed.\n        if (strlen($microseconds) > 6) {\n            $roundingDigit = (int) substr($microseconds, 6, 1);\n            $microseconds = (int) substr($microseconds, 0, 6);\n\n            if ($roundingDigit >= 5) {\n                $microseconds++;\n            }\n        }\n\n        return [\n            'sec' => $split[0],\n            'usec' => str_pad((string) $microseconds, 6, '0', STR_PAD_RIGHT),\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Converter/Time/UnixTimeConverter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter\\Time;\n\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Math\\CalculatorInterface;\nuse Ramsey\\Uuid\\Math\\RoundingMode;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\n\nuse function explode;\nuse function str_pad;\n\nuse const STR_PAD_LEFT;\n\n/**\n * UnixTimeConverter converts Unix Epoch timestamps to/from hexadecimal values consisting of milliseconds elapsed since\n * the Unix Epoch\n *\n * @immutable\n */\nclass UnixTimeConverter implements TimeConverterInterface\n{\n    private const MILLISECONDS = 1000;\n\n    public function __construct(private CalculatorInterface $calculator)\n    {\n    }\n\n    public function calculateTime(string $seconds, string $microseconds): Hexadecimal\n    {\n        /** @phpstan-ignore possiblyImpure.new */\n        $timestamp = new Time($seconds, $microseconds);\n\n        // Convert the seconds into milliseconds.\n        $sec = $this->calculator->multiply(\n            $timestamp->getSeconds(),\n            new IntegerObject(self::MILLISECONDS) /** @phpstan-ignore possiblyImpure.new */\n        );\n\n        // Convert the microseconds into milliseconds; the scale is zero because we need to discard the fractional part.\n        $usec = $this->calculator->divide(\n            RoundingMode::DOWN, // Always round down to stay in the previous millisecond.\n            0,\n            $timestamp->getMicroseconds(),\n            new IntegerObject(self::MILLISECONDS), /** @phpstan-ignore possiblyImpure.new */\n        );\n\n        /** @var IntegerObject $unixTime */\n        $unixTime = $this->calculator->add($sec, $usec);\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Hexadecimal(\n            str_pad(\n                $this->calculator->toHexadecimal($unixTime)->toString(),\n                12,\n                '0',\n                STR_PAD_LEFT\n            ),\n        );\n    }\n\n    public function convertTime(Hexadecimal $uuidTimestamp): Time\n    {\n        $milliseconds = $this->calculator->toInteger($uuidTimestamp);\n\n        $unixTimestamp = $this->calculator->divide(\n            RoundingMode::HALF_UP,\n            6,\n            $milliseconds,\n            new IntegerObject(self::MILLISECONDS), /** @phpstan-ignore possiblyImpure.new */\n        );\n\n        $split = explode('.', (string) $unixTimestamp, 2);\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Time($split[0], $split[1] ?? '0');\n    }\n}\n"
  },
  {
    "path": "src/Converter/TimeConverterInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Converter;\n\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\n\n/**\n * A time converter converts timestamps into representations that may be used in UUIDs\n *\n * @immutable\n */\ninterface TimeConverterInterface\n{\n    /**\n     * Uses the provided seconds and micro-seconds to calculate the count of 100-nanosecond intervals since\n     * UTC 00:00:00.00, 15 October 1582, for RFC 9562 (formerly RFC 4122) variant UUIDs\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#appendix-A RFC 9562, Appendix A. Test Vectors\n     *\n     * @param string $seconds A string representation of seconds since the Unix epoch for the time to calculate\n     * @param string $microseconds A string representation of the micro-seconds associated with the time to calculate\n     *\n     * @return Hexadecimal The full UUID timestamp as a Hexadecimal value\n     *\n     * @pure\n     */\n    public function calculateTime(string $seconds, string $microseconds): Hexadecimal;\n\n    /**\n     * Converts a timestamp extracted from a UUID to a Unix timestamp\n     *\n     * @param Hexadecimal $uuidTimestamp A hexadecimal representation of a UUID timestamp; a UUID timestamp is a count\n     *     of 100-nanosecond intervals since UTC 00:00:00.00, 15 October 1582.\n     *\n     * @return Time An instance of {@see Time}\n     *\n     * @pure\n     */\n    public function convertTime(Hexadecimal $uuidTimestamp): Time;\n}\n"
  },
  {
    "path": "src/DegradedUuid.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\n/**\n * @deprecated DegradedUuid is no longer necessary to represent UUIDs on 32-bit systems.\n *     Transition any type declarations using this class to {@see UuidInterface}.\n *\n * @immutable\n */\nclass DegradedUuid extends Uuid\n{\n}\n"
  },
  {
    "path": "src/DeprecatedUuidInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\n\n/**\n * This interface encapsulates deprecated methods for ramsey/uuid\n *\n * @immutable\n */\ninterface DeprecatedUuidInterface\n{\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no alternative recommendation, so plan accordingly.\n     */\n    public function getNumberConverter(): NumberConverterInterface;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance.\n     *\n     * @return string[]\n     */\n    public function getFieldsHex(): array;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeqHiAndReserved()}.\n     */\n    public function getClockSeqHiAndReservedHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeqLow()}.\n     */\n    public function getClockSeqLowHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeq()}.\n     */\n    public function getClockSequenceHex(): string;\n\n    /**\n     * @deprecated In ramsey/uuid version 5.0.0, this will be removed from the interface. It is available at\n     *     {@see UuidV1::getDateTime()}.\n     */\n    public function getDateTime(): DateTimeInterface;\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getLeastSignificantBitsHex(): string;\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getMostSignificantBitsHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getNode()}.\n     */\n    public function getNodeHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeHiAndVersion()}.\n     */\n    public function getTimeHiAndVersionHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeLow()}.\n     */\n    public function getTimeLowHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeMid()}.\n     */\n    public function getTimeMidHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimestamp()}.\n     */\n    public function getTimestampHex(): string;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getVariant()}.\n     */\n    public function getVariant(): ?int;\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getVersion()}.\n     */\n    public function getVersion(): ?int;\n}\n"
  },
  {
    "path": "src/DeprecatedUuidMethodsTrait.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Throwable;\n\nuse function str_pad;\nuse function substr;\n\nuse const STR_PAD_LEFT;\n\n/**\n * This trait encapsulates deprecated methods for ramsey/uuid; this trait and its methods will be removed in ramsey/uuid 5.0.0.\n *\n * @deprecated This trait and its methods will be removed in ramsey/uuid 5.0.0.\n *\n * @immutable\n */\ntrait DeprecatedUuidMethodsTrait\n{\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeqHiAndReserved()} and use the arbitrary-precision math\n     *     library of your choice to convert it to a string integer.\n     */\n    public function getClockSeqHiAndReserved(): string\n    {\n        return $this->numberConverter->fromHex($this->fields->getClockSeqHiAndReserved()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeqHiAndReserved()}.\n     */\n    public function getClockSeqHiAndReservedHex(): string\n    {\n        return $this->fields->getClockSeqHiAndReserved()->toString();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeqLow()} and use the arbitrary-precision math library of\n     *     your choice to convert it to a string integer.\n     */\n    public function getClockSeqLow(): string\n    {\n        return $this->numberConverter->fromHex($this->fields->getClockSeqLow()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeqLow()}.\n     */\n    public function getClockSeqLowHex(): string\n    {\n        return $this->fields->getClockSeqLow()->toString();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeq()} and use the arbitrary-precision math library of\n     *     your choice to convert it to a string integer.\n     */\n    public function getClockSequence(): string\n    {\n        return $this->numberConverter->fromHex($this->fields->getClockSeq()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getClockSeq()}.\n     */\n    public function getClockSequenceHex(): string\n    {\n        return $this->fields->getClockSeq()->toString();\n    }\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no alternative recommendation, so plan accordingly.\n     */\n    public function getNumberConverter(): NumberConverterInterface\n    {\n        return $this->numberConverter;\n    }\n\n    /**\n     * @deprecated In ramsey/uuid version 5.0.0, this will be removed. It is available at {@see UuidV1::getDateTime()}.\n     *\n     * @return DateTimeImmutable An immutable instance of DateTimeInterface\n     *\n     * @throws UnsupportedOperationException if UUID is not time-based\n     * @throws DateTimeException if DateTime throws an exception/error\n     */\n    public function getDateTime(): DateTimeInterface\n    {\n        if ($this->fields->getVersion() !== 1) {\n            throw new UnsupportedOperationException('Not a time-based UUID');\n        }\n\n        $time = $this->timeConverter->convertTime($this->fields->getTimestamp());\n\n        try {\n            return new DateTimeImmutable(\n                '@'\n                . $time->getSeconds()->toString()\n                . '.'\n                . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT)\n            );\n        } catch (Throwable $e) {\n            throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e);\n        }\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *\n     * @return string[]\n     */\n    public function getFieldsHex(): array\n    {\n        return [\n            'time_low' => $this->fields->getTimeLow()->toString(),\n            'time_mid' => $this->fields->getTimeMid()->toString(),\n            'time_hi_and_version' => $this->fields->getTimeHiAndVersion()->toString(),\n            'clock_seq_hi_and_reserved' => $this->fields->getClockSeqHiAndReserved()->toString(),\n            'clock_seq_low' => $this->fields->getClockSeqLow()->toString(),\n            'node' => $this->fields->getNode()->toString(),\n        ];\n    }\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getLeastSignificantBits(): string\n    {\n        $leastSignificantHex = substr($this->getHex()->toString(), 16);\n\n        return $this->numberConverter->fromHex($leastSignificantHex);\n    }\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getLeastSignificantBitsHex(): string\n    {\n        return substr($this->getHex()->toString(), 16);\n    }\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getMostSignificantBits(): string\n    {\n        $mostSignificantHex = substr($this->getHex()->toString(), 0, 16);\n\n        return $this->numberConverter->fromHex($mostSignificantHex);\n    }\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getMostSignificantBitsHex(): string\n    {\n        return substr($this->getHex()->toString(), 0, 16);\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getNode()} and use the arbitrary-precision math library of your\n     *     choice to convert it to a string integer.\n     */\n    public function getNode(): string\n    {\n        return $this->numberConverter->fromHex($this->fields->getNode()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getNode()}.\n     */\n    public function getNodeHex(): string\n    {\n        return $this->fields->getNode()->toString();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeHiAndVersion()} and use the arbitrary-precision math\n     *     library of your choice to convert it to a string integer.\n     */\n    public function getTimeHiAndVersion(): string\n    {\n        return $this->numberConverter->fromHex($this->fields->getTimeHiAndVersion()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeHiAndVersion()}.\n     */\n    public function getTimeHiAndVersionHex(): string\n    {\n        return $this->fields->getTimeHiAndVersion()->toString();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeLow()} and use the arbitrary-precision math library of\n     *     your choice to convert it to a string integer.\n     */\n    public function getTimeLow(): string\n    {\n        return $this->numberConverter->fromHex($this->fields->getTimeLow()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeLow()}.\n     */\n    public function getTimeLowHex(): string\n    {\n        return $this->fields->getTimeLow()->toString();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeMid()} and use the arbitrary-precision math library of\n     *     your choice to convert it to a string integer.\n     */\n    public function getTimeMid(): string\n    {\n        return $this->numberConverter->fromHex($this->fields->getTimeMid()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimeMid()}.\n     */\n    public function getTimeMidHex(): string\n    {\n        return $this->fields->getTimeMid()->toString();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimestamp()} and use the arbitrary-precision math library of\n     *     your choice to convert it to a string integer.\n     */\n    public function getTimestamp(): string\n    {\n        if ($this->fields->getVersion() !== 1) {\n            throw new UnsupportedOperationException('Not a time-based UUID');\n        }\n\n        return $this->numberConverter->fromHex($this->fields->getTimestamp()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getTimestamp()}.\n     */\n    public function getTimestampHex(): string\n    {\n        if ($this->fields->getVersion() !== 1) {\n            throw new UnsupportedOperationException('Not a time-based UUID');\n        }\n\n        return $this->fields->getTimestamp()->toString();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getVariant()}.\n     */\n    public function getVariant(): ?int\n    {\n        return $this->fields->getVariant();\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \\Ramsey\\Uuid\\Fields\\FieldsInterface} instance.\n     *     If it is a {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface} instance, you may call\n     *     {@see \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface::getVersion()}.\n     */\n    public function getVersion(): ?int\n    {\n        return $this->fields->getVersion();\n    }\n}\n"
  },
  {
    "path": "src/Exception/BuilderNotFoundException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate that no suitable builder could be found\n */\nclass BuilderNotFoundException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/DateTimeException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate that the PHP DateTime extension encountered an exception/error\n */\nclass DateTimeException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/DceSecurityException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate an exception occurred while dealing with DCE Security (version 2) UUIDs\n */\nclass DceSecurityException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/InvalidArgumentException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse InvalidArgumentException as PhpInvalidArgumentException;\n\n/**\n * Thrown to indicate that the argument received is not valid\n */\nclass InvalidArgumentException extends PhpInvalidArgumentException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/InvalidBytesException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate that the bytes being operated on are invalid in some way\n */\nclass InvalidBytesException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/InvalidUuidStringException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\n/**\n * Thrown to indicate that the string received is not a valid UUID\n *\n * The InvalidArgumentException that this extends is the ramsey/uuid version of this exception. It exists in the same\n * namespace as this class.\n */\nclass InvalidUuidStringException extends InvalidArgumentException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/NameException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate that an error occurred while attempting to hash a namespace and name\n */\nclass NameException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/NodeException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate that attempting to fetch or create a node ID encountered an error\n */\nclass NodeException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/RandomSourceException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate that the source of random data encountered an error\n *\n * This exception is used mostly to indicate that random_bytes() or random_int() threw an exception. However, it may be\n * used for other sources of random data.\n */\nclass RandomSourceException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/TimeSourceException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate that the source of time encountered an error\n */\nclass TimeSourceException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/UnableToBuildUuidException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse RuntimeException as PhpRuntimeException;\n\n/**\n * Thrown to indicate a builder is unable to build a UUID\n */\nclass UnableToBuildUuidException extends PhpRuntimeException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/UnsupportedOperationException.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse LogicException as PhpLogicException;\n\n/**\n * Thrown to indicate that the requested operation is not supported\n */\nclass UnsupportedOperationException extends PhpLogicException implements UuidExceptionInterface\n{\n}\n"
  },
  {
    "path": "src/Exception/UuidExceptionInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Exception;\n\nuse Throwable;\n\ninterface UuidExceptionInterface extends Throwable\n{\n}\n"
  },
  {
    "path": "src/FeatureSet.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse Ramsey\\Uuid\\Builder\\FallbackBuilder;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Codec\\GuidStringCodec;\nuse Ramsey\\Uuid\\Codec\\StringCodec;\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\PhpTimeConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Generator\\DceSecurityGenerator;\nuse Ramsey\\Uuid\\Generator\\DceSecurityGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\NameGeneratorFactory;\nuse Ramsey\\Uuid\\Generator\\NameGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\PeclUuidNameGenerator;\nuse Ramsey\\Uuid\\Generator\\PeclUuidRandomGenerator;\nuse Ramsey\\Uuid\\Generator\\PeclUuidTimeGenerator;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorFactory;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\TimeGeneratorFactory;\nuse Ramsey\\Uuid\\Generator\\TimeGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\UnixTimeGenerator;\nuse Ramsey\\Uuid\\Guid\\GuidBuilder;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Math\\CalculatorInterface;\nuse Ramsey\\Uuid\\Nonstandard\\UuidBuilder as NonstandardUuidBuilder;\nuse Ramsey\\Uuid\\Provider\\Dce\\SystemDceSecurityProvider;\nuse Ramsey\\Uuid\\Provider\\DceSecurityProviderInterface;\nuse Ramsey\\Uuid\\Provider\\Node\\FallbackNodeProvider;\nuse Ramsey\\Uuid\\Provider\\Node\\RandomNodeProvider;\nuse Ramsey\\Uuid\\Provider\\Node\\SystemNodeProvider;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Provider\\Time\\SystemTimeProvider;\nuse Ramsey\\Uuid\\Provider\\TimeProviderInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidBuilder as Rfc4122UuidBuilder;\nuse Ramsey\\Uuid\\Validator\\GenericValidator;\nuse Ramsey\\Uuid\\Validator\\ValidatorInterface;\n\nuse const PHP_INT_SIZE;\n\n/**\n * FeatureSet detects and exposes available features in the current environment\n *\n * A feature set is used by UuidFactory to determine the available features and capabilities of the environment.\n */\nclass FeatureSet\n{\n    private ?TimeProviderInterface $timeProvider = null;\n    private CalculatorInterface $calculator;\n    private CodecInterface $codec;\n    private DceSecurityGeneratorInterface $dceSecurityGenerator;\n    private NameGeneratorInterface $nameGenerator;\n    private NodeProviderInterface $nodeProvider;\n    private NumberConverterInterface $numberConverter;\n    private RandomGeneratorInterface $randomGenerator;\n    private TimeConverterInterface $timeConverter;\n    private TimeGeneratorInterface $timeGenerator;\n    private TimeGeneratorInterface $unixTimeGenerator;\n    private UuidBuilderInterface $builder;\n    private ValidatorInterface $validator;\n\n    /**\n     * @param bool $useGuids True build UUIDs using the GuidStringCodec\n     * @param bool $force32Bit True to force the use of 32-bit functionality (primarily for testing purposes)\n     * @param bool $forceNoBigNumber (obsolete)\n     * @param bool $ignoreSystemNode True to disable attempts to check for the system node ID (primarily for testing purposes)\n     * @param bool $enablePecl True to enable the use of the PeclUuidTimeGenerator to generate version 1 UUIDs\n     *\n     * @phpstan-ignore constructor.unusedParameter ($forceNoBigNumber is deprecated)\n     */\n    public function __construct(\n        bool $useGuids = false,\n        private bool $force32Bit = false,\n        bool $forceNoBigNumber = false,\n        private bool $ignoreSystemNode = false,\n        private bool $enablePecl = false,\n    ) {\n        $this->randomGenerator = $this->buildRandomGenerator();\n        $this->setCalculator(new BrickMathCalculator());\n        $this->builder = $this->buildUuidBuilder($useGuids);\n        $this->codec = $this->buildCodec($useGuids);\n        $this->nodeProvider = $this->buildNodeProvider();\n        $this->nameGenerator = $this->buildNameGenerator();\n        $this->setTimeProvider(new SystemTimeProvider());\n        $this->setDceSecurityProvider(new SystemDceSecurityProvider());\n        $this->validator = new GenericValidator();\n\n        assert($this->timeProvider !== null);\n        $this->unixTimeGenerator = $this->buildUnixTimeGenerator();\n    }\n\n    /**\n     * Returns the builder configured for this environment\n     */\n    public function getBuilder(): UuidBuilderInterface\n    {\n        return $this->builder;\n    }\n\n    /**\n     * Returns the calculator configured for this environment\n     */\n    public function getCalculator(): CalculatorInterface\n    {\n        return $this->calculator;\n    }\n\n    /**\n     * Returns the codec configured for this environment\n     */\n    public function getCodec(): CodecInterface\n    {\n        return $this->codec;\n    }\n\n    /**\n     * Returns the DCE Security generator configured for this environment\n     */\n    public function getDceSecurityGenerator(): DceSecurityGeneratorInterface\n    {\n        return $this->dceSecurityGenerator;\n    }\n\n    /**\n     * Returns the name generator configured for this environment\n     */\n    public function getNameGenerator(): NameGeneratorInterface\n    {\n        return $this->nameGenerator;\n    }\n\n    /**\n     * Returns the node provider configured for this environment\n     */\n    public function getNodeProvider(): NodeProviderInterface\n    {\n        return $this->nodeProvider;\n    }\n\n    /**\n     * Returns the number converter configured for this environment\n     */\n    public function getNumberConverter(): NumberConverterInterface\n    {\n        return $this->numberConverter;\n    }\n\n    /**\n     * Returns the random generator configured for this environment\n     */\n    public function getRandomGenerator(): RandomGeneratorInterface\n    {\n        return $this->randomGenerator;\n    }\n\n    /**\n     * Returns the time converter configured for this environment\n     */\n    public function getTimeConverter(): TimeConverterInterface\n    {\n        return $this->timeConverter;\n    }\n\n    /**\n     * Returns the time generator configured for this environment\n     */\n    public function getTimeGenerator(): TimeGeneratorInterface\n    {\n        return $this->timeGenerator;\n    }\n\n    /**\n     * Returns the Unix Epoch time generator configured for this environment\n     */\n    public function getUnixTimeGenerator(): TimeGeneratorInterface\n    {\n        return $this->unixTimeGenerator;\n    }\n\n    /**\n     * Returns the validator configured for this environment\n     */\n    public function getValidator(): ValidatorInterface\n    {\n        return $this->validator;\n    }\n\n    /**\n     * Sets the calculator to use in this environment\n     */\n    public function setCalculator(CalculatorInterface $calculator): void\n    {\n        $this->calculator = $calculator;\n        $this->numberConverter = $this->buildNumberConverter($calculator);\n        $this->timeConverter = $this->buildTimeConverter($calculator);\n\n        if (isset($this->timeProvider)) {\n            $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider);\n        }\n    }\n\n    /**\n     * Sets the DCE Security provider to use in this environment\n     */\n    public function setDceSecurityProvider(DceSecurityProviderInterface $dceSecurityProvider): void\n    {\n        $this->dceSecurityGenerator = $this->buildDceSecurityGenerator($dceSecurityProvider);\n    }\n\n    /**\n     * Sets the node provider to use in this environment\n     */\n    public function setNodeProvider(NodeProviderInterface $nodeProvider): void\n    {\n        $this->nodeProvider = $nodeProvider;\n\n        if (isset($this->timeProvider)) {\n            $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider);\n        }\n    }\n\n    /**\n     * Sets the time provider to use in this environment\n     */\n    public function setTimeProvider(TimeProviderInterface $timeProvider): void\n    {\n        $this->timeProvider = $timeProvider;\n        $this->timeGenerator = $this->buildTimeGenerator($timeProvider);\n    }\n\n    /**\n     * Set the validator to use in this environment\n     */\n    public function setValidator(ValidatorInterface $validator): void\n    {\n        $this->validator = $validator;\n    }\n\n    /**\n     * Returns a codec configured for this environment\n     *\n     * @param bool $useGuids Whether to build UUIDs using the GuidStringCodec\n     */\n    private function buildCodec(bool $useGuids = false): CodecInterface\n    {\n        if ($useGuids) {\n            return new GuidStringCodec($this->builder);\n        }\n\n        return new StringCodec($this->builder);\n    }\n\n    /**\n     * Returns a DCE Security generator configured for this environment\n     */\n    private function buildDceSecurityGenerator(\n        DceSecurityProviderInterface $dceSecurityProvider,\n    ): DceSecurityGeneratorInterface {\n        return new DceSecurityGenerator($this->numberConverter, $this->timeGenerator, $dceSecurityProvider);\n    }\n\n    /**\n     * Returns a node provider configured for this environment\n     */\n    private function buildNodeProvider(): NodeProviderInterface\n    {\n        if ($this->ignoreSystemNode) {\n            return new RandomNodeProvider();\n        }\n\n        return new FallbackNodeProvider([new SystemNodeProvider(), new RandomNodeProvider()]);\n    }\n\n    /**\n     * Returns a number converter configured for this environment\n     */\n    private function buildNumberConverter(CalculatorInterface $calculator): NumberConverterInterface\n    {\n        return new GenericNumberConverter($calculator);\n    }\n\n    /**\n     * Returns a random generator configured for this environment\n     */\n    private function buildRandomGenerator(): RandomGeneratorInterface\n    {\n        if ($this->enablePecl) {\n            return new PeclUuidRandomGenerator();\n        }\n\n        return (new RandomGeneratorFactory())->getGenerator();\n    }\n\n    /**\n     * Returns a time generator configured for this environment\n     *\n     * @param TimeProviderInterface $timeProvider The time provider to use with\n     *     the time generator\n     */\n    private function buildTimeGenerator(TimeProviderInterface $timeProvider): TimeGeneratorInterface\n    {\n        if ($this->enablePecl) {\n            return new PeclUuidTimeGenerator();\n        }\n\n        return (new TimeGeneratorFactory($this->nodeProvider, $this->timeConverter, $timeProvider))->getGenerator();\n    }\n\n    /**\n     * Returns a Unix Epoch time generator configured for this environment\n     */\n    private function buildUnixTimeGenerator(): TimeGeneratorInterface\n    {\n        return new UnixTimeGenerator($this->randomGenerator);\n    }\n\n    /**\n     * Returns a name generator configured for this environment\n     */\n    private function buildNameGenerator(): NameGeneratorInterface\n    {\n        if ($this->enablePecl) {\n            return new PeclUuidNameGenerator();\n        }\n\n        return (new NameGeneratorFactory())->getGenerator();\n    }\n\n    /**\n     * Returns a time converter configured for this environment\n     */\n    private function buildTimeConverter(CalculatorInterface $calculator): TimeConverterInterface\n    {\n        $genericConverter = new GenericTimeConverter($calculator);\n\n        if ($this->is64BitSystem()) {\n            return new PhpTimeConverter($calculator, $genericConverter);\n        }\n\n        return $genericConverter;\n    }\n\n    /**\n     * Returns a UUID builder configured for this environment\n     *\n     * @param bool $useGuids Whether to build UUIDs using the GuidStringCodec\n     */\n    private function buildUuidBuilder(bool $useGuids = false): UuidBuilderInterface\n    {\n        if ($useGuids) {\n            return new GuidBuilder($this->numberConverter, $this->timeConverter);\n        }\n\n        return new FallbackBuilder([\n            new Rfc4122UuidBuilder($this->numberConverter, $this->timeConverter),\n            new NonstandardUuidBuilder($this->numberConverter, $this->timeConverter),\n        ]);\n    }\n\n    /**\n     * Returns true if the PHP build is 64-bit\n     */\n    private function is64BitSystem(): bool\n    {\n        return PHP_INT_SIZE === 8 && !$this->force32Bit;\n    }\n}\n"
  },
  {
    "path": "src/Fields/FieldsInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Fields;\n\nuse Serializable;\n\n/**\n * UUIDs consist of unsigned integers, the bytes of which are separated into fields and arranged in a particular layout\n * defined by the specification for the variant\n *\n * @immutable\n */\ninterface FieldsInterface extends Serializable\n{\n    /**\n     * Returns the bytes that comprise the fields\n     *\n     * @pure\n     */\n    public function getBytes(): string;\n}\n"
  },
  {
    "path": "src/Fields/SerializableFieldsTrait.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Fields;\n\nuse ValueError;\n\nuse function base64_decode;\nuse function sprintf;\nuse function strlen;\n\n/**\n * Provides common serialization functionality to fields\n *\n * @immutable\n */\ntrait SerializableFieldsTrait\n{\n    /**\n     * @param string $bytes The bytes that comprise the fields\n     */\n    abstract public function __construct(string $bytes);\n\n    /**\n     * Returns the bytes that comprise the fields\n     */\n    abstract public function getBytes(): string;\n\n    /**\n     * Returns a string representation of the object\n     */\n    public function serialize(): string\n    {\n        return $this->getBytes();\n    }\n\n    /**\n     * @return array{bytes: string}\n     */\n    public function __serialize(): array\n    {\n        return ['bytes' => $this->getBytes()];\n    }\n\n    /**\n     * Constructs the object from a serialized string representation\n     *\n     * @param string $data The serialized string representation of the object\n     */\n    public function unserialize(string $data): void\n    {\n        if (strlen($data) === 16) {\n            $this->__construct($data);\n        } else {\n            $this->__construct(base64_decode($data));\n        }\n    }\n\n    /**\n     * @param array{bytes?: string} $data\n     */\n    public function __unserialize(array $data): void\n    {\n        // @codeCoverageIgnoreStart\n        if (!isset($data['bytes'])) {\n            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));\n        }\n        // @codeCoverageIgnoreEnd\n\n        $this->unserialize($data['bytes']);\n    }\n}\n"
  },
  {
    "path": "src/Generator/CombGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\n\nuse function bin2hex;\nuse function explode;\nuse function hex2bin;\nuse function microtime;\nuse function str_pad;\nuse function substr;\n\nuse const STR_PAD_LEFT;\n\n/**\n * CombGenerator generates COMBs (combined UUID/timestamp)\n *\n * The CombGenerator, when used with the StringCodec (and, by proxy, the TimestampLastCombCodec) or the\n * TimestampFirstCombCodec, combines the current timestamp with a UUID (hence the name \"COMB\"). The timestamp either\n * appears as the first or last 48 bits of the COMB, depending on the codec used.\n *\n * By default, COMBs will have the timestamp set as the last 48 bits of the identifier.\n *\n * ```\n * $factory = new UuidFactory();\n *\n * $factory->setRandomGenerator(new CombGenerator(\n *     $factory->getRandomGenerator(),\n *     $factory->getNumberConverter(),\n * ));\n *\n * $comb = $factory->uuid4();\n * ```\n *\n * To generate a COMB with the timestamp as the first 48 bits, set the TimestampFirstCombCodec as the codec.\n *\n * ```\n * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder()));\n * ```\n *\n * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version7.html Version 7, Unix Epoch Time UUIDs}.\n *\n * @link https://web.archive.org/web/20240118030355/https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys\n */\nclass CombGenerator implements RandomGeneratorInterface\n{\n    public const TIMESTAMP_BYTES = 6;\n\n    public function __construct(\n        private RandomGeneratorInterface $generator,\n        private NumberConverterInterface $numberConverter\n    ) {\n    }\n\n    /**\n     * @throws InvalidArgumentException if $length is not a positive integer greater than or equal to CombGenerator::TIMESTAMP_BYTES\n     *\n     * @inheritDoc\n     */\n    public function generate(int $length): string\n    {\n        if ($length < self::TIMESTAMP_BYTES) {\n            throw new InvalidArgumentException(\n                'Length must be a positive integer greater than or equal to ' . self::TIMESTAMP_BYTES\n            );\n        }\n\n        if ($length % 2 !== 0) {\n            throw new InvalidArgumentException('Length must be an even number');\n        }\n\n        $hash = '';\n\n        /** @phpstan-ignore greater.alwaysTrue (TIMESTAMP_BYTES constant could change in child classes) */\n        if (self::TIMESTAMP_BYTES > 0 && $length > self::TIMESTAMP_BYTES) {\n            $hash = $this->generator->generate($length - self::TIMESTAMP_BYTES);\n        }\n\n        $lsbTime = str_pad(\n            $this->numberConverter->toHex($this->timestamp()),\n            self::TIMESTAMP_BYTES * 2,\n            '0',\n            STR_PAD_LEFT,\n        );\n\n        return (string) hex2bin(str_pad(bin2hex($hash), $length - self::TIMESTAMP_BYTES, '0') . $lsbTime);\n    }\n\n    /**\n     * Returns the current timestamp as a string integer, precise to 0.00001 seconds\n     */\n    private function timestamp(): string\n    {\n        $time = explode(' ', microtime(false));\n\n        return $time[1] . substr($time[0], 2, 5);\n    }\n}\n"
  },
  {
    "path": "src/Generator/DceSecurityGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DceSecurityException;\nuse Ramsey\\Uuid\\Provider\\DceSecurityProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function hex2bin;\nuse function in_array;\nuse function pack;\nuse function str_pad;\nuse function strlen;\nuse function substr_replace;\n\nuse const STR_PAD_LEFT;\n\n/**\n * DceSecurityGenerator generates strings of binary data based on a local domain, local identifier, node ID, clock\n * sequence, and the current time\n */\nclass DceSecurityGenerator implements DceSecurityGeneratorInterface\n{\n    private const DOMAINS = [\n        Uuid::DCE_DOMAIN_PERSON,\n        Uuid::DCE_DOMAIN_GROUP,\n        Uuid::DCE_DOMAIN_ORG,\n    ];\n\n    /**\n     * Upper bounds for the clock sequence in DCE Security UUIDs.\n     */\n    private const CLOCK_SEQ_HIGH = 63;\n\n    /**\n     * Lower bounds for the clock sequence in DCE Security UUIDs.\n     */\n    private const CLOCK_SEQ_LOW = 0;\n\n    public function __construct(\n        private NumberConverterInterface $numberConverter,\n        private TimeGeneratorInterface $timeGenerator,\n        private DceSecurityProviderInterface $dceSecurityProvider,\n    ) {\n    }\n\n    public function generate(\n        int $localDomain,\n        ?IntegerObject $localIdentifier = null,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null,\n    ): string {\n        if (!in_array($localDomain, self::DOMAINS)) {\n            throw new DceSecurityException('Local domain must be a valid DCE Security domain');\n        }\n\n        if ($localIdentifier && $localIdentifier->isNegative()) {\n            throw new DceSecurityException(\n                'Local identifier out of bounds; it must be a value between 0 and 4294967295',\n            );\n        }\n\n        if ($clockSeq > self::CLOCK_SEQ_HIGH || $clockSeq < self::CLOCK_SEQ_LOW) {\n            throw new DceSecurityException('Clock sequence out of bounds; it must be a value between 0 and 63');\n        }\n\n        switch ($localDomain) {\n            case Uuid::DCE_DOMAIN_ORG:\n                if ($localIdentifier === null) {\n                    throw new DceSecurityException('A local identifier must be provided for the org domain');\n                }\n\n                break;\n            case Uuid::DCE_DOMAIN_PERSON:\n                if ($localIdentifier === null) {\n                    $localIdentifier = $this->dceSecurityProvider->getUid();\n                }\n\n                break;\n            case Uuid::DCE_DOMAIN_GROUP:\n            default:\n                if ($localIdentifier === null) {\n                    $localIdentifier = $this->dceSecurityProvider->getGid();\n                }\n\n                break;\n        }\n\n        $identifierHex = $this->numberConverter->toHex($localIdentifier->toString());\n\n        // The maximum value for the local identifier is 0xffffffff, or 4,294,967,295. This is 8 hexadecimal digits, so\n        // if the length of hexadecimal digits is greater than 8, we know the value is greater than 0xffffffff.\n        if (strlen($identifierHex) > 8) {\n            throw new DceSecurityException(\n                'Local identifier out of bounds; it must be a value between 0 and 4294967295',\n            );\n        }\n\n        $domainByte = pack('n', $localDomain)[1];\n        $identifierBytes = (string) hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT));\n\n        if ($node instanceof Hexadecimal) {\n            $node = $node->toString();\n        }\n\n        // Shift the clock sequence 8 bits to the left, so it matches 0x3f00.\n        if ($clockSeq !== null) {\n            $clockSeq = $clockSeq << 8;\n        }\n\n        $bytes = $this->timeGenerator->generate($node, $clockSeq);\n\n        // Replace bytes in the time-based UUID with DCE Security values.\n        $bytes = substr_replace($bytes, $identifierBytes, 0, 4);\n\n        return substr_replace($bytes, $domainByte, 9, 1);\n    }\n}\n"
  },
  {
    "path": "src/Generator/DceSecurityGeneratorInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Rfc4122\\UuidV2;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n\n/**\n * A DCE Security generator generates strings of binary data based on a local domain, local identifier, node ID, clock\n * sequence, and the current time\n *\n * @see UuidV2\n */\ninterface DceSecurityGeneratorInterface\n{\n    /**\n     * Generate a binary string from a local domain, local identifier, node ID, clock sequence, and current time\n     *\n     * @param int $localDomain The local domain to use when generating bytes, according to DCE Security\n     * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID\n     *     on POSIX systems if the local domain is \"person\" or \"group,\" or it may be a site-defined identifier if the\n     *     local domain is \"org\"\n     * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return string A binary string\n     */\n    public function generate(\n        int $localDomain,\n        ?IntegerObject $localIdentifier = null,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null,\n    ): string;\n}\n"
  },
  {
    "path": "src/Generator/DefaultNameGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Exception\\NameException;\nuse Ramsey\\Uuid\\UuidInterface;\nuse ValueError;\n\nuse function hash;\n\n/**\n * DefaultNameGenerator generates strings of binary data based on a namespace, name, and hashing algorithm\n */\nclass DefaultNameGenerator implements NameGeneratorInterface\n{\n    /**\n     * @pure\n     */\n    public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string\n    {\n        try {\n            return hash($hashAlgorithm, $ns->getBytes() . $name, true);\n        } catch (ValueError $e) {\n            throw new NameException(\n                message: sprintf('Unable to hash namespace and name with algorithm \\'%s\\'', $hashAlgorithm),\n                previous: $e,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/Generator/DefaultTimeGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Exception\\RandomSourceException;\nuse Ramsey\\Uuid\\Exception\\TimeSourceException;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Provider\\TimeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Throwable;\n\nuse function dechex;\nuse function hex2bin;\nuse function is_int;\nuse function pack;\nuse function preg_match;\nuse function sprintf;\nuse function str_pad;\nuse function strlen;\n\nuse const STR_PAD_LEFT;\n\n/**\n * DefaultTimeGenerator generates strings of binary data based on a node ID, clock sequence, and the current time\n */\nclass DefaultTimeGenerator implements TimeGeneratorInterface\n{\n    public function __construct(\n        private NodeProviderInterface $nodeProvider,\n        private TimeConverterInterface $timeConverter,\n        private TimeProviderInterface $timeProvider,\n    ) {\n    }\n\n    /**\n     * @throws InvalidArgumentException if the parameters contain invalid values\n     * @throws RandomSourceException if random_int() throws an exception/error\n     *\n     * @inheritDoc\n     */\n    public function generate($node = null, ?int $clockSeq = null): string\n    {\n        if ($node instanceof Hexadecimal) {\n            $node = $node->toString();\n        }\n\n        $node = $this->getValidNode($node);\n\n        if ($clockSeq === null) {\n            try {\n                // This does not use \"stable storage\"; see RFC 9562, section 6.3.\n                $clockSeq = random_int(0, 0x3fff);\n            } catch (Throwable $exception) {\n                throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception);\n            }\n        }\n\n        $time = $this->timeProvider->getTime();\n\n        $uuidTime = $this->timeConverter->calculateTime(\n            $time->getSeconds()->toString(),\n            $time->getMicroseconds()->toString()\n        );\n\n        $timeHex = str_pad($uuidTime->toString(), 16, '0', STR_PAD_LEFT);\n\n        if (strlen($timeHex) !== 16) {\n            throw new TimeSourceException(sprintf('The generated time of \\'%s\\' is larger than expected', $timeHex));\n        }\n\n        $timeBytes = (string) hex2bin($timeHex);\n\n        return $timeBytes[4] . $timeBytes[5] . $timeBytes[6] . $timeBytes[7]\n            . $timeBytes[2] . $timeBytes[3] . $timeBytes[0] . $timeBytes[1]\n            . pack('n*', $clockSeq) . $node;\n    }\n\n    /**\n     * Uses the node provider given when constructing this instance to get the node ID (usually a MAC address)\n     *\n     * @param int | string | null $node A node value that may be used to override the node provider\n     *\n     * @return string 6-byte binary string representation of the node\n     *\n     * @throws InvalidArgumentException\n     */\n    private function getValidNode(int | string | null $node): string\n    {\n        if ($node === null) {\n            $node = $this->nodeProvider->getNode();\n        }\n\n        // Convert the node to hex if it is still an integer.\n        if (is_int($node)) {\n            $node = dechex($node);\n        }\n\n        if (!preg_match('/^[A-Fa-f0-9]+$/', (string) $node) || strlen((string) $node) > 12) {\n            throw new InvalidArgumentException('Invalid node value');\n        }\n\n        return (string) hex2bin(str_pad((string) $node, 12, '0', STR_PAD_LEFT));\n    }\n}\n"
  },
  {
    "path": "src/Generator/NameGeneratorFactory.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\n/**\n * NameGeneratorFactory retrieves a default name generator, based on the environment\n */\nclass NameGeneratorFactory\n{\n    /**\n     * Returns a default name generator, based on the current environment\n     */\n    public function getGenerator(): NameGeneratorInterface\n    {\n        return new DefaultNameGenerator();\n    }\n}\n"
  },
  {
    "path": "src/Generator/NameGeneratorInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\UuidInterface;\n\n/**\n * A name generator generates strings of binary data created by hashing together a namespace with a name, according to a\n * hashing algorithm\n */\ninterface NameGeneratorInterface\n{\n    /**\n     * Generate a binary string from a namespace and name hashed together with the specified hashing algorithm\n     *\n     * @param UuidInterface $ns The namespace\n     * @param string $name The name to use for creating a UUID\n     * @param string $hashAlgorithm The hashing algorithm to use\n     *\n     * @return string A binary string\n     *\n     * @pure\n     */\n    public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string;\n}\n"
  },
  {
    "path": "src/Generator/PeclUuidNameGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Exception\\NameException;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function sprintf;\nuse function uuid_generate_md5;\nuse function uuid_generate_sha1;\nuse function uuid_parse;\n\n/**\n * PeclUuidNameGenerator generates strings of binary data from a namespace and a name, using ext-uuid\n *\n * @link https://pecl.php.net/package/uuid ext-uuid\n */\nclass PeclUuidNameGenerator implements NameGeneratorInterface\n{\n    /**\n     * @pure\n     */\n    public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string\n    {\n        $uuid = match ($hashAlgorithm) {\n            'md5' => uuid_generate_md5($ns->toString(), $name), /** @phpstan-ignore possiblyImpure.functionCall */\n            'sha1' => uuid_generate_sha1($ns->toString(), $name), /** @phpstan-ignore possiblyImpure.functionCall */\n            default => throw new NameException(\n                sprintf('Unable to hash namespace and name with algorithm \\'%s\\'', $hashAlgorithm),\n            ),\n        };\n\n        /** @phpstan-ignore possiblyImpure.functionCall */\n        return (string) uuid_parse($uuid);\n    }\n}\n"
  },
  {
    "path": "src/Generator/PeclUuidRandomGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse function uuid_create;\nuse function uuid_parse;\n\nuse const UUID_TYPE_RANDOM;\n\n/**\n * PeclUuidRandomGenerator generates strings of random binary data using ext-uuid\n *\n * @link https://pecl.php.net/package/uuid ext-uuid\n */\nclass PeclUuidRandomGenerator implements RandomGeneratorInterface\n{\n    public function generate(int $length): string\n    {\n        $uuid = uuid_create(UUID_TYPE_RANDOM);\n\n        return (string) uuid_parse($uuid);\n    }\n}\n"
  },
  {
    "path": "src/Generator/PeclUuidTimeGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse function uuid_create;\nuse function uuid_parse;\n\nuse const UUID_TYPE_TIME;\n\n/**\n * PeclUuidTimeGenerator generates strings of binary data for time-base UUIDs, using ext-uuid\n *\n * @link https://pecl.php.net/package/uuid ext-uuid\n */\nclass PeclUuidTimeGenerator implements TimeGeneratorInterface\n{\n    /**\n     * @inheritDoc\n     */\n    public function generate($node = null, ?int $clockSeq = null): string\n    {\n        $uuid = uuid_create(UUID_TYPE_TIME);\n\n        return (string) uuid_parse($uuid);\n    }\n}\n"
  },
  {
    "path": "src/Generator/RandomBytesGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Exception\\RandomSourceException;\nuse Throwable;\n\n/**\n * RandomBytesGenerator generates strings of random binary data using the built-in `random_bytes()` PHP function\n *\n * @link http://php.net/random_bytes random_bytes()\n */\nclass RandomBytesGenerator implements RandomGeneratorInterface\n{\n    /**\n     * @throws RandomSourceException if random_bytes() throws an exception/error\n     *\n     * @inheritDoc\n     */\n    public function generate(int $length): string\n    {\n        try {\n            return random_bytes($length);\n        } catch (Throwable $exception) {\n            throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Generator/RandomGeneratorFactory.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\n/**\n * RandomGeneratorFactory retrieves a default random generator, based on the environment\n */\nclass RandomGeneratorFactory\n{\n    /**\n     * Returns a default random generator, based on the current environment\n     */\n    public function getGenerator(): RandomGeneratorInterface\n    {\n        return new RandomBytesGenerator();\n    }\n}\n"
  },
  {
    "path": "src/Generator/RandomGeneratorInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\n/**\n * A random generator generates strings of random binary data\n */\ninterface RandomGeneratorInterface\n{\n    /**\n     * Generates a string of randomized binary data\n     *\n     * @param int<1, max> $length The number of bytes to generate of random binary data\n     *\n     * @return string A binary string\n     */\n    public function generate(int $length): string;\n}\n"
  },
  {
    "path": "src/Generator/RandomLibAdapter.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse RandomLib\\Factory;\nuse RandomLib\\Generator;\n\n/**\n * RandomLibAdapter generates strings of random binary data using the paragonie/random-lib library\n *\n * @deprecated This class will be removed in 5.0.0. Use the default RandomBytesGenerator or implement your own generator\n *     that implements RandomGeneratorInterface.\n *\n * @link https://packagist.org/packages/paragonie/random-lib paragonie/random-lib\n */\nclass RandomLibAdapter implements RandomGeneratorInterface\n{\n    private Generator $generator;\n\n    /**\n     * Constructs a RandomLibAdapter\n     *\n     * By default, if no Generator is passed in, this creates a high-strength generator to use when generating random\n     * binary data.\n     *\n     * @param Generator | null $generator The generator to use when generating binary data\n     */\n    public function __construct(?Generator $generator = null)\n    {\n        if ($generator === null) {\n            $factory = new Factory();\n            $generator = $factory->getHighStrengthGenerator();\n        }\n\n        $this->generator = $generator;\n    }\n\n    public function generate(int $length): string\n    {\n        return $this->generator->generate($length);\n    }\n}\n"
  },
  {
    "path": "src/Generator/TimeGeneratorFactory.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Provider\\TimeProviderInterface;\n\n/**\n * TimeGeneratorFactory retrieves a default time generator, based on the environment\n */\nclass TimeGeneratorFactory\n{\n    public function __construct(\n        private NodeProviderInterface $nodeProvider,\n        private TimeConverterInterface $timeConverter,\n        private TimeProviderInterface $timeProvider,\n    ) {\n    }\n\n    /**\n     * Returns a default time generator, based on the current environment\n     */\n    public function getGenerator(): TimeGeneratorInterface\n    {\n        return new DefaultTimeGenerator($this->nodeProvider, $this->timeConverter, $this->timeProvider);\n    }\n}\n"
  },
  {
    "path": "src/Generator/TimeGeneratorInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\n/**\n * A time generator generates strings of binary data based on a node ID, clock sequence, and the current time\n */\ninterface TimeGeneratorInterface\n{\n    /**\n     * Generate a binary string from a node ID, clock sequence, and current time\n     *\n     * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may\n     *     be represented as an integer or a hexadecimal string\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return string A binary string\n     */\n    public function generate($node = null, ?int $clockSeq = null): string;\n}\n"
  },
  {
    "path": "src/Generator/UnixTimeGenerator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Generator;\n\nuse Brick\\Math\\BigInteger;\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function assert;\nuse function hash;\nuse function pack;\nuse function str_pad;\nuse function strlen;\nuse function substr;\nuse function substr_replace;\nuse function unpack;\n\nuse const PHP_INT_SIZE;\nuse const STR_PAD_LEFT;\n\n/**\n * UnixTimeGenerator generates bytes, combining a 48-bit timestamp in milliseconds since the Unix Epoch with 80 random bits\n *\n * Code and concepts within this class are borrowed from the symfony/uid package and are used under the terms of the MIT\n * license distributed with symfony/uid.\n *\n * symfony/uid is copyright (c) Fabien Potencier.\n *\n * @link https://symfony.com/components/Uid Symfony Uid component\n * @link https://github.com/symfony/uid/blob/4f9f537e57261519808a7ce1d941490736522bbc/UuidV7.php Symfony UuidV7 class\n * @link https://github.com/symfony/uid/blob/6.2/LICENSE MIT License\n */\nclass UnixTimeGenerator implements TimeGeneratorInterface\n{\n    private static string $time = '';\n    private static ?string $seed = null;\n    private static int $seedIndex = 0;\n\n    /** @var int[] */\n    private static array $rand = [];\n\n    /** @var int[] */\n    private static array $seedParts;\n\n    public function __construct(\n        private RandomGeneratorInterface $randomGenerator,\n        private int $intSize = PHP_INT_SIZE,\n    ) {\n    }\n\n    /**\n     * @param Hexadecimal | int | string | null $node Unused in this generator\n     * @param int | null $clockSeq Unused in this generator\n     * @param DateTimeInterface | null $dateTime A date-time instance to use when generating bytes\n     */\n    public function generate($node = null, ?int $clockSeq = null, ?DateTimeInterface $dateTime = null): string\n    {\n        if ($dateTime === null) {\n            $time = microtime(false);\n            $time = substr($time, 11) . substr($time, 2, 3);\n        } else {\n            $time = $dateTime->format('Uv');\n        }\n\n        if ($time > self::$time || ($dateTime !== null && $time !== self::$time)) {\n            $this->randomize($time);\n        } else {\n            $time = $this->increment();\n        }\n\n        if ($this->intSize >= 8) {\n            $time = substr(pack('J', (int) $time), -6);\n        } else {\n            $time = str_pad(BigInteger::of($time)->toBytes(false), 6, \"\\x00\", STR_PAD_LEFT);\n        }\n\n        assert(strlen($time) === 6);\n\n        return $time . pack('n*', self::$rand[1], self::$rand[2], self::$rand[3], self::$rand[4], self::$rand[5]);\n    }\n\n    private function randomize(string $time): void\n    {\n        if (self::$seed === null) {\n            $seed = $this->randomGenerator->generate(16);\n            self::$seed = $seed;\n        } else {\n            $seed = $this->randomGenerator->generate(10);\n        }\n\n        /** @var int[] $rand */\n        $rand = unpack('n*', $seed);\n        $rand[1] &= 0x03ff;\n\n        self::$rand = $rand;\n        self::$time = $time;\n    }\n\n    /**\n     * Special thanks to Nicolas Grekas (<https://github.com/nicolas-grekas>) for sharing the following information:\n     *\n     * Within the same ms, we increment the rand part by a random 24-bit number.\n     *\n     * Instead of getting this number from random_bytes(), which is slow, we get it by sha512-hashing self::$seed. This\n     * produces 64 bytes of entropy, which we need to split in a list of 24-bit numbers. `unpack()` first splits them\n     * into 16 x 32-bit numbers; we take the first byte of each number to get 5 extra 24-bit numbers. Then, we consume\n     * each number one-by-one and run this logic every 21 iterations.\n     *\n     * `self::$rand` holds the random part of the UUID, split into 5 x 16-bit numbers for x86 portability. We increment\n     * this random part by the next 24-bit number in the `self::$seedParts` list and decrement `self::$seedIndex`.\n     */\n    private function increment(): string\n    {\n        if (self::$seedIndex === 0 && self::$seed !== null) {\n            self::$seed = hash('sha512', self::$seed, true);\n\n            /** @var int[] $s */\n            $s = unpack('l*', self::$seed);\n            $s[] = ($s[1] >> 8 & 0xff0000) | ($s[2] >> 16 & 0xff00) | ($s[3] >> 24 & 0xff);\n            $s[] = ($s[4] >> 8 & 0xff0000) | ($s[5] >> 16 & 0xff00) | ($s[6] >> 24 & 0xff);\n            $s[] = ($s[7] >> 8 & 0xff0000) | ($s[8] >> 16 & 0xff00) | ($s[9] >> 24 & 0xff);\n            $s[] = ($s[10] >> 8 & 0xff0000) | ($s[11] >> 16 & 0xff00) | ($s[12] >> 24 & 0xff);\n            $s[] = ($s[13] >> 8 & 0xff0000) | ($s[14] >> 16 & 0xff00) | ($s[15] >> 24 & 0xff);\n\n            self::$seedParts = $s;\n            self::$seedIndex = 21;\n        }\n\n        self::$rand[5] = 0xffff & $carry = self::$rand[5] + 1 + (self::$seedParts[self::$seedIndex--] & 0xffffff);\n        self::$rand[4] = 0xffff & $carry = self::$rand[4] + ($carry >> 16);\n        self::$rand[3] = 0xffff & $carry = self::$rand[3] + ($carry >> 16);\n        self::$rand[2] = 0xffff & $carry = self::$rand[2] + ($carry >> 16);\n        self::$rand[1] += $carry >> 16;\n\n        if (0xfc00 & self::$rand[1]) {\n            $time = self::$time;\n            $mtime = (int) substr($time, -9);\n\n            if ($this->intSize >= 8 || strlen($time) < 10) {\n                $time = (string) ((int) $time + 1);\n            } elseif ($mtime === 999999999) {\n                $time = (1 + (int) substr($time, 0, -9)) . '000000000';\n            } else {\n                $mtime++;\n                $time = substr_replace($time, str_pad((string) $mtime, 9, '0', STR_PAD_LEFT), -9);\n            }\n\n            $this->randomize($time);\n        }\n\n        return self::$time;\n    }\n}\n"
  },
  {
    "path": "src/Guid/Fields.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Guid;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Fields\\SerializableFieldsTrait;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\MaxTrait;\nuse Ramsey\\Uuid\\Rfc4122\\NilTrait;\nuse Ramsey\\Uuid\\Rfc4122\\VariantTrait;\nuse Ramsey\\Uuid\\Rfc4122\\VersionTrait;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function bin2hex;\nuse function dechex;\nuse function hexdec;\nuse function pack;\nuse function sprintf;\nuse function str_pad;\nuse function strlen;\nuse function substr;\nuse function unpack;\n\nuse const STR_PAD_LEFT;\n\n/**\n * GUIDs consist of a set of named fields, according to RFC 9562 (formerly RFC 4122)\n *\n * @see Guid\n *\n * @immutable\n */\nfinal class Fields implements FieldsInterface\n{\n    use MaxTrait;\n    use NilTrait;\n    use SerializableFieldsTrait;\n    use VariantTrait;\n    use VersionTrait;\n\n    /**\n     * @param string $bytes A 16-byte binary string representation of a UUID\n     *\n     * @throws InvalidArgumentException if the byte string is not exactly 16 bytes\n     * @throws InvalidArgumentException if the byte string does not represent a GUID\n     * @throws InvalidArgumentException if the byte string does not contain a valid version\n     */\n    public function __construct(private string $bytes)\n    {\n        if (strlen($this->bytes) !== 16) {\n            throw new InvalidArgumentException(\n                'The byte string must be 16 bytes long; received ' . strlen($this->bytes) . ' bytes',\n            );\n        }\n\n        if (!$this->isCorrectVariant()) {\n            throw new InvalidArgumentException(\n                'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) '\n                . 'or Microsoft Corporation variants',\n            );\n        }\n\n        if (!$this->isCorrectVersion()) {\n            throw new InvalidArgumentException('The byte string received does not contain a valid version');\n        }\n    }\n\n    public function getBytes(): string\n    {\n        return $this->bytes;\n    }\n\n    public function getTimeLow(): Hexadecimal\n    {\n        // Swap the bytes from little endian to network byte order.\n        /** @var string[] $hex */\n        $hex = unpack(\n            'H*',\n            pack(\n                'v*',\n                hexdec(bin2hex(substr($this->bytes, 2, 2))),\n                hexdec(bin2hex(substr($this->bytes, 0, 2))),\n            ),\n        );\n\n        return new Hexadecimal($hex[1] ?? '');\n    }\n\n    public function getTimeMid(): Hexadecimal\n    {\n        // Swap the bytes from little endian to network byte order.\n        /** @var string[] $hex */\n        $hex = unpack('H*', pack('v', hexdec(bin2hex(substr($this->bytes, 4, 2)))));\n\n        return new Hexadecimal($hex[1] ?? '');\n    }\n\n    public function getTimeHiAndVersion(): Hexadecimal\n    {\n        // Swap the bytes from little endian to network byte order.\n        /** @var string[] $hex */\n        $hex = unpack('H*', pack('v', hexdec(bin2hex(substr($this->bytes, 6, 2)))));\n\n        return new Hexadecimal($hex[1] ?? '');\n    }\n\n    public function getTimestamp(): Hexadecimal\n    {\n        return new Hexadecimal(sprintf(\n            '%03x%04s%08s',\n            hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff,\n            $this->getTimeMid()->toString(),\n            $this->getTimeLow()->toString()\n        ));\n    }\n\n    public function getClockSeq(): Hexadecimal\n    {\n        if ($this->isMax()) {\n            $clockSeq = 0xffff;\n        } elseif ($this->isNil()) {\n            $clockSeq = 0x0000;\n        } else {\n            $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;\n        }\n\n        return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT));\n    }\n\n    public function getClockSeqHiAndReserved(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1)));\n    }\n\n    public function getClockSeqLow(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1)));\n    }\n\n    public function getNode(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 10)));\n    }\n\n    public function getVersion(): ?int\n    {\n        if ($this->isNil() || $this->isMax()) {\n            return null;\n        }\n\n        /** @var int[] $parts */\n        $parts = unpack('n*', $this->bytes);\n\n        return ($parts[4] >> 4) & 0x00f;\n    }\n\n    private function isCorrectVariant(): bool\n    {\n        if ($this->isNil() || $this->isMax()) {\n            return true;\n        }\n\n        $variant = $this->getVariant();\n\n        return $variant === Uuid::RFC_4122 || $variant === Uuid::RESERVED_MICROSOFT;\n    }\n}\n"
  },
  {
    "path": "src/Guid/Guid.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Guid;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Guid represents a UUID with \"native\" (little-endian) byte order\n *\n * From Wikipedia:\n *\n * > The first three fields are unsigned 32- and 16-bit integers and are subject to swapping, while the last two fields\n * > consist of uninterpreted bytes, not subject to swapping. This byte swapping applies even for versions 3, 4, and 5,\n * > where the canonical fields do not correspond to the content of the UUID.\n *\n * The first three fields of a GUID are encoded in little-endian byte order, while the last three fields are in network\n * (big-endian) byte order. This is according to the history of the Microsoft GUID definition.\n *\n * According to the .NET Guid.ToByteArray method documentation:\n *\n * > Note that the order of bytes in the returned byte array is different from the string representation of a Guid value.\n * > The order of the beginning four-byte group and the next two two-byte groups is reversed, whereas the order of the\n * > last two-byte group and the closing six-byte group is the same.\n *\n * @link https://en.wikipedia.org/wiki/Universally_unique_identifier#Variants UUID Variants on Wikipedia\n * @link https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid Windows GUID structure\n * @link https://docs.microsoft.com/en-us/dotnet/api/system.guid .NET Guid Struct\n * @link https://docs.microsoft.com/en-us/dotnet/api/system.guid.tobytearray .NET Guid.ToByteArray Method\n *\n * @immutable\n */\nfinal class Guid extends Uuid\n{\n    public function __construct(\n        Fields $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Guid/GuidBuilder.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Guid;\n\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\UuidInterface;\nuse Throwable;\n\n/**\n * GuidBuilder builds instances of Guid\n *\n * @see Guid\n *\n * @immutable\n */\nclass GuidBuilder implements UuidBuilderInterface\n{\n    /**\n     * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Guid\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to Unix timestamps\n     */\n    public function __construct(\n        private NumberConverterInterface $numberConverter,\n        private TimeConverterInterface $timeConverter,\n    ) {\n    }\n\n    /**\n     * Builds and returns a Guid\n     *\n     * @param CodecInterface $codec The codec to use for building this Guid instance\n     * @param string $bytes The byte string from which to construct a UUID\n     *\n     * @return Guid The GuidBuilder returns an instance of Ramsey\\Uuid\\Guid\\Guid\n     *\n     * @pure\n     */\n    public function build(CodecInterface $codec, string $bytes): UuidInterface\n    {\n        try {\n            /** @phpstan-ignore possiblyImpure.new */\n            return new Guid($this->buildFields($bytes), $this->numberConverter, $codec, $this->timeConverter);\n        } catch (Throwable $e) {\n            /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */\n            throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e);\n        }\n    }\n\n    /**\n     * Proxy method to allow injecting a mock for testing\n     *\n     * @pure\n     */\n    protected function buildFields(string $bytes): Fields\n    {\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Fields($bytes);\n    }\n}\n"
  },
  {
    "path": "src/Lazy/LazyUuidFromString.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Lazy;\n\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\Fields\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV1;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV6;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\UuidFactory;\nuse Ramsey\\Uuid\\UuidInterface;\nuse ValueError;\n\nuse function assert;\nuse function bin2hex;\nuse function hex2bin;\nuse function sprintf;\nuse function str_replace;\nuse function substr;\n\n/**\n * Lazy version of a UUID: its format has not been determined yet, so it is mostly only usable for string/bytes\n * conversion. This object optimizes instantiation, serialization and string conversion time, at the cost of increased\n * overhead for more advanced UUID operations.\n *\n * > [!NOTE]\n * > The {@see FieldsInterface} does not declare methods that deprecated API relies upon: the API has been ported from\n * > the {@see \\Ramsey\\Uuid\\Uuid} definition, and is deprecated anyway.\n *\n * > [!NOTE]\n * > The deprecated API from {@see \\Ramsey\\Uuid\\Uuid} is in use here (on purpose): it will be removed once the\n * > deprecated API is gone from this class too.\n *\n * @internal this type is used internally for performance reasons and is not supposed to be directly referenced in consumer libraries.\n */\nfinal class LazyUuidFromString implements UuidInterface\n{\n    public const VALID_REGEX = '/\\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\z/ms';\n\n    private ?UuidInterface $unwrapped = null;\n\n    /**\n     * @param non-empty-string $uuid\n     */\n    public function __construct(private string $uuid)\n    {\n    }\n\n    public static function fromBytes(string $bytes): self\n    {\n        $base16Uuid = bin2hex($bytes);\n\n        return new self(\n            substr($base16Uuid, 0, 8)\n            . '-'\n            . substr($base16Uuid, 8, 4)\n            . '-'\n            . substr($base16Uuid, 12, 4)\n            . '-'\n            . substr($base16Uuid, 16, 4)\n            . '-'\n            . substr($base16Uuid, 20, 12)\n        );\n    }\n\n    public function serialize(): string\n    {\n        return $this->uuid;\n    }\n\n    /**\n     * @return array{string: non-empty-string}\n     */\n    public function __serialize(): array\n    {\n        return ['string' => $this->uuid];\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @param non-empty-string $data\n     */\n    public function unserialize(string $data): void\n    {\n        $this->uuid = $data;\n    }\n\n    /**\n     * @param array{string?: non-empty-string} $data\n     */\n    public function __unserialize(array $data): void\n    {\n        // @codeCoverageIgnoreStart\n        if (!isset($data['string'])) {\n            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));\n        }\n        // @codeCoverageIgnoreEnd\n\n        $this->unserialize($data['string']);\n    }\n\n    public function getNumberConverter(): NumberConverterInterface\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getNumberConverter();\n    }\n\n    /**\n     * @inheritDoc\n     */\n    public function getFieldsHex(): array\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getFieldsHex();\n    }\n\n    public function getClockSeqHiAndReservedHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getClockSeqHiAndReservedHex();\n    }\n\n    public function getClockSeqLowHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getClockSeqLowHex();\n    }\n\n    public function getClockSequenceHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getClockSequenceHex();\n    }\n\n    public function getDateTime(): DateTimeInterface\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getDateTime();\n    }\n\n    public function getLeastSignificantBitsHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getLeastSignificantBitsHex();\n    }\n\n    public function getMostSignificantBitsHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getMostSignificantBitsHex();\n    }\n\n    public function getNodeHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getNodeHex();\n    }\n\n    public function getTimeHiAndVersionHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getTimeHiAndVersionHex();\n    }\n\n    public function getTimeLowHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getTimeLowHex();\n    }\n\n    public function getTimeMidHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getTimeMidHex();\n    }\n\n    public function getTimestampHex(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getTimestampHex();\n    }\n\n    public function getUrn(): string\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getUrn();\n    }\n\n    public function getVariant(): ?int\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getVariant();\n    }\n\n    public function getVersion(): ?int\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getVersion();\n    }\n\n    public function compareTo(UuidInterface $other): int\n    {\n        return ($this->unwrapped ?? $this->unwrap())->compareTo($other);\n    }\n\n    public function equals(?object $other): bool\n    {\n        if (!$other instanceof UuidInterface) {\n            return false;\n        }\n\n        return $this->uuid === $other->toString();\n    }\n\n    public function getBytes(): string\n    {\n        /**\n         * @var non-empty-string\n         * @phpstan-ignore possiblyImpure.functionCall, possiblyImpure.functionCall\n         */\n        return (string) hex2bin(str_replace('-', '', $this->uuid));\n    }\n\n    public function getFields(): FieldsInterface\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getFields();\n    }\n\n    public function getHex(): Hexadecimal\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getHex();\n    }\n\n    public function getInteger(): IntegerObject\n    {\n        return ($this->unwrapped ?? $this->unwrap())->getInteger();\n    }\n\n    public function toString(): string\n    {\n        return $this->uuid;\n    }\n\n    public function __toString(): string\n    {\n        return $this->uuid;\n    }\n\n    public function jsonSerialize(): string\n    {\n        return $this->uuid;\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()}\n     *     and use the arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getClockSeqHiAndReserved(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        return $instance->getNumberConverter()->fromHex($fields->getClockSeqHiAndReserved()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} and use\n     *     the arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getClockSeqLow(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        return $instance->getNumberConverter()->fromHex($fields->getClockSeqLow()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} and use the\n     *     arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getClockSequence(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        return $instance->getNumberConverter()->fromHex($fields->getClockSeq()->toString());\n    }\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getLeastSignificantBits(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        return $instance->getNumberConverter()->fromHex(substr($instance->getHex()->toString(), 16));\n    }\n\n    /**\n     * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be\n     *     obtained by splitting in half the value returned by {@see UuidInterface::getHex()}.\n     */\n    public function getMostSignificantBits(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        return $instance->getNumberConverter()->fromHex(substr($instance->getHex()->toString(), 0, 16));\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getNode()} and use the\n     *     arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getNode(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        return $instance->getNumberConverter()->fromHex($fields->getNode()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} and\n     *     use the arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getTimeHiAndVersion(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        return $instance->getNumberConverter()->fromHex($fields->getTimeHiAndVersion()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} and use the\n     *     arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getTimeLow(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        return $instance->getNumberConverter()->fromHex($fields->getTimeLow()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} and use the\n     *     arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getTimeMid(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        return $instance->getNumberConverter()->fromHex($fields->getTimeMid()->toString());\n    }\n\n    /**\n     * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a\n     *     {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} and use\n     *     the arbitrary-precision math library of your choice to convert it to a string integer.\n     */\n    public function getTimestamp(): string\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        $fields = $instance->getFields();\n        assert($fields instanceof \\Ramsey\\Uuid\\Rfc4122\\FieldsInterface);\n\n        if ($fields->getVersion() !== 1) {\n            throw new UnsupportedOperationException('Not a time-based UUID');\n        }\n\n        return $instance->getNumberConverter()->fromHex($fields->getTimestamp()->toString());\n    }\n\n    public function toUuidV1(): UuidV1\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        if ($instance instanceof UuidV1) {\n            return $instance;\n        }\n\n        assert($instance instanceof UuidV6);\n\n        return $instance->toUuidV1();\n    }\n\n    public function toUuidV6(): UuidV6\n    {\n        $instance = ($this->unwrapped ?? $this->unwrap());\n\n        assert($instance instanceof UuidV6);\n\n        return $instance;\n    }\n\n    private function unwrap(): UuidInterface\n    {\n        return $this->unwrapped = (new UuidFactory())->fromString($this->uuid);\n    }\n}\n"
  },
  {
    "path": "src/Math/BrickMathCalculator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Math;\n\nuse Brick\\Math\\BigDecimal;\nuse Brick\\Math\\BigInteger;\nuse Brick\\Math\\Exception\\MathException;\nuse Brick\\Math\\RoundingMode as BrickMathRounding;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Type\\Decimal;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\NumberInterface;\n\n/**\n * A calculator using the brick/math library for arbitrary-precision arithmetic\n *\n * @immutable\n */\nfinal class BrickMathCalculator implements CalculatorInterface\n{\n    private const ROUNDING_MODE_MAP = [\n        RoundingMode::UNNECESSARY => BrickMathRounding::UNNECESSARY,\n        RoundingMode::UP => BrickMathRounding::UP,\n        RoundingMode::DOWN => BrickMathRounding::DOWN,\n        RoundingMode::CEILING => BrickMathRounding::CEILING,\n        RoundingMode::FLOOR => BrickMathRounding::FLOOR,\n        RoundingMode::HALF_UP => BrickMathRounding::HALF_UP,\n        RoundingMode::HALF_DOWN => BrickMathRounding::HALF_DOWN,\n        RoundingMode::HALF_CEILING => BrickMathRounding::HALF_CEILING,\n        RoundingMode::HALF_FLOOR => BrickMathRounding::HALF_FLOOR,\n        RoundingMode::HALF_EVEN => BrickMathRounding::HALF_EVEN,\n    ];\n\n    public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface\n    {\n        $sum = BigInteger::of($augend->toString());\n\n        foreach ($addends as $addend) {\n            $sum = $sum->plus($addend->toString());\n        }\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new IntegerObject((string) $sum);\n    }\n\n    public function subtract(NumberInterface $minuend, NumberInterface ...$subtrahends): NumberInterface\n    {\n        $difference = BigInteger::of($minuend->toString());\n\n        foreach ($subtrahends as $subtrahend) {\n            $difference = $difference->minus($subtrahend->toString());\n        }\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new IntegerObject((string) $difference);\n    }\n\n    public function multiply(NumberInterface $multiplicand, NumberInterface ...$multipliers): NumberInterface\n    {\n        $product = BigInteger::of($multiplicand->toString());\n\n        foreach ($multipliers as $multiplier) {\n            $product = $product->multipliedBy($multiplier->toString());\n        }\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new IntegerObject((string) $product);\n    }\n\n    public function divide(\n        int $roundingMode,\n        int $scale,\n        NumberInterface $dividend,\n        NumberInterface ...$divisors,\n    ): NumberInterface {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $brickRounding = $this->getBrickRoundingMode($roundingMode);\n\n        $quotient = BigDecimal::of($dividend->toString());\n\n        foreach ($divisors as $divisor) {\n            $quotient = $quotient->dividedBy($divisor->toString(), $scale, $brickRounding);\n        }\n\n        if ($scale === 0) {\n            /** @phpstan-ignore possiblyImpure.new */\n            return new IntegerObject((string) $quotient->toBigInteger());\n        }\n\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Decimal((string) $quotient);\n    }\n\n    public function fromBase(string $value, int $base): IntegerObject\n    {\n        try {\n            /** @phpstan-ignore possiblyImpure.new */\n            return new IntegerObject((string) BigInteger::fromBase($value, $base));\n        } catch (MathException | \\InvalidArgumentException $exception) {\n            throw new InvalidArgumentException(\n                $exception->getMessage(),\n                (int) $exception->getCode(),\n                $exception\n            );\n        }\n    }\n\n    public function toBase(IntegerObject $value, int $base): string\n    {\n        try {\n            return BigInteger::of($value->toString())->toBase($base);\n        } catch (MathException | \\InvalidArgumentException $exception) {\n            throw new InvalidArgumentException(\n                $exception->getMessage(),\n                (int) $exception->getCode(),\n                $exception\n            );\n        }\n    }\n\n    public function toHexadecimal(IntegerObject $value): Hexadecimal\n    {\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Hexadecimal($this->toBase($value, 16));\n    }\n\n    public function toInteger(Hexadecimal $value): IntegerObject\n    {\n        return $this->fromBase($value->toString(), 16);\n    }\n\n    /**\n     * Maps ramsey/uuid rounding modes to those used by brick/math\n     *\n     * @return BrickMathRounding::*\n     */\n    private function getBrickRoundingMode(int $roundingMode)\n    {\n        return self::ROUNDING_MODE_MAP[$roundingMode] ?? BrickMathRounding::UNNECESSARY;\n    }\n}\n"
  },
  {
    "path": "src/Math/CalculatorInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Math;\n\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\NumberInterface;\n\n/**\n * A calculator performs arithmetic operations on numbers\n *\n * @immutable\n */\ninterface CalculatorInterface\n{\n    /**\n     * Returns the sum of all the provided parameters\n     *\n     * @param NumberInterface $augend The first addend (the integer being added to)\n     * @param NumberInterface ...$addends The additional integers to a add to the augend\n     *\n     * @return NumberInterface The sum of all the parameters\n     *\n     * @pure\n     */\n    public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface;\n\n    /**\n     * Returns the difference of all the provided parameters\n     *\n     * @param NumberInterface $minuend The integer being subtracted from\n     * @param NumberInterface ...$subtrahends The integers to subtract from the minuend\n     *\n     * @return NumberInterface The difference after subtracting all parameters\n     *\n     * @pure\n     */\n    public function subtract(NumberInterface $minuend, NumberInterface ...$subtrahends): NumberInterface;\n\n    /**\n     * Returns the product of all the provided parameters\n     *\n     * @param NumberInterface $multiplicand The integer to be multiplied\n     * @param NumberInterface ...$multipliers The factors by which to multiply the multiplicand\n     *\n     * @return NumberInterface The product of multiplying all the provided parameters\n     *\n     * @pure\n     */\n    public function multiply(NumberInterface $multiplicand, NumberInterface ...$multipliers): NumberInterface;\n\n    /**\n     * Returns the quotient of the provided parameters divided left-to-right\n     *\n     * @param int $roundingMode The RoundingMode constant to use for this operation\n     * @param int $scale The scale to use for this operation\n     * @param NumberInterface $dividend The integer to be divided\n     * @param NumberInterface ...$divisors The integers to divide $dividend by, in the order in which the division\n     *     operations should take place (left-to-right)\n     *\n     * @return NumberInterface The quotient of dividing the provided parameters left-to-right\n     *\n     * @pure\n     */\n    public function divide(\n        int $roundingMode,\n        int $scale,\n        NumberInterface $dividend,\n        NumberInterface ...$divisors,\n    ): NumberInterface;\n\n    /**\n     * Converts a value from an arbitrary base to a base-10 integer value\n     *\n     * @param string $value The value to convert\n     * @param int $base The base to convert from (i.e., 2, 16, 32, etc.)\n     *\n     * @return IntegerObject The base-10 integer value of the converted value\n     *\n     * @pure\n     */\n    public function fromBase(string $value, int $base): IntegerObject;\n\n    /**\n     * Converts a base-10 integer value to an arbitrary base\n     *\n     * @param IntegerObject $value The integer value to convert\n     * @param int $base The base to convert to (i.e., 2, 16, 32, etc.)\n     *\n     * @return string The value represented in the specified base\n     *\n     * @pure\n     */\n    public function toBase(IntegerObject $value, int $base): string;\n\n    /**\n     * Converts an Integer instance to a Hexadecimal instance\n     *\n     * @pure\n     */\n    public function toHexadecimal(IntegerObject $value): Hexadecimal;\n\n    /**\n     * Converts a Hexadecimal instance to an Integer instance\n     *\n     * @pure\n     */\n    public function toInteger(Hexadecimal $value): IntegerObject;\n}\n"
  },
  {
    "path": "src/Math/RoundingMode.php",
    "content": "<?php\n\n/**\n * This file was originally part of brick/math\n *\n * Copyright (c) 2013-present Benjamin Morel\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * @link https://github.com/brick/math brick/math at GitHub\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Math;\n\n/**\n * Specifies a rounding behavior for numerical operations capable of discarding precision.\n *\n * Each rounding mode indicates how the least significant returned digit of a rounded result is to be calculated. If\n * fewer digits are returned than the digits needed to represent the exact numerical result, the discarded digits will\n * be referred to as the discarded fraction regardless of the digits' contribution to the value of the number. In other\n * words, considered as a numerical value, the discarded fraction could have an absolute value greater than one.\n */\nfinal class RoundingMode\n{\n    /**\n     * Asserts that the requested operation has an exact result; hence no rounding is necessary.\n     */\n    public const UNNECESSARY = 0;\n\n    /**\n     * Rounds away from zero.\n     *\n     * Always increments the digit prior to a nonzero discarded fraction. Note that this rounding mode never decreases\n     * the magnitude of the calculated value.\n     */\n    public const UP = 1;\n\n    /**\n     * Rounds towards zero.\n     *\n     * Never increments the digit prior to a discarded fraction (i.e., truncates). Note that this rounding mode never\n     * increases the magnitude of the calculated value.\n     */\n    public const DOWN = 2;\n\n    /**\n     * Rounds towards positive infinity.\n     *\n     * If the result is positive, behaves as for UP; if negative, behaves as for DOWN. Note that this rounding mode\n     * never decreases the calculated value.\n     */\n    public const CEILING = 3;\n\n    /**\n     * Rounds towards negative infinity.\n     *\n     * If the result is positive, behave as for DOWN; if negative, behave as for UP. Note that this rounding mode never\n     * increases the calculated value.\n     */\n    public const FLOOR = 4;\n\n    /**\n     * Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round up.\n     *\n     * Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves as for DOWN. Note that this is the\n     * rounding mode commonly taught at school.\n     */\n    public const HALF_UP = 5;\n\n    /**\n     * Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round down.\n     *\n     * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN.\n     */\n    public const HALF_DOWN = 6;\n\n    /**\n     * Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round towards positive infinity.\n     *\n     * If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN.\n     */\n    public const HALF_CEILING = 7;\n\n    /**\n     * Rounds towards \"nearest neighbor\" unless both neighbors are equidistant, in which case round towards negative infinity.\n     *\n     * If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP.\n     */\n    public const HALF_FLOOR = 8;\n\n    /**\n     * Rounds towards the \"nearest neighbor\" unless both neighbors are equidistant, in which case rounds towards the even neighbor.\n     *\n     * Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for HALF_DOWN if it's even.\n     *\n     * Note that this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a\n     * sequence of calculations. It is sometimes known as \"Banker's rounding\", and is chiefly used in the USA.\n     */\n    public const HALF_EVEN = 9;\n\n    /**\n     * Private constructor. This class is not instantiable.\n     *\n     * @codeCoverageIgnore\n     */\n    private function __construct()\n    {\n    }\n}\n"
  },
  {
    "path": "src/Nonstandard/Fields.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Nonstandard;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Fields\\SerializableFieldsTrait;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\VariantTrait;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function bin2hex;\nuse function dechex;\nuse function hexdec;\nuse function sprintf;\nuse function str_pad;\nuse function strlen;\nuse function substr;\n\nuse const STR_PAD_LEFT;\n\n/**\n * Nonstandard UUID fields do not conform to the RFC 9562 (formerly RFC 4122) standard\n *\n * Since some systems may create nonstandard UUIDs, this implements the {@see FieldsInterface}, so that functionality of\n * a nonstandard UUID is not degraded, in the event these UUIDs are expected to contain RFC 9562 (formerly RFC 4122) fields.\n *\n * Internally, this class represents the fields together as a 16-byte binary string.\n *\n * @immutable\n */\nfinal class Fields implements FieldsInterface\n{\n    use SerializableFieldsTrait;\n    use VariantTrait;\n\n    /**\n     * @param string $bytes A 16-byte binary string representation of a UUID\n     *\n     * @throws InvalidArgumentException if the byte string is not exactly 16 bytes\n     */\n    public function __construct(private string $bytes)\n    {\n        if (strlen($this->bytes) !== 16) {\n            throw new InvalidArgumentException(\n                'The byte string must be 16 bytes long; received ' . strlen($this->bytes) . ' bytes',\n            );\n        }\n    }\n\n    public function getBytes(): string\n    {\n        return $this->bytes;\n    }\n\n    public function getClockSeq(): Hexadecimal\n    {\n        $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;\n\n        return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT));\n    }\n\n    public function getClockSeqHiAndReserved(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1)));\n    }\n\n    public function getClockSeqLow(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1)));\n    }\n\n    public function getNode(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 10)));\n    }\n\n    public function getTimeHiAndVersion(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2)));\n    }\n\n    public function getTimeLow(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4)));\n    }\n\n    public function getTimeMid(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2)));\n    }\n\n    public function getTimestamp(): Hexadecimal\n    {\n        return new Hexadecimal(sprintf(\n            '%03x%04s%08s',\n            hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff,\n            $this->getTimeMid()->toString(),\n            $this->getTimeLow()->toString()\n        ));\n    }\n\n    public function getVersion(): ?int\n    {\n        return null;\n    }\n\n    public function isNil(): bool\n    {\n        return false;\n    }\n\n    public function isMax(): bool\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Nonstandard/Uuid.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Nonstandard;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Uuid as BaseUuid;\n\n/**\n * Nonstandard\\Uuid is a UUID that doesn't conform to RFC 9562 (formerly RFC 4122)\n *\n * @immutable\n * @pure\n */\nfinal class Uuid extends BaseUuid\n{\n    public function __construct(\n        Fields $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Nonstandard/UuidBuilder.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Nonstandard;\n\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\UuidInterface;\nuse Throwable;\n\n/**\n * Nonstandard\\UuidBuilder builds instances of Nonstandard\\Uuid\n *\n * @immutable\n */\nclass UuidBuilder implements UuidBuilderInterface\n{\n    /**\n     * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Nonstandard\\Uuid\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to Unix timestamps\n     */\n    public function __construct(\n        private NumberConverterInterface $numberConverter,\n        private TimeConverterInterface $timeConverter,\n    ) {\n    }\n\n    /**\n     * Builds and returns a Nonstandard\\Uuid\n     *\n     * @param CodecInterface $codec The codec to use for building this instance\n     * @param string $bytes The byte string from which to construct a UUID\n     *\n     * @return Uuid The Nonstandard\\UuidBuilder returns an instance of Nonstandard\\Uuid\n     *\n     * @pure\n     */\n    public function build(CodecInterface $codec, string $bytes): UuidInterface\n    {\n        try {\n            /** @phpstan-ignore possiblyImpure.new */\n            return new Uuid($this->buildFields($bytes), $this->numberConverter, $codec, $this->timeConverter);\n        } catch (Throwable $e) {\n            /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */\n            throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e);\n        }\n    }\n\n    /**\n     * Proxy method to allow injecting a mock for testing\n     *\n     * @pure\n     */\n    protected function buildFields(string $bytes): Fields\n    {\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Fields($bytes);\n    }\n}\n"
  },
  {
    "path": "src/Nonstandard/UuidV6.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Nonstandard;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Lazy\\LazyUuidFromString;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\TimeTrait;\nuse Ramsey\\Uuid\\Rfc4122\\UuidInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV1;\nuse Ramsey\\Uuid\\Uuid as BaseUuid;\n\n/**\n * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and node values that are combined into a\n * 128-bit unsigned integer\n *\n * @deprecated Use {@see \\Ramsey\\Uuid\\Rfc4122\\UuidV6} instead.\n *\n * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft\n * @link http://gh.peabody.io/uuidv6/ \"Version 6\" UUIDs\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.6 RFC 9562, 5.6. UUID Version 6\n *\n * @immutable\n */\nclass UuidV6 extends BaseUuid implements UuidInterface\n{\n    use TimeTrait;\n\n    /**\n     * Creates a version 6 (reordered Gregorian time) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== BaseUuid::UUID_TYPE_REORDERED_TIME) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV6 must represent a version 6 (reordered time) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * Converts this UUID into an instance of a version 1 UUID\n     */\n    public function toUuidV1(): UuidV1\n    {\n        $hex = $this->getHex()->toString();\n        $hex = substr($hex, 7, 5)\n            . substr($hex, 13, 3)\n            . substr($hex, 3, 4)\n            . '1' . substr($hex, 0, 3)\n            . substr($hex, 16);\n\n        /** @var LazyUuidFromString $uuid */\n        $uuid = BaseUuid::fromBytes((string) hex2bin($hex));\n\n        return $uuid->toUuidV1();\n    }\n\n    /**\n     * Converts a version 1 UUID into an instance of a version 6 UUID\n     */\n    public static function fromUuidV1(UuidV1 $uuidV1): \\Ramsey\\Uuid\\Rfc4122\\UuidV6\n    {\n        $hex = $uuidV1->getHex()->toString();\n        $hex = substr($hex, 13, 3)\n            . substr($hex, 8, 4)\n            . substr($hex, 0, 5)\n            . '6' . substr($hex, 5, 3)\n            . substr($hex, 16);\n\n        /** @var LazyUuidFromString $uuid */\n        $uuid = BaseUuid::fromBytes((string) hex2bin($hex));\n\n        return $uuid->toUuidV6();\n    }\n}\n"
  },
  {
    "path": "src/Provider/Dce/SystemDceSecurityProvider.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Dce;\n\nuse Ramsey\\Uuid\\Exception\\DceSecurityException;\nuse Ramsey\\Uuid\\Provider\\DceSecurityProviderInterface;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n\nuse function escapeshellarg;\nuse function preg_split;\nuse function str_getcsv;\nuse function strrpos;\nuse function strtolower;\nuse function strtoupper;\nuse function substr;\nuse function trim;\n\nuse const PREG_SPLIT_NO_EMPTY;\n\n/**\n * SystemDceSecurityProvider retrieves the user or group identifiers from the system\n */\nclass SystemDceSecurityProvider implements DceSecurityProviderInterface\n{\n    /**\n     * @throws DceSecurityException if unable to get a user identifier\n     *\n     * @inheritDoc\n     */\n    public function getUid(): IntegerObject\n    {\n        /** @var IntegerObject | int | float | string | null $uid */\n        static $uid = null;\n\n        if ($uid instanceof IntegerObject) {\n            return $uid;\n        }\n\n        if ($uid === null) {\n            $uid = $this->getSystemUid();\n        }\n\n        if ($uid === '') {\n            throw new DceSecurityException(\n                'Unable to get a user identifier using the system DCE Security provider; please provide a custom '\n                . 'identifier or use a different provider',\n            );\n        }\n\n        $uid = new IntegerObject($uid);\n\n        return $uid;\n    }\n\n    /**\n     * @throws DceSecurityException if unable to get a group identifier\n     *\n     * @inheritDoc\n     */\n    public function getGid(): IntegerObject\n    {\n        /** @var IntegerObject | int | float | string | null $gid */\n        static $gid = null;\n\n        if ($gid instanceof IntegerObject) {\n            return $gid;\n        }\n\n        if ($gid === null) {\n            $gid = $this->getSystemGid();\n        }\n\n        if ($gid === '') {\n            throw new DceSecurityException(\n                'Unable to get a group identifier using the system DCE Security provider; please provide a custom '\n                . 'identifier or use a different provider',\n            );\n        }\n\n        $gid = new IntegerObject($gid);\n\n        return $gid;\n    }\n\n    /**\n     * Returns the UID from the system\n     */\n    private function getSystemUid(): string\n    {\n        if (!$this->hasShellExec()) {\n            return '';\n        }\n\n        return match ($this->getOs()) {\n            'WIN' => $this->getWindowsUid(),\n            default => trim((string) shell_exec('id -u')),\n        };\n    }\n\n    /**\n     * Returns the GID from the system\n     */\n    private function getSystemGid(): string\n    {\n        if (!$this->hasShellExec()) {\n            return '';\n        }\n\n        return match ($this->getOs()) {\n            'WIN' => $this->getWindowsGid(),\n            default => trim((string) shell_exec('id -g')),\n        };\n    }\n\n    /**\n     * Returns true if shell_exec() is available for use\n     */\n    private function hasShellExec(): bool\n    {\n        return !str_contains(strtolower((string) ini_get('disable_functions')), 'shell_exec');\n    }\n\n    /**\n     * Returns the PHP_OS string\n     */\n    private function getOs(): string\n    {\n        /** @var string $phpOs */\n        $phpOs = constant('PHP_OS');\n\n        return strtoupper(substr($phpOs, 0, 3));\n    }\n\n    /**\n     * Returns the user identifier for a user on a Windows system\n     *\n     * Windows does not have the same concept as an effective POSIX UID for the running script. Instead, each user is\n     * uniquely identified by an SID (security identifier). The SID includes three 32-bit unsigned integers that make up\n     * a unique domain identifier, followed by an RID (relative identifier) that we will use as the UID. The primary\n     * caveat is that this UID may not be unique to the system, since it is, instead, unique to the domain.\n     *\n     * @link https://www.lifewire.com/what-is-an-sid-number-2626005 What Is an SID Number?\n     * @link https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/81d92bba-d22b-4a8c-908a-554ab29148ab Well-known SID Structures\n     * @link https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers#well-known-sids Well-known SIDs\n     * @link https://www.windows-commandline.com/get-sid-of-user/ Get SID of user\n     */\n    private function getWindowsUid(): string\n    {\n        $response = shell_exec('whoami /user /fo csv /nh');\n\n        if ($response === null) {\n            return '';\n        }\n\n        $sid = str_getcsv(trim((string) $response), escape: '\\\\')[1] ?? '';\n\n        if (($lastHyphen = strrpos($sid, '-')) === false) {\n            return '';\n        }\n\n        return trim(substr($sid, $lastHyphen + 1));\n    }\n\n    /**\n     * Returns a group identifier for a user on a Windows system\n     *\n     * Since Windows does not have the same concept as an effective POSIX GID for the running script, we will get the\n     * local group memberships for the user running the script. Then, we will get the SID (security identifier) for the\n     * first group that appears in that list. Finally, we will return the RID (relative identifier) for the group and\n     * use that as the GID.\n     *\n     * @link https://www.windows-commandline.com/list-of-user-groups-command-line/ List of user groups command line\n     */\n    private function getWindowsGid(): string\n    {\n        $response = shell_exec('net user %username% | findstr /b /i \"Local Group Memberships\"');\n\n        if ($response === null) {\n            return '';\n        }\n\n        $userGroups = preg_split('/\\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY);\n        $firstGroup = trim($userGroups[1] ?? '', \"* \\t\\n\\r\\0\\x0B\");\n\n        if ($firstGroup === '') {\n            return '';\n        }\n\n        $response = shell_exec('wmic group get name,sid | findstr /b /i ' . escapeshellarg($firstGroup));\n\n        if ($response === null) {\n            return '';\n        }\n\n        $userGroup = preg_split('/\\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY);\n        $sid = $userGroup[1] ?? '';\n\n        if (($lastHyphen = strrpos($sid, '-')) === false) {\n            return '';\n        }\n\n        return trim(substr($sid, $lastHyphen + 1));\n    }\n}\n"
  },
  {
    "path": "src/Provider/DceSecurityProviderInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider;\n\nuse Ramsey\\Uuid\\Rfc4122\\UuidV2;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n\n/**\n * A DCE provider provides access to local domain identifiers for version 2, DCE Security, UUIDs\n *\n * @see UuidV2\n */\ninterface DceSecurityProviderInterface\n{\n    /**\n     * Returns a user identifier for the system\n     *\n     * @link https://en.wikipedia.org/wiki/User_identifier User identifier\n     */\n    public function getUid(): IntegerObject;\n\n    /**\n     * Returns a group identifier for the system\n     *\n     * @link https://en.wikipedia.org/wiki/Group_identifier Group identifier\n     */\n    public function getGid(): IntegerObject;\n}\n"
  },
  {
    "path": "src/Provider/Node/FallbackNodeProvider.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Node;\n\nuse Ramsey\\Uuid\\Exception\\NodeException;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\n/**\n * FallbackNodeProvider retrieves the system node ID by stepping through a list of providers until a node ID can be obtained\n */\nclass FallbackNodeProvider implements NodeProviderInterface\n{\n    /**\n     * @param iterable<NodeProviderInterface> $providers Array of node providers\n     */\n    public function __construct(private iterable $providers)\n    {\n    }\n\n    public function getNode(): Hexadecimal\n    {\n        $lastProviderException = null;\n\n        foreach ($this->providers as $provider) {\n            try {\n                return $provider->getNode();\n            } catch (NodeException $exception) {\n                $lastProviderException = $exception;\n\n                continue;\n            }\n        }\n\n        throw new NodeException(message: 'Unable to find a suitable node provider', previous: $lastProviderException);\n    }\n}\n"
  },
  {
    "path": "src/Provider/Node/NodeProviderCollection.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Node;\n\nuse Ramsey\\Collection\\AbstractCollection;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\n/**\n * A collection of NodeProviderInterface objects\n *\n * @deprecated this class has been deprecated and will be removed in 5.0.0. The use-case for this class comes from a\n *     pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced at runtime:\n *     that is no longer necessary, now that you can safely verify your code to be correct and use more generic types\n *     like `iterable<T>` instead.\n *\n * @extends AbstractCollection<NodeProviderInterface>\n */\nclass NodeProviderCollection extends AbstractCollection\n{\n    public function getType(): string\n    {\n        return NodeProviderInterface::class;\n    }\n\n    /**\n     * Re-constructs the object from its serialized form\n     *\n     * @param string $serialized The serialized PHP string to unserialize into a UuidInterface instance\n     */\n    public function unserialize($serialized): void\n    {\n        /** @var array<array-key, NodeProviderInterface> $data */\n        $data = unserialize($serialized, [\n            'allowed_classes' => [\n                Hexadecimal::class,\n                RandomNodeProvider::class,\n                StaticNodeProvider::class,\n                SystemNodeProvider::class,\n            ],\n        ]);\n\n        /** @phpstan-ignore-next-line */\n        $this->data = array_filter($data, fn ($unserialized): bool => $unserialized instanceof NodeProviderInterface);\n    }\n}\n"
  },
  {
    "path": "src/Provider/Node/RandomNodeProvider.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Node;\n\nuse Ramsey\\Uuid\\Exception\\RandomSourceException;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Throwable;\n\nuse function bin2hex;\nuse function dechex;\nuse function hex2bin;\nuse function hexdec;\nuse function str_pad;\nuse function substr;\n\nuse const STR_PAD_LEFT;\n\n/**\n * RandomNodeProvider generates a random node ID\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.10 RFC 9562, 6.10. UUIDs That Do Not Identify the Host\n */\nclass RandomNodeProvider implements NodeProviderInterface\n{\n    public function getNode(): Hexadecimal\n    {\n        try {\n            $nodeBytes = random_bytes(6);\n        } catch (Throwable $exception) {\n            throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception);\n        }\n\n        // Split the node bytes for math on 32-bit systems.\n        $nodeMsb = substr($nodeBytes, 0, 3);\n        $nodeLsb = substr($nodeBytes, 3);\n\n        // Set the multicast bit; see RFC 9562, section 6.10.\n        $nodeMsb = hex2bin(str_pad(dechex(hexdec(bin2hex($nodeMsb)) | 0x010000), 6, '0', STR_PAD_LEFT));\n\n        return new Hexadecimal(str_pad(bin2hex($nodeMsb . $nodeLsb), 12, '0', STR_PAD_LEFT));\n    }\n}\n"
  },
  {
    "path": "src/Provider/Node/StaticNodeProvider.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Node;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function dechex;\nuse function hexdec;\nuse function str_pad;\nuse function substr;\n\nuse const STR_PAD_LEFT;\n\n/**\n * StaticNodeProvider provides a static node value with the multicast bit set\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.10 RFC 9562, 6.10. UUIDs That Do Not Identify the Host\n */\nclass StaticNodeProvider implements NodeProviderInterface\n{\n    private Hexadecimal $node;\n\n    /**\n     * @param Hexadecimal $node The static node value to use\n     */\n    public function __construct(Hexadecimal $node)\n    {\n        if (strlen($node->toString()) > 12) {\n            throw new InvalidArgumentException('Static node value cannot be greater than 12 hexadecimal characters');\n        }\n\n        $this->node = $this->setMulticastBit($node);\n    }\n\n    public function getNode(): Hexadecimal\n    {\n        return $this->node;\n    }\n\n    /**\n     * Set the multicast bit for the static node value\n     */\n    private function setMulticastBit(Hexadecimal $node): Hexadecimal\n    {\n        $nodeHex = str_pad($node->toString(), 12, '0', STR_PAD_LEFT);\n        $firstOctet = substr($nodeHex, 0, 2);\n        $firstOctet = str_pad(dechex(hexdec($firstOctet) | 0x01), 2, '0', STR_PAD_LEFT);\n\n        return new Hexadecimal($firstOctet . substr($nodeHex, 2));\n    }\n}\n"
  },
  {
    "path": "src/Provider/Node/SystemNodeProvider.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Node;\n\nuse Ramsey\\Uuid\\Exception\\NodeException;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function array_filter;\nuse function array_map;\nuse function array_walk;\nuse function count;\nuse function ob_get_clean;\nuse function ob_start;\nuse function preg_match;\nuse function preg_match_all;\nuse function reset;\nuse function str_contains;\nuse function str_replace;\nuse function strtolower;\nuse function strtoupper;\nuse function substr;\n\nuse const GLOB_NOSORT;\nuse const PREG_PATTERN_ORDER;\n\n/**\n * SystemNodeProvider retrieves the system node ID, if possible\n *\n * The system node ID, or host ID, is often the same as the MAC address for a network interface on the host.\n */\nclass SystemNodeProvider implements NodeProviderInterface\n{\n    /**\n     * Pattern to match nodes in `ifconfig` and `ipconfig` output.\n     */\n    private const IFCONFIG_PATTERN = '/[^:]([0-9a-f]{2}([:-])[0-9a-f]{2}(\\2[0-9a-f]{2}){4})[^:]/i';\n\n    /**\n     * Pattern to match nodes in sysfs stream output.\n     */\n    private const SYSFS_PATTERN = '/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i';\n\n    public function getNode(): Hexadecimal\n    {\n        $node = $this->getNodeFromSystem();\n\n        if ($node === '') {\n            throw new NodeException('Unable to fetch a node for this system');\n        }\n\n        return new Hexadecimal($node);\n    }\n\n    /**\n     * Returns the system node if found\n     */\n    protected function getNodeFromSystem(): string\n    {\n        /** @var string | null $node */\n        static $node = null;\n\n        if ($node !== null) {\n            return $node;\n        }\n\n        // First, try a Linux-specific approach.\n        $node = $this->getSysfs();\n\n        if ($node === '') {\n            // Search ifconfig output for MAC addresses & return the first one.\n            $node = $this->getIfconfig();\n        }\n\n        $node = str_replace([':', '-'], '', $node);\n\n        return $node;\n    }\n\n    /**\n     * Returns the network interface configuration for the system\n     *\n     * @codeCoverageIgnore\n     */\n    protected function getIfconfig(): string\n    {\n        if (str_contains(strtolower((string) ini_get('disable_functions')), 'passthru')) {\n            return '';\n        }\n\n        /** @var string $phpOs */\n        $phpOs = constant('PHP_OS');\n\n        ob_start();\n        switch (strtoupper(substr($phpOs, 0, 3))) {\n            case 'WIN':\n                passthru('ipconfig /all 2>&1');\n\n                break;\n            case 'DAR':\n                passthru('ifconfig 2>&1');\n\n                break;\n            case 'FRE':\n                passthru('netstat -i -f link 2>&1');\n\n                break;\n            case 'LIN':\n            default:\n                passthru('netstat -ie 2>&1');\n\n                break;\n        }\n\n        $ifconfig = (string) ob_get_clean();\n\n        if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) {\n            foreach ($matches[1] as $iface) {\n                if ($iface !== '00:00:00:00:00:00' && $iface !== '00-00-00-00-00-00') {\n                    return $iface;\n                }\n            }\n        }\n\n        return '';\n    }\n\n    /**\n     * Returns MAC address from the first system interface via the sysfs interface\n     */\n    protected function getSysfs(): string\n    {\n        /** @var string $phpOs */\n        $phpOs = constant('PHP_OS');\n\n        if (strtoupper($phpOs) !== 'LINUX') {\n            return '';\n        }\n\n        $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT);\n\n        if ($addressPaths === false || count($addressPaths) === 0) {\n            return '';\n        }\n\n        /** @var array<array-key, string> $macs */\n        $macs = [];\n\n        array_walk($addressPaths, function (string $addressPath) use (&$macs): void {\n            if (is_readable($addressPath)) {\n                $macs[] = file_get_contents($addressPath);\n            }\n        });\n\n        /** @var callable $trim */\n        $trim = 'trim';\n\n        $macs = array_map($trim, $macs);\n\n        // Remove invalid entries.\n        $macs = array_filter($macs, function (mixed $address): bool {\n            assert(is_string($address));\n\n            return $address !== '00:00:00:00:00:00' && preg_match(self::SYSFS_PATTERN, $address);\n        });\n\n        /** @var bool | string $mac */\n        $mac = reset($macs);\n\n        return (string) $mac;\n    }\n}\n"
  },
  {
    "path": "src/Provider/NodeProviderInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider;\n\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\n/**\n * A node provider retrieves or generates a node ID\n */\ninterface NodeProviderInterface\n{\n    /**\n     * Returns a node ID\n     *\n     * @return Hexadecimal The node ID as a hexadecimal string\n     */\n    public function getNode(): Hexadecimal;\n}\n"
  },
  {
    "path": "src/Provider/Time/FixedTimeProvider.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Time;\n\nuse Ramsey\\Uuid\\Provider\\TimeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\n\n/**\n * FixedTimeProvider uses a known time to provide the time\n *\n * This provider allows the use of a previously generated, or known, time when generating time-based UUIDs.\n */\nclass FixedTimeProvider implements TimeProviderInterface\n{\n    public function __construct(private Time $time)\n    {\n    }\n\n    /**\n     * Sets the `usec` component of the time\n     *\n     * @param IntegerObject | int | string $value The `usec` value to set\n     */\n    public function setUsec($value): void\n    {\n        $this->time = new Time($this->time->getSeconds(), $value);\n    }\n\n    /**\n     * Sets the `sec` component of the time\n     *\n     * @param IntegerObject | int | string $value The `sec` value to set\n     */\n    public function setSec($value): void\n    {\n        $this->time = new Time($value, $this->time->getMicroseconds());\n    }\n\n    public function getTime(): Time\n    {\n        return $this->time;\n    }\n}\n"
  },
  {
    "path": "src/Provider/Time/SystemTimeProvider.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider\\Time;\n\nuse Ramsey\\Uuid\\Provider\\TimeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Time;\n\nuse function gettimeofday;\n\n/**\n * SystemTimeProvider retrieves the current time using built-in PHP functions\n */\nclass SystemTimeProvider implements TimeProviderInterface\n{\n    public function getTime(): Time\n    {\n        $time = gettimeofday();\n\n        return new Time($time['sec'], $time['usec']);\n    }\n}\n"
  },
  {
    "path": "src/Provider/TimeProviderInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Provider;\n\nuse Ramsey\\Uuid\\Type\\Time;\n\n/**\n * A time provider retrieves the current time\n */\ninterface TimeProviderInterface\n{\n    /**\n     * Returns a time object\n     */\n    public function getTime(): Time;\n}\n"
  },
  {
    "path": "src/Rfc4122/Fields.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Fields\\SerializableFieldsTrait;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function bin2hex;\nuse function dechex;\nuse function hexdec;\nuse function sprintf;\nuse function str_pad;\nuse function strlen;\nuse function substr;\nuse function unpack;\n\nuse const STR_PAD_LEFT;\n\n/**\n * RFC 9562 (formerly RFC 4122) variant UUIDs consist of a set of named fields\n *\n * Internally, this class represents the fields together as a 16-byte binary string.\n *\n * @immutable\n */\nfinal class Fields implements FieldsInterface\n{\n    use MaxTrait;\n    use NilTrait;\n    use SerializableFieldsTrait;\n    use VariantTrait;\n    use VersionTrait;\n\n    /**\n     * @param string $bytes A 16-byte binary string representation of a UUID\n     *\n     * @throws InvalidArgumentException if the byte string is not exactly 16 bytes\n     * @throws InvalidArgumentException if the byte string does not represent an RFC 9562 (formerly RFC 4122) UUID\n     * @throws InvalidArgumentException if the byte string does not contain a valid version\n     */\n    public function __construct(private string $bytes)\n    {\n        if (strlen($this->bytes) !== 16) {\n            throw new InvalidArgumentException(\n                'The byte string must be 16 bytes long; ' . 'received ' . strlen($this->bytes) . ' bytes',\n            );\n        }\n\n        if (!$this->isCorrectVariant()) {\n            throw new InvalidArgumentException(\n                'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant',\n            );\n        }\n\n        if (!$this->isCorrectVersion()) {\n            throw new InvalidArgumentException(\n                'The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version',\n            );\n        }\n    }\n\n    /**\n     * @pure\n     */\n    public function getBytes(): string\n    {\n        return $this->bytes;\n    }\n\n    public function getClockSeq(): Hexadecimal\n    {\n        if ($this->isMax()) {\n            $clockSeq = 0xffff;\n        } elseif ($this->isNil()) {\n            $clockSeq = 0x0000;\n        } else {\n            $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;\n        }\n\n        return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT));\n    }\n\n    public function getClockSeqHiAndReserved(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1)));\n    }\n\n    public function getClockSeqLow(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1)));\n    }\n\n    public function getNode(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 10)));\n    }\n\n    public function getTimeHiAndVersion(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2)));\n    }\n\n    public function getTimeLow(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4)));\n    }\n\n    public function getTimeMid(): Hexadecimal\n    {\n        return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2)));\n    }\n\n    /**\n     * Returns the full 60-bit timestamp, without the version\n     *\n     * For version 2 UUIDs, the time_low field is the local identifier and should not be returned as part of the time.\n     * For this reason, we set the bottom 32 bits of the timestamp to 0's. As a result, there is some loss of timestamp\n     * fidelity, for version 2 UUIDs. The timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 minutes, 9\n     * seconds, and 496,730 microseconds).\n     *\n     * For version 6 UUIDs, the timestamp order is reversed from the typical RFC 9562 (formerly RFC 4122) order (the\n     * time bits are in the correct bit order, so that it is monotonically increasing). In returning the timestamp\n     * value, we put the bits in the order: time_low + time_mid + time_hi.\n     */\n    public function getTimestamp(): Hexadecimal\n    {\n        return new Hexadecimal(match ($this->getVersion()) {\n            Uuid::UUID_TYPE_DCE_SECURITY => sprintf(\n                '%03x%04s%08s',\n                hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff,\n                $this->getTimeMid()->toString(),\n                ''\n            ),\n            Uuid::UUID_TYPE_REORDERED_TIME => sprintf(\n                '%08s%04s%03x',\n                $this->getTimeLow()->toString(),\n                $this->getTimeMid()->toString(),\n                hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff\n            ),\n            // The Unix timestamp in version 7 UUIDs is a 48-bit number, but for consistency, we will return a 60-bit\n            // number, padded to the left with zeros.\n            Uuid::UUID_TYPE_UNIX_TIME => sprintf(\n                '%011s%04s',\n                $this->getTimeLow()->toString(),\n                $this->getTimeMid()->toString(),\n            ),\n            default => sprintf(\n                '%03x%04s%08s',\n                hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff,\n                $this->getTimeMid()->toString(),\n                $this->getTimeLow()->toString()\n            ),\n        });\n    }\n\n    public function getVersion(): ?int\n    {\n        if ($this->isNil() || $this->isMax()) {\n            return null;\n        }\n\n        /** @var int[] $parts */\n        $parts = unpack('n*', $this->bytes);\n\n        return $parts[4] >> 12;\n    }\n\n    private function isCorrectVariant(): bool\n    {\n        if ($this->isNil() || $this->isMax()) {\n            return true;\n        }\n\n        return $this->getVariant() === Uuid::RFC_4122;\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/FieldsInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Fields\\FieldsInterface as BaseFieldsInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\n/**\n * UUID fields, as defined by RFC 4122\n *\n * This interface defines the fields of an RFC 4122 variant UUID. Since RFC 9562 removed the concept of fields and\n * instead defined layouts that are specific to a given version, this interface is a legacy artifact of the earlier, and\n * now obsolete, RFC 4122.\n *\n * The fields of an RFC 4122 variant UUID are:\n *\n * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer\n * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer\n * * **time_hi_and_version**: The high field of the timestamp multiplexed with the version number, an unsigned 16-bit integer\n * * **clock_seq_hi_and_reserved**: The high field of the clock sequence multiplexed with the variant, an unsigned 8-bit integer\n * * **clock_seq_low**: The low field of the clock sequence, an unsigned 8-bit integer\n * * **node**: The spatially unique node identifier, an unsigned 48-bit integer\n *\n * @link https://www.rfc-editor.org/rfc/rfc4122#section-4.1 RFC 4122, 4.1. Format\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-4 RFC 9562, 4. UUID Format\n *\n * @immutable\n */\ninterface FieldsInterface extends BaseFieldsInterface\n{\n    /**\n     * Returns the full 16-bit clock sequence, with the variant bits (two most significant bits) masked out\n     */\n    public function getClockSeq(): Hexadecimal;\n\n    /**\n     * Returns the high field of the clock sequence multiplexed with the variant\n     */\n    public function getClockSeqHiAndReserved(): Hexadecimal;\n\n    /**\n     * Returns the low field of the clock sequence\n     */\n    public function getClockSeqLow(): Hexadecimal;\n\n    /**\n     * Returns the node field\n     */\n    public function getNode(): Hexadecimal;\n\n    /**\n     * Returns the high field of the timestamp multiplexed with the version\n     */\n    public function getTimeHiAndVersion(): Hexadecimal;\n\n    /**\n     * Returns the low field of the timestamp\n     */\n    public function getTimeLow(): Hexadecimal;\n\n    /**\n     * Returns the middle field of the timestamp\n     */\n    public function getTimeMid(): Hexadecimal;\n\n    /**\n     * Returns the full 60-bit timestamp, without the version\n     */\n    public function getTimestamp(): Hexadecimal;\n\n    /**\n     * Returns the variant\n     *\n     * The variant number describes the layout of the UUID. The variant number has the following meaning:\n     *\n     * - 0 - Reserved for NCS backward compatibility\n     * - 2 - The RFC 9562 (formerly RFC 4122) variant\n     * - 6 - Reserved, Microsoft Corporation backward compatibility\n     * - 7 - Reserved for future definition\n     *\n     * For RFC 9562 (formerly RFC 4122) variant UUIDs, this value should always be the integer `2`.\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     */\n    public function getVariant(): int;\n\n    /**\n     * Returns the UUID version\n     *\n     * The version number describes how the UUID was generated and has the following meaning:\n     *\n     * 1. Gregorian time UUID\n     * 2. DCE security UUID\n     * 3. Name-based UUID hashed with MD5\n     * 4. Randomly generated UUID\n     * 5. Name-based UUID hashed with SHA-1\n     * 6. Reordered Gregorian time UUID\n     * 7. Unix Epoch time UUID\n     * 8. Custom format UUID\n     *\n     * This returns `null` if the UUID is not an RFC 9562 (formerly RFC 4122) variant, since the version is only\n     * meaningful for this variant.\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     *\n     * @pure\n     */\n    public function getVersion(): ?int;\n\n    /**\n     * Returns true if these fields represent a nil UUID\n     *\n     * The nil UUID is a special form of UUID that is specified to have all 128 bits set to zero.\n     *\n     * @pure\n     */\n    public function isNil(): bool;\n}\n"
  },
  {
    "path": "src/Rfc4122/MaxTrait.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\n/**\n * Provides common functionality for max UUIDs\n *\n * @immutable\n */\ntrait MaxTrait\n{\n    /**\n     * Returns the bytes that comprise the fields\n     *\n     * @pure\n     */\n    abstract public function getBytes(): string;\n\n    /**\n     * Returns true if the byte string represents a max UUID\n     *\n     * @pure\n     */\n    public function isMax(): bool\n    {\n        return $this->getBytes() === \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\";\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/MaxUuid.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * The max UUID is a special form of UUID that has all 128 bits set to one (`1`)\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 RFC 9562, 5.10. Max UUID\n *\n * @immutable\n */\nfinal class MaxUuid extends Uuid implements UuidInterface\n{\n}\n"
  },
  {
    "path": "src/Rfc4122/NilTrait.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\n/**\n * Provides common functionality for nil UUIDs\n *\n * @immutable\n */\ntrait NilTrait\n{\n    /**\n     * Returns the bytes that comprise the fields\n     *\n     * @pure\n     */\n    abstract public function getBytes(): string;\n\n    /**\n     * Returns true if the byte string represents a nil UUID\n     */\n    public function isNil(): bool\n    {\n        return $this->getBytes() === \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/NilUuid.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * The nil UUID is a special form of UUID that has all 128 bits set to zero (`0`)\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 RFC 9562, 5.9. Nil UUID\n *\n * @immutable\n */\nfinal class NilUuid extends Uuid implements UuidInterface\n{\n}\n"
  },
  {
    "path": "src/Rfc4122/TimeTrait.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Throwable;\n\nuse function str_pad;\n\nuse const STR_PAD_LEFT;\n\n/**\n * Provides common functionality for getting the time from a time-based UUID\n *\n * @immutable\n */\ntrait TimeTrait\n{\n    /**\n     * Returns a DateTimeInterface object representing the timestamp associated with the UUID\n     *\n     * @return DateTimeImmutable A PHP DateTimeImmutable instance representing the timestamp of a time-based UUID\n     */\n    public function getDateTime(): DateTimeInterface\n    {\n        $time = $this->timeConverter->convertTime($this->fields->getTimestamp());\n\n        try {\n            return new DateTimeImmutable(\n                '@'\n                . $time->getSeconds()->toString()\n                . '.'\n                . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT)\n            );\n        } catch (Throwable $e) {\n            throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidBuilder.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\Time\\UnixTimeConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Rfc4122\\UuidInterface as Rfc4122UuidInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\nuse Throwable;\n\n/**\n * UuidBuilder builds instances of RFC 9562 (formerly 4122) UUIDs\n *\n * @immutable\n */\nclass UuidBuilder implements UuidBuilderInterface\n{\n    private TimeConverterInterface $unixTimeConverter;\n\n    /**\n     * Constructs the DefaultUuidBuilder\n     *\n     * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Uuid\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting Gregorian time extracted\n     *     from version 1, 2, and 6 UUIDs to Unix timestamps\n     * @param TimeConverterInterface | null $unixTimeConverter The time converter to use for converter Unix Epoch time\n     *     extracted from version 7 UUIDs to Unix timestamps\n     */\n    public function __construct(\n        private NumberConverterInterface $numberConverter,\n        private TimeConverterInterface $timeConverter,\n        ?TimeConverterInterface $unixTimeConverter = null,\n    ) {\n        $this->unixTimeConverter = $unixTimeConverter ?? new UnixTimeConverter(new BrickMathCalculator());\n    }\n\n    /**\n     * Builds and returns a Uuid\n     *\n     * @param CodecInterface $codec The codec to use for building this Uuid instance\n     * @param string $bytes The byte string from which to construct a UUID\n     *\n     * @return Rfc4122UuidInterface UuidBuilder returns instances of Rfc4122UuidInterface\n     *\n     * @pure\n     */\n    public function build(CodecInterface $codec, string $bytes): UuidInterface\n    {\n        try {\n            /** @var Fields $fields */\n            $fields = $this->buildFields($bytes);\n\n            if ($fields->isNil()) {\n                /** @phpstan-ignore possiblyImpure.new */\n                return new NilUuid($fields, $this->numberConverter, $codec, $this->timeConverter);\n            }\n\n            if ($fields->isMax()) {\n                /** @phpstan-ignore possiblyImpure.new */\n                return new MaxUuid($fields, $this->numberConverter, $codec, $this->timeConverter);\n            }\n\n            return match ($fields->getVersion()) {\n                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_TIME => new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter),\n                Uuid::UUID_TYPE_DCE_SECURITY\n                    /** @phpstan-ignore possiblyImpure.new */\n                    => new UuidV2($fields, $this->numberConverter, $codec, $this->timeConverter),\n                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_HASH_MD5 => new UuidV3($fields, $this->numberConverter, $codec, $this->timeConverter),\n                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_RANDOM => new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter),\n                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_HASH_SHA1 => new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter),\n                Uuid::UUID_TYPE_REORDERED_TIME\n                    /** @phpstan-ignore possiblyImpure.new */\n                    => new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter),\n                Uuid::UUID_TYPE_UNIX_TIME\n                    /** @phpstan-ignore possiblyImpure.new */\n                    => new UuidV7($fields, $this->numberConverter, $codec, $this->unixTimeConverter),\n                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_CUSTOM => new UuidV8($fields, $this->numberConverter, $codec, $this->timeConverter),\n                default => throw new UnsupportedOperationException(\n                    'The UUID version in the given fields is not supported by this UUID builder',\n                ),\n            };\n        } catch (Throwable $e) {\n            /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */\n            throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e);\n        }\n    }\n\n    /**\n     * Proxy method to allow injecting a mock for testing\n     *\n     * @pure\n     */\n    protected function buildFields(string $bytes): FieldsInterface\n    {\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Fields($bytes);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\UuidInterface as BaseUuidInterface;\n\n/**\n * A universally unique identifier (UUID), as defined in RFC 9562 (formerly RFC 4122)\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562 RFC 9562\n *\n * @immutable\n */\ninterface UuidInterface extends BaseUuidInterface\n{\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV1.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Gregorian time, or version 1, UUIDs include timestamp, clock sequence, and node values, combined into a 128-bit unsigned integer\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.1 RFC 9562, 5.1. UUID Version 1\n *\n * @immutable\n */\nfinal class UuidV1 extends Uuid implements UuidInterface\n{\n    use TimeTrait;\n\n    /**\n     * Creates a version 1 (Gregorian time) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_TIME) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV1 must represent a version 1 (time-based) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV2.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function hexdec;\n\n/**\n * DCE Security version, or version 2, UUIDs include local domain identifier, local ID for the specified domain, and\n * node values that are combined into a 128-bit unsigned integer\n *\n * It is important to note that a version 2 UUID suffers from some loss of timestamp fidelity, due to replacing the\n * time_low field with the local identifier. When constructing the timestamp value for date purposes, we replace the\n * local identifier bits with zeros. As a result, the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7\n * minutes, 9 seconds, and 496,730 microseconds).\n *\n * Astute observers might note this value directly corresponds to `2^32-1`, or `0xffffffff`. The local identifier is\n * 32-bits, and we have set each of these bits to `0`, so the maximum range of timestamp drift is `0x00000000` to\n * `0xffffffff` (counted in 100-nanosecond intervals).\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.2 RFC 9562, 5.2. UUID Version 2\n * @link https://publications.opengroup.org/c311 DCE 1.1: Authentication and Security Services\n * @link https://publications.opengroup.org/c706 DCE 1.1: Remote Procedure Call\n * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1: Auth & Sec, §5.2.1.1\n * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1: Auth & Sec, §11.5.1.1\n * @link https://pubs.opengroup.org/onlinepubs/9629399/apdxa.htm DCE 1.1: RPC, Appendix A\n * @link https://github.com/google/uuid Go package for UUIDs (includes DCE implementation)\n *\n * @immutable\n */\nfinal class UuidV2 extends Uuid implements UuidInterface\n{\n    use TimeTrait;\n\n    /**\n     * Creates a version 2 (DCE Security) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_DCE_SECURITY) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV2 must represent a version 2 (DCE Security) UUID'\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * Returns the local domain used to create this version 2 UUID\n     */\n    public function getLocalDomain(): int\n    {\n        /** @var Rfc4122FieldsInterface $fields */\n        $fields = $this->getFields();\n\n        return (int) hexdec($fields->getClockSeqLow()->toString());\n    }\n\n    /**\n     * Returns the string name of the local domain\n     */\n    public function getLocalDomainName(): string\n    {\n        return Uuid::DCE_DOMAIN_NAMES[$this->getLocalDomain()];\n    }\n\n    /**\n     * Returns the local identifier for the domain used to create this version 2 UUID\n     */\n    public function getLocalIdentifier(): IntegerObject\n    {\n        /** @var Rfc4122FieldsInterface $fields */\n        $fields = $this->getFields();\n\n        return new IntegerObject($this->numberConverter->fromHex($fields->getTimeLow()->toString()));\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV3.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Version 3 UUIDs are named-based, using a combination of a namespace and name that are hashed into a 128-bit unsigned\n * integer using the MD5 hashing algorithm\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.3 RFC 9562, 5.3. UUID Version 3\n *\n * @immutable\n */\nfinal class UuidV3 extends Uuid implements UuidInterface\n{\n    /**\n     * Creates a version 3 (name-based, MD5-hashed) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_HASH_MD5) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV3 must represent a version 3 (name-based, MD5-hashed) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV4.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Random, or version 4, UUIDs are randomly or pseudo-randomly generated 128-bit integers\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.4 RFC 9562, 5.4. UUID Version 4\n *\n * @immutable\n */\nfinal class UuidV4 extends Uuid implements UuidInterface\n{\n    /**\n     * Creates a version 4 (random) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_RANDOM) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV4 must represent a version 4 (random) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV5.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Version 5 UUIDs are named-based, using a combination of a namespace and name that are hashed into a 128-bit unsigned\n * integer using the SHA1 hashing algorithm\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.5 RFC 9562, 5.5. UUID Version 5\n *\n * @immutable\n */\nfinal class UuidV5 extends Uuid implements UuidInterface\n{\n    /**\n     * Creates a version 5 (name-based, SHA1-hashed) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_HASH_SHA1) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV5 must represent a version 5 (named-based, SHA1-hashed) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV6.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Nonstandard\\UuidV6 as NonstandardUuidV6;\n\n/**\n * Reordered Gregorian time, or version 6, UUIDs include timestamp, clock sequence, and node values that are combined\n * into a 128-bit unsigned integer\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.6 RFC 9562, 5.6. UUID Version 6\n *\n * @immutable\n */\nfinal class UuidV6 extends NonstandardUuidV6 implements UuidInterface\n{\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV7.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Unix Epoch time, or version 7, UUIDs include a timestamp in milliseconds since the Unix Epoch, along with random bytes\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.7 RFC 9562, 5.7. UUID Version 7\n *\n * @immutable\n */\nfinal class UuidV7 extends Uuid implements UuidInterface\n{\n    use TimeTrait;\n\n    /**\n     * Creates a version 7 (Unix Epoch time) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_UNIX_TIME) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV7 must represent a version 7 (Unix Epoch time) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/UuidV8.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Custom format, or version 8, UUIDs provide an RFC-compatible format for experimental or vendor-specific uses\n *\n * The only requirement for version 8 UUIDs is that the version and variant bits must be set. Otherwise, implementations\n * are free to set the other bits according to their needs. As a result, the uniqueness of version 8 UUIDs is\n * implementation-specific and should not be assumed.\n *\n * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.8 RFC 9562, 5.8. UUID Version 8\n *\n * @immutable\n */\nfinal class UuidV8 extends Uuid implements UuidInterface\n{\n    /**\n     * Creates a version 8 (custom format) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_CUSTOM) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV8 must represent a version 8 (custom format) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/Validator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\Validator\\ValidatorInterface;\n\nuse function preg_match;\nuse function str_replace;\n\n/**\n * Rfc4122\\Validator validates strings as UUIDs of the RFC 9562 (formerly RFC 4122) variant\n *\n * @immutable\n */\nfinal class Validator implements ValidatorInterface\n{\n    private const VALID_PATTERN = '\\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-'\n        . '[1-8][0-9A-Fa-f]{3}-[ABab89][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\\z';\n\n    /**\n     * @return non-empty-string\n     */\n    public function getPattern(): string\n    {\n        return self::VALID_PATTERN;\n    }\n\n    public function validate(string $uuid): bool\n    {\n        /** @phpstan-ignore possiblyImpure.functionCall */\n        $uuid = strtolower(str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid));\n\n        /** @phpstan-ignore possiblyImpure.functionCall */\n        return $uuid === Uuid::NIL || $uuid === Uuid::MAX || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid);\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/VariantTrait.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Exception\\InvalidBytesException;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function decbin;\nuse function str_pad;\nuse function str_starts_with;\nuse function strlen;\nuse function substr;\nuse function unpack;\n\nuse const STR_PAD_LEFT;\n\n/**\n * Provides common functionality for handling the variant, as defined by RFC 9562 (formerly RFC 4122)\n *\n * @immutable\n */\ntrait VariantTrait\n{\n    /**\n     * Returns the bytes that comprise the fields\n     */\n    abstract public function getBytes(): string;\n\n    /**\n     * Returns the variant\n     *\n     * The variant number describes the layout of the UUID. The variant number has the following meaning:\n     *\n     * - 0 - Reserved for NCS backward compatibility\n     * - 2 - The RFC 9562 (formerly RFC 4122) variant\n     * - 6 - Reserved, Microsoft Corporation backward compatibility\n     * - 7 - Reserved for future definition\n     *\n     * For RFC 9562 (formerly RFC 4122) variant UUIDs, this value should always be the integer `2`.\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     */\n    public function getVariant(): int\n    {\n        if (strlen($this->getBytes()) !== 16) {\n            throw new InvalidBytesException('Invalid number of bytes');\n        }\n\n        // According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and\n        // {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 5.10}, the Max UUID falls within the range\n        // of the future variant.\n        if ($this->isMax()) {\n            return Uuid::RESERVED_FUTURE;\n        }\n\n        // According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and\n        // {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 5.9}, the Nil UUID falls within the range\n        // of the Apollo NCS variant.\n        if ($this->isNil()) {\n            return Uuid::RESERVED_NCS;\n        }\n\n        /** @var int[] $parts */\n        $parts = unpack('n*', $this->getBytes());\n\n        // $parts[5] is a 16-bit, unsigned integer containing the variant bits of the UUID. We convert this integer into\n        // a string containing a binary representation, padded to 16 characters. We analyze the first three characters\n        // (three most-significant bits) to determine the variant.\n        $msb = substr(str_pad(decbin($parts[5]), 16, '0', STR_PAD_LEFT), 0, 3);\n\n        if ($msb === '111') {\n            return Uuid::RESERVED_FUTURE;\n        } elseif ($msb === '110') {\n            return Uuid::RESERVED_MICROSOFT;\n        } elseif (str_starts_with($msb, '10')) {\n            return Uuid::RFC_4122;\n        }\n\n        return Uuid::RESERVED_NCS;\n    }\n}\n"
  },
  {
    "path": "src/Rfc4122/VersionTrait.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Rfc4122;\n\nuse Ramsey\\Uuid\\Uuid;\n\n/**\n * Provides common functionality for handling the version, as defined by RFC 9562 (formerly RFC 4122)\n *\n * @immutable\n */\ntrait VersionTrait\n{\n    /**\n     * Returns the UUID version\n     *\n     * The version number describes how the UUID was generated and has the following meaning:\n     *\n     * 1. Gregorian time UUID\n     * 2. DCE security UUID\n     * 3. Name-based UUID hashed with MD5\n     * 4. Randomly generated UUID\n     * 5. Name-based UUID hashed with SHA-1\n     * 6. Reordered Gregorian time UUID\n     * 7. Unix Epoch time UUID\n     * 8. Custom format UUID\n     *\n     * This returns `null` if the UUID is not an RFC 9562 (formerly RFC 4122) variant, since the version is only\n     * meaningful for this variant.\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     *\n     * @pure\n     */\n    abstract public function getVersion(): ?int;\n\n    /**\n     * Returns true if these fields represent a max UUID\n     */\n    abstract public function isMax(): bool;\n\n    /**\n     * Returns true if these fields represent a nil UUID\n     */\n    abstract public function isNil(): bool;\n\n    /**\n     * Returns true if the version matches one of those defined by RFC 9562 (formerly RFC 4122)\n     *\n     * @return bool True if the UUID version is valid, false otherwise\n     */\n    private function isCorrectVersion(): bool\n    {\n        if ($this->isNil() || $this->isMax()) {\n            return true;\n        }\n\n        return match ($this->getVersion()) {\n            Uuid::UUID_TYPE_TIME, Uuid::UUID_TYPE_DCE_SECURITY,\n                Uuid::UUID_TYPE_HASH_MD5, Uuid::UUID_TYPE_RANDOM,\n                Uuid::UUID_TYPE_HASH_SHA1, Uuid::UUID_TYPE_REORDERED_TIME,\n                Uuid::UUID_TYPE_UNIX_TIME, Uuid::UUID_TYPE_CUSTOM => true,\n            default => false,\n        };\n    }\n}\n"
  },
  {
    "path": "src/Type/Decimal.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Type;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse ValueError;\n\nuse function is_numeric;\nuse function sprintf;\nuse function str_starts_with;\n\n/**\n * A value object representing a decimal\n *\n * This class exists for type-safety purposes, to ensure that decimals returned from ramsey/uuid methods as strings are\n * truly decimals and not some other kind of string.\n *\n * To support values as true decimals and not as floats or doubles, we store the decimals as strings.\n *\n * @immutable\n */\nfinal class Decimal implements NumberInterface\n{\n    private string $value;\n    private bool $isNegative;\n\n    public function __construct(float | int | string | self $value)\n    {\n        $value = (string) $value;\n\n        if (!is_numeric($value)) {\n            throw new InvalidArgumentException(\n                'Value must be a signed decimal or a string containing only '\n                . 'digits 0-9 and, optionally, a decimal point or sign (+ or -)'\n            );\n        }\n\n        // Remove the leading +-symbol.\n        if (str_starts_with($value, '+')) {\n            $value = substr($value, 1);\n        }\n\n        // For cases like `-0` or `-0.0000`, convert the value to `0`.\n        if (abs((float) $value) === 0.0) {\n            $value = '0';\n        }\n\n        if (str_starts_with($value, '-')) {\n            $this->isNegative = true;\n        } else {\n            $this->isNegative = false;\n        }\n\n        $this->value = $value;\n    }\n\n    public function isNegative(): bool\n    {\n        return $this->isNegative;\n    }\n\n    public function toString(): string\n    {\n        return $this->value;\n    }\n\n    public function __toString(): string\n    {\n        return $this->toString();\n    }\n\n    public function jsonSerialize(): string\n    {\n        return $this->toString();\n    }\n\n    public function serialize(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * @return array{string: string}\n     */\n    public function __serialize(): array\n    {\n        return ['string' => $this->toString()];\n    }\n\n    /**\n     * Constructs the object from a serialized string representation\n     *\n     * @param string $data The serialized string representation of the object\n     */\n    public function unserialize(string $data): void\n    {\n        $this->__construct($data);\n    }\n\n    /**\n     * @param array{string?: string} $data\n     */\n    public function __unserialize(array $data): void\n    {\n        // @codeCoverageIgnoreStart\n        if (!isset($data['string'])) {\n            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));\n        }\n        // @codeCoverageIgnoreEnd\n\n        $this->unserialize($data['string']);\n    }\n}\n"
  },
  {
    "path": "src/Type/Hexadecimal.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Type;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse ValueError;\n\nuse function preg_match;\nuse function sprintf;\nuse function substr;\n\n/**\n * A value object representing a hexadecimal number\n *\n * This class exists for type-safety purposes, to ensure that hexadecimal numbers returned from ramsey/uuid methods as\n * strings are truly hexadecimal and not some other kind of string.\n *\n * @immutable\n */\nfinal class Hexadecimal implements TypeInterface\n{\n    /**\n     * @var non-empty-string\n     */\n    private string $value;\n\n    /**\n     * @param self | string $value The hexadecimal value to store\n     */\n    public function __construct(self | string $value)\n    {\n        $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value);\n    }\n\n    /**\n     * @return non-empty-string\n     *\n     * @pure\n     */\n    public function toString(): string\n    {\n        return $this->value;\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function __toString(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function jsonSerialize(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function serialize(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * @return array{string: string}\n     */\n    public function __serialize(): array\n    {\n        return ['string' => $this->toString()];\n    }\n\n    /**\n     * Constructs the object from a serialized string representation\n     *\n     * @param string $data The serialized string representation of the object\n     */\n    public function unserialize(string $data): void\n    {\n        $this->__construct($data);\n    }\n\n    /**\n     * @param array{string?: string} $data\n     */\n    public function __unserialize(array $data): void\n    {\n        // @codeCoverageIgnoreStart\n        if (!isset($data['string'])) {\n            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));\n        }\n        // @codeCoverageIgnoreEnd\n\n        $this->unserialize($data['string']);\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    private function prepareValue(string $value): string\n    {\n        $value = strtolower($value);\n\n        if (str_starts_with($value, '0x')) {\n            $value = substr($value, 2);\n        }\n\n        if (!preg_match('/^[A-Fa-f0-9]+$/', $value)) {\n            throw new InvalidArgumentException('Value must be a hexadecimal number');\n        }\n\n        /** @var non-empty-string */\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Type/Integer.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Type;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse ValueError;\n\nuse function assert;\nuse function is_numeric;\nuse function preg_match;\nuse function sprintf;\nuse function substr;\n\n/**\n * A value object representing an integer\n *\n * This class exists for type-safety purposes, to ensure that integers returned from ramsey/uuid methods as strings are\n * truly integers and not some other kind of string.\n *\n * To support large integers beyond PHP_INT_MAX and PHP_INT_MIN on both 64-bit and 32-bit systems, we store the integers\n * as strings.\n *\n * @immutable\n */\nfinal class Integer implements NumberInterface\n{\n    /**\n     * @var numeric-string\n     */\n    private string $value;\n\n    /**\n     * @phpstan-ignore property.readOnlyByPhpDocDefaultValue\n     */\n    private bool $isNegative = false;\n\n    public function __construct(self | float | int | string $value)\n    {\n        $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value);\n    }\n\n    public function isNegative(): bool\n    {\n        return $this->isNegative;\n    }\n\n    /**\n     * @return numeric-string\n     *\n     * @pure\n     */\n    public function toString(): string\n    {\n        return $this->value;\n    }\n\n    /**\n     * @return numeric-string\n     */\n    public function __toString(): string\n    {\n        return $this->toString();\n    }\n\n    public function jsonSerialize(): string\n    {\n        return $this->toString();\n    }\n\n    public function serialize(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * @return array{string: string}\n     */\n    public function __serialize(): array\n    {\n        return ['string' => $this->toString()];\n    }\n\n    /**\n     * Constructs the object from a serialized string representation\n     *\n     * @param string $data The serialized string representation of the object\n     */\n    public function unserialize(string $data): void\n    {\n        $this->__construct($data);\n    }\n\n    /**\n     * @param array{string?: string} $data\n     */\n    public function __unserialize(array $data): void\n    {\n        // @codeCoverageIgnoreStart\n        if (!isset($data['string'])) {\n            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));\n        }\n        // @codeCoverageIgnoreEnd\n\n        $this->unserialize($data['string']);\n    }\n\n    /**\n     * @return numeric-string\n     */\n    private function prepareValue(float | int | string $value): string\n    {\n        $value = (string) $value;\n        $sign = '+';\n\n        // If the value contains a sign, remove it for the digit pattern check.\n        if (str_starts_with($value, '-') || str_starts_with($value, '+')) {\n            $sign = substr($value, 0, 1);\n            $value = substr($value, 1);\n        }\n\n        if (!preg_match('/^\\d+$/', $value)) {\n            throw new InvalidArgumentException(\n                'Value must be a signed integer or a string containing only '\n                . 'digits 0-9 and, optionally, a sign (+ or -)'\n            );\n        }\n\n        // Trim any leading zeros.\n        $value = ltrim($value, '0');\n\n        // Set to zero if the string is empty after trimming zeros.\n        if ($value === '') {\n            $value = '0';\n        }\n\n        // Add the negative sign back to the value.\n        if ($sign === '-' && $value !== '0') {\n            $value = $sign . $value;\n\n            /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */\n            $this->isNegative = true;\n        }\n\n        assert(is_numeric($value));\n\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Type/NumberInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Type;\n\n/**\n * NumberInterface ensures consistency in numeric values returned by ramsey/uuid\n *\n * @immutable\n */\ninterface NumberInterface extends TypeInterface\n{\n    /**\n     * Returns true if this number is less than zero\n     */\n    public function isNegative(): bool;\n}\n"
  },
  {
    "path": "src/Type/Time.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Type;\n\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse ValueError;\n\nuse function json_decode;\nuse function json_encode;\nuse function sprintf;\n\n/**\n * A value object representing a timestamp\n *\n * This class exists for type-safety purposes, to ensure that timestamps used by ramsey/uuid are truly timestamp\n * integers and not some other kind of string or integer.\n *\n * @immutable\n */\nfinal class Time implements TypeInterface\n{\n    private IntegerObject $seconds;\n    private IntegerObject $microseconds;\n\n    public function __construct(\n        IntegerObject | float | int | string $seconds,\n        IntegerObject | float | int | string $microseconds = 0,\n    ) {\n        $this->seconds = new IntegerObject($seconds);\n        $this->microseconds = new IntegerObject($microseconds);\n    }\n\n    /**\n     * @pure\n     */\n    public function getSeconds(): IntegerObject\n    {\n        return $this->seconds;\n    }\n\n    /**\n     * @pure\n     */\n    public function getMicroseconds(): IntegerObject\n    {\n        return $this->microseconds;\n    }\n\n    public function toString(): string\n    {\n        return $this->seconds->toString() . '.' . sprintf('%06s', $this->microseconds->toString());\n    }\n\n    public function __toString(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * @return string[]\n     */\n    public function jsonSerialize(): array\n    {\n        return [\n            'seconds' => $this->getSeconds()->toString(),\n            'microseconds' => $this->getMicroseconds()->toString(),\n        ];\n    }\n\n    public function serialize(): string\n    {\n        return (string) json_encode($this);\n    }\n\n    /**\n     * @return array{seconds: string, microseconds: string}\n     */\n    public function __serialize(): array\n    {\n        return [\n            'seconds' => $this->getSeconds()->toString(),\n            'microseconds' => $this->getMicroseconds()->toString(),\n        ];\n    }\n\n    /**\n     * Constructs the object from a serialized string representation\n     *\n     * @param string $data The serialized string representation of the object\n     */\n    public function unserialize(string $data): void\n    {\n        /** @var array{seconds?: float | int | string, microseconds?: float | int | string} $time */\n        $time = json_decode($data, true);\n\n        if (!isset($time['seconds']) || !isset($time['microseconds'])) {\n            throw new UnsupportedOperationException('Attempted to unserialize an invalid value');\n        }\n\n        $this->__construct($time['seconds'], $time['microseconds']);\n    }\n\n    /**\n     * @param array{seconds?: string, microseconds?: string} $data\n     */\n    public function __unserialize(array $data): void\n    {\n        // @codeCoverageIgnoreStart\n        if (!isset($data['seconds']) || !isset($data['microseconds'])) {\n            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));\n        }\n        // @codeCoverageIgnoreEnd\n\n        $this->__construct($data['seconds'], $data['microseconds']);\n    }\n}\n"
  },
  {
    "path": "src/Type/TypeInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Type;\n\nuse JsonSerializable;\nuse Serializable;\n\n/**\n * TypeInterface ensures consistency in typed values returned by ramsey/uuid\n *\n * @immutable\n */\ninterface TypeInterface extends JsonSerializable, Serializable\n{\n    /**\n     * @pure\n     */\n    public function toString(): string;\n\n    /**\n     * @pure\n     */\n    public function __toString(): string;\n}\n"
  },
  {
    "path": "src/Uuid.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse BadMethodCallException;\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\Fields\\FieldsInterface;\nuse Ramsey\\Uuid\\Lazy\\LazyUuidFromString;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface as Rfc4122FieldsInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse ValueError;\n\nuse function assert;\nuse function bin2hex;\nuse function method_exists;\nuse function preg_match;\nuse function sprintf;\nuse function str_replace;\nuse function strcmp;\nuse function strlen;\nuse function strtolower;\nuse function substr;\n\n/**\n * Uuid provides constants and static methods for working with and generating UUIDs\n *\n * @immutable\n */\nclass Uuid implements UuidInterface\n{\n    use DeprecatedUuidMethodsTrait;\n\n    /**\n     * When this namespace is specified, the name string is a fully qualified domain name\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation\n     */\n    public const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n\n    /**\n     * When this namespace is specified, the name string is a URL\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation\n     */\n    public const NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n\n    /**\n     * When this namespace is specified, the name string is an ISO OID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation\n     */\n    public const NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n\n    /**\n     * When this namespace is specified, the name string is an X.500 DN (in DER or a text output format)\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation\n     */\n    public const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n\n    /**\n     * The Nil UUID is a special form of UUID that is specified to have all 128 bits set to zero\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 RFC 9562, 5.9. Nil UUID\n     */\n    public const NIL = '00000000-0000-0000-0000-000000000000';\n\n    /**\n     * The Max UUID is a special form of UUID that is specified to have all 128 bits set to one\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 RFC 9562, 5.10. Max UUID\n     */\n    public const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\n\n    /**\n     * Variant: reserved, NCS backward compatibility\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     */\n    public const RESERVED_NCS = 0;\n\n    /**\n     * Variant: the UUID layout specified in RFC 9562 (formerly RFC 4122)\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     * @see Uuid::RFC_9562\n     */\n    public const RFC_4122 = 2;\n\n    /**\n     * Variant: the UUID layout specified in RFC 9562 (formerly RFC 4122)\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     */\n    public const RFC_9562 = 2;\n\n    /**\n     * Variant: reserved, Microsoft Corporation backward compatibility\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     */\n    public const RESERVED_MICROSOFT = 6;\n\n    /**\n     * Variant: reserved for future definition\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     */\n    public const RESERVED_FUTURE = 7;\n\n    /**\n     * @deprecated Use {@see ValidatorInterface::getPattern()} instead.\n     */\n    public const VALID_PATTERN = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$';\n\n    /**\n     * Version 1 (Gregorian time) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_TIME = 1;\n\n    /**\n     * Version 2 (DCE Security) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_DCE_SECURITY = 2;\n\n    /**\n     * @deprecated Use {@see Uuid::UUID_TYPE_DCE_SECURITY} instead.\n     */\n    public const UUID_TYPE_IDENTIFIER = 2;\n\n    /**\n     * Version 3 (name-based and hashed with MD5) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_HASH_MD5 = 3;\n\n    /**\n     * Version 4 (random) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_RANDOM = 4;\n\n    /**\n     * Version 5 (name-based and hashed with SHA1) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_HASH_SHA1 = 5;\n\n    /**\n     * @deprecated Use {@see Uuid::UUID_TYPE_REORDERED_TIME} instead.\n     */\n    public const UUID_TYPE_PEABODY = 6;\n\n    /**\n     * Version 6 (reordered Gregorian time) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_REORDERED_TIME = 6;\n\n    /**\n     * Version 7 (Unix Epoch time) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_UNIX_TIME = 7;\n\n    /**\n     * Version 8 (custom format) UUID\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field\n     */\n    public const UUID_TYPE_CUSTOM = 8;\n\n    /**\n     * DCE Security principal domain\n     *\n     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1\n     */\n    public const DCE_DOMAIN_PERSON = 0;\n\n    /**\n     * DCE Security group domain\n     *\n     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1\n     */\n    public const DCE_DOMAIN_GROUP = 1;\n\n    /**\n     * DCE Security organization domain\n     *\n     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1\n     */\n    public const DCE_DOMAIN_ORG = 2;\n\n    /**\n     * DCE Security domain string names\n     *\n     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1\n     */\n    public const DCE_DOMAIN_NAMES = [\n        self::DCE_DOMAIN_PERSON => 'person',\n        self::DCE_DOMAIN_GROUP => 'group',\n        self::DCE_DOMAIN_ORG => 'org',\n    ];\n\n    /**\n     * @phpstan-ignore property.readOnlyByPhpDocDefaultValue\n     */\n    private static ?UuidFactoryInterface $factory = null;\n\n    /**\n     * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations for the\n     *     default/happy path internal scenarios\n     * @phpstan-ignore property.readOnlyByPhpDocDefaultValue\n     */\n    private static bool $factoryReplaced = false;\n\n    protected CodecInterface $codec;\n    protected NumberConverterInterface $numberConverter;\n    protected Rfc4122FieldsInterface $fields;\n    protected TimeConverterInterface $timeConverter;\n\n    /**\n     * Creates a universally unique identifier (UUID) from an array of fields\n     *\n     * Unless you're making advanced use of this library to generate identifiers that deviate from RFC 9562 (formerly\n     * RFC 4122), you probably do not want to instantiate a UUID directly. Use the static methods, instead:\n     *\n     * ```\n     * use Ramsey\\Uuid\\Uuid;\n     *\n     * $timeBasedUuid = Uuid::uuid1();\n     * $namespaceMd5Uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'http://php.net/');\n     * $randomUuid = Uuid::uuid4();\n     * $namespaceSha1Uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'http://php.net/');\n     * ```\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        $this->fields = $fields;\n        $this->codec = $codec;\n        $this->numberConverter = $numberConverter;\n        $this->timeConverter = $timeConverter;\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function __toString(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * Converts the UUID to a string for JSON serialization\n     */\n    public function jsonSerialize(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * Converts the UUID to a string for PHP serialization\n     */\n    public function serialize(): string\n    {\n        return $this->codec->encode($this);\n    }\n\n    /**\n     * @return array{bytes: string}\n     */\n    public function __serialize(): array\n    {\n        return ['bytes' => $this->serialize()];\n    }\n\n    /**\n     * Re-constructs the object from its serialized form\n     *\n     * @param string $data The serialized PHP string to unserialize into a UuidInterface instance\n     */\n    public function unserialize(string $data): void\n    {\n        if (strlen($data) === 16) {\n            /** @var Uuid $uuid */\n            $uuid = self::getFactory()->fromBytes($data);\n        } else {\n            /** @var Uuid $uuid */\n            $uuid = self::getFactory()->fromString($data);\n        }\n\n        /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */\n        $this->codec = $uuid->codec;\n\n        /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */\n        $this->numberConverter = $uuid->numberConverter;\n\n        /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */\n        $this->fields = $uuid->fields;\n\n        /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */\n        $this->timeConverter = $uuid->timeConverter;\n    }\n\n    /**\n     * @param array{bytes?: string} $data\n     */\n    public function __unserialize(array $data): void\n    {\n        // @codeCoverageIgnoreStart\n        if (!isset($data['bytes'])) {\n            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));\n        }\n        // @codeCoverageIgnoreEnd\n\n        $this->unserialize($data['bytes']);\n    }\n\n    public function compareTo(UuidInterface $other): int\n    {\n        $compare = strcmp($this->toString(), $other->toString());\n\n        if ($compare < 0) {\n            return -1;\n        }\n\n        if ($compare > 0) {\n            return 1;\n        }\n\n        return 0;\n    }\n\n    public function equals(?object $other): bool\n    {\n        if (!$other instanceof UuidInterface) {\n            return false;\n        }\n\n        return $this->compareTo($other) === 0;\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function getBytes(): string\n    {\n        return $this->codec->encodeBinary($this);\n    }\n\n    public function getFields(): FieldsInterface\n    {\n        return $this->fields;\n    }\n\n    public function getHex(): Hexadecimal\n    {\n        return new Hexadecimal(str_replace('-', '', $this->toString()));\n    }\n\n    public function getInteger(): IntegerObject\n    {\n        return new IntegerObject($this->numberConverter->fromHex($this->getHex()->toString()));\n    }\n\n    public function getUrn(): string\n    {\n        return 'urn:uuid:' . $this->toString();\n    }\n\n    /**\n     * @return non-empty-string\n     */\n    public function toString(): string\n    {\n        return $this->codec->encode($this);\n    }\n\n    /**\n     * Returns the factory used to create UUIDs\n     */\n    public static function getFactory(): UuidFactoryInterface\n    {\n        if (self::$factory === null) {\n            self::$factory = new UuidFactory();\n        }\n\n        return self::$factory;\n    }\n\n    /**\n     * Sets the factory used to create UUIDs\n     *\n     * @param UuidFactoryInterface $factory A factory that will be used by this class to create UUIDs\n     */\n    public static function setFactory(UuidFactoryInterface $factory): void\n    {\n        // Note: non-strict equality is intentional here. If the factory is configured differently, every assumption\n        //       around purity is broken, and we have to internally decide everything differently.\n        // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator\n        self::$factoryReplaced = ($factory != new UuidFactory());\n\n        self::$factory = $factory;\n    }\n\n    /**\n     * Creates a UUID from a byte string\n     *\n     * @param string $bytes A binary string\n     *\n     * @return UuidInterface A UuidInterface instance created from a binary string representation\n     *\n     * @throws InvalidArgumentException\n     *\n     * @pure\n     */\n    public static function fromBytes(string $bytes): UuidInterface\n    {\n        /** @phpstan-ignore impure.staticPropertyAccess */\n        if (!self::$factoryReplaced && strlen($bytes) === 16) {\n            $base16Uuid = bin2hex($bytes);\n\n            // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID\n            return self::fromString(\n                substr($base16Uuid, 0, 8)\n                    . '-'\n                    . substr($base16Uuid, 8, 4)\n                    . '-'\n                    . substr($base16Uuid, 12, 4)\n                    . '-'\n                    . substr($base16Uuid, 16, 4)\n                    . '-'\n                    . substr($base16Uuid, 20, 12),\n            );\n        }\n\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return self::getFactory()->fromBytes($bytes);\n    }\n\n    /**\n     * Creates a UUID from the string standard representation\n     *\n     * @param string $uuid A hexadecimal string\n     *\n     * @return UuidInterface A UuidInterface instance created from a hexadecimal string representation\n     *\n     * @throws InvalidArgumentException\n     *\n     * @pure\n     */\n    public static function fromString(string $uuid): UuidInterface\n    {\n        $uuid = strtolower($uuid);\n        /** @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.functionCall */\n        if (!self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) {\n            /** @phpstan-ignore possiblyImpure.functionCall */\n            assert($uuid !== '');\n\n            /** @phpstan-ignore possiblyImpure.new */\n            return new LazyUuidFromString($uuid);\n        }\n\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return self::getFactory()->fromString($uuid);\n    }\n\n    /**\n     * Creates a UUID from a DateTimeInterface instance\n     *\n     * @param DateTimeInterface $dateTime The date and time\n     * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 1 UUID created from a DateTimeInterface instance\n     */\n    public static function fromDateTime(\n        DateTimeInterface $dateTime,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null\n    ): UuidInterface {\n        return self::getFactory()->fromDateTime($dateTime, $node, $clockSeq);\n    }\n\n    /**\n     * Creates a UUID from the Hexadecimal object\n     *\n     * @param Hexadecimal $hex Hexadecimal object representing a hexadecimal number\n     *\n     * @return UuidInterface A UuidInterface instance created from the Hexadecimal object representing a hexadecimal number\n     *\n     * @throws InvalidArgumentException\n     *\n     * @pure\n     */\n    public static function fromHexadecimal(Hexadecimal $hex): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $factory = self::getFactory();\n\n        if (method_exists($factory, 'fromHexadecimal')) {\n            /** @phpstan-ignore possiblyImpure.methodCall */\n            $uuid = $factory->fromHexadecimal($hex);\n            /** @phpstan-ignore possiblyImpure.functionCall */\n            assert($uuid instanceof UuidInterface);\n\n            return $uuid;\n        }\n\n        throw new BadMethodCallException('The method fromHexadecimal() does not exist on the provided factory');\n    }\n\n    /**\n     * Creates a UUID from a 128-bit integer string\n     *\n     * @param string $integer String representation of 128-bit integer\n     *\n     * @return UuidInterface A UuidInterface instance created from the string representation of a 128-bit integer\n     *\n     * @throws InvalidArgumentException\n     *\n     * @pure\n     */\n    public static function fromInteger(string $integer): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return self::getFactory()->fromInteger($integer);\n    }\n\n    /**\n     * Returns true if the provided string is a valid UUID\n     *\n     * @param string $uuid A string to validate as a UUID\n     *\n     * @return bool True if the string is a valid UUID, false otherwise\n     *\n     * @phpstan-assert-if-true =non-empty-string $uuid\n     *\n     * @pure\n     */\n    public static function isValid(string $uuid): bool\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */\n        return self::getFactory()->getValidator()->validate($uuid);\n    }\n\n    /**\n     * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time\n     *\n     * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may\n     *     be represented as an integer or a hexadecimal string\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 1 UUID\n     */\n    public static function uuid1($node = null, ?int $clockSeq = null): UuidInterface\n    {\n        return self::getFactory()->uuid1($node, $clockSeq);\n    }\n\n    /**\n     * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the current time\n     *\n     * @param int $localDomain The local domain to use when generating bytes, according to DCE Security\n     * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID\n     *     on POSIX systems, if the local domain is \"person\" or \"group,\" or it may be a site-defined identifier if the\n     *     local domain is \"org\"\n     * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes (in a version 2 UUID, the lower 8 bits of this number are\n     *     replaced with the domain).\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 2 UUID\n     */\n    public static function uuid2(\n        int $localDomain,\n        ?IntegerObject $localIdentifier = null,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null\n    ): UuidInterface {\n        return self::getFactory()->uuid2($localDomain, $localIdentifier, $node, $clockSeq);\n    }\n\n    /**\n     * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name\n     *\n     * @param UuidInterface | string $ns The namespace (must be a valid UUID)\n     * @param string $name The name to use for creating a UUID\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 3 UUID\n     *\n     * @pure\n     */\n    public static function uuid3($ns, string $name): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return self::getFactory()->uuid3($ns, $name);\n    }\n\n    /**\n     * Returns a version 4 (random) UUID\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 4 UUID\n     */\n    public static function uuid4(): UuidInterface\n    {\n        return self::getFactory()->uuid4();\n    }\n\n    /**\n     * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name\n     *\n     * @param UuidInterface | string $ns The namespace (must be a valid UUID)\n     * @param string $name The name to use for creating a UUID\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 5 UUID\n     *\n     * @pure\n     */\n    public static function uuid5($ns, string $name): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return self::getFactory()->uuid5($ns, $name);\n    }\n\n    /**\n     * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time\n     *\n     * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 6 UUID\n     */\n    public static function uuid6(\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null\n    ): UuidInterface {\n        return self::getFactory()->uuid6($node, $clockSeq);\n    }\n\n    /**\n     * Returns a version 7 (Unix Epoch time) UUID\n     *\n     * @param DateTimeInterface | null $dateTime An optional date/time from which to create the version 7 UUID. If not\n     *     provided, the UUID is generated using the current date/time.\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 7 UUID\n     */\n    public static function uuid7(?DateTimeInterface $dateTime = null): UuidInterface\n    {\n        $factory = self::getFactory();\n\n        if (method_exists($factory, 'uuid7')) {\n            /** @var UuidInterface */\n            return $factory->uuid7($dateTime);\n        }\n\n        throw new UnsupportedOperationException('The provided factory does not support the uuid7() method');\n    }\n\n    /**\n     * Returns a version 8 (custom format) UUID\n     *\n     * The bytes provided may contain any value according to your application's needs. Be aware, however, that other\n     * applications may not understand the semantics of the value.\n     *\n     * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of\n     *     information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64\n     *     and 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs.\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 8 UUID\n     *\n     * @pure\n     */\n    public static function uuid8(string $bytes): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $factory = self::getFactory();\n\n        if (method_exists($factory, 'uuid8')) {\n            /**\n             * @var UuidInterface\n             * @phpstan-ignore possiblyImpure.methodCall\n             */\n            return $factory->uuid8($bytes);\n        }\n\n        throw new UnsupportedOperationException('The provided factory does not support the uuid8() method');\n    }\n}\n"
  },
  {
    "path": "src/UuidFactory.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Generator\\DceSecurityGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\DefaultTimeGenerator;\nuse Ramsey\\Uuid\\Generator\\NameGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\TimeGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\UnixTimeGenerator;\nuse Ramsey\\Uuid\\Lazy\\LazyUuidFromString;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Provider\\Time\\FixedTimeProvider;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Validator\\ValidatorInterface;\n\nuse function bin2hex;\nuse function hex2bin;\nuse function pack;\nuse function str_pad;\nuse function strtolower;\nuse function substr;\nuse function substr_replace;\nuse function unpack;\n\nuse const STR_PAD_LEFT;\n\nclass UuidFactory implements UuidFactoryInterface\n{\n    private CodecInterface $codec;\n    private DceSecurityGeneratorInterface $dceSecurityGenerator;\n    private NameGeneratorInterface $nameGenerator;\n    private NodeProviderInterface $nodeProvider;\n    private NumberConverterInterface $numberConverter;\n    private RandomGeneratorInterface $randomGenerator;\n    private TimeConverterInterface $timeConverter;\n    private TimeGeneratorInterface $timeGenerator;\n    private TimeGeneratorInterface $unixTimeGenerator;\n    private UuidBuilderInterface $uuidBuilder;\n    private ValidatorInterface $validator;\n\n    /**\n     * @var bool whether the feature set was provided from outside, or we can operate under \"default\" assumptions\n     */\n    private bool $isDefaultFeatureSet;\n\n    /**\n     * @param FeatureSet | null $features A set of available features in the current environment\n     */\n    public function __construct(?FeatureSet $features = null)\n    {\n        $this->isDefaultFeatureSet = $features === null;\n\n        $features = $features ?: new FeatureSet();\n\n        $this->codec = $features->getCodec();\n        $this->dceSecurityGenerator = $features->getDceSecurityGenerator();\n        $this->nameGenerator = $features->getNameGenerator();\n        $this->nodeProvider = $features->getNodeProvider();\n        $this->numberConverter = $features->getNumberConverter();\n        $this->randomGenerator = $features->getRandomGenerator();\n        $this->timeConverter = $features->getTimeConverter();\n        $this->timeGenerator = $features->getTimeGenerator();\n        $this->uuidBuilder = $features->getBuilder();\n        $this->validator = $features->getValidator();\n        $this->unixTimeGenerator = $features->getUnixTimeGenerator();\n    }\n\n    /**\n     * Returns the codec used by this factory\n     */\n    public function getCodec(): CodecInterface\n    {\n        return $this->codec;\n    }\n\n    /**\n     * Sets the codec to use for this factory\n     *\n     * @param CodecInterface $codec A UUID encoder-decoder\n     */\n    public function setCodec(CodecInterface $codec): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->codec = $codec;\n    }\n\n    /**\n     * Returns the name generator used by this factory\n     */\n    public function getNameGenerator(): NameGeneratorInterface\n    {\n        return $this->nameGenerator;\n    }\n\n    /**\n     * Sets the name generator to use for this factory\n     *\n     * @param NameGeneratorInterface $nameGenerator A generator to generate binary data, based on a namespace and name\n     */\n    public function setNameGenerator(NameGeneratorInterface $nameGenerator): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->nameGenerator = $nameGenerator;\n    }\n\n    /**\n     * Returns the node provider used by this factory\n     */\n    public function getNodeProvider(): NodeProviderInterface\n    {\n        return $this->nodeProvider;\n    }\n\n    /**\n     * Returns the random generator used by this factory\n     */\n    public function getRandomGenerator(): RandomGeneratorInterface\n    {\n        return $this->randomGenerator;\n    }\n\n    /**\n     * Returns the time generator used by this factory\n     */\n    public function getTimeGenerator(): TimeGeneratorInterface\n    {\n        return $this->timeGenerator;\n    }\n\n    /**\n     * Sets the time generator to use for this factory\n     *\n     * @param TimeGeneratorInterface $generator A generator to generate binary data, based on the time\n     */\n    public function setTimeGenerator(TimeGeneratorInterface $generator): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->timeGenerator = $generator;\n    }\n\n    /**\n     * Returns the DCE Security generator used by this factory\n     */\n    public function getDceSecurityGenerator(): DceSecurityGeneratorInterface\n    {\n        return $this->dceSecurityGenerator;\n    }\n\n    /**\n     * Sets the DCE Security generator to use for this factory\n     *\n     * @param DceSecurityGeneratorInterface $generator A generator to generate binary data, based on a local domain and\n     *     local identifier\n     */\n    public function setDceSecurityGenerator(DceSecurityGeneratorInterface $generator): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->dceSecurityGenerator = $generator;\n    }\n\n    /**\n     * Returns the number converter used by this factory\n     */\n    public function getNumberConverter(): NumberConverterInterface\n    {\n        return $this->numberConverter;\n    }\n\n    /**\n     * Sets the random generator to use for this factory\n     *\n     * @param RandomGeneratorInterface $generator A generator to generate binary data, based on some random input\n     */\n    public function setRandomGenerator(RandomGeneratorInterface $generator): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->randomGenerator = $generator;\n    }\n\n    /**\n     * Sets the number converter to use for this factory\n     *\n     * @param NumberConverterInterface $converter A converter to use for working with large integers (i.e., integers\n     *     greater than PHP_INT_MAX)\n     */\n    public function setNumberConverter(NumberConverterInterface $converter): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->numberConverter = $converter;\n    }\n\n    /**\n     * Returns the UUID builder used by this factory\n     */\n    public function getUuidBuilder(): UuidBuilderInterface\n    {\n        return $this->uuidBuilder;\n    }\n\n    /**\n     * Sets the UUID builder to use for this factory\n     *\n     * @param UuidBuilderInterface $builder A builder for constructing instances of UuidInterface\n     */\n    public function setUuidBuilder(UuidBuilderInterface $builder): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->uuidBuilder = $builder;\n    }\n\n    public function getValidator(): ValidatorInterface\n    {\n        return $this->validator;\n    }\n\n    /**\n     * Sets the validator to use for this factory\n     *\n     * @param ValidatorInterface $validator A validator to use for validating whether a string is a valid UUID\n     */\n    public function setValidator(ValidatorInterface $validator): void\n    {\n        $this->isDefaultFeatureSet = false;\n\n        $this->validator = $validator;\n    }\n\n    /**\n     * @pure\n     */\n    public function fromBytes(string $bytes): UuidInterface\n    {\n        return $this->codec->decodeBytes($bytes);\n    }\n\n    /**\n     * @pure\n     */\n    public function fromString(string $uuid): UuidInterface\n    {\n        $uuid = strtolower($uuid);\n\n        return $this->codec->decode($uuid);\n    }\n\n    /**\n     * @pure\n     */\n    public function fromInteger(string $integer): UuidInterface\n    {\n        $hex = $this->numberConverter->toHex($integer);\n        $hex = str_pad($hex, 32, '0', STR_PAD_LEFT);\n\n        return $this->fromString($hex);\n    }\n\n    public function fromDateTime(\n        DateTimeInterface $dateTime,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null,\n    ): UuidInterface {\n        $timeProvider = new FixedTimeProvider(new Time($dateTime->format('U'), $dateTime->format('u')));\n        $timeGenerator = new DefaultTimeGenerator($this->nodeProvider, $this->timeConverter, $timeProvider);\n        $bytes = $timeGenerator->generate($node?->toString(), $clockSeq);\n\n        return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME);\n    }\n\n    /**\n     * @pure\n     */\n    public function fromHexadecimal(Hexadecimal $hex): UuidInterface\n    {\n        return $this->codec->decode($hex->__toString());\n    }\n\n    /**\n     * @inheritDoc\n     */\n    public function uuid1($node = null, ?int $clockSeq = null): UuidInterface\n    {\n        $bytes = $this->timeGenerator->generate($node, $clockSeq);\n\n        return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME);\n    }\n\n    public function uuid2(\n        int $localDomain,\n        ?IntegerObject $localIdentifier = null,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null,\n    ): UuidInterface {\n        $bytes = $this->dceSecurityGenerator->generate($localDomain, $localIdentifier, $node, $clockSeq);\n\n        return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_DCE_SECURITY);\n    }\n\n    /**\n     * @inheritDoc\n     * @pure\n     */\n    public function uuid3($ns, string $name): UuidInterface\n    {\n        return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_MD5, 'md5');\n    }\n\n    public function uuid4(): UuidInterface\n    {\n        $bytes = $this->randomGenerator->generate(16);\n\n        return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_RANDOM);\n    }\n\n    /**\n     * @inheritDoc\n     * @pure\n     */\n    public function uuid5($ns, string $name): UuidInterface\n    {\n        return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_SHA1, 'sha1');\n    }\n\n    public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface\n    {\n        $bytes = $this->timeGenerator->generate($node?->toString(), $clockSeq);\n\n        // Rearrange the bytes, according to the UUID version 6 specification.\n        $v6 = $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5]\n            . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3];\n        $v6 = bin2hex($v6);\n\n        // Drop the first four bits, while adding an empty four bits for the version field. This allows us to\n        // reconstruct the correct time from the bytes of this UUID.\n        $v6Bytes = hex2bin(substr($v6, 1, 12) . '0' . substr($v6, -3));\n        $v6Bytes .= substr($bytes, 8);\n\n        return $this->uuidFromBytesAndVersion($v6Bytes, Uuid::UUID_TYPE_REORDERED_TIME);\n    }\n\n    /**\n     * Returns a version 7 (Unix Epoch time) UUID\n     *\n     * @param DateTimeInterface | null $dateTime An optional date/time from which to create the version 7 UUID. If not\n     *     provided, the UUID is generated using the current date/time.\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 7 UUID\n     */\n    public function uuid7(?DateTimeInterface $dateTime = null): UuidInterface\n    {\n        assert($this->unixTimeGenerator instanceof UnixTimeGenerator);\n        $bytes = $this->unixTimeGenerator->generate(null, null, $dateTime);\n\n        return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_UNIX_TIME);\n    }\n\n    /**\n     * Returns a version 8 (custom format) UUID\n     *\n     * The bytes provided may contain any value according to your application's needs. Be aware, however, that other\n     * applications may not understand the semantics of the value.\n     *\n     * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of\n     *     information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64\n     *     and 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs.\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 8 UUID\n     *\n     * @pure\n     */\n    public function uuid8(string $bytes): UuidInterface\n    {\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_CUSTOM);\n    }\n\n    /**\n     * Returns a Uuid created from the provided byte string\n     *\n     * Uses the configured builder and codec and the provided byte string to construct a Uuid object.\n     *\n     * @param string $bytes The byte string from which to construct a UUID\n     *\n     * @return UuidInterface An instance of UuidInterface, created from the provided bytes\n     *\n     * @pure\n     */\n    public function uuid(string $bytes): UuidInterface\n    {\n        return $this->uuidBuilder->build($this->codec, $bytes);\n    }\n\n    /**\n     * Returns a version 3 or 5 namespaced Uuid\n     *\n     * @param UuidInterface | string $ns The namespace (must be a valid UUID)\n     * @param string $name The name to hash together with the namespace\n     * @param int $version The version of UUID to create (3 or 5)\n     * @param string $hashAlgorithm The hashing algorithm to use when hashing together the namespace and name\n     *\n     * @return UuidInterface An instance of UuidInterface, created by hashing together the provided namespace and name\n     *\n     * @pure\n     */\n    private function uuidFromNsAndName(\n        UuidInterface | string $ns,\n        string $name,\n        int $version,\n        string $hashAlgorithm,\n    ): UuidInterface {\n        if (!($ns instanceof UuidInterface)) {\n            $ns = $this->fromString($ns);\n        }\n\n        $bytes = $this->nameGenerator->generate($ns, $name, $hashAlgorithm);\n\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        return $this->uuidFromBytesAndVersion(substr($bytes, 0, 16), $version);\n    }\n\n    /**\n     * Returns a Uuid created from the provided bytes and version\n     *\n     * @param string $bytes The byte string to convert to a UUID\n     * @param int $version The version to apply to the UUID\n     *\n     * @return UuidInterface An instance of UuidInterface, created from the byte string and version\n     */\n    private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInterface\n    {\n        /** @var int[] $unpackedTime */\n        $unpackedTime = unpack('n*', substr($bytes, 6, 2));\n        $timeHi = $unpackedTime[1];\n        $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version));\n\n        /** @var int[] $unpackedClockSeq */\n        $unpackedClockSeq = unpack('n*', substr($bytes, 8, 2));\n        $clockSeqHi = $unpackedClockSeq[1];\n        $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi));\n\n        $bytes = substr_replace($bytes, $timeHiAndVersion, 6, 2);\n        $bytes = substr_replace($bytes, $clockSeqHiAndReserved, 8, 2);\n\n        if ($this->isDefaultFeatureSet) {\n            return LazyUuidFromString::fromBytes($bytes);\n        }\n\n        return $this->uuid($bytes);\n    }\n}\n"
  },
  {
    "path": "src/UuidFactoryInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Validator\\ValidatorInterface;\n\n/**\n * UuidFactoryInterface defines the common functionality all `UuidFactory` instances must implement\n */\ninterface UuidFactoryInterface\n{\n    /**\n     * Creates a UUID from a byte string\n     *\n     * @param string $bytes A binary string\n     *\n     * @return UuidInterface A UuidInterface instance created from a binary string representation\n     *\n     * @pure\n     */\n    public function fromBytes(string $bytes): UuidInterface;\n\n    /**\n     * Creates a UUID from a DateTimeInterface instance\n     *\n     * @param DateTimeInterface $dateTime The date and time\n     * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 1 UUID created from a DateTimeInterface instance\n     */\n    public function fromDateTime(\n        DateTimeInterface $dateTime,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null,\n    ): UuidInterface;\n\n    /**\n     * Creates a UUID from a 128-bit integer string\n     *\n     * @param string $integer String representation of 128-bit integer\n     *\n     * @return UuidInterface A UuidInterface instance created from the string representation of a 128-bit integer\n     *\n     * @pure\n     */\n    public function fromInteger(string $integer): UuidInterface;\n\n    /**\n     * Creates a UUID from the string standard representation\n     *\n     * @param string $uuid A hexadecimal string\n     *\n     * @return UuidInterface A UuidInterface instance created from a hexadecimal string representation\n     *\n     * @pure\n     */\n    public function fromString(string $uuid): UuidInterface;\n\n    /**\n     * Returns the validator used by the factory\n     */\n    public function getValidator(): ValidatorInterface;\n\n    /**\n     * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time\n     *\n     * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may\n     *     be represented as an integer or a hexadecimal string\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 1 UUID\n     */\n    public function uuid1($node = null, ?int $clockSeq = null): UuidInterface;\n\n    /**\n     * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the\n     * current time\n     *\n     * @param int $localDomain The local domain to use when generating bytes, according to DCE Security\n     * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID\n     *     on POSIX systems, if the local domain is a person or group, or it may be a site-defined identifier if the\n     *     local domain is org\n     * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 2 UUID\n     */\n    public function uuid2(\n        int $localDomain,\n        ?IntegerObject $localIdentifier = null,\n        ?Hexadecimal $node = null,\n        ?int $clockSeq = null,\n    ): UuidInterface;\n\n    /**\n     * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name\n     *\n     * @param UuidInterface | string $ns The namespace (must be a valid UUID)\n     * @param string $name The name to use for creating a UUID\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 3 UUID\n     *\n     * @pure\n     */\n    public function uuid3($ns, string $name): UuidInterface;\n\n    /**\n     * Returns a version 4 (random) UUID\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 4 UUID\n     */\n    public function uuid4(): UuidInterface;\n\n    /**\n     * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name\n     *\n     * @param UuidInterface | string $ns The namespace (must be a valid UUID)\n     * @param string $name The name to use for creating a UUID\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 5 UUID\n     *\n     * @pure\n     */\n    public function uuid5($ns, string $name): UuidInterface;\n\n    /**\n     * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time\n     *\n     * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n     * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n     *     backwards in time or if the node ID changes\n     *\n     * @return UuidInterface A UuidInterface instance that represents a version 6 UUID\n     */\n    public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface;\n}\n"
  },
  {
    "path": "src/UuidInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse JsonSerializable;\nuse Ramsey\\Uuid\\Fields\\FieldsInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Serializable;\nuse Stringable;\n\n/**\n * A UUID is a universally unique identifier adhering to an agreed-upon representation format and standard for generation\n *\n * @immutable\n */\ninterface UuidInterface extends\n    DeprecatedUuidInterface,\n    JsonSerializable,\n    Serializable,\n    Stringable\n{\n    /**\n     * Returns -1, 0, or 1 if the UUID is less than, equal to, or greater than the other UUID\n     *\n     * The first of two UUIDs is greater than the second if the most significant field in which the UUIDs differ is\n     * greater for the first UUID.\n     *\n     * @param UuidInterface $other The UUID to compare\n     *\n     * @return int<-1,1> -1, 0, or 1 if the UUID is less than, equal to, or greater than $other\n     */\n    public function compareTo(UuidInterface $other): int;\n\n    /**\n     * Returns true if the UUID is equal to the provided object\n     *\n     * The result is true if and only if the argument is not null, is a UUID object, has the same variant, and contains\n     * the same value, bit-for-bit, as the UUID.\n     *\n     * @param object | null $other An object to test for equality with this UUID\n     *\n     * @return bool True if the other object is equal to this UUID\n     */\n    public function equals(?object $other): bool;\n\n    /**\n     * Returns the binary string representation of the UUID\n     *\n     * @return non-empty-string\n     *\n     * @pure\n     */\n    public function getBytes(): string;\n\n    /**\n     * Returns the fields that comprise this UUID\n     */\n    public function getFields(): FieldsInterface;\n\n    /**\n     * Returns the hexadecimal representation of the UUID\n     */\n    public function getHex(): Hexadecimal;\n\n    /**\n     * Returns the integer representation of the UUID\n     */\n    public function getInteger(): IntegerObject;\n\n    /**\n     * Returns the string standard representation of the UUID as a URN\n     *\n     * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name\n     * @link https://www.rfc-editor.org/rfc/rfc9562.html#section-4 RFC 9562, 4. UUID Format\n     * @link https://www.rfc-editor.org/rfc/rfc9562.html#section-7 RFC 9562, 7. IANA Considerations\n     * @link https://www.rfc-editor.org/rfc/rfc4122.html#section-3 RFC 4122, 3. Namespace Registration Template\n     */\n    public function getUrn(): string;\n\n    /**\n     * Returns the string standard representation of the UUID\n     *\n     * @return non-empty-string\n     *\n     * @pure\n     */\n    public function toString(): string;\n\n    /**\n     * Casts the UUID to the string standard representation\n     *\n     * @return non-empty-string\n     *\n     * @pure\n     */\n    public function __toString(): string;\n}\n"
  },
  {
    "path": "src/Validator/GenericValidator.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Validator;\n\nuse Ramsey\\Uuid\\Uuid;\n\nuse function preg_match;\nuse function str_replace;\n\n/**\n * GenericValidator validates strings as UUIDs of any variant\n *\n * @immutable\n */\nfinal class GenericValidator implements ValidatorInterface\n{\n    /**\n     * Regular expression pattern for matching a UUID of any variant.\n     */\n    private const VALID_PATTERN = '\\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\z';\n\n    /**\n     * @return non-empty-string\n     */\n    public function getPattern(): string\n    {\n        return self::VALID_PATTERN;\n    }\n\n    public function validate(string $uuid): bool\n    {\n        /** @phpstan-ignore possiblyImpure.functionCall */\n        $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid);\n\n        /** @phpstan-ignore possiblyImpure.functionCall */\n        return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid);\n    }\n}\n"
  },
  {
    "path": "src/Validator/ValidatorInterface.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Validator;\n\n/**\n * A validator validates a string as a proper UUID\n *\n * @immutable\n */\ninterface ValidatorInterface\n{\n    /**\n     * Returns the regular expression pattern used by this validator\n     *\n     * @return non-empty-string The regular expression pattern this validator uses\n     */\n    public function getPattern(): string;\n\n    /**\n     * Returns true if the provided string represents a UUID\n     *\n     * @param string $uuid The string to validate as a UUID\n     *\n     * @return bool True if the string is a valid UUID, false otherwise\n     *\n     * @pure\n     */\n    public function validate(string $uuid): bool;\n}\n"
  },
  {
    "path": "src/functions.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n * phpcs:disable Squiz.Functions.GlobalFunction\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid;\n\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n\n/**\n * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time\n *\n * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may be\n *     represented as an integer or a hexadecimal string\n * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n *     backwards in time or if the node ID changes\n *\n * @return non-empty-string Version 1 UUID as a string\n */\nfunction v1($node = null, ?int $clockSeq = null): string\n{\n    return Uuid::uuid1($node, $clockSeq)->toString();\n}\n\n/**\n * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the current time\n *\n * @param int $localDomain The local domain to use when generating bytes, according to DCE Security\n * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID on\n *     POSIX systems, if the local domain is a person or group, or it may be a site-defined identifier if the local\n *     domain is org\n * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n *     backwards in time or if the node ID changes\n *\n * @return non-empty-string Version 2 UUID as a string\n */\nfunction v2(\n    int $localDomain,\n    ?IntegerObject $localIdentifier = null,\n    ?Hexadecimal $node = null,\n    ?int $clockSeq = null,\n): string {\n    return Uuid::uuid2($localDomain, $localIdentifier, $node, $clockSeq)->toString();\n}\n\n/**\n * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name\n *\n * @param UuidInterface | string $ns The namespace (must be a valid UUID)\n *\n * @return non-empty-string Version 3 UUID as a string\n *\n * @pure\n */\nfunction v3($ns, string $name): string\n{\n    return Uuid::uuid3($ns, $name)->toString();\n}\n\n/**\n * Returns a version 4 (random) UUID\n *\n * @return non-empty-string Version 4 UUID as a string\n */\nfunction v4(): string\n{\n    return Uuid::uuid4()->toString();\n}\n\n/**\n * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name\n *\n * @param UuidInterface | string $ns The namespace (must be a valid UUID)\n *\n * @return non-empty-string Version 5 UUID as a string\n *\n * @pure\n */\nfunction v5($ns, string $name): string\n{\n    return Uuid::uuid5($ns, $name)->toString();\n}\n\n/**\n * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time\n *\n * @param Hexadecimal | null $node A 48-bit number representing the hardware address\n * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set\n *     backwards in time or if the node ID changes\n *\n * @return non-empty-string Version 6 UUID as a string\n */\nfunction v6(?Hexadecimal $node = null, ?int $clockSeq = null): string\n{\n    return Uuid::uuid6($node, $clockSeq)->toString();\n}\n\n/**\n * Returns a version 7 (Unix Epoch time) UUID\n *\n * @param DateTimeInterface|null $dateTime An optional date/time from which to create the version 7 UUID. If not\n *     provided, the UUID is generated using the current date/time.\n *\n * @return non-empty-string Version 7 UUID as a string\n */\nfunction v7(?DateTimeInterface $dateTime = null): string\n{\n    return Uuid::uuid7($dateTime)->toString();\n}\n\n/**\n * Returns a version 8 (custom format) UUID\n *\n * The bytes provided may contain any value according to your application's needs. Be aware, however, that other\n * applications may not understand the semantics of the value.\n *\n * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of\n *     information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64 and\n *     65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs.\n *\n * @return non-empty-string Version 8 UUID as a string\n *\n * @pure\n */\nfunction v8(string $bytes): string\n{\n    return Uuid::uuid8($bytes)->toString();\n}\n"
  },
  {
    "path": "tests/BinaryUtilsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse Ramsey\\Uuid\\BinaryUtils;\n\nuse function dechex;\n\nclass BinaryUtilsTest extends TestCase\n{\n    /**\n     * @dataProvider provideVersionTestValues\n     */\n    public function testApplyVersion(int $timeHi, int $version, int $expectedInt, string $expectedHex): void\n    {\n        $this->assertSame($expectedInt, BinaryUtils::applyVersion($timeHi, $version));\n        $this->assertSame($expectedHex, dechex(BinaryUtils::applyVersion($timeHi, $version)));\n    }\n\n    /**\n     * @dataProvider provideVariantTestValues\n     */\n    public function testApplyVariant(int $clockSeq, int $expectedInt, string $expectedHex): void\n    {\n        $this->assertSame($expectedInt, BinaryUtils::applyVariant($clockSeq));\n        $this->assertSame($expectedHex, dechex(BinaryUtils::applyVariant($clockSeq)));\n    }\n\n    /**\n     * @return array<array{timeHi: int, version: int, expectedInt: int, expectedHex: non-empty-string}>\n     */\n    public function provideVersionTestValues(): array\n    {\n        return [\n            [\n                'timeHi' => 1001,\n                'version' => 1,\n                'expectedInt' => 5097,\n                'expectedHex' => '13e9',\n            ],\n            [\n                'timeHi' => 1001,\n                'version' => 2,\n                'expectedInt' => 9193,\n                'expectedHex' => '23e9',\n            ],\n            [\n                'timeHi' => 1001,\n                'version' => 3,\n                'expectedInt' => 13289,\n                'expectedHex' => '33e9',\n            ],\n            [\n                'timeHi' => 1001,\n                'version' => 4,\n                'expectedInt' => 17385,\n                'expectedHex' => '43e9',\n            ],\n            [\n                'timeHi' => 1001,\n                'version' => 5,\n                'expectedInt' => 21481,\n                'expectedHex' => '53e9',\n            ],\n            [\n                'timeHi' => 65535,\n                'version' => 1,\n                'expectedInt' => 8191,\n                'expectedHex' => '1fff',\n            ],\n            [\n                'timeHi' => 65535,\n                'version' => 2,\n                'expectedInt' => 12287,\n                'expectedHex' => '2fff',\n            ],\n            [\n                'timeHi' => 65535,\n                'version' => 3,\n                'expectedInt' => 16383,\n                'expectedHex' => '3fff',\n            ],\n            [\n                'timeHi' => 65535,\n                'version' => 4,\n                'expectedInt' => 20479,\n                'expectedHex' => '4fff',\n            ],\n            [\n                'timeHi' => 65535,\n                'version' => 5,\n                'expectedInt' => 24575,\n                'expectedHex' => '5fff',\n            ],\n            [\n                'timeHi' => 0,\n                'version' => 1,\n                'expectedInt' => 4096,\n                'expectedHex' => '1000',\n            ],\n            [\n                'timeHi' => 0,\n                'version' => 2,\n                'expectedInt' => 8192,\n                'expectedHex' => '2000',\n            ],\n            [\n                'timeHi' => 0,\n                'version' => 3,\n                'expectedInt' => 12288,\n                'expectedHex' => '3000',\n            ],\n            [\n                'timeHi' => 0,\n                'version' => 4,\n                'expectedInt' => 16384,\n                'expectedHex' => '4000',\n            ],\n            [\n                'timeHi' => 0,\n                'version' => 5,\n                'expectedInt' => 20480,\n                'expectedHex' => '5000',\n            ],\n        ];\n    }\n\n    /**\n     * @return array<array{clockSeq: int, expectedInt: int, expectedHex: non-empty-string}>\n     */\n    public function provideVariantTestValues(): array\n    {\n        return [\n            [\n                'clockSeq' => 0,\n                'expectedInt' => 32768,\n                'expectedHex' => '8000',\n            ],\n            [\n                'clockSeq' => 4096,\n                'expectedInt' => 36864,\n                'expectedHex' => '9000',\n            ],\n            [\n                'clockSeq' => 8192,\n                'expectedInt' => 40960,\n                'expectedHex' => 'a000',\n            ],\n            [\n                'clockSeq' => 12288,\n                'expectedInt' => 45056,\n                'expectedHex' => 'b000',\n            ],\n            [\n                'clockSeq' => 4095,\n                'expectedInt' => 36863,\n                'expectedHex' => '8fff',\n            ],\n            [\n                'clockSeq' => 8191,\n                'expectedInt' => 40959,\n                'expectedHex' => '9fff',\n            ],\n            [\n                'clockSeq' => 12287,\n                'expectedInt' => 45055,\n                'expectedHex' => 'afff',\n            ],\n            [\n                'clockSeq' => 16383,\n                'expectedInt' => 49151,\n                'expectedHex' => 'bfff',\n            ],\n            [\n                'clockSeq' => 16384,\n                'expectedInt' => 32768,\n                'expectedHex' => '8000',\n            ],\n            [\n                'clockSeq' => 20480,\n                'expectedInt' => 36864,\n                'expectedHex' => '9000',\n            ],\n            [\n                'clockSeq' => 24576,\n                'expectedInt' => 40960,\n                'expectedHex' => 'a000',\n            ],\n            [\n                'clockSeq' => 28672,\n                'expectedInt' => 45056,\n                'expectedHex' => 'b000',\n            ],\n            [\n                'clockSeq' => 32768,\n                'expectedInt' => 32768,\n                'expectedHex' => '8000',\n            ],\n            [\n                'clockSeq' => 36864,\n                'expectedInt' => 36864,\n                'expectedHex' => '9000',\n            ],\n            [\n                'clockSeq' => 40960,\n                'expectedInt' => 40960,\n                'expectedHex' => 'a000',\n            ],\n            [\n                'clockSeq' => 45056,\n                'expectedInt' => 45056,\n                'expectedHex' => 'b000',\n            ],\n            [\n                'clockSeq' => 36863,\n                'expectedInt' => 36863,\n                'expectedHex' => '8fff',\n            ],\n            [\n                'clockSeq' => 40959,\n                'expectedInt' => 40959,\n                'expectedHex' => '9fff',\n            ],\n            [\n                'clockSeq' => 45055,\n                'expectedInt' => 45055,\n                'expectedHex' => 'afff',\n            ],\n            [\n                'clockSeq' => 49151,\n                'expectedInt' => 49151,\n                'expectedHex' => 'bfff',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Builder/DefaultUuidBuilderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Builder;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Builder\\DefaultUuidBuilder;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function hex2bin;\nuse function implode;\n\nclass DefaultUuidBuilderTest extends TestCase\n{\n    public function testBuildCreatesUuid(): void\n    {\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $builder = new DefaultUuidBuilder($numberConverter, $timeConverter);\n\n        $fields = [\n            'time_low' => '754cd475',\n            'time_mid' => '7e58',\n            'time_hi_and_version' => '4411',\n            'clock_seq_hi_and_reserved' => '93',\n            'clock_seq_low' => '22',\n            'node' => 'be0725c8ce01',\n        ];\n\n        $bytes = (string) hex2bin(implode('', $fields));\n\n        $result = $builder->build($codec, $bytes);\n        $this->assertInstanceOf(Uuid::class, $result);\n    }\n}\n"
  },
  {
    "path": "tests/Builder/FallbackBuilderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Builder;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Builder\\FallbackBuilder;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Codec\\StringCodec;\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\PhpTimeConverter;\nuse Ramsey\\Uuid\\Exception\\BuilderNotFoundException;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\Guid\\GuidBuilder;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Nonstandard\\UuidBuilder as NonstandardUuidBuilder;\nuse Ramsey\\Uuid\\Rfc4122\\UuidBuilder as Rfc4122UuidBuilder;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV1;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV2;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV6;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass FallbackBuilderTest extends TestCase\n{\n    public function testBuildThrowsExceptionAfterAllConfiguredBuildersHaveErrored(): void\n    {\n        $codec = Mockery::mock(CodecInterface::class);\n        $bytes = 'foobar';\n\n        $builder1 = Mockery::mock(UuidBuilderInterface::class);\n        $builder1\n            ->shouldReceive('build')\n            ->once()\n            ->with($codec, $bytes)\n            ->andThrow(UnableToBuildUuidException::class);\n\n        $builder2 = Mockery::mock(UuidBuilderInterface::class);\n        $builder2\n            ->shouldReceive('build')\n            ->once()\n            ->with($codec, $bytes)\n            ->andThrow(UnableToBuildUuidException::class);\n\n        $builder3 = Mockery::mock(UuidBuilderInterface::class);\n        $builder3\n            ->shouldReceive('build')\n            ->once()\n            ->with($codec, $bytes)\n            ->andThrow(UnableToBuildUuidException::class);\n\n        $fallbackBuilder = new FallbackBuilder([$builder1, $builder2, $builder3]);\n\n        $this->expectException(BuilderNotFoundException::class);\n        $this->expectExceptionMessage(\n            'Could not find a suitable builder for the provided codec and fields'\n        );\n\n        $fallbackBuilder->build($codec, $bytes);\n    }\n\n    /**\n     * @dataProvider provideBytes\n     */\n    public function testSerializationOfBuilderCollection(string $bytes): void\n    {\n        $calculator = new BrickMathCalculator();\n        $genericNumberConverter = new GenericNumberConverter($calculator);\n        $genericTimeConverter = new GenericTimeConverter($calculator);\n        $phpTimeConverter = new PhpTimeConverter($calculator, $genericTimeConverter);\n\n        // Use the GenericTimeConverter.\n        $guidBuilder = new GuidBuilder($genericNumberConverter, $genericTimeConverter);\n        $rfc4122Builder = new Rfc4122UuidBuilder($genericNumberConverter, $genericTimeConverter);\n        $nonstandardBuilder = new NonstandardUuidBuilder($genericNumberConverter, $genericTimeConverter);\n\n        // Use the PhpTimeConverter.\n        $guidBuilder2 = new GuidBuilder($genericNumberConverter, $phpTimeConverter);\n        $rfc4122Builder2 = new Rfc4122UuidBuilder($genericNumberConverter, $phpTimeConverter);\n        $nonstandardBuilder2 = new NonstandardUuidBuilder($genericNumberConverter, $phpTimeConverter);\n\n        /** @var list<UuidBuilderInterface> $unserializedBuilderCollection */\n        $unserializedBuilderCollection = unserialize(serialize([\n            $guidBuilder,\n            $guidBuilder2,\n            $rfc4122Builder,\n            $rfc4122Builder2,\n            $nonstandardBuilder,\n            $nonstandardBuilder2,\n        ]));\n\n        foreach ($unserializedBuilderCollection as $builder) {\n            $codec = new StringCodec($builder);\n\n            $this->assertInstanceOf(UuidBuilderInterface::class, $builder);\n\n            try {\n                $uuid = $builder->build($codec, $bytes);\n\n                if (($uuid instanceof UuidV1) || ($uuid instanceof UuidV2) || ($uuid instanceof UuidV6)) {\n                    $this->assertNotEmpty($uuid->getDateTime()->format('r'));\n                }\n            } catch (UnableToBuildUuidException $exception) {\n                switch ($exception->getMessage()) {\n                    case 'The byte string received does not contain a valid version':\n                    case 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant':\n                    case 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) '\n                        . 'or Microsoft Corporation variants':\n                        // This is expected; ignoring.\n                        break;\n                    default:\n                        throw $exception;\n                }\n            }\n        }\n    }\n\n    /**\n     * @return array<array{bytes: string}>\n     */\n    public function provideBytes(): array\n    {\n        return [\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1110b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1111b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1112b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1113b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1114b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1115b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1116b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e1117b210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e111eb210800200c9a66'),\n            ],\n            [\n                // GUID bytes\n                'bytes' => (string) hex2bin('b08c6fff7dc5e111fb210800200c9a66'),\n            ],\n            [\n                // Version 1 bytes\n                'bytes' => (string) hex2bin('ff6f8cb0c57d11e19b210800200c9a66'),\n            ],\n            [\n                // Version 2 bytes\n                'bytes' => (string) hex2bin('000001f55cde21ea84000242ac130003'),\n            ],\n            [\n                // Version 3 bytes\n                'bytes' => (string) hex2bin('ff6f8cb0c57d31e1bb210800200c9a66'),\n            ],\n            [\n                // Version 4 bytes\n                'bytes' => (string) hex2bin('ff6f8cb0c57d41e1ab210800200c9a66'),\n            ],\n            [\n                // Version 5 bytes\n                'bytes' => (string) hex2bin('ff6f8cb0c57d51e18b210800200c9a66'),\n            ],\n            [\n                // Version 6 bytes\n                'bytes' => (string) hex2bin('ff6f8cb0c57d61e18b210800200c9a66'),\n            ],\n            [\n                // NIL bytes\n                'bytes' => (string) hex2bin('00000000000000000000000000000000'),\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Codec/GuidStringCodecTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Codec;\n\nuse Mockery;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\GuidStringCodec;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Guid\\Fields;\nuse Ramsey\\Uuid\\Guid\\Guid;\nuse Ramsey\\Uuid\\Guid\\GuidBuilder;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function hex2bin;\nuse function pack;\n\nclass GuidStringCodecTest extends TestCase\n{\n    /**\n     * @var UuidBuilderInterface & MockObject\n     */\n    private $builder;\n\n    /**\n     * @var UuidInterface & MockObject\n     */\n    private $uuid;\n\n    /**\n     * @var Fields\n     */\n    private $fields;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->builder = $this->getMockBuilder(UuidBuilderInterface::class)->getMock();\n        $this->uuid = $this->getMockBuilder(UuidInterface::class)->getMock();\n        $this->fields = new Fields((string) hex2bin('785634123412cd4babef1234abcd4321'));\n    }\n\n    protected function tearDown(): void\n    {\n        parent::tearDown();\n        unset($this->builder, $this->fields, $this->uuid);\n    }\n\n    public function testEncodeUsesFieldsArray(): void\n    {\n        $this->uuid->expects($this->once())\n            ->method('getFields')\n            ->willReturn($this->fields);\n        $codec = new GuidStringCodec($this->builder);\n        $codec->encode($this->uuid);\n    }\n\n    public function testEncodeReturnsFormattedString(): void\n    {\n        $this->uuid->method('getFields')\n            ->willReturn($this->fields);\n        $codec = new GuidStringCodec($this->builder);\n        $result = $codec->encode($this->uuid);\n        $this->assertSame('12345678-1234-4bcd-abef-1234abcd4321', $result);\n    }\n\n    public function testEncodeBinary(): void\n    {\n        $expectedBytes = (string) hex2bin('785634123412cd4babef1234abcd4321');\n\n        $fields = new Fields($expectedBytes);\n        $codec = new GuidStringCodec($this->builder);\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $uuid = new Guid($fields, $numberConverter, $codec, $timeConverter);\n\n        $bytes = $codec->encodeBinary($uuid);\n\n        $this->assertSame($expectedBytes, $bytes);\n    }\n\n    public function testDecodeReturnsGuid(): void\n    {\n        $string = 'uuid:12345678-1234-4bcd-abef-1234abcd4321';\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $builder = new GuidBuilder($numberConverter, $timeConverter);\n        $codec = new GuidStringCodec($builder);\n        $guid = $codec->decode($string);\n\n        $this->assertInstanceOf(Guid::class, $guid);\n        $this->assertSame('12345678-1234-4bcd-abef-1234abcd4321', $guid->toString());\n    }\n\n    public function testDecodeReturnsUuidFromBuilder(): void\n    {\n        $string = 'uuid:78563412-3412-cd4b-abef-1234abcd4321';\n        $this->builder->method('build')\n            ->willReturn($this->uuid);\n\n        $codec = new GuidStringCodec($this->builder);\n        $result = $codec->decode($string);\n        $this->assertSame($this->uuid, $result);\n    }\n\n    public function testDecodeBytesReturnsUuid(): void\n    {\n        $string = '1234567812344bcd4bef1234abcd4321';\n        $bytes = pack('H*', $string);\n        $codec = new GuidStringCodec($this->builder);\n        $this->builder->method('build')\n            ->willReturn($this->uuid);\n        $result = $codec->decodeBytes($bytes);\n        $this->assertSame($this->uuid, $result);\n    }\n}\n"
  },
  {
    "path": "tests/Codec/OrderedTimeCodecTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Codec;\n\nuse Mockery;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Builder\\DefaultUuidBuilder;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\OrderedTimeCodec;\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Nonstandard\\Fields as NonstandardFields;\nuse Ramsey\\Uuid\\Nonstandard\\UuidBuilder;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidFactory;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function hex2bin;\nuse function pack;\nuse function serialize;\nuse function str_replace;\nuse function unserialize;\n\nclass OrderedTimeCodecTest extends TestCase\n{\n    /**\n     * @var UuidBuilderInterface & MockObject\n     */\n    private $builder;\n\n    /**\n     * @var UuidInterface & MockObject\n     */\n    private $uuid;\n\n    /**\n     * @var Fields\n     */\n    private $fields;\n\n    /**\n     * @var string\n     */\n    private $uuidString = '58e0a7d7-eebc-11d8-9669-0800200c9a66';\n\n    /**\n     * @var string\n     */\n    private $optimizedHex = '11d8eebc58e0a7d796690800200c9a66';\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->builder = $this->getMockBuilder(UuidBuilderInterface::class)->getMock();\n        $this->uuid = $this->getMockBuilder(UuidInterface::class)->getMock();\n        $this->fields = new Fields((string) hex2bin('58e0a7d7eebc11d896690800200c9a66'));\n    }\n\n    protected function tearDown(): void\n    {\n        parent::tearDown();\n        unset($this->builder, $this->uuid, $this->fields);\n    }\n\n    public function testEncodeUsesFieldsArray(): void\n    {\n        $this->uuid->expects($this->once())\n            ->method('getFields')\n            ->willReturn($this->fields);\n        $codec = new OrderedTimeCodec($this->builder);\n        $codec->encode($this->uuid);\n    }\n\n    public function testEncodeReturnsFormattedString(): void\n    {\n        $this->uuid->method('getFields')\n            ->willReturn($this->fields);\n        $codec = new OrderedTimeCodec($this->builder);\n        $result = $codec->encode($this->uuid);\n        $this->assertSame($this->uuidString, $result);\n    }\n\n    public function testEncodeBinary(): void\n    {\n        $expected = hex2bin($this->optimizedHex);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $builder = new DefaultUuidBuilder($numberConverter, $timeConverter);\n        $codec = new OrderedTimeCodec($builder);\n\n        $factory = new UuidFactory();\n        $factory->setCodec($codec);\n\n        $uuid = $factory->fromString($this->uuidString);\n\n        $this->assertSame($expected, $codec->encodeBinary($uuid));\n    }\n\n    public function testDecodeBytesThrowsExceptionWhenBytesStringNotSixteenCharacters(): void\n    {\n        $string = '61';\n        $bytes = pack('H*', $string);\n        $codec = new OrderedTimeCodec($this->builder);\n\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('$bytes string should contain 16 characters.');\n        $codec->decodeBytes($bytes);\n    }\n\n    public function testDecodeReturnsUuidFromBuilder(): void\n    {\n        $string = 'uuid:58e0a7d7-eebc-11d8-9669-0800200c9a66';\n        $this->builder->method('build')\n            ->willReturn($this->uuid);\n        $codec = new OrderedTimeCodec($this->builder);\n        $result = $codec->decode($string);\n        $this->assertSame($this->uuid, $result);\n    }\n\n    public function testDecodeBytesRearrangesFields(): void\n    {\n        $bytes = (string) hex2bin($this->optimizedHex);\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $builder = new DefaultUuidBuilder($numberConverter, $timeConverter);\n        $codec = new OrderedTimeCodec($builder);\n\n        $factory = new UuidFactory();\n        $factory->setCodec($codec);\n\n        $expectedUuid = $factory->fromString($this->uuidString);\n        $uuidReturned = $codec->decodeBytes($bytes);\n\n        $this->assertTrue($uuidReturned->equals($expectedUuid));\n    }\n\n    public function testEncodeBinaryThrowsExceptionForNonRfc4122Uuid(): void\n    {\n        $nonRfc4122Uuid = '58e0a7d7-eebc-11d8-d669-0800200c9a66';\n\n        $fields = new NonstandardFields((string) hex2bin(str_replace('-', '', $nonRfc4122Uuid)));\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $builder = new DefaultUuidBuilder($numberConverter, $timeConverter);\n        $codec = new OrderedTimeCodec($builder);\n\n        $uuid = Mockery::mock(UuidInterface::class, [\n            'getVariant' => 0,\n            'toString' => $nonRfc4122Uuid,\n            'getFields' => $fields,\n        ]);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Expected version 1 (time-based) UUID');\n\n        $codec->encodeBinary($uuid);\n    }\n\n    public function testEncodeBinaryThrowsExceptionForNonTimeBasedUuid(): void\n    {\n        $nonTimeBasedUuid = '58e0a7d7-eebc-41d8-9669-0800200c9a66';\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $builder = new DefaultUuidBuilder($numberConverter, $timeConverter);\n        $codec = new OrderedTimeCodec($builder);\n\n        $factory = new UuidFactory();\n        $factory->setCodec($codec);\n\n        $uuid = $factory->fromString($nonTimeBasedUuid);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Expected version 1 (time-based) UUID');\n\n        $codec->encodeBinary($uuid);\n    }\n\n    public function testDecodeBytesThrowsExceptionsForNonRfc4122Uuid(): void\n    {\n        $nonRfc4122OptimizedHex = '11d8eebc58e0a7d716690800200c9a66';\n        $bytes = (string) hex2bin($nonRfc4122OptimizedHex);\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n        $timeConverter = new GenericTimeConverter($calculator);\n        $builder = new UuidBuilder($numberConverter, $timeConverter);\n\n        $codec = new OrderedTimeCodec($builder);\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage(\n            'Attempting to decode a non-time-based UUID using OrderedTimeCodec'\n        );\n\n        $codec->decodeBytes($bytes);\n    }\n\n    public function testDecodeBytesThrowsExceptionsForNonTimeBasedUuid(): void\n    {\n        $nonTimeBasedOptimizedHex = '41d8eebc58e0a7d796690800200c9a66';\n        $bytes = (string) hex2bin($nonTimeBasedOptimizedHex);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $builder = new DefaultUuidBuilder($numberConverter, $timeConverter);\n        $codec = new OrderedTimeCodec($builder);\n\n        $factory = new UuidFactory();\n        $factory->setCodec($codec);\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage(\n            'Attempting to decode a non-time-based UUID using OrderedTimeCodec'\n        );\n\n        $codec->decodeBytes($bytes);\n    }\n\n    public function testSerializationDoesNotUseOrderedTimeCodec(): void\n    {\n        $expected = '9ec692cc-67c8-11eb-ae93-0242ac130002';\n\n        $codec = new OrderedTimeCodec(\n            (new UuidFactory())->getUuidBuilder()\n        );\n        $decoded = $codec->decode($expected);\n        $serialized = serialize($decoded);\n\n        /** @var UuidInterface $unserializedUuid */\n        $unserializedUuid = unserialize($serialized);\n\n        $expectedUuid = Uuid::fromString($expected);\n        $this->assertSame($expectedUuid->getVersion(), $unserializedUuid->getVersion());\n        $this->assertTrue($expectedUuid->equals($unserializedUuid));\n    }\n}\n"
  },
  {
    "path": "tests/Codec/StringCodecTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Codec;\n\nuse InvalidArgumentException;\nuse Mockery;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\StringCodec;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function hex2bin;\nuse function implode;\nuse function pack;\n\nclass StringCodecTest extends TestCase\n{\n    /**\n     * @var UuidBuilderInterface & MockObject\n     */\n    private $builder;\n\n    /**\n     * @var UuidInterface & MockObject\n     */\n    private $uuid;\n\n    /**\n     * @var Fields\n     */\n    private $fields;\n\n    /**\n     * @var string\n     */\n    private $uuidString = '12345678-1234-4bcd-abef-1234abcd4321';\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->builder = $this->getMockBuilder(UuidBuilderInterface::class)->getMock();\n        $this->uuid = $this->getMockBuilder(UuidInterface::class)->getMock();\n        $this->fields = new Fields((string) hex2bin('1234567812344bcdabef1234abcd4321'));\n    }\n\n    protected function tearDown(): void\n    {\n        parent::tearDown();\n        unset($this->builder, $this->uuid, $this->fields);\n    }\n\n    public function testEncodeUsesFieldsArray(): void\n    {\n        $this->uuid->expects($this->once())\n            ->method('getFields')\n            ->willReturn($this->fields);\n        $codec = new StringCodec($this->builder);\n        $codec->encode($this->uuid);\n    }\n\n    public function testEncodeReturnsFormattedString(): void\n    {\n        $this->uuid->method('getFields')\n            ->willReturn($this->fields);\n        $codec = new StringCodec($this->builder);\n        $result = $codec->encode($this->uuid);\n        $this->assertSame($this->uuidString, $result);\n    }\n\n    public function testEncodeBinaryReturnsBinaryString(): void\n    {\n        $expected = hex2bin('123456781234abcdabef1234abcd4321');\n\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getBytes' => hex2bin('123456781234abcdabef1234abcd4321'),\n        ]);\n\n        $this->uuid->method('getFields')->willReturn($fields);\n\n        $codec = new StringCodec($this->builder);\n        $result = $codec->encodeBinary($this->uuid);\n        $this->assertSame($expected, $result);\n    }\n\n    public function testDecodeUsesBuilderOnFields(): void\n    {\n        $fields = [\n            'time_low' => $this->fields->getTimeLow()->toString(),\n            'time_mid' => $this->fields->getTimeMid()->toString(),\n            'time_hi_and_version' => $this->fields->getTimeHiAndVersion()->toString(),\n            'clock_seq_hi_and_reserved' => $this->fields->getClockSeqHiAndReserved()->toString(),\n            'clock_seq_low' => $this->fields->getClockSeqLow()->toString(),\n            'node' => $this->fields->getNode()->toString(),\n        ];\n\n        $bytes = hex2bin(implode('', $fields));\n\n        $string = 'uuid:12345678-1234-4bcd-abef-1234abcd4321';\n        $this->builder->expects($this->once())\n            ->method('build')\n            ->with($this->isInstanceOf(StringCodec::class), $bytes);\n        $codec = new StringCodec($this->builder);\n        $codec->decode($string);\n    }\n\n    public function testDecodeThrowsExceptionOnInvalidUuid(): void\n    {\n        $string = 'invalid-uuid';\n        $codec = new StringCodec($this->builder);\n\n        $this->expectException(InvalidArgumentException::class);\n        $codec->decode($string);\n    }\n\n    public function testDecodeReturnsUuidFromBuilder(): void\n    {\n        $string = 'uuid:12345678-1234-abcd-abef-1234abcd4321';\n        $this->builder->method('build')\n            ->willReturn($this->uuid);\n        $codec = new StringCodec($this->builder);\n        $result = $codec->decode($string);\n        $this->assertSame($this->uuid, $result);\n    }\n\n    public function testDecodeBytesThrowsExceptionWhenBytesStringNotSixteenCharacters(): void\n    {\n        $string = '61';\n        $bytes = pack('H*', $string);\n        $codec = new StringCodec($this->builder);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('$bytes string should contain 16 characters.');\n        $codec->decodeBytes($bytes);\n    }\n\n    public function testDecodeBytesReturnsUuid(): void\n    {\n        $string = '123456781234abcdabef1234abcd4321';\n        $bytes = pack('H*', $string);\n        $codec = new StringCodec($this->builder);\n        $this->builder->method('build')\n            ->willReturn($this->uuid);\n        $result = $codec->decodeBytes($bytes);\n        $this->assertSame($this->uuid, $result);\n    }\n}\n"
  },
  {
    "path": "tests/Converter/Number/BigNumberConverterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Converter\\Number;\n\nuse Ramsey\\Uuid\\Converter\\Number\\BigNumberConverter;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass BigNumberConverterTest extends TestCase\n{\n    public function testFromHexThrowsExceptionWhenStringDoesNotContainOnlyHexadecimalCharacters(): void\n    {\n        $converter = new BigNumberConverter();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('\".\" is not a valid character in base 16');\n\n        $converter->fromHex('123.34');\n    }\n\n    public function testToHexThrowsExceptionWhenStringDoesNotContainOnlyDigits(): void\n    {\n        $converter = new BigNumberConverter();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a signed integer or a string containing only digits '\n            . '0-9 and, optionally, a sign (+ or -)'\n        );\n\n        $converter->toHex('123.34');\n    }\n\n    public function testFromHex(): void\n    {\n        $converter = new BigNumberConverter();\n\n        $this->assertSame('65535', $converter->fromHex('ffff'));\n    }\n\n    public function testToHex(): void\n    {\n        $converter = new BigNumberConverter();\n\n        $this->assertSame('ffff', $converter->toHex('65535'));\n    }\n}\n"
  },
  {
    "path": "tests/Converter/Number/GenericNumberConverterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Converter\\Number;\n\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass GenericNumberConverterTest extends TestCase\n{\n    public function testFromHex(): void\n    {\n        $calculator = new BrickMathCalculator();\n        $converter = new GenericNumberConverter($calculator);\n\n        $this->assertSame('65535', $converter->fromHex('ffff'));\n    }\n\n    public function testToHex(): void\n    {\n        $calculator = new BrickMathCalculator();\n        $converter = new GenericNumberConverter($calculator);\n\n        $this->assertSame('ffff', $converter->toHex('65535'));\n    }\n}\n"
  },
  {
    "path": "tests/Converter/Time/BigNumberTimeConverterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Converter\\Time;\n\nuse Brick\\Math\\BigInteger;\nuse Ramsey\\Uuid\\Converter\\Time\\BigNumberTimeConverter;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function sprintf;\n\nclass BigNumberTimeConverterTest extends TestCase\n{\n    public function testCalculateTimeReturnsArrayOfTimeSegments(): void\n    {\n        $seconds = BigInteger::of(5);\n        $microseconds = BigInteger::of(3);\n\n        $calculatedTime = BigInteger::zero()\n            ->plus($seconds->multipliedBy(10000000))\n            ->plus($microseconds->multipliedBy(10))\n            ->plus(BigInteger::fromBase('01b21dd213814000', 16));\n\n        $maskLow = BigInteger::fromBase('ffffffff', 16);\n        $maskMid = BigInteger::fromBase('ffff', 16);\n        $maskHi = BigInteger::fromBase('0fff', 16);\n\n        $expected = sprintf('%04s', $calculatedTime->shiftedRight(48)->and($maskHi)->toBase(16));\n        $expected .= sprintf('%04s', $calculatedTime->shiftedRight(32)->and($maskMid)->toBase(16));\n        $expected .= sprintf('%08s', $calculatedTime->and($maskLow)->toBase(16));\n\n        $converter = new BigNumberTimeConverter();\n        $returned = $converter->calculateTime((string) $seconds, (string) $microseconds);\n\n        $this->assertSame($expected, $returned->toString());\n    }\n\n    public function testConvertTime(): void\n    {\n        $converter = new BigNumberTimeConverter();\n        $returned = $converter->convertTime(new Hexadecimal('1e1c57dff6f8cb0'));\n\n        $this->assertSame('1341368074', $returned->getSeconds()->toString());\n    }\n\n    public function testCalculateTimeThrowsExceptionWhenSecondsIsNotOnlyDigits(): void\n    {\n        $converter = new BigNumberTimeConverter();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a signed integer or a string containing only digits '\n            . '0-9 and, optionally, a sign (+ or -)'\n        );\n\n        $converter->calculateTime('12.34', '5678');\n    }\n\n    public function testCalculateTimeThrowsExceptionWhenMicrosecondsIsNotOnlyDigits(): void\n    {\n        $converter = new BigNumberTimeConverter();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a signed integer or a string containing only digits '\n            . '0-9 and, optionally, a sign (+ or -)'\n        );\n\n        $converter->calculateTime('1234', '56.78');\n    }\n}\n"
  },
  {
    "path": "tests/Converter/Time/GenericTimeConverterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Converter\\Time;\n\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nclass GenericTimeConverterTest extends TestCase\n{\n    /**\n     * @param numeric-string $seconds\n     * @param numeric-string $microseconds\n     * @param non-empty-string $expected\n     *\n     * @dataProvider provideCalculateTime\n     */\n    public function testCalculateTime(string $seconds, string $microseconds, string $expected): void\n    {\n        $calculator = new BrickMathCalculator();\n        $converter = new GenericTimeConverter($calculator);\n\n        $result = $converter->calculateTime($seconds, $microseconds);\n\n        $this->assertSame($expected, $result->toString());\n    }\n\n    /**\n     * @return array<array{seconds: numeric-string, microseconds: numeric-string, expected: non-empty-string}>\n     */\n    public function provideCalculateTime(): array\n    {\n        return [\n            [\n                'seconds' => '-12219146756',\n                'microseconds' => '0',\n                'expected' => '000001540901e600',\n            ],\n            [\n                'seconds' => '103072857659',\n                'microseconds' => '999999',\n                'expected' => '0fffffffff9785f6',\n            ],\n            [\n                'seconds' => '1578612359',\n                'microseconds' => '521023',\n                'expected' => '01ea333764c71df6',\n            ],\n\n            // This is the earliest possible date supported by v1 UUIDs:\n            // 1582-10-15 00:00:00.000000\n            [\n                'seconds' => '-12219292800',\n                'microseconds' => '0',\n                'expected' => '0000000000000000',\n            ],\n\n            // This is the last possible time supported by the GenericTimeConverter:\n            // 60038-03-11 05:36:10.955161\n            // When a UUID is created from this time, however, the highest 4 bits\n            // are replaced with the version (1), so we lose fidelity and cannot\n            // accurately decompose the date from the UUID.\n            [\n                'seconds' => '1832455114570',\n                'microseconds' => '955161',\n                'expected' => 'fffffffffffffffa',\n            ],\n\n            // This is technically the last possible time supported by v1 UUIDs:\n            // 5236-03-31 21:21:00.684697\n            // All dates above this will lose fidelity, since the highest 4 bits\n            // are replaced with the UUID version (1). As a result, we cannot\n            // accurately decompose the date from UUIDs created from dates\n            // greater than this one.\n            [\n                'seconds' => '103072857660',\n                'microseconds' => '684697',\n                'expected' => '0ffffffffffffffa',\n            ],\n        ];\n    }\n\n    /**\n     * @param numeric-string $unixTimestamp\n     * @param numeric-string $microseconds\n     *\n     * @dataProvider provideConvertTime\n     */\n    public function testConvertTime(Hexadecimal $uuidTimestamp, string $unixTimestamp, string $microseconds): void\n    {\n        $calculator = new BrickMathCalculator();\n        $converter = new GenericTimeConverter($calculator);\n\n        $result = $converter->convertTime($uuidTimestamp);\n\n        $this->assertSame($unixTimestamp, $result->getSeconds()->toString());\n        $this->assertSame($microseconds, $result->getMicroseconds()->toString());\n    }\n\n    /**\n     * @return array<array{uuidTimestamp: Hexadecimal, unixTimestamp: numeric-string, microseconds: numeric-string}>\n     */\n    public function provideConvertTime(): array\n    {\n        return [\n            [\n                'uuidTimestamp' => new Hexadecimal('1e1c57dff6f8cb0'),\n                'unixTimestamp' => '1341368074',\n                'microseconds' => '491000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('1ea333764c71df6'),\n                'unixTimestamp' => '1578612359',\n                'microseconds' => '521023',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('fffffffff9785f6'),\n                'unixTimestamp' => '103072857659',\n                'microseconds' => '999999',\n            ],\n\n            // This is the last possible time supported by v1 UUIDs. When\n            // converted to a Unix timestamp, the microseconds are lost.\n            // 60038-03-11 05:36:10.955161\n            [\n                'uuidTimestamp' => new Hexadecimal('fffffffffffffffa'),\n                'unixTimestamp' => '1832455114570',\n                'microseconds' => '955161',\n            ],\n\n            // This is the earliest possible date supported by v1 UUIDs:\n            // 1582-10-15 00:00:00.000000\n            [\n                'uuidTimestamp' => new Hexadecimal('000000000000'),\n                'unixTimestamp' => '-12219292800',\n                'microseconds' => '0',\n            ],\n\n            // This is the Unix epoch:\n            // 1970-01-01 00:00:00.000000\n            [\n                'uuidTimestamp' => new Hexadecimal('1b21dd213814000'),\n                'unixTimestamp' => '0',\n                'microseconds' => '0',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Converter/Time/PhpTimeConverterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Converter\\Time;\n\nuse Brick\\Math\\BigInteger;\nuse Mockery;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\PhpTimeConverter;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function sprintf;\n\nclass PhpTimeConverterTest extends TestCase\n{\n    public function testCalculateTimeReturnsArrayOfTimeSegments(): void\n    {\n        $seconds = BigInteger::of(5);\n        $microseconds = BigInteger::of(3);\n\n        $calculatedTime = BigInteger::zero()\n            ->plus($seconds->multipliedBy(10000000))\n            ->plus($microseconds->multipliedBy(10))\n            ->plus(BigInteger::fromBase('01b21dd213814000', 16));\n\n        $maskLow = BigInteger::fromBase('ffffffff', 16);\n        $maskMid = BigInteger::fromBase('ffff', 16);\n        $maskHi = BigInteger::fromBase('0fff', 16);\n\n        $expected = sprintf('%04s', $calculatedTime->shiftedRight(48)->and($maskHi)->toBase(16));\n        $expected .= sprintf('%04s', $calculatedTime->shiftedRight(32)->and($maskMid)->toBase(16));\n        $expected .= sprintf('%08s', $calculatedTime->and($maskLow)->toBase(16));\n\n        $converter = new PhpTimeConverter();\n        $returned = $converter->calculateTime((string) $seconds, (string) $microseconds);\n\n        $this->assertSame($expected, $returned->toString());\n    }\n\n    public function testCalculateTimeThrowsExceptionWhenSecondsIsNotOnlyDigits(): void\n    {\n        /** @var Mockery\\MockInterface & PhpTimeConverter $converter */\n        $converter = Mockery::mock(PhpTimeConverter::class)->makePartial();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a signed integer or a string containing only digits '\n            . '0-9 and, optionally, a sign (+ or -)'\n        );\n\n        $converter->calculateTime('12.34', '5678');\n    }\n\n    public function testCalculateTimeThrowsExceptionWhenMicrosecondsIsNotOnlyDigits(): void\n    {\n        /** @var Mockery\\MockInterface & PhpTimeConverter $converter */\n        $converter = Mockery::mock(PhpTimeConverter::class)->makePartial();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a signed integer or a string containing only digits '\n            . '0-9 and, optionally, a sign (+ or -)'\n        );\n\n        $converter->calculateTime('1234', '56.78');\n    }\n\n    /**\n     * @param numeric-string $unixTimestamp\n     * @param numeric-string $microseconds\n     *\n     * @dataProvider provideConvertTime\n     */\n    public function testConvertTime(Hexadecimal $uuidTimestamp, string $unixTimestamp, string $microseconds): void\n    {\n        $calculator = new BrickMathCalculator();\n        $fallbackConverter = new GenericTimeConverter($calculator);\n        $converter = new PhpTimeConverter($calculator, $fallbackConverter);\n\n        $result = $converter->convertTime($uuidTimestamp);\n\n        $this->assertSame($unixTimestamp, $result->getSeconds()->toString());\n        $this->assertSame($microseconds, $result->getMicroseconds()->toString());\n    }\n\n    /**\n     * @return array<array{uuidTimestamp: Hexadecimal, unixTimestamp: numeric-string, microseconds: numeric-string}>\n     */\n    public function provideConvertTime(): array\n    {\n        return [\n            [\n                'uuidTimestamp' => new Hexadecimal('1e1c57dff6f8cb0'),\n                'unixTimestamp' => '1341368074',\n                'microseconds' => '491000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('1ea333764c71df6'),\n                'unixTimestamp' => '1578612359',\n                'microseconds' => '521023',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('fffffffff9785f6'),\n                'unixTimestamp' => '103072857659',\n                'microseconds' => '999999',\n            ],\n\n            // This is the last possible time supported by v1 UUIDs. When\n            // converted to a Unix timestamp, the microseconds are lost.\n            // 60038-03-11 05:36:10.955161\n            [\n                'uuidTimestamp' => new Hexadecimal('fffffffffffffffa'),\n                'unixTimestamp' => '1832455114570',\n                'microseconds' => '955161',\n            ],\n\n            // This is the earliest possible date supported by v1 UUIDs:\n            // 1582-10-15 00:00:00.000000\n            [\n                'uuidTimestamp' => new Hexadecimal('000000000000'),\n                'unixTimestamp' => '-12219292800',\n                'microseconds' => '0',\n            ],\n\n            // This is the Unix epoch:\n            // 1970-01-01 00:00:00.000000\n            [\n                'uuidTimestamp' => new Hexadecimal('1b21dd213814000'),\n                'unixTimestamp' => '0',\n                'microseconds' => '0',\n            ],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $seconds\n     * @param non-empty-string $microseconds\n     * @param non-empty-string $expected\n     *\n     * @dataProvider provideCalculateTime\n     */\n    public function testCalculateTime(string $seconds, string $microseconds, string $expected): void\n    {\n        $calculator = new BrickMathCalculator();\n        $fallbackConverter = new GenericTimeConverter($calculator);\n        $converter = new PhpTimeConverter($calculator, $fallbackConverter);\n\n        $result = $converter->calculateTime($seconds, $microseconds);\n\n        $this->assertSame($expected, $result->toString());\n    }\n\n    /**\n     * @return array<array{seconds: non-empty-string, microseconds: non-empty-string, expected: non-empty-string}>\n     */\n    public function provideCalculateTime(): array\n    {\n        return [\n            [\n                'seconds' => '-12219146756',\n                'microseconds' => '0',\n                'expected' => '000001540901e600',\n            ],\n            [\n                'seconds' => '103072857659',\n                'microseconds' => '999999',\n                'expected' => '0fffffffff9785f6',\n            ],\n            [\n                'seconds' => '1578612359',\n                'microseconds' => '521023',\n                'expected' => '01ea333764c71df6',\n            ],\n\n            // This is the earliest possible date supported by v1 UUIDs:\n            // 1582-10-15 00:00:00.000000\n            [\n                'seconds' => '-12219292800',\n                'microseconds' => '0',\n                'expected' => '0000000000000000',\n            ],\n\n            // This is the last possible time supported by v1 UUIDs:\n            // 60038-03-11 05:36:10.955161\n            [\n                'seconds' => '1832455114570',\n                'microseconds' => '955161',\n                'expected' => 'fffffffffffffffa',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Converter/Time/UnixTimeConverterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Converter\\Time;\n\nuse Ramsey\\Uuid\\Converter\\Time\\UnixTimeConverter;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nclass UnixTimeConverterTest extends TestCase\n{\n    /**\n     * @dataProvider provideConvertTime\n     */\n    public function testConvertTime(Hexadecimal $uuidTimestamp, string $unixTimestamp, string $microseconds): void\n    {\n        $calculator = new BrickMathCalculator();\n        $converter = new UnixTimeConverter($calculator);\n\n        $result = $converter->convertTime($uuidTimestamp);\n\n        $this->assertSame($unixTimestamp, $result->getSeconds()->toString());\n        $this->assertSame($microseconds, $result->getMicroseconds()->toString());\n    }\n\n    /**\n     * @return array<array{uuidTimestamp: Hexadecimal, unixTimestamp: string, microseconds: string}>\n     */\n    public function provideConvertTime(): array\n    {\n        return [\n            [\n                'uuidTimestamp' => new Hexadecimal('017F22E279B0'),\n                'unixTimestamp' => '1645557742',\n                'microseconds' => '0',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('01384fc480fb'),\n                'unixTimestamp' => '1341368074',\n                'microseconds' => '491000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('016f8ca10161'),\n                'unixTimestamp' => '1578612359',\n                'microseconds' => '521000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('5dbe85111a5f'),\n                'unixTimestamp' => '103072857659',\n                'microseconds' => '999000',\n            ],\n\n            // This is the last possible time supported by v7 UUIDs (2 ^ 48 - 1).\n            // 10889-08-02 05:31:50.655 +00:00\n            [\n                'uuidTimestamp' => new Hexadecimal('ffffffffffff'),\n                'unixTimestamp' => '281474976710',\n                'microseconds' => '655000',\n            ],\n\n            // This is the earliest possible date supported by v7 UUIDs.\n            // It is the Unix Epoch (big surprise!).\n            // 1970-01-01 00:00:00.0 +00:00\n            [\n                'uuidTimestamp' => new Hexadecimal('000000000000'),\n                'unixTimestamp' => '0',\n                'microseconds' => '0',\n            ],\n\n            [\n                'uuidTimestamp' => new Hexadecimal('000000000001'),\n                'unixTimestamp' => '0',\n                'microseconds' => '1000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('00000000000f'),\n                'unixTimestamp' => '0',\n                'microseconds' => '15000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('000000000064'),\n                'unixTimestamp' => '0',\n                'microseconds' => '100000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('0000000003e7'),\n                'unixTimestamp' => '0',\n                'microseconds' => '999000',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('0000000003e8'),\n                'unixTimestamp' => '1',\n                'microseconds' => '0',\n            ],\n            [\n                'uuidTimestamp' => new Hexadecimal('0000000003e9'),\n                'unixTimestamp' => '1',\n                'microseconds' => '1000',\n            ],\n        ];\n    }\n\n    /**\n     * @dataProvider provideCalculateTime\n     */\n    public function testCalculateTime(string $seconds, string $microseconds, string $expected): void\n    {\n        $calculator = new BrickMathCalculator();\n        $converter = new UnixTimeConverter($calculator);\n\n        $result = $converter->calculateTime($seconds, $microseconds);\n\n        $this->assertSame($expected, $result->toString());\n    }\n\n    /**\n     * @return array<array{seconds: string, microseconds: string, expected: string}>\n     */\n    public function provideCalculateTime(): array\n    {\n        return [\n            [\n                'seconds' => '1645557742',\n                'microseconds' => '0',\n                'expected' => '017f22e279b0',\n            ],\n            [\n                'seconds' => '1341368074',\n                'microseconds' => '491000',\n                'expected' => '01384fc480fb',\n            ],\n            [\n                'seconds' => '1578612359',\n                'microseconds' => '521023',\n                'expected' => '016f8ca10161',\n            ],\n            [\n                'seconds' => '103072857659',\n                'microseconds' => '999499',\n                'expected' => '5dbe85111a5f',\n            ],\n            [\n                'seconds' => '103072857659',\n                'microseconds' => '999999',\n                'expected' => '5dbe85111a5f',\n            ],\n\n            // This is the earliest possible date supported by v7 UUIDs.\n            // It is the Unix Epoch (big surprise!): 1970-01-01 00:00:00.0 +00:00\n            [\n                'seconds' => '0',\n                'microseconds' => '0',\n                'expected' => '000000000000',\n            ],\n\n            // This is the last possible time supported by v7 UUIDs (2 ^ 48 - 1):\n            // 10889-08-02 05:31:50.655 +00:00\n            [\n                'seconds' => '281474976710',\n                'microseconds' => '655000',\n                'expected' => 'ffffffffffff',\n            ],\n\n            [\n                'seconds' => '0',\n                'microseconds' => '1000',\n                'expected' => '000000000001',\n            ],\n            [\n                'seconds' => '0',\n                'microseconds' => '15000',\n                'expected' => '00000000000f',\n            ],\n            [\n                'seconds' => '0',\n                'microseconds' => '100000',\n                'expected' => '000000000064',\n            ],\n            [\n                'seconds' => '0',\n                'microseconds' => '999000',\n                'expected' => '0000000003e7',\n            ],\n            [\n                'seconds' => '1',\n                'microseconds' => '0',\n                'expected' => '0000000003e8',\n            ],\n            [\n                'seconds' => '1',\n                'microseconds' => '1000',\n                'expected' => '0000000003e9',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/DeprecatedUuidMethodsTraitTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\n\nclass DeprecatedUuidMethodsTraitTest extends TestCase\n{\n    public function testGetDateTime(): void\n    {\n        $calculator = new BrickMathCalculator();\n\n        $fields = new Fields((string) hex2bin('ff6f8cb0c57d11e19b210800200c9a66'));\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = new GenericTimeConverter($calculator);\n\n        $uuid = new Uuid($fields, $numberConverter, $codec, $timeConverter);\n\n        $this->assertSame('2012-07-04T02:14:34+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('1341368074.491000', $uuid->getDateTime()->format('U.u'));\n    }\n\n    public function testGetDateTimeThrowsException(): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => 1,\n            'getTimestamp' => new Hexadecimal('0'),\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $timeConverter = Mockery::mock(TimeConverterInterface::class, [\n            'convertTime' => new Time('0', '1234567'),\n        ]);\n\n        $uuid = new Uuid($fields, $numberConverter, $codec, $timeConverter);\n\n        $this->expectException(DateTimeException::class);\n\n        $uuid->getDateTime();\n    }\n}\n"
  },
  {
    "path": "tests/Encoder/TimestampFirstCombCodecTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Encoder;\n\nuse Mockery;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Codec\\TimestampFirstCombCodec;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function hex2bin;\nuse function implode;\n\nclass TimestampFirstCombCodecTest extends TestCase\n{\n    /**\n     * @var CodecInterface\n     */\n    private $codec;\n\n    /**\n     * @var MockObject & UuidBuilderInterface\n     */\n    private $builderMock;\n\n    protected function setUp(): void\n    {\n        $this->builderMock = $this->getMockBuilder(UuidBuilderInterface::class)->getMock();\n        $this->codec = new TimestampFirstCombCodec($this->builderMock);\n    }\n\n    public function testEncoding(): void\n    {\n        $fields = new Fields((string) hex2bin('ff6f8cb0c57d11e19b210800200c9a66'));\n\n        $uuidMock = Mockery::mock(UuidInterface::class, [\n            'getFields' => $fields,\n        ]);\n\n        $encodedUuid = $this->codec->encode($uuidMock);\n\n        $this->assertSame('0800200c-9a66-11e1-9b21-ff6f8cb0c57d', $encodedUuid);\n    }\n\n    public function testBinaryEncoding(): void\n    {\n        $fields = new Fields((string) hex2bin('ff6f8cb0c57d11e19b210800200c9a66'));\n\n        $uuidMock = Mockery::mock(UuidInterface::class, [\n            'getFields' => $fields,\n        ]);\n\n        $encodedUuid = $this->codec->encodeBinary($uuidMock);\n\n        $this->assertSame(hex2bin('0800200c9a6611e19b21ff6f8cb0c57d'), $encodedUuid);\n    }\n\n    public function testDecoding(): void\n    {\n        $this->builderMock->expects($this->exactly(1))\n            ->method('build')\n            ->with(\n                $this->codec,\n                hex2bin(implode('', [\n                    'time_low' => 'ff6f8cb0',\n                    'time_mid' => 'c57d',\n                    'time_hi_and_version' => '11e1',\n                    'clock_seq_hi_and_reserved' => '9b',\n                    'clock_seq_low' => '21',\n                    'node' => '0800200c9a66',\n                ]))\n            );\n        $this->codec->decode('0800200c-9a66-11e1-9b21-ff6f8cb0c57d');\n    }\n\n    public function testBinaryDecoding(): void\n    {\n        $this->builderMock->expects($this->exactly(1))\n            ->method('build')\n            ->with(\n                $this->codec,\n                hex2bin(implode('', [\n                    'time_low' => 'ff6f8cb0',\n                    'time_mid' => 'c57d',\n                    'time_hi_and_version' => '11e1',\n                    'clock_seq_hi_and_reserved' => '9b',\n                    'clock_seq_low' => '21',\n                    'node' => '0800200c9a66',\n                ]))\n            );\n        $this->codec->decodeBytes((string) hex2bin('0800200c9a6611e19b21ff6f8cb0c57d'));\n    }\n}\n"
  },
  {
    "path": "tests/Encoder/TimestampLastCombCodecTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Encoder;\n\nuse Mockery;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Codec\\TimestampLastCombCodec;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function hex2bin;\nuse function implode;\n\nclass TimestampLastCombCodecTest extends TestCase\n{\n    /**\n     * @var CodecInterface\n     */\n    private $codec;\n\n    /**\n     * @var MockObject & UuidBuilderInterface\n     */\n    private $builderMock;\n\n    protected function setUp(): void\n    {\n        $this->builderMock = $this->getMockBuilder(UuidBuilderInterface::class)->getMock();\n        $this->codec = new TimestampLastCombCodec($this->builderMock);\n    }\n\n    public function testEncoding(): void\n    {\n        $fields = new Fields((string) hex2bin('0800200c9a6611e19b21ff6f8cb0c57d'));\n\n        $uuidMock = Mockery::mock(UuidInterface::class, [\n            'getFields' => $fields,\n        ]);\n\n        $encodedUuid = $this->codec->encode($uuidMock);\n\n        $this->assertSame('0800200c-9a66-11e1-9b21-ff6f8cb0c57d', $encodedUuid);\n    }\n\n    public function testBinaryEncoding(): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getBytes' => hex2bin('0800200c9a6611e19b21ff6f8cb0c57d'),\n        ]);\n\n        /** @var MockObject & UuidInterface $uuidMock */\n        $uuidMock = $this->getMockBuilder(UuidInterface::class)->getMock();\n        $uuidMock->expects($this->any())->method('getFields')->willReturn($fields);\n\n        $encodedUuid = $this->codec->encodeBinary($uuidMock);\n\n        $this->assertSame(hex2bin('0800200c9a6611e19b21ff6f8cb0c57d'), $encodedUuid);\n    }\n\n    public function testDecoding(): void\n    {\n        $this->builderMock->expects($this->exactly(1))\n            ->method('build')\n            ->with(\n                $this->codec,\n                hex2bin(implode('', [\n                    'time_low' => '0800200c',\n                    'time_mid' => '9a66',\n                    'time_hi_and_version' => '11e1',\n                    'clock_seq_hi_and_reserved' => '9b',\n                    'clock_seq_low' => '21',\n                    'node' => 'ff6f8cb0c57d',\n                ]))\n            );\n        $this->codec->decode('0800200c-9a66-11e1-9b21-ff6f8cb0c57d');\n    }\n\n    public function testBinaryDecoding(): void\n    {\n        $this->builderMock->expects($this->exactly(1))\n            ->method('build')\n            ->with(\n                $this->codec,\n                hex2bin(implode('', [\n                    'time_low' => '0800200c',\n                    'time_mid' => '9a66',\n                    'time_hi_and_version' => '11e1',\n                    'clock_seq_hi_and_reserved' => '9b',\n                    'clock_seq_low' => '21',\n                    'node' => 'ff6f8cb0c57d',\n                ]))\n            );\n        $this->codec->decodeBytes((string) hex2bin('0800200c9a6611e19b21ff6f8cb0c57d'));\n    }\n}\n"
  },
  {
    "path": "tests/ExpectedBehaviorTest.php",
    "content": "<?php\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse Brick\\Math\\BigInteger;\nuse Ramsey\\Uuid\\Builder\\DegradedUuidBuilder;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Codec\\OrderedTimeCodec;\nuse Ramsey\\Uuid\\Codec\\TimestampFirstCombCodec;\nuse Ramsey\\Uuid\\Converter\\Number\\DegradedNumberConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\DegradedTimeConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\DegradedUuid;\nuse Ramsey\\Uuid\\Generator\\CombGenerator;\nuse Ramsey\\Uuid\\Generator\\DefaultTimeGenerator;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidFactory;\nuse stdClass;\n\n/**\n * These tests exist to ensure a seamless upgrade path from 3.x to 4.x. If any\n * of these tests fail in 4.x, then it's because we've changed functionality\n * in such a way that compatibility with 3.x is broken.\n *\n * Naturally, there are some BC-breaks between 3.x and 4.x, but these tests\n * ensure that the base-level functionality that satisfies 80% of use-cases\n * does not change. The remaining 20% of use-cases should refer to the README\n * for details on the easiest path to transition from 3.x to 4.x.\n *\n * @codingStandardsIgnoreFile\n */\nclass ExpectedBehaviorTest extends TestCase\n{\n    /**\n     * @dataProvider provideStaticCreationMethods\n     */\n    public function testStaticCreationMethodsAndStandardBehavior($method, $args)\n    {\n        $uuid = call_user_func_array(['Ramsey\\Uuid\\Uuid', $method], $args);\n\n        $this->assertInstanceOf('Ramsey\\Uuid\\UuidInterface', $uuid);\n        $this->assertIsInt($uuid->compareTo(Uuid::uuid1()));\n        $this->assertNotSame(0, $uuid->compareTo(Uuid::uuid4()));\n        $this->assertSame(0, $uuid->compareTo(clone $uuid));\n        $this->assertFalse($uuid->equals(new stdClass()));\n        $this->assertTrue($uuid->equals(clone $uuid));\n        $this->assertIsString($uuid->getBytes());\n        $this->assertInstanceOf('Ramsey\\Uuid\\Converter\\NumberConverterInterface', $uuid->getNumberConverter());\n        $this->assertIsString((string) $uuid->getHex());\n        $this->assertIsArray($uuid->getFieldsHex());\n        $this->assertArrayHasKey('time_low', $uuid->getFieldsHex());\n        $this->assertArrayHasKey('time_mid', $uuid->getFieldsHex());\n        $this->assertArrayHasKey('time_hi_and_version', $uuid->getFieldsHex());\n        $this->assertArrayHasKey('clock_seq_hi_and_reserved', $uuid->getFieldsHex());\n        $this->assertArrayHasKey('clock_seq_low', $uuid->getFieldsHex());\n        $this->assertArrayHasKey('node', $uuid->getFieldsHex());\n        $this->assertIsString($uuid->getTimeLowHex());\n        $this->assertIsString($uuid->getTimeMidHex());\n        $this->assertIsString($uuid->getTimeHiAndVersionHex());\n        $this->assertIsString($uuid->getClockSeqHiAndReservedHex());\n        $this->assertIsString($uuid->getClockSeqLowHex());\n        $this->assertIsString($uuid->getNodeHex());\n        $this->assertSame($uuid->getFieldsHex()['time_low'], $uuid->getTimeLowHex());\n        $this->assertSame($uuid->getFieldsHex()['time_mid'], $uuid->getTimeMidHex());\n        $this->assertSame($uuid->getFieldsHex()['time_hi_and_version'], $uuid->getTimeHiAndVersionHex());\n        $this->assertSame($uuid->getFieldsHex()['clock_seq_hi_and_reserved'], $uuid->getClockSeqHiAndReservedHex());\n        $this->assertSame($uuid->getFieldsHex()['clock_seq_low'], $uuid->getClockSeqLowHex());\n        $this->assertSame($uuid->getFieldsHex()['node'], $uuid->getNodeHex());\n        $this->assertSame(substr((string) $uuid->getHex(), 16), $uuid->getLeastSignificantBitsHex());\n        $this->assertSame(substr((string) $uuid->getHex(), 0, 16), $uuid->getMostSignificantBitsHex());\n\n        $this->assertSame(\n            (string) $uuid->getHex(),\n            $uuid->getTimeLowHex()\n                . $uuid->getTimeMidHex()\n                . $uuid->getTimeHiAndVersionHex()\n                . $uuid->getClockSeqHiAndReservedHex()\n                . $uuid->getClockSeqLowHex()\n                . $uuid->getNodeHex()\n        );\n\n        $this->assertSame(\n            (string) $uuid->getHex(),\n            $uuid->getFieldsHex()['time_low']\n                . $uuid->getFieldsHex()['time_mid']\n                . $uuid->getFieldsHex()['time_hi_and_version']\n                . $uuid->getFieldsHex()['clock_seq_hi_and_reserved']\n                . $uuid->getFieldsHex()['clock_seq_low']\n                . $uuid->getFieldsHex()['node']\n        );\n\n        $this->assertIsString($uuid->getUrn());\n        $this->assertStringStartsWith('urn:uuid:', $uuid->getUrn());\n        $this->assertSame('urn:uuid:' . (string) $uuid->getHex(), str_replace('-', '', $uuid->getUrn()));\n        $this->assertSame((string) $uuid->getHex(), str_replace('-', '', $uuid->toString()));\n        $this->assertSame((string) $uuid->getHex(), str_replace('-', '', (string) $uuid));\n\n        $this->assertSame(\n            $uuid->toString(),\n            $uuid->getTimeLowHex() . '-'\n                . $uuid->getTimeMidHex() . '-'\n                . $uuid->getTimeHiAndVersionHex() . '-'\n                . $uuid->getClockSeqHiAndReservedHex()\n                . $uuid->getClockSeqLowHex() . '-'\n                . $uuid->getNodeHex()\n        );\n\n        $this->assertSame(\n            (string) $uuid,\n            $uuid->getTimeLowHex() . '-'\n                . $uuid->getTimeMidHex() . '-'\n                . $uuid->getTimeHiAndVersionHex() . '-'\n                . $uuid->getClockSeqHiAndReservedHex()\n                . $uuid->getClockSeqLowHex() . '-'\n                . $uuid->getNodeHex()\n        );\n\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame((int) substr($method, -1), $uuid->getVersion());\n        $this->assertSame(1, preg_match('/^\\d+$/', (string) $uuid->getInteger()));\n    }\n\n    public function provideStaticCreationMethods()\n    {\n        return [\n            ['uuid1', []],\n            ['uuid1', ['00000fffffff']],\n            ['uuid1', [null, 1234]],\n            ['uuid1', ['00000fffffff', 1234]],\n            ['uuid1', ['00000fffffff', null]],\n            ['uuid1', [268435455]],\n            ['uuid1', [268435455, 1234]],\n            ['uuid1', [268435455, null]],\n            ['uuid3', [Uuid::NAMESPACE_URL, 'https://example.com/foo']],\n            ['uuid4', []],\n            ['uuid5', [Uuid::NAMESPACE_URL, 'https://example.com/foo']],\n        ];\n    }\n\n    public function testUuidVersion1MethodBehavior()\n    {\n        $uuid = Uuid::uuid1('00000fffffff', 0xffff);\n\n        $this->assertInstanceOf('DateTimeInterface', $uuid->getDateTime());\n        $this->assertSame('00000fffffff', $uuid->getNodeHex());\n        $this->assertSame('3fff', $uuid->getClockSequenceHex());\n        $this->assertSame('16383', (string) $uuid->getClockSequence());\n    }\n\n    public function testUuidVersion1MethodBehavior64Bit()\n    {\n        $uuid = Uuid::uuid1('ffffffffffff', 0xffff);\n\n        $this->assertInstanceOf('DateTimeInterface', $uuid->getDateTime());\n        $this->assertSame('ffffffffffff', $uuid->getNodeHex());\n        $this->assertSame('281474976710655', (string) $uuid->getNode());\n        $this->assertSame('3fff', $uuid->getClockSequenceHex());\n        $this->assertSame('16383', (string) $uuid->getClockSequence());\n        $this->assertSame(1, preg_match('/^\\d+$/', (string) $uuid->getTimestamp()));\n    }\n\n    /**\n     * @dataProvider provideIsValid\n     */\n    public function testIsValid($uuid, $expected)\n    {\n        $this->assertSame($expected, Uuid::isValid($uuid), \"{$uuid} is not a valid UUID\");\n        $this->assertSame($expected, Uuid::isValid(strtoupper($uuid)), strtoupper($uuid) . ' is not a valid UUID');\n    }\n\n    public function provideIsValid()\n    {\n        return [\n            // RFC 4122 UUIDs\n            ['00000000-0000-0000-0000-000000000000', true],\n            ['ff6f8cb0-c57d-11e1-8b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-11e1-ab21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-11e1-bb21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-21e1-8b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-21e1-ab21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-21e1-bb21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-31e1-8b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-31e1-9b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-31e1-ab21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-41e1-8b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-41e1-9b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-41e1-bb21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-51e1-9b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-51e1-ab21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-51e1-bb21-0800200c9a66', true],\n\n            // Non RFC 4122 UUIDs\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', true],\n            ['00000000-0000-0000-0000-000000000000', true],\n            ['ff6f8cb0-c57d-01e1-0b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-1b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-2b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-3b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-4b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-5b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-6b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-7b21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-db21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-eb21-0800200c9a66', true],\n            ['ff6f8cb0-c57d-01e1-fb21-0800200c9a66', true],\n\n            // Other valid patterns\n            ['{ff6f8cb0-c57d-01e1-fb21-0800200c9a66}', true],\n            ['urn:uuid:ff6f8cb0-c57d-01e1-fb21-0800200c9a66', true],\n\n            // Invalid UUIDs\n            ['ffffffffffffffffffffffffffffffff', false],\n            ['00000000000000000000000000000000', false],\n            [0, false],\n            ['foobar', false],\n            ['ff6f8cb0c57d51e1bb210800200c9a66', false],\n            ['gf6f8cb0-c57d-51e1-bb21-0800200c9a66', false],\n        ];\n    }\n\n    /**\n     * @dataProvider provideFromStringInteger\n     */\n    public function testSerialization($string)\n    {\n        $uuid = Uuid::fromString($string);\n\n        $serialized = serialize($uuid);\n        $unserialized = unserialize($serialized);\n\n        $this->assertSame(0, $uuid->compareTo($unserialized));\n        $this->assertTrue($uuid->equals($unserialized));\n        $this->assertSame(\"\\\"{$string}\\\"\", json_encode($uuid));\n    }\n\n    /**\n     * @dataProvider provideFromStringInteger\n     */\n    public function testSerializationWithOrderedTimeCodec($string)\n    {\n        $factory = new UuidFactory();\n        $factory->setCodec(new OrderedTimeCodec(\n            $factory->getUuidBuilder()\n        ));\n\n        $previousFactory = Uuid::getFactory();\n        Uuid::setFactory($factory);\n        $uuid = Uuid::fromString($string);\n\n        $serialized = serialize($uuid);\n        $unserialized = unserialize($serialized);\n\n        Uuid::setFactory($previousFactory);\n\n        $this->assertSame(0, $uuid->compareTo($unserialized));\n        $this->assertTrue($uuid->equals($unserialized));\n        $this->assertSame(\"\\\"{$string}\\\"\", json_encode($uuid));\n    }\n\n    /**\n     * @dataProvider provideFromStringInteger\n     */\n    public function testNumericReturnValues($string)\n    {\n        $leastSignificantBitsHex = substr(str_replace('-', '', $string), 16);\n        $mostSignificantBitsHex = substr(str_replace('-', '', $string), 0, 16);\n        $leastSignificantBits = BigInteger::fromBase($leastSignificantBitsHex, 16)->__toString();\n        $mostSignificantBits = BigInteger::fromBase($mostSignificantBitsHex, 16)->__toString();\n\n        $components = explode('-', $string);\n        array_walk($components, function (&$value) {\n            $value = BigInteger::fromBase($value, 16)->__toString();\n        });\n\n        if (strtolower($string) === Uuid::MAX) {\n            $clockSeq = (int) $components[3];\n        } else {\n            $clockSeq = (int) $components[3] & 0x3fff;\n        }\n\n        $clockSeqHiAndReserved = (int) $components[3] >> 8;\n        $clockSeqLow = (int) $components[3] & 0x00ff;\n\n        $uuid = Uuid::fromString($string);\n\n        $this->assertSame($components[0], (string) $uuid->getTimeLow());\n        $this->assertSame($components[1], (string) $uuid->getTimeMid());\n        $this->assertSame($components[2], (string) $uuid->getTimeHiAndVersion());\n        $this->assertSame((string) $clockSeq, (string) $uuid->getClockSequence());\n        $this->assertSame((string) $clockSeqHiAndReserved, (string) $uuid->getClockSeqHiAndReserved());\n        $this->assertSame((string) $clockSeqLow, (string) $uuid->getClockSeqLow());\n        $this->assertSame($components[4], (string) $uuid->getNode());\n        $this->assertSame($leastSignificantBits, (string) $uuid->getLeastSignificantBits());\n        $this->assertSame($mostSignificantBits, (string) $uuid->getMostSignificantBits());\n    }\n\n    /**\n     * @dataProvider provideFromStringInteger\n     */\n    public function testFromBytes($string, $version, $variant, $integer)\n    {\n        $bytes = hex2bin(str_replace('-', '', $string));\n\n        $uuid = Uuid::fromBytes($bytes);\n\n        $this->assertInstanceOf('Ramsey\\Uuid\\UuidInterface', $uuid);\n        $this->assertSame($string, $uuid->toString());\n        $this->assertSame($version, $uuid->getVersion());\n        $this->assertSame($variant, $uuid->getVariant());\n\n        $components = explode('-', $string);\n\n        $this->assertSame($components[0], $uuid->getTimeLowHex());\n        $this->assertSame($components[1], $uuid->getTimeMidHex());\n        $this->assertSame($components[2], $uuid->getTimeHiAndVersionHex());\n        $this->assertSame($components[3], $uuid->getClockSeqHiAndReservedHex() . $uuid->getClockSeqLowHex());\n        $this->assertSame($components[4], $uuid->getNodeHex());\n        $this->assertSame($integer, (string) $uuid->getInteger());\n        $this->assertSame($bytes, $uuid->getBytes());\n    }\n\n    /**\n     * @dataProvider provideFromStringInteger\n     */\n    public function testFromInteger($string, $version, $variant, $integer)\n    {\n        $bytes = hex2bin(str_replace('-', '', $string));\n\n        $uuid = Uuid::fromInteger($integer);\n\n        $this->assertInstanceOf('Ramsey\\Uuid\\UuidInterface', $uuid);\n        $this->assertSame($string, $uuid->toString());\n        $this->assertSame($version, $uuid->getVersion());\n        $this->assertSame($variant, $uuid->getVariant());\n\n        $components = explode('-', $string);\n\n        $this->assertSame($components[0], $uuid->getTimeLowHex());\n        $this->assertSame($components[1], $uuid->getTimeMidHex());\n        $this->assertSame($components[2], $uuid->getTimeHiAndVersionHex());\n        $this->assertSame($components[3], $uuid->getClockSeqHiAndReservedHex() . $uuid->getClockSeqLowHex());\n        $this->assertSame($components[4], $uuid->getNodeHex());\n        $this->assertSame($integer, (string) $uuid->getInteger());\n        $this->assertSame($bytes, $uuid->getBytes());\n    }\n\n    /**\n     * @dataProvider provideFromStringInteger\n     */\n    public function testFromString($string, $version, $variant, $integer)\n    {\n        $bytes = hex2bin(str_replace('-', '', $string));\n\n        $uuid = Uuid::fromString($string);\n\n        $this->assertInstanceOf('Ramsey\\Uuid\\UuidInterface', $uuid);\n        $this->assertSame($string, $uuid->toString());\n        $this->assertSame($version, $uuid->getVersion());\n        $this->assertSame($variant, $uuid->getVariant());\n\n        $components = explode('-', $string);\n\n        $this->assertSame($components[0], $uuid->getTimeLowHex());\n        $this->assertSame($components[1], $uuid->getTimeMidHex());\n        $this->assertSame($components[2], $uuid->getTimeHiAndVersionHex());\n        $this->assertSame($components[3], $uuid->getClockSeqHiAndReservedHex() . $uuid->getClockSeqLowHex());\n        $this->assertSame($components[4], $uuid->getNodeHex());\n        $this->assertSame($integer, (string) $uuid->getInteger());\n        $this->assertSame($bytes, $uuid->getBytes());\n    }\n\n    public function provideFromStringInteger()\n    {\n        return [\n            ['00000000-0000-0000-0000-000000000000', null, 0, '0'],\n            ['ff6f8cb0-c57d-11e1-8b21-0800200c9a66', 1, 2, '339532337419071774304650190139318639206'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 1, 2, '339532337419071774305803111643925486182'],\n            ['ff6f8cb0-c57d-11e1-ab21-0800200c9a66', 1, 2, '339532337419071774306956033148532333158'],\n            ['ff6f8cb0-c57d-11e1-bb21-0800200c9a66', 1, 2, '339532337419071774308108954653139180134'],\n            ['ff6f8cb0-c57d-21e1-8b21-0800200c9a66', 2, 2, '339532337419071849862513916053642058342'],\n            ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66', 2, 2, '339532337419071849863666837558248905318'],\n            ['ff6f8cb0-c57d-21e1-ab21-0800200c9a66', 2, 2, '339532337419071849864819759062855752294'],\n            ['ff6f8cb0-c57d-21e1-bb21-0800200c9a66', 2, 2, '339532337419071849865972680567462599270'],\n            ['ff6f8cb0-c57d-31e1-8b21-0800200c9a66', 3, 2, '339532337419071925420377641967965477478'],\n            ['ff6f8cb0-c57d-31e1-9b21-0800200c9a66', 3, 2, '339532337419071925421530563472572324454'],\n            ['ff6f8cb0-c57d-31e1-ab21-0800200c9a66', 3, 2, '339532337419071925422683484977179171430'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 3, 2, '339532337419071925423836406481786018406'],\n            ['ff6f8cb0-c57d-41e1-8b21-0800200c9a66', 4, 2, '339532337419072000978241367882288896614'],\n            ['ff6f8cb0-c57d-41e1-9b21-0800200c9a66', 4, 2, '339532337419072000979394289386895743590'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 4, 2, '339532337419072000980547210891502590566'],\n            ['ff6f8cb0-c57d-41e1-bb21-0800200c9a66', 4, 2, '339532337419072000981700132396109437542'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 5, 2, '339532337419072076536105093796612315750'],\n            ['ff6f8cb0-c57d-51e1-9b21-0800200c9a66', 5, 2, '339532337419072076537258015301219162726'],\n            ['ff6f8cb0-c57d-51e1-ab21-0800200c9a66', 5, 2, '339532337419072076538410936805826009702'],\n            ['ff6f8cb0-c57d-51e1-bb21-0800200c9a66', 5, 2, '339532337419072076539563858310432856678'],\n            ['ff6f8cb0-c57d-01e1-0b21-0800200c9a66', null, 0, '339532337419071698737563092188140444262'],\n            ['ff6f8cb0-c57d-01e1-1b21-0800200c9a66', null, 0, '339532337419071698738716013692747291238'],\n            ['ff6f8cb0-c57d-01e1-2b21-0800200c9a66', null, 0, '339532337419071698739868935197354138214'],\n            ['ff6f8cb0-c57d-01e1-3b21-0800200c9a66', null, 0, '339532337419071698741021856701960985190'],\n            ['ff6f8cb0-c57d-01e1-4b21-0800200c9a66', null, 0, '339532337419071698742174778206567832166'],\n            ['ff6f8cb0-c57d-01e1-5b21-0800200c9a66', null, 0, '339532337419071698743327699711174679142'],\n            ['ff6f8cb0-c57d-01e1-6b21-0800200c9a66', null, 0, '339532337419071698744480621215781526118'],\n            ['ff6f8cb0-c57d-01e1-7b21-0800200c9a66', null, 0, '339532337419071698745633542720388373094'],\n            ['ff6f8cb0-c57d-01e1-cb21-0800200c9a66', null, 6, '339532337419071698751398150243422607974'],\n            ['ff6f8cb0-c57d-01e1-db21-0800200c9a66', null, 6, '339532337419071698752551071748029454950'],\n            ['ff6f8cb0-c57d-01e1-eb21-0800200c9a66', null, 7, '339532337419071698753703993252636301926'],\n            ['ff6f8cb0-c57d-01e1-fb21-0800200c9a66', null, 7, '339532337419071698754856914757243148902'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', null, 7, '340282366920938463463374607431768211455'],\n        ];\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetSetFactory()\n    {\n        $this->assertInstanceOf('Ramsey\\Uuid\\UuidFactory', Uuid::getFactory());\n\n        $factory = \\Mockery::mock('Ramsey\\Uuid\\UuidFactory');\n        Uuid::setFactory($factory);\n\n        $this->assertSame($factory, Uuid::getFactory());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testFactoryProvidesFunctionality()\n    {\n        $uuid = \\Mockery::mock('Ramsey\\Uuid\\UuidInterface');\n\n        $factory = \\Mockery::mock('Ramsey\\Uuid\\UuidFactoryInterface', [\n            'uuid1' => $uuid,\n            'uuid3' => $uuid,\n            'uuid4' => $uuid,\n            'uuid5' => $uuid,\n            'fromBytes' => $uuid,\n            'fromString' => $uuid,\n            'fromInteger' => $uuid,\n        ]);\n\n        Uuid::setFactory($factory);\n\n        $this->assertSame($uuid, Uuid::uuid1('ffffffffffff', 0xffff));\n        $this->assertSame($uuid, Uuid::uuid3(Uuid::NAMESPACE_URL, 'https://example.com/foo'));\n        $this->assertSame($uuid, Uuid::uuid4());\n        $this->assertSame($uuid, Uuid::uuid5(Uuid::NAMESPACE_URL, 'https://example.com/foo'));\n        $this->assertSame($uuid, Uuid::fromBytes(hex2bin('ffffffffffffffffffffffffffffffff')));\n        $this->assertSame($uuid, Uuid::fromString('ffffffff-ffff-ffff-ffff-ffffffffffff'));\n        $this->assertSame($uuid, Uuid::fromInteger('340282366920938463463374607431768211455'));\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testUsingDegradedFeatures()\n    {\n        $numberConverter = new DegradedNumberConverter();\n        $builder = new DegradedUuidBuilder($numberConverter);\n\n        $factory = new UuidFactory();\n        $factory->setNumberConverter($numberConverter);\n        $factory->setUuidBuilder($builder);\n\n        Uuid::setFactory($factory);\n\n        $uuid = Uuid::uuid1();\n\n        $this->assertInstanceOf('Ramsey\\Uuid\\UuidInterface', $uuid);\n        $this->assertInstanceOf('Ramsey\\Uuid\\DegradedUuid', $uuid);\n        $this->assertInstanceOf('Ramsey\\Uuid\\Converter\\Number\\DegradedNumberConverter', $uuid->getNumberConverter());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testUsingCustomCodec()\n    {\n        $mockUuid = \\Mockery::mock('Ramsey\\Uuid\\UuidInterface');\n\n        $codec = \\Mockery::mock('Ramsey\\Uuid\\Codec\\CodecInterface', [\n            'encode' => 'abcd1234',\n            'encodeBinary' => hex2bin('abcd1234'),\n            'decode' => $mockUuid,\n            'decodeBytes' => $mockUuid,\n        ]);\n\n        $factory = new UuidFactory();\n        $factory->setCodec($codec);\n\n        Uuid::setFactory($factory);\n\n        $uuid = Uuid::uuid4();\n\n        $this->assertSame('abcd1234', $uuid->toString());\n        $this->assertSame(hex2bin('abcd1234'), $uuid->getBytes());\n        $this->assertSame($mockUuid, Uuid::fromString('f00ba2'));\n        $this->assertSame($mockUuid, Uuid::fromBytes(hex2bin('f00ba2')));\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testUsingCustomRandomGenerator()\n    {\n        $generator = \\Mockery::mock('Ramsey\\Uuid\\Generator\\RandomGeneratorInterface', [\n            'generate' => hex2bin('01234567abcd5432dcba0123456789ab'),\n        ]);\n\n        $factory = new UuidFactory();\n        $factory->setRandomGenerator($generator);\n\n        Uuid::setFactory($factory);\n\n        $uuid = Uuid::uuid4();\n\n        $this->assertSame('01234567-abcd-4432-9cba-0123456789ab', $uuid->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testUsingCustomTimeGenerator()\n    {\n        $generator = \\Mockery::mock('Ramsey\\Uuid\\Generator\\TimeGeneratorInterface', [\n            'generate' => hex2bin('01234567abcd5432dcba0123456789ab'),\n        ]);\n\n        $factory = new UuidFactory();\n        $factory->setTimeGenerator($generator);\n\n        Uuid::setFactory($factory);\n\n        $uuid = Uuid::uuid1();\n\n        $this->assertSame('01234567-abcd-1432-9cba-0123456789ab', $uuid->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testUsingDefaultTimeGeneratorWithCustomProviders()\n    {\n        $nodeProvider = \\Mockery::mock('Ramsey\\Uuid\\Provider\\NodeProviderInterface', [\n            'getNode' => new Hexadecimal('0123456789ab'),\n        ]);\n\n        $timeConverter = \\Mockery::mock('Ramsey\\Uuid\\Converter\\TimeConverterInterface');\n        $timeConverter\n            ->shouldReceive('calculateTime')\n            ->andReturnUsing(function ($seconds, $microseconds) {\n                return new Hexadecimal('abcd' . dechex($microseconds) . dechex($seconds));\n            });\n\n        $timeProvider = \\Mockery::mock('Ramsey\\Uuid\\Provider\\TimeProviderInterface', [\n            'currentTime' => [\n                'sec' => 1578522046,\n                'usec' => 10000,\n            ],\n            'getTime' => new Time(1578522046, 10000),\n        ]);\n\n        $generator = new DefaultTimeGenerator($nodeProvider, $timeConverter, $timeProvider);\n\n        $factory = new UuidFactory();\n        $factory->setTimeGenerator($generator);\n\n        Uuid::setFactory($factory);\n\n        $uuid = Uuid::uuid1(null, 4095);\n\n        $this->assertSame('5e1655be-2710-1bcd-8fff-0123456789ab', $uuid->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testHelperFunctions()\n    {\n        $uuid1 = \\Mockery::mock('Ramsey\\Uuid\\UuidInterface', [\n            'toString' => 'aVersion1Uuid',\n        ]);\n        $uuid3 = \\Mockery::mock('Ramsey\\Uuid\\UuidInterface', [\n            'toString' => 'aVersion3Uuid',\n        ]);\n        $uuid4 = \\Mockery::mock('Ramsey\\Uuid\\UuidInterface', [\n            'toString' => 'aVersion4Uuid',\n        ]);\n        $uuid5 = \\Mockery::mock('Ramsey\\Uuid\\UuidInterface', [\n            'toString' => 'aVersion5Uuid',\n        ]);\n\n        $factory = \\Mockery::mock('Ramsey\\Uuid\\UuidFactoryInterface', [\n            'uuid1' => $uuid1,\n            'uuid3' => $uuid3,\n            'uuid4' => $uuid4,\n            'uuid5' => $uuid5,\n        ]);\n\n        Uuid::setFactory($factory);\n\n        $this->assertSame('aVersion1Uuid', \\Ramsey\\Uuid\\v1('ffffffffffff', 0xffff));\n        $this->assertSame('aVersion3Uuid', \\Ramsey\\Uuid\\v3(Uuid::NAMESPACE_URL, 'https://example.com/foo'));\n        $this->assertSame('aVersion4Uuid', \\Ramsey\\Uuid\\v4());\n        $this->assertSame('aVersion5Uuid', \\Ramsey\\Uuid\\v5(Uuid::NAMESPACE_URL, 'https://example.com/foo'));\n    }\n\n    /**\n     * @link https://git.io/JvJZo Use of TimestampFirstCombCodec in laravel/framework\n     */\n    public function testUseOfTimestampFirstCombCodec()\n    {\n        $factory = new UuidFactory();\n\n        $factory->setRandomGenerator(new CombGenerator(\n            $factory->getRandomGenerator(),\n            $factory->getNumberConverter()\n        ));\n\n        $factory->setCodec(new TimestampFirstCombCodec(\n            $factory->getUuidBuilder()\n        ));\n\n        $uuid = $factory->uuid4();\n\n        // Swap fields according to the rules for TimestampFirstCombCodec.\n        $fields = array_values($uuid->getFieldsHex());\n        $last48Bits = $fields[5];\n        $fields[5] = $fields[0] . $fields[1];\n        $fields[0] = substr($last48Bits, 0, 8);\n        $fields[1] = substr($last48Bits, 8, 4);\n\n        $expectedHex = implode('', $fields);\n        $expectedBytes = hex2bin($expectedHex);\n\n        $this->assertInstanceOf('Ramsey\\Uuid\\UuidInterface', $uuid);\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(4, $uuid->getVersion());\n        $this->assertSame($expectedBytes, $uuid->getBytes());\n        $this->assertSame($expectedHex, (string) $uuid->getHex());\n    }\n\n    /**\n     * @dataProvider provideUuidConstantTests\n     */\n    public function testUuidConstants($constantName, $expected)\n    {\n        $this->assertSame($expected, constant(\"Ramsey\\\\Uuid\\\\Uuid::{$constantName}\"));\n    }\n\n    public function provideUuidConstantTests()\n    {\n        return [\n            ['NAMESPACE_DNS', '6ba7b810-9dad-11d1-80b4-00c04fd430c8'],\n            ['NAMESPACE_URL', '6ba7b811-9dad-11d1-80b4-00c04fd430c8'],\n            ['NAMESPACE_OID', '6ba7b812-9dad-11d1-80b4-00c04fd430c8'],\n            ['NAMESPACE_X500', '6ba7b814-9dad-11d1-80b4-00c04fd430c8'],\n            ['NIL', '00000000-0000-0000-0000-000000000000'],\n            ['MAX', 'ffffffff-ffff-ffff-ffff-ffffffffffff'],\n            ['RESERVED_NCS', 0],\n            ['RFC_4122', 2],\n            ['RESERVED_MICROSOFT', 6],\n            ['RESERVED_FUTURE', 7],\n            ['VALID_PATTERN', '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$'],\n            ['UUID_TYPE_TIME', 1],\n            ['UUID_TYPE_IDENTIFIER', 2],\n            ['UUID_TYPE_HASH_MD5', 3],\n            ['UUID_TYPE_RANDOM', 4],\n            ['UUID_TYPE_HASH_SHA1', 5],\n            ['UUID_TYPE_REORDERED_TIME', 6],\n            ['UUID_TYPE_UNIX_TIME', 7],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/FeatureSetTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Builder\\FallbackBuilder;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\FeatureSet;\nuse Ramsey\\Uuid\\Generator\\DefaultNameGenerator;\nuse Ramsey\\Uuid\\Generator\\PeclUuidTimeGenerator;\nuse Ramsey\\Uuid\\Generator\\UnixTimeGenerator;\nuse Ramsey\\Uuid\\Guid\\GuidBuilder;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Validator\\ValidatorInterface;\n\nclass FeatureSetTest extends TestCase\n{\n    public function testGuidBuilderIsSelected(): void\n    {\n        $featureSet = new FeatureSet(true, true);\n\n        $this->assertInstanceOf(GuidBuilder::class, $featureSet->getBuilder());\n    }\n\n    public function testFallbackBuilderIsSelected(): void\n    {\n        $featureSet = new FeatureSet(false, true);\n\n        $this->assertInstanceOf(FallbackBuilder::class, $featureSet->getBuilder());\n    }\n\n    public function testSetValidatorSetsTheProvidedValidator(): void\n    {\n        $validator = Mockery::mock(ValidatorInterface::class);\n\n        $featureSet = new FeatureSet();\n        $featureSet->setValidator($validator);\n\n        $this->assertSame($validator, $featureSet->getValidator());\n    }\n\n    public function testGetTimeConverter(): void\n    {\n        $featureSet = new FeatureSet();\n\n        /** @phpstan-ignore method.alreadyNarrowedType */\n        $this->assertInstanceOf(TimeConverterInterface::class, $featureSet->getTimeConverter());\n    }\n\n    public function testDefaultNameGeneratorIsSelected(): void\n    {\n        $featureSet = new FeatureSet();\n\n        $this->assertInstanceOf(DefaultNameGenerator::class, $featureSet->getNameGenerator());\n    }\n\n    public function testPeclUuidTimeGeneratorIsSelected(): void\n    {\n        $featureSet = new FeatureSet(false, false, false, false, true);\n\n        $this->assertInstanceOf(PeclUuidTimeGenerator::class, $featureSet->getTimeGenerator());\n    }\n\n    public function testGetCalculator(): void\n    {\n        $featureSet = new FeatureSet();\n\n        $this->assertInstanceOf(BrickMathCalculator::class, $featureSet->getCalculator());\n    }\n\n    public function testSetNodeProvider(): void\n    {\n        $nodeProvider = Mockery::mock(NodeProviderInterface::class);\n        $featureSet = new FeatureSet();\n        $featureSet->setNodeProvider($nodeProvider);\n\n        $this->assertSame($nodeProvider, $featureSet->getNodeProvider());\n    }\n\n    public function testGetUnixTimeGenerator(): void\n    {\n        $featureSet = new FeatureSet();\n\n        $this->assertInstanceOf(UnixTimeGenerator::class, $featureSet->getUnixTimeGenerator());\n    }\n}\n"
  },
  {
    "path": "tests/FunctionsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV7;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV8;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function Ramsey\\Uuid\\v1;\nuse function Ramsey\\Uuid\\v2;\nuse function Ramsey\\Uuid\\v3;\nuse function Ramsey\\Uuid\\v4;\nuse function Ramsey\\Uuid\\v5;\nuse function Ramsey\\Uuid\\v6;\nuse function Ramsey\\Uuid\\v7;\nuse function Ramsey\\Uuid\\v8;\n\nclass FunctionsTest extends TestCase\n{\n    public function testV1ReturnsVersion1UuidString(): void\n    {\n        $v1 = v1();\n\n        $this->assertIsString($v1);\n        $this->assertSame(Uuid::UUID_TYPE_TIME, Uuid::fromString($v1)->getVersion());\n    }\n\n    public function testV2ReturnsVersion2UuidString(): void\n    {\n        $v2 = v2(\n            Uuid::DCE_DOMAIN_PERSON,\n            new IntegerObject('1004'),\n            new Hexadecimal('aabbccdd0011'),\n            63\n        );\n\n        /** @var FieldsInterface $fields */\n        $fields = Uuid::fromString($v2)->getFields();\n\n        $this->assertIsString($v2);\n        $this->assertSame(Uuid::UUID_TYPE_DCE_SECURITY, $fields->getVersion());\n    }\n\n    public function testV3ReturnsVersion3UuidString(): void\n    {\n        $ns = Uuid::fromString(Uuid::NAMESPACE_URL);\n        $v3 = v3($ns, 'https://example.com/foo');\n\n        $this->assertIsString($v3);\n        $this->assertSame(Uuid::UUID_TYPE_HASH_MD5, Uuid::fromString($v3)->getVersion());\n    }\n\n    public function testV4ReturnsVersion4UuidString(): void\n    {\n        $v4 = v4();\n\n        $this->assertIsString($v4);\n        $this->assertSame(Uuid::UUID_TYPE_RANDOM, Uuid::fromString($v4)->getVersion());\n    }\n\n    public function testV5ReturnsVersion5UuidString(): void\n    {\n        $ns = Uuid::fromString(Uuid::NAMESPACE_URL);\n        $v5 = v5($ns, 'https://example.com/foo');\n\n        $this->assertIsString($v5);\n        $this->assertSame(Uuid::UUID_TYPE_HASH_SHA1, Uuid::fromString($v5)->getVersion());\n    }\n\n    public function testV6ReturnsVersion6UuidString(): void\n    {\n        $v6 = v6(\n            new Hexadecimal('aabbccdd0011'),\n            1234\n        );\n\n        /** @var FieldsInterface $fields */\n        $fields = Uuid::fromString($v6)->getFields();\n\n        $this->assertIsString($v6);\n        $this->assertSame(Uuid::UUID_TYPE_REORDERED_TIME, $fields->getVersion());\n    }\n\n    public function testV7ReturnsVersion7UuidString(): void\n    {\n        $v7 = v7();\n\n        /** @var UuidV7 $uuid */\n        $uuid = Uuid::fromString($v7);\n\n        /** @var FieldsInterface $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertIsString($v7);\n        $this->assertSame(Uuid::UUID_TYPE_UNIX_TIME, $fields->getVersion());\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n    }\n\n    public function testV7WithCustomDateTimeReturnsVersion7UuidString(): void\n    {\n        $dateTime = new DateTimeImmutable('2022-09-14T22:44:33+00:00');\n\n        $v7 = v7($dateTime);\n\n        /** @var UuidV7 $uuid */\n        $uuid = Uuid::fromString($v7);\n\n        /** @var FieldsInterface $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertIsString($v7);\n        $this->assertSame(Uuid::UUID_TYPE_UNIX_TIME, $fields->getVersion());\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n        $this->assertSame(1663195473, $uuid->getDateTime()->getTimestamp());\n    }\n\n    public function testV8ReturnsVersion8UuidString(): void\n    {\n        $v8 = v8(\"\\x00\\x11\\x22\\x33\\x44\\x55\\x66\\x77\\x88\\x99\\xaa\\xbb\\xcc\\xdd\\xee\\xff\");\n\n        /** @var UuidV8 $uuid */\n        $uuid = Uuid::fromString($v8);\n\n        /** @var FieldsInterface $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertIsString($v8);\n        $this->assertSame(Uuid::UUID_TYPE_CUSTOM, $fields->getVersion());\n    }\n}\n"
  },
  {
    "path": "tests/Generator/CombGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Generator\\CombGenerator;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nuse function bin2hex;\nuse function dechex;\nuse function hex2bin;\nuse function str_pad;\n\nuse const STR_PAD_LEFT;\n\nclass CombGeneratorTest extends TestCase\n{\n    private int $timestampBytes = 6;\n\n    public function testGenerateUsesRandomGeneratorWithLengthMinusTimestampBytes(): void\n    {\n        $length = 10;\n        $expectedLength = $length - $this->timestampBytes;\n\n        /** @var MockObject & RandomGeneratorInterface $randomGenerator */\n        $randomGenerator = $this->getMockBuilder(RandomGeneratorInterface::class)->getMock();\n        $randomGenerator->expects($this->once())\n            ->method('generate')\n            ->with($expectedLength);\n\n        /** @var MockObject & NumberConverterInterface $converter */\n        $converter = $this->getMockBuilder(NumberConverterInterface::class)->getMock();\n\n        $generator = new CombGenerator($randomGenerator, $converter);\n        $generator->generate($length);\n    }\n\n    public function testGenerateCalculatesPaddedHexStringFromCurrentTimestamp(): void\n    {\n        /** @var MockObject & RandomGeneratorInterface $randomGenerator */\n        $randomGenerator = $this->getMockBuilder(RandomGeneratorInterface::class)->getMock();\n\n        /** @var MockObject & NumberConverterInterface $converter */\n        $converter = $this->getMockBuilder(NumberConverterInterface::class)->getMock();\n        $converter->expects($this->once())\n            ->method('toHex')\n            ->with($this->isType('string'));\n\n        $generator = new CombGenerator($randomGenerator, $converter);\n        $generator->generate(10);\n    }\n\n    public function testGenerateReturnsBinaryStringCreatedFromGeneratorAndConverter(): void\n    {\n        $length = 20;\n        $hash = dechex(1234567891);\n        $timeHash = dechex(1458147405);\n\n        /** @var MockObject & RandomGeneratorInterface $randomGenerator */\n        $randomGenerator = $this->getMockBuilder(RandomGeneratorInterface::class)->getMock();\n        $randomGenerator->method('generate')\n            ->with($length - $this->timestampBytes)\n            ->willReturn($hash);\n\n        /** @var MockObject & NumberConverterInterface $converter */\n        $converter = $this->getMockBuilder(NumberConverterInterface::class)->getMock();\n        $converter->method('toHex')\n            ->with($this->isType('string'))\n            ->willReturn($timeHash);\n\n        $time = str_pad($timeHash, 12, '0', STR_PAD_LEFT);\n        $expected = hex2bin(str_pad(bin2hex($hash), $length - $this->timestampBytes, '0')) . hex2bin($time);\n\n        $generator = new CombGenerator($randomGenerator, $converter);\n        $returned = $generator->generate($length);\n        $this->assertIsString($returned);\n        $this->assertSame($expected, $returned);\n    }\n\n    /**\n     * @return array<array{0: int}>\n     */\n    public function lengthLessThanSix(): array\n    {\n        return [[0], [1], [2], [3], [4], [5]];\n    }\n\n    /**\n     * @param int<1, max> $length\n     *\n     * @dataProvider lengthLessThanSix\n     */\n    public function testGenerateWithLessThanTimestampBytesThrowsException(int $length): void\n    {\n        /** @var MockObject & RandomGeneratorInterface $randomGenerator */\n        $randomGenerator = $this->getMockBuilder(RandomGeneratorInterface::class)->getMock();\n\n        /** @var MockObject & NumberConverterInterface $converter */\n        $converter = $this->getMockBuilder(NumberConverterInterface::class)->getMock();\n\n        $generator = new CombGenerator($randomGenerator, $converter);\n\n        $this->expectException(InvalidArgumentException::class);\n        $generator->generate($length);\n    }\n\n    public function testGenerateWithOddNumberOverTimestampBytesCausesError(): void\n    {\n        /** @var MockObject & RandomGeneratorInterface $randomGenerator */\n        $randomGenerator = $this->getMockBuilder(RandomGeneratorInterface::class)->getMock();\n\n        /** @var MockObject & NumberConverterInterface $converter */\n        $converter = $this->getMockBuilder(NumberConverterInterface::class)->getMock();\n\n        $generator = new CombGenerator($randomGenerator, $converter);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Length must be an even number');\n\n        $generator->generate(7);\n    }\n}\n"
  },
  {
    "path": "tests/Generator/DceSecurityGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Exception\\DceSecurityException;\nuse Ramsey\\Uuid\\Generator\\DceSecurityGenerator;\nuse Ramsey\\Uuid\\Generator\\DefaultTimeGenerator;\nuse Ramsey\\Uuid\\Generator\\TimeGeneratorInterface;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Provider\\DceSecurityProviderInterface;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Provider\\Time\\FixedTimeProvider;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function bin2hex;\nuse function substr;\n\nclass DceSecurityGeneratorTest extends TestCase\n{\n    /**\n     * @param int|string $uid\n     * @param int|string $gid\n     * @param int|string $seconds\n     * @param int|string $microseconds\n     *\n     * @dataProvider provideValuesForDceSecurityGenerator\n     */\n    public function testGenerateBytesReplacesBytesWithDceValues(\n        $uid,\n        $gid,\n        string $node,\n        $seconds,\n        $microseconds,\n        int $providedDomain,\n        ?IntegerObject $providedId,\n        ?Hexadecimal $providedNode,\n        string $expectedId,\n        string $expectedDomain,\n        string $expectedNode,\n        string $expectedTimeMidHi\n    ): void {\n        /** @var DceSecurityProviderInterface $dceSecurityProvider */\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class, [\n            'getUid' => new IntegerObject($uid),\n            'getGid' => new IntegerObject($gid),\n        ]);\n\n        /** @var NodeProviderInterface $nodeProvider */\n        $nodeProvider = Mockery::mock(NodeProviderInterface::class, [\n            'getNode' => new Hexadecimal($node),\n        ]);\n\n        $timeProvider = new FixedTimeProvider(new Time($seconds, $microseconds));\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n        $timeConverter = new GenericTimeConverter($calculator);\n        $timeGenerator = new DefaultTimeGenerator($nodeProvider, $timeConverter, $timeProvider);\n\n        $dceSecurityGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $bytes = $dceSecurityGenerator->generate($providedDomain, $providedId, $providedNode);\n\n        $this->assertSame($expectedId, bin2hex(substr($bytes, 0, 4)));\n        $this->assertSame($expectedDomain, bin2hex(substr($bytes, 9, 1)));\n        $this->assertSame($expectedNode, bin2hex(substr($bytes, 10)));\n        $this->assertSame($expectedTimeMidHi, bin2hex(substr($bytes, 4, 4)));\n    }\n\n    /**\n     * @return array<array{uid: int|string, node: string, seconds: int, microseconds: int, providedDomain: int, providedId: IntegerObject|null, providedNode: null, expectedId: string, expectedDomain: string, expectedNode: string, expectedTimeMidHi: string}>\n     */\n    public function provideValuesForDceSecurityGenerator(): array\n    {\n        return [\n            [\n                'uid' => '1001',\n                'gid' => '2001',\n                'node' => '001122334455',\n                'seconds' => 1579132397,\n                'microseconds' => 500000,\n                'providedDomain' => Uuid::DCE_DOMAIN_PERSON,\n                'providedId' => null,\n                'providedNode' => null,\n                'expectedId' => '000003e9',\n                'expectedDomain' => '00',\n                'expectedNode' => '001122334455',\n                'expectedTimeMidHi' => '37f201ea',\n            ],\n            [\n                'uid' => '1001',\n                'gid' => '2001',\n                'node' => '001122334455',\n                'seconds' => 1579132397,\n                'microseconds' => 500000,\n                'providedDomain' => Uuid::DCE_DOMAIN_GROUP,\n                'providedId' => null,\n                'providedNode' => null,\n                'expectedId' => '000007d1',\n                'expectedDomain' => '01',\n                'expectedNode' => '001122334455',\n                'expectedTimeMidHi' => '37f201ea',\n            ],\n            [\n                'uid' => 0,\n                'gid' => 0,\n                'node' => '001122334455',\n                'seconds' => 1579132397,\n                'microseconds' => 500000,\n                'providedDomain' => Uuid::DCE_DOMAIN_ORG,\n                'providedId' => new IntegerObject('4294967295'),\n                'providedNode' => null,\n                'expectedId' => 'ffffffff',\n                'expectedDomain' => '02',\n                'expectedNode' => '001122334455',\n                'expectedTimeMidHi' => '37f201ea',\n            ],\n        ];\n    }\n\n    public function testGenerateThrowsExceptionForInvalidDomain(): void\n    {\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n\n        $generator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage('Local domain must be a valid DCE Security domain');\n\n        $generator->generate(42);\n    }\n\n    public function testGenerateThrowsExceptionForOrgWithoutIdentifier(): void\n    {\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $timeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n\n        $generator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage('A local identifier must be provided for the org domain');\n\n        $generator->generate(Uuid::DCE_DOMAIN_ORG);\n    }\n\n    public function testClockSequenceLowerBounds(): void\n    {\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n        $nodeProvider = Mockery::mock(NodeProviderInterface::class);\n        $timeProvider = new FixedTimeProvider(new Time(1583527677, 111984));\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n        $timeConverter = new GenericTimeConverter($calculator);\n        $timeGenerator = new DefaultTimeGenerator($nodeProvider, $timeConverter, $timeProvider);\n\n        $dceSecurityGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $bytes = $dceSecurityGenerator->generate(\n            Uuid::DCE_DOMAIN_ORG,\n            new IntegerObject(1001),\n            new Hexadecimal('0123456789ab'),\n            0\n        );\n\n        $hex = bin2hex($bytes);\n\n        $this->assertSame('000003e9', substr($hex, 0, 8));\n        $this->assertSame('5feb01ea', substr($hex, 8, 8));\n        $this->assertSame('00', substr($hex, 16, 2));\n        $this->assertSame('02', substr($hex, 18, 2));\n        $this->assertSame('0123456789ab', substr($hex, 20));\n    }\n\n    public function testClockSequenceUpperBounds(): void\n    {\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n        $nodeProvider = Mockery::mock(NodeProviderInterface::class);\n        $timeProvider = new FixedTimeProvider(new Time(1583527677, 111984));\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n        $timeConverter = new GenericTimeConverter($calculator);\n        $timeGenerator = new DefaultTimeGenerator($nodeProvider, $timeConverter, $timeProvider);\n\n        $dceSecurityGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $bytes = $dceSecurityGenerator->generate(\n            Uuid::DCE_DOMAIN_ORG,\n            new IntegerObject(1001),\n            new Hexadecimal('0123456789ab'),\n            63\n        );\n\n        $hex = bin2hex($bytes);\n\n        $this->assertSame('000003e9', substr($hex, 0, 8));\n        $this->assertSame('5feb01ea', substr($hex, 8, 8));\n        $this->assertSame('3f', substr($hex, 16, 2));\n        $this->assertSame('02', substr($hex, 18, 2));\n        $this->assertSame('0123456789ab', substr($hex, 20));\n    }\n\n    public function testExceptionThrownWhenClockSequenceTooLow(): void\n    {\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n        $timeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n\n        $dceSecurityGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Clock sequence out of bounds; it must be a value between 0 and 63'\n        );\n\n        $dceSecurityGenerator->generate(Uuid::DCE_DOMAIN_ORG, null, null, -1);\n    }\n\n    public function testExceptionThrownWhenClockSequenceTooHigh(): void\n    {\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n        $timeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n\n        $dceSecurityGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Clock sequence out of bounds; it must be a value between 0 and 63'\n        );\n\n        $dceSecurityGenerator->generate(Uuid::DCE_DOMAIN_ORG, null, null, 64);\n    }\n\n    public function testExceptionThrownWhenLocalIdTooLow(): void\n    {\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n        $timeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n\n        $dceSecurityGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Local identifier out of bounds; it must be a value between 0 and 4294967295'\n        );\n\n        $dceSecurityGenerator->generate(Uuid::DCE_DOMAIN_ORG, new IntegerObject(-1));\n    }\n\n    public function testExceptionThrownWhenLocalIdTooHigh(): void\n    {\n        $dceSecurityProvider = Mockery::mock(DceSecurityProviderInterface::class);\n        $timeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n\n        $dceSecurityGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceSecurityProvider);\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Local identifier out of bounds; it must be a value between 0 and 4294967295'\n        );\n\n        $dceSecurityGenerator->generate(Uuid::DCE_DOMAIN_ORG, new IntegerObject('4294967296'));\n    }\n}\n"
  },
  {
    "path": "tests/Generator/DefaultNameGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Ramsey\\Uuid\\Exception\\NameException;\nuse Ramsey\\Uuid\\Generator\\DefaultNameGenerator;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function hash;\n\nclass DefaultNameGeneratorTest extends TestCase\n{\n    /**\n     * @param non-empty-string $ns\n     * @param non-empty-string $name\n     * @param non-empty-string $algorithm\n     *\n     * @dataProvider provideNamesForHashingTest\n     */\n    public function testDefaultNameGeneratorHashesName(string $ns, string $name, string $algorithm): void\n    {\n        $namespace = Uuid::fromString($ns);\n        $expectedBytes = hash($algorithm, $namespace->getBytes() . $name, true);\n\n        $generator = new DefaultNameGenerator();\n\n        $this->assertSame($expectedBytes, $generator->generate($namespace, $name, $algorithm));\n    }\n\n    /**\n     * @return array<array{ns: non-empty-string, name: non-empty-string, algorithm: non-empty-string}>\n     */\n    public function provideNamesForHashingTest(): array\n    {\n        return [\n            [\n                'ns' => Uuid::NAMESPACE_URL,\n                'name' => 'https://example.com/foobar',\n                'algorithm' => 'md5',\n            ],\n            [\n                'ns' => Uuid::NAMESPACE_URL,\n                'name' => 'https://example.com/foobar',\n                'algorithm' => 'sha1',\n            ],\n            [\n                'ns' => Uuid::NAMESPACE_URL,\n                'name' => 'https://example.com/foobar',\n                'algorithm' => 'sha256',\n            ],\n            [\n                'ns' => Uuid::NAMESPACE_OID,\n                'name' => '1.3.6.1.4.1.343',\n                'algorithm' => 'sha1',\n            ],\n            [\n                'ns' => Uuid::NAMESPACE_OID,\n                'name' => '1.3.6.1.4.1.52627',\n                'algorithm' => 'md5',\n            ],\n            [\n                'ns' => 'd988ae29-674e-48e7-b93c-2825e2a96fbe',\n                'name' => 'foobar',\n                'algorithm' => 'sha1',\n            ],\n        ];\n    }\n\n    public function testGenerateThrowsException(): void\n    {\n        $namespace = Uuid::fromString('cd998804-c661-4264-822c-00cada75a87b');\n        $generator = new DefaultNameGenerator();\n\n        $this->expectException(NameException::class);\n        $this->expectExceptionMessage(\n            'Unable to hash namespace and name with algorithm \\'aBadAlgorithm\\''\n        );\n\n        $generator->generate($namespace, 'a test name', 'aBadAlgorithm');\n    }\n}\n"
  },
  {
    "path": "tests/Generator/DefaultTimeGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Exception;\nuse Mockery;\nuse Mockery\\MockInterface;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\BinaryUtils;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\RandomSourceException;\nuse Ramsey\\Uuid\\Exception\\TimeSourceException;\nuse Ramsey\\Uuid\\FeatureSet;\nuse Ramsey\\Uuid\\Generator\\DefaultTimeGenerator;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Provider\\Time\\FixedTimeProvider;\nuse Ramsey\\Uuid\\Provider\\TimeProviderInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse phpmock\\mockery\\PHPMockery;\n\nuse function hex2bin;\n\nclass DefaultTimeGeneratorTest extends TestCase\n{\n    /**\n     * @var TimeProviderInterface & MockInterface\n     */\n    private $timeProvider;\n\n    /**\n     * @var NodeProviderInterface & MockObject\n     */\n    private $nodeProvider;\n\n    /**\n     * @var TimeConverterInterface & MockObject\n     */\n    private $timeConverter;\n\n    /**\n     * @var string\n     */\n    private $nodeId = '122f80ca9e06';\n\n    /**\n     * @var int[]\n     */\n    private $currentTime;\n\n    /**\n     * @var Hexadecimal\n     */\n    private $calculatedTime;\n\n    /**\n     * @var int\n     */\n    private $clockSeq = 4066;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->nodeProvider = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n        $this->timeConverter = $this->getMockBuilder(TimeConverterInterface::class)->getMock();\n        $this->currentTime = ['sec' => 1458733431, 'usec' => 877449];\n        $this->calculatedTime = new Hexadecimal('03cb98e083cb98e0');\n\n        $time = new Time($this->currentTime['sec'], $this->currentTime['usec']);\n        $this->timeProvider = Mockery::mock(TimeProviderInterface::class, [\n            'getTime' => $time,\n        ]);\n    }\n\n    protected function tearDown(): void\n    {\n        parent::tearDown();\n        unset($this->timeProvider, $this->nodeProvider, $this->timeConverter);\n        Mockery::close();\n    }\n\n    public function testGenerateUsesNodeProviderWhenNodeIsNull(): void\n    {\n        $this->nodeProvider->expects($this->once())\n            ->method('getNode')\n            ->willReturn(new Hexadecimal('122f80ca9e06'));\n        $this->timeConverter->expects($this->once())\n            ->method('calculateTime')\n            ->with($this->currentTime['sec'], $this->currentTime['usec'])\n            ->willReturn($this->calculatedTime);\n        $defaultTimeGenerator = new DefaultTimeGenerator(\n            $this->nodeProvider,\n            $this->timeConverter,\n            $this->timeProvider\n        );\n        $defaultTimeGenerator->generate(null, $this->clockSeq);\n    }\n\n    public function testGenerateUsesTimeProvidersCurrentTime(): void\n    {\n        $this->timeConverter->expects($this->once())\n            ->method('calculateTime')\n            ->with($this->currentTime['sec'], $this->currentTime['usec'])\n            ->willReturn($this->calculatedTime);\n        $defaultTimeGenerator = new DefaultTimeGenerator(\n            $this->nodeProvider,\n            $this->timeConverter,\n            $this->timeProvider\n        );\n        $defaultTimeGenerator->generate($this->nodeId, $this->clockSeq);\n    }\n\n    public function testGenerateCalculatesTimeWithConverter(): void\n    {\n        $this->timeConverter->expects($this->once())\n            ->method('calculateTime')\n            ->with($this->currentTime['sec'], $this->currentTime['usec'])\n            ->willReturn($this->calculatedTime);\n        $defaultTimeGenerator = new DefaultTimeGenerator(\n            $this->nodeProvider,\n            $this->timeConverter,\n            $this->timeProvider\n        );\n        $defaultTimeGenerator->generate($this->nodeId, $this->clockSeq);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateDoesNotApplyVersionAndVariant(): void\n    {\n        $expectedBytes = hex2bin('83cb98e098e003cb0fe2122f80ca9e06');\n\n        $this->timeConverter->method('calculateTime')\n            ->with($this->currentTime['sec'], $this->currentTime['usec'])\n            ->willReturn($this->calculatedTime);\n\n        $binaryUtils = Mockery::mock('alias:' . BinaryUtils::class);\n        $binaryUtils->shouldNotReceive('applyVersion');\n        $binaryUtils->shouldNotReceive('applyVariant');\n\n        $defaultTimeGenerator = new DefaultTimeGenerator(\n            $this->nodeProvider,\n            $this->timeConverter,\n            $this->timeProvider\n        );\n\n        $this->assertSame($expectedBytes, $defaultTimeGenerator->generate($this->nodeId, $this->clockSeq));\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateUsesRandomSequenceWhenClockSeqNull(): void\n    {\n        PHPMockery::mock('Ramsey\\Uuid\\Generator', 'random_int')\n            ->once()\n            ->with(0, 0x3fff)\n            ->andReturn(9622);\n        $this->timeConverter->expects($this->once())\n            ->method('calculateTime')\n            ->with($this->currentTime['sec'], $this->currentTime['usec'])\n            ->willReturn($this->calculatedTime);\n        $defaultTimeGenerator = new DefaultTimeGenerator(\n            $this->nodeProvider,\n            $this->timeConverter,\n            $this->timeProvider\n        );\n        $defaultTimeGenerator->generate($this->nodeId);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateThrowsExceptionWhenExceptionThrownByRandomint(): void\n    {\n        PHPMockery::mock('Ramsey\\Uuid\\Generator', 'random_int')\n            ->once()\n            ->andThrow(new Exception('Could not gather sufficient random data'));\n\n        $defaultTimeGenerator = new DefaultTimeGenerator(\n            $this->nodeProvider,\n            $this->timeConverter,\n            $this->timeProvider\n        );\n\n        $this->expectException(RandomSourceException::class);\n        $this->expectExceptionMessage('Could not gather sufficient random data');\n\n        $defaultTimeGenerator->generate($this->nodeId);\n    }\n\n    public function testDefaultTimeGeneratorThrowsExceptionForLargeGeneratedValue(): void\n    {\n        $timeProvider = new FixedTimeProvider(new Time('1832455114570', '955162'));\n        $featureSet = new FeatureSet();\n        $timeGenerator = new DefaultTimeGenerator(\n            $featureSet->getNodeProvider(),\n            $featureSet->getTimeConverter(),\n            $timeProvider\n        );\n\n        $this->expectException(TimeSourceException::class);\n        $this->expectExceptionMessage(\n            'The generated time of \\'10000000000000004\\' is larger than expected'\n        );\n\n        $timeGenerator->generate();\n    }\n}\n"
  },
  {
    "path": "tests/Generator/NameGeneratorFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Ramsey\\Uuid\\Generator\\DefaultNameGenerator;\nuse Ramsey\\Uuid\\Generator\\NameGeneratorFactory;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass NameGeneratorFactoryTest extends TestCase\n{\n    public function testGetGenerator(): void\n    {\n        $factory = new NameGeneratorFactory();\n\n        $this->assertInstanceOf(DefaultNameGenerator::class, $factory->getGenerator());\n    }\n}\n"
  },
  {
    "path": "tests/Generator/PeclUuidNameGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Ramsey\\Uuid\\BinaryUtils;\nuse Ramsey\\Uuid\\Exception\\NameException;\nuse Ramsey\\Uuid\\Generator\\PeclUuidNameGenerator;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function hash;\nuse function pack;\nuse function substr;\nuse function substr_replace;\nuse function unpack;\n\nclass PeclUuidNameGeneratorTest extends TestCase\n{\n    /**\n     * @param non-empty-string $ns\n     *\n     * @dataProvider provideNamesForHashingTest\n     * @requires extension uuid\n     */\n    public function testPeclUuidNameGeneratorHashesName(string $ns, string $name, string $algorithm): void\n    {\n        $namespace = Uuid::fromString($ns);\n        $version = $algorithm === 'md5' ? 3 : 5;\n        $expectedBytes = substr(hash($algorithm, $namespace->getBytes() . $name, true), 0, 16);\n\n        // Need to add the version and variant, since ext-uuid already includes\n        // these in the values returned.\n        /** @var int[] $unpackedTime */\n        $unpackedTime = unpack('n*', substr($expectedBytes, 6, 2));\n        $timeHi = $unpackedTime[1];\n        $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version));\n\n        /** @var int[] $unpackedClockSeq */\n        $unpackedClockSeq = unpack('n*', substr($expectedBytes, 8, 2));\n        $clockSeqHi = $unpackedClockSeq[1];\n        $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi));\n\n        $expectedBytes = substr_replace($expectedBytes, $timeHiAndVersion, 6, 2);\n        $expectedBytes = substr_replace($expectedBytes, $clockSeqHiAndReserved, 8, 2);\n\n        $generator = new PeclUuidNameGenerator();\n        $generatedBytes = $generator->generate($namespace, $name, $algorithm);\n\n        $this->assertSame(\n            $expectedBytes,\n            $generatedBytes,\n            'Expected: ' . bin2hex($expectedBytes) . '; Received: ' . bin2hex($generatedBytes)\n        );\n    }\n\n    /**\n     * @return array<array{ns: string, name: string, algorithm: string}>\n     */\n    public function provideNamesForHashingTest(): array\n    {\n        return [\n            [\n                'ns' => Uuid::NAMESPACE_URL,\n                'name' => 'https://example.com/foobar',\n                'algorithm' => 'md5',\n            ],\n            [\n                'ns' => Uuid::NAMESPACE_URL,\n                'name' => 'https://example.com/foobar',\n                'algorithm' => 'sha1',\n            ],\n            [\n                'ns' => Uuid::NAMESPACE_OID,\n                'name' => '1.3.6.1.4.1.343',\n                'algorithm' => 'sha1',\n            ],\n            [\n                'ns' => Uuid::NAMESPACE_OID,\n                'name' => '1.3.6.1.4.1.52627',\n                'algorithm' => 'md5',\n            ],\n            [\n                'ns' => 'd988ae29-674e-48e7-b93c-2825e2a96fbe',\n                'name' => 'foobar',\n                'algorithm' => 'sha1',\n            ],\n        ];\n    }\n\n    public function testGenerateThrowsException(): void\n    {\n        $namespace = Uuid::fromString('cd998804-c661-4264-822c-00cada75a87b');\n        $generator = new PeclUuidNameGenerator();\n\n        $this->expectException(NameException::class);\n        $this->expectExceptionMessage(\n            'Unable to hash namespace and name with algorithm \\'aBadAlgorithm\\''\n        );\n\n        $generator->generate($namespace, 'a test name', 'aBadAlgorithm');\n    }\n}\n"
  },
  {
    "path": "tests/Generator/PeclUuidRandomGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Ramsey\\Uuid\\Generator\\PeclUuidRandomGenerator;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\n\nclass PeclUuidRandomGeneratorTest extends TestCase\n{\n    /**\n     * @requires extension uuid\n     */\n    public function testGenerateCreatesUuidUsingPeclUuidMethods(): void\n    {\n        $generator = new PeclUuidRandomGenerator();\n        $bytes = $generator->generate(10);\n        $uuid = Uuid::fromBytes($bytes);\n\n        /** @var Fields $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertSame(16, strlen($bytes));\n        $this->assertSame(Uuid::UUID_TYPE_RANDOM, $fields->getVersion());\n    }\n}\n"
  },
  {
    "path": "tests/Generator/PeclUuidTimeGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Ramsey\\Uuid\\Generator\\PeclUuidTimeGenerator;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\n\nclass PeclUuidTimeGeneratorTest extends TestCase\n{\n    /**\n     * @requires extension uuid\n     */\n    public function testGenerateCreatesUuidUsingPeclUuidMethods(): void\n    {\n        $generator = new PeclUuidTimeGenerator();\n        $bytes = $generator->generate();\n        $uuid = Uuid::fromBytes($bytes);\n\n        /** @var Fields $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertSame(16, strlen($bytes));\n        $this->assertSame(Uuid::UUID_TYPE_TIME, $fields->getVersion());\n    }\n}\n"
  },
  {
    "path": "tests/Generator/RandomBytesGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Exception;\nuse Ramsey\\Uuid\\Exception\\RandomSourceException;\nuse Ramsey\\Uuid\\Generator\\RandomBytesGenerator;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse phpmock\\mockery\\PHPMockery;\n\nuse function hex2bin;\n\nclass RandomBytesGeneratorTest extends TestCase\n{\n    /**\n     * @return array<array{0: positive-int, 1: non-empty-string}>\n     */\n    public function lengthAndHexDataProvider(): array\n    {\n        return [\n            [6, '4f17dd046fb8'],\n            [10, '4d25f6fe5327cb04267a'],\n            [12, '1ea89f83bd49cacfdf119e24'],\n        ];\n    }\n\n    /**\n     * @param positive-int $length\n     * @param non-empty-string $hex\n     *\n     * @throws Exception\n     *\n     * @dataProvider lengthAndHexDataProvider\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateReturnsRandomBytes(int $length, string $hex): void\n    {\n        $bytes = hex2bin($hex);\n\n        PHPMockery::mock('Ramsey\\Uuid\\Generator', 'random_bytes')\n            ->once()\n            ->with($length)\n            ->andReturn($bytes);\n\n        $generator = new RandomBytesGenerator();\n\n        $this->assertSame($bytes, $generator->generate($length));\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateThrowsExceptionWhenExceptionThrownByRandomBytes(): void\n    {\n        PHPMockery::mock('Ramsey\\Uuid\\Generator', 'random_bytes')\n            ->once()\n            ->with(16)\n            ->andThrow(new Exception('Could not gather sufficient random data'));\n\n        $generator = new RandomBytesGenerator();\n\n        $this->expectException(RandomSourceException::class);\n        $this->expectExceptionMessage('Could not gather sufficient random data');\n\n        $generator->generate(16);\n    }\n}\n"
  },
  {
    "path": "tests/Generator/RandomGeneratorFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Ramsey\\Uuid\\Generator\\RandomBytesGenerator;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorFactory;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass RandomGeneratorFactoryTest extends TestCase\n{\n    public function testFactoryReturnsRandomBytesGenerator(): void\n    {\n        $generator = (new RandomGeneratorFactory())->getGenerator();\n\n        $this->assertInstanceOf(RandomBytesGenerator::class, $generator);\n    }\n}\n"
  },
  {
    "path": "tests/Generator/RandomLibAdapterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse Mockery;\nuse Mockery\\MockInterface;\nuse Ramsey\\Uuid\\Generator\\RandomLibAdapter;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse RandomLib\\Factory as RandomLibFactory;\nuse RandomLib\\Generator;\n\nclass RandomLibAdapterTest extends TestCase\n{\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testAdapterWithGeneratorDoesNotCreateGenerator(): void\n    {\n        $factory = Mockery::mock('overload:' . RandomLibFactory::class);\n        $factory->shouldNotReceive('getHighStrengthGenerator');\n\n        $generator = $this->getMockBuilder(Generator::class)\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        /** @phpstan-ignore method.alreadyNarrowedType */\n        $this->assertInstanceOf(RandomLibAdapter::class, new RandomLibAdapter($generator));\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testAdapterWithoutGeneratorCreatesGenerator(): void\n    {\n        $generator = Mockery::mock(Generator::class);\n\n        /** @var RandomLibFactory&MockInterface $factory */\n        $factory = Mockery::mock('overload:' . RandomLibFactory::class);\n        $factory->expects()->getHighStrengthGenerator()->andReturns($generator);\n\n        /** @phpstan-ignore method.alreadyNarrowedType */\n        $this->assertInstanceOf(RandomLibAdapter::class, new RandomLibAdapter());\n    }\n\n    public function testGenerateUsesGenerator(): void\n    {\n        $length = 10;\n        $generator = $this->getMockBuilder(Generator::class)\n            ->disableOriginalConstructor()\n            ->getMock();\n        $generator->expects($this->once())\n            ->method('generate')\n            ->with($length)\n            ->willReturn('foo');\n\n        $adapter = new RandomLibAdapter($generator);\n        $adapter->generate($length);\n    }\n\n    public function testGenerateReturnsString(): void\n    {\n        $generator = $this->getMockBuilder(Generator::class)\n            ->disableOriginalConstructor()\n            ->getMock();\n        $generator->expects($this->once())\n            ->method('generate')\n            ->willReturn('random-string');\n\n        $adapter = new RandomLibAdapter($generator);\n        $result = $adapter->generate(1);\n        $this->assertSame('random-string', $result);\n    }\n}\n"
  },
  {
    "path": "tests/Generator/TimeGeneratorFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Generator\\TimeGeneratorFactory;\nuse Ramsey\\Uuid\\Generator\\TimeGeneratorInterface;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Provider\\TimeProviderInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass TimeGeneratorFactoryTest extends TestCase\n{\n    public function testGeneratorReturnsNewGenerator(): void\n    {\n        /** @var MockObject & TimeProviderInterface $timeProvider */\n        $timeProvider = $this->getMockBuilder(TimeProviderInterface::class)->getMock();\n\n        /** @var MockObject & NodeProviderInterface $nodeProvider */\n        $nodeProvider = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n\n        /** @var MockObject & TimeConverterInterface $timeConverter */\n        $timeConverter = $this->getMockBuilder(TimeConverterInterface::class)->getMock();\n\n        $factory = new TimeGeneratorFactory($nodeProvider, $timeConverter, $timeProvider);\n        $generator = $factory->getGenerator();\n\n        /** @phpstan-ignore method.alreadyNarrowedType */\n        $this->assertInstanceOf(TimeGeneratorInterface::class, $generator);\n    }\n}\n"
  },
  {
    "path": "tests/Generator/UnixTimeGeneratorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Generator;\n\nuse DateTimeImmutable;\nuse Mockery;\nuse Mockery\\MockInterface;\nuse Ramsey\\Uuid\\Generator\\RandomBytesGenerator;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\UnixTimeGenerator;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass UnixTimeGeneratorTest extends TestCase\n{\n    private const ITERATIONS = 2000;\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerate(): void\n    {\n        $dateTime = new DateTimeImmutable('@1578612359.521023');\n        $expectedBytes = \"\\x01\\x6f\\x8c\\xa1\\x01\\x61\\x03\\x00\\xff\\x00\\xff\\x00\\xff\\x00\\xff\\x00\";\n\n        /** @var RandomGeneratorInterface&MockInterface $randomGenerator */\n        $randomGenerator = Mockery::mock(RandomGeneratorInterface::class);\n        $randomGenerator->expects()->generate(16)->andReturns(\n            \"\\xff\\x00\\xff\\x00\\xff\\x00\\xff\\x00\\xff\\x00\\xff\\x00\\xff\\x00\\xff\\x00\",\n        );\n\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator);\n\n        $bytes = $unixTimeGenerator->generate(null, null, $dateTime);\n\n        $this->assertSame(\n            $expectedBytes,\n            $bytes,\n            'Failed asserting that \"' . bin2hex($bytes) . '\" is equal to \"' . bin2hex($expectedBytes) . '\"',\n        );\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateProducesMonotonicResults(): void\n    {\n        $randomGenerator = new RandomBytesGenerator();\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator);\n\n        $previous = '';\n        for ($i = 0; $i < self::ITERATIONS; $i++) {\n            $bytes = $unixTimeGenerator->generate();\n            $this->assertTrue(\n                $bytes > $previous,\n                'Failed on iteration ' . $i . ' when evaluating ' . bin2hex($bytes) . ' > ' . bin2hex($previous),\n            );\n            $previous = $bytes;\n        }\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateProducesMonotonicResultsWithSameDate(): void\n    {\n        $dateTime = new DateTimeImmutable('now');\n        $randomGenerator = new RandomBytesGenerator();\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator);\n\n        $previous = '';\n        for ($i = 0; $i < self::ITERATIONS; $i++) {\n            $bytes = $unixTimeGenerator->generate(null, null, $dateTime);\n            $this->assertTrue(\n                $bytes > $previous,\n                'Failed on iteration ' . $i . ' when evaluating ' . bin2hex($bytes) . ' > ' . bin2hex($previous),\n            );\n            $previous = $bytes;\n        }\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateProducesMonotonicResultsFor32BitPath(): void\n    {\n        $randomGenerator = new RandomBytesGenerator();\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator, 4);\n\n        $previous = '';\n        for ($i = 0; $i < self::ITERATIONS; $i++) {\n            $bytes = $unixTimeGenerator->generate();\n            $this->assertTrue(\n                $bytes > $previous,\n                'Failed on iteration ' . $i . ' when evaluating ' . bin2hex($bytes) . ' > ' . bin2hex($previous),\n            );\n            $previous = $bytes;\n        }\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateProducesMonotonicResultsWithSameDateFor32BitPath(): void\n    {\n        $dateTime = new DateTimeImmutable('now');\n        $randomGenerator = new RandomBytesGenerator();\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator, 4);\n\n        $previous = '';\n        for ($i = 0; $i < self::ITERATIONS; $i++) {\n            $bytes = $unixTimeGenerator->generate(null, null, $dateTime);\n            $this->assertTrue(\n                $bytes > $previous,\n                'Failed on iteration ' . $i . ' when evaluating ' . bin2hex($bytes) . ' > ' . bin2hex($previous),\n            );\n            $previous = $bytes;\n        }\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateProducesMonotonicResultsStartingWithAllBitsSet(): void\n    {\n        /** @var RandomGeneratorInterface&MockInterface $randomGenerator */\n        $randomGenerator = Mockery::mock(RandomGeneratorInterface::class);\n        $randomGenerator->expects()->generate(16)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n        $randomGenerator->allows()->generate(10)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator);\n\n        $previous = '';\n        for ($i = 0; $i < self::ITERATIONS; $i++) {\n            $bytes = $unixTimeGenerator->generate();\n            $this->assertTrue(\n                $bytes > $previous,\n                'Failed on iteration ' . $i . ' when evaluating ' . bin2hex($bytes) . ' > ' . bin2hex($previous),\n            );\n            $previous = $bytes;\n        }\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateRollsOverWithAllBitsSetWithSameDate(): void\n    {\n        $dateTime = new DateTimeImmutable('now');\n\n        /** @var RandomGeneratorInterface&MockInterface $randomGenerator */\n        $randomGenerator = Mockery::mock(RandomGeneratorInterface::class);\n        $randomGenerator->expects()->generate(16)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n        $randomGenerator->allows()->generate(10)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator);\n\n        // We can only call this twice before the overflow kicks in, \"randomizing\" all the bits back to 1's, according to\n        // our mocked random generator. As a result, we can't run this in a loop like with the other monotonicity tests\n        // in this class; it starts failing at the third loop. This is okay, since our goal is to test the overflow.\n        $first = $unixTimeGenerator->generate(null, null, $dateTime);\n        $second = $unixTimeGenerator->generate(null, null, $dateTime);\n\n        $this->assertTrue($second > $first);\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateProducesMonotonicResultsStartingWithAllBitsSetFor32BitPath(): void\n    {\n        /** @var RandomGeneratorInterface&MockInterface $randomGenerator */\n        $randomGenerator = Mockery::mock(RandomGeneratorInterface::class);\n        $randomGenerator->expects()->generate(16)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n        $randomGenerator->allows()->generate(10)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator, 4);\n\n        $previous = '';\n        for ($i = 0; $i < self::ITERATIONS; $i++) {\n            $bytes = $unixTimeGenerator->generate();\n            $this->assertTrue(\n                $bytes > $previous,\n                'Failed on iteration ' . $i . ' when evaluating ' . bin2hex($bytes) . ' > ' . bin2hex($previous),\n            );\n            $previous = $bytes;\n        }\n    }\n\n    /**\n     * @runInSeparateProcess since values are stored statically on the class\n     * @preserveGlobalState disabled\n     */\n    public function testGenerateRollsOverWithAllBitsSetWithSameDateFor32BitPath(): void\n    {\n        $dateTime = new DateTimeImmutable('now');\n\n        /** @var RandomGeneratorInterface&MockInterface $randomGenerator */\n        $randomGenerator = Mockery::mock(RandomGeneratorInterface::class);\n        $randomGenerator->expects()->generate(16)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n        $randomGenerator->allows()->generate(10)->andReturns(\n            \"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n        );\n\n        $unixTimeGenerator = new UnixTimeGenerator($randomGenerator, 4);\n\n        // We can only call this twice before the overflow kicks in, \"randomizing\" all the bits back to 1's, according to\n        // our mocked random generator. As a result, we can't run this in a loop like with the other monotonicity tests\n        // in this class; it starts failing at the third loop. This is okay, since our goal is to test the overflow.\n        $first = $unixTimeGenerator->generate(null, null, $dateTime);\n        $second = $unixTimeGenerator->generate(null, null, $dateTime);\n\n        $this->assertTrue($second > $first);\n    }\n}\n"
  },
  {
    "path": "tests/Guid/FieldsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Guid;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Guid\\Fields;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function hex2bin;\nuse function serialize;\nuse function unserialize;\n\nclass FieldsTest extends TestCase\n{\n    public function testConstructorThrowsExceptionIfNotSixteenByteString(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'The byte string must be 16 bytes long; received 6 bytes'\n        );\n\n        new Fields('foobar');\n    }\n\n    /**\n     * @param non-empty-string $guid\n     *\n     * @dataProvider nonRfc4122GuidVariantProvider\n     */\n    public function testConstructorThrowsExceptionIfNotRfc4122Variant(string $guid): void\n    {\n        $bytes = (string) hex2bin($guid);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) or '\n            . 'Microsoft Corporation variants'\n        );\n\n        new Fields($bytes);\n    }\n\n    /**\n     * These values are already in GUID byte order, for easy testing.\n     *\n     * @return array<array{0: non-empty-string}>\n     */\n    public function nonRfc4122GuidVariantProvider(): array\n    {\n        // In string representation, the following IDs would begin as:\n        // ff6f8cb0-c57d-11e1-...\n        return [\n            ['b08c6fff7dc5e1110b210800200c9a66'],\n            ['b08c6fff7dc5e1111b210800200c9a66'],\n            ['b08c6fff7dc5e1112b210800200c9a66'],\n            ['b08c6fff7dc5e1113b210800200c9a66'],\n            ['b08c6fff7dc5e1114b210800200c9a66'],\n            ['b08c6fff7dc5e1115b210800200c9a66'],\n            ['b08c6fff7dc5e1116b210800200c9a66'],\n            ['b08c6fff7dc5e1117b210800200c9a66'],\n            ['b08c6fff7dc5e111eb210800200c9a66'],\n            ['b08c6fff7dc5e111fb210800200c9a66'],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $guid\n     *\n     * @dataProvider invalidVersionProvider\n     */\n    public function testConstructorThrowsExceptionIfInvalidVersion(string $guid): void\n    {\n        $bytes = (string) hex2bin($guid);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'The byte string received does not contain a valid version'\n        );\n\n        new Fields($bytes);\n    }\n\n    /**\n     * @return array<array{0: non-empty-string}>\n     */\n    public function invalidVersionProvider(): array\n    {\n        // The following UUIDs are in GUID byte order. Dashes have\n        // been removed in the tests to distinguish these from string\n        // representations, which are never in GUID byte order.\n        return [\n            ['b08c6fff7dc5e1018b210800200c9a66'],\n            ['b08c6fff7dc5e191bb210800200c9a66'],\n            ['b08c6fff7dc5e1a19b210800200c9a66'],\n            ['b08c6fff7dc5e1b1ab210800200c9a66'],\n            ['b08c6fff7dc5e1c1ab210800200c9a66'],\n            ['b08c6fff7dc5e1d1ab210800200c9a66'],\n            ['b08c6fff7dc5e1e1ab210800200c9a66'],\n            ['b08c6fff7dc5e1f1ab210800200c9a66'],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $bytes\n     * @param non-empty-string $methodName\n     * @param non-empty-string | bool | int | null $expectedValue\n     *\n     * @dataProvider fieldGetterMethodProvider\n     */\n    public function testFieldGetterMethods(\n        string $bytes,\n        string $methodName,\n        bool | int | string | null $expectedValue,\n    ): void {\n        $bytes = (string) hex2bin($bytes);\n        $fields = new Fields($bytes);\n\n        $result = $fields->$methodName();\n\n        if ($result instanceof Hexadecimal) {\n            $this->assertSame($expectedValue, $result->toString());\n        } else {\n            $this->assertSame($expectedValue, $result);\n        }\n    }\n\n    /**\n     * @return array<array{0: non-empty-string, 1: non-empty-string, 2: non-empty-string | int | bool | null}>\n     */\n    public function fieldGetterMethodProvider(): array\n    {\n        // The following UUIDs are in GUID byte order. Dashes have\n        // been removed in the tests to distinguish these from string\n        // representations, which are never in GUID byte order.\n        return [\n            // For ff6f8cb0-c57d-11e1-cb21-0800200c9a66\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeq', '0b21'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeqHiAndReserved', 'cb'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeqLow', '21'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getNode', '0800200c9a66'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeHiAndVersion', '11e1'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeMid', 'c57d'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getVariant', 6],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'getVersion', 1],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'isNil', false],\n            ['b08c6fff7dc5e111cb210800200c9a66', 'isMax', false],\n\n            // For ff6f8cb0-c57d-41e1-db21-0800200c9a66\n            ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeq', '1b21'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeqHiAndReserved', 'db'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeqLow', '21'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getNode', '0800200c9a66'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getTimeHiAndVersion', '41e1'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getTimeMid', 'c57d'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getVariant', 6],\n            ['b08c6fff7dc5e141db210800200c9a66', 'getVersion', 4],\n            ['b08c6fff7dc5e141db210800200c9a66', 'isNil', false],\n            ['b08c6fff7dc5e141db210800200c9a66', 'isMax', false],\n\n            // For ff6f8cb0-c57d-31e1-8b21-0800200c9a66\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeq', '0b21'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeqHiAndReserved', '8b'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeqLow', '21'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getNode', '0800200c9a66'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeHiAndVersion', '31e1'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeMid', 'c57d'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getVariant', 2],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'getVersion', 3],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'isNil', false],\n            ['b08c6fff7dc5e1318b210800200c9a66', 'isMax', false],\n\n            // For ff6f8cb0-c57d-51e1-9b21-0800200c9a66\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeq', '1b21'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeqHiAndReserved', '9b'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeqLow', '21'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getNode', '0800200c9a66'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeHiAndVersion', '51e1'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeMid', 'c57d'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getVariant', 2],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'getVersion', 5],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'isNil', false],\n            ['b08c6fff7dc5e1519b210800200c9a66', 'isMax', false],\n\n            // For 00000000-0000-0000-0000-000000000000\n            ['00000000000000000000000000000000', 'getClockSeq', '0000'],\n            ['00000000000000000000000000000000', 'getClockSeqHiAndReserved', '00'],\n            ['00000000000000000000000000000000', 'getClockSeqLow', '00'],\n            ['00000000000000000000000000000000', 'getNode', '000000000000'],\n            ['00000000000000000000000000000000', 'getTimeHiAndVersion', '0000'],\n            ['00000000000000000000000000000000', 'getTimeLow', '00000000'],\n            ['00000000000000000000000000000000', 'getTimeMid', '0000'],\n            ['00000000000000000000000000000000', 'getTimestamp', '000000000000000'],\n            ['00000000000000000000000000000000', 'getVariant', 0],\n            ['00000000000000000000000000000000', 'getVersion', null],\n            ['00000000000000000000000000000000', 'isNil', true],\n            ['00000000000000000000000000000000', 'isMax', false],\n\n            // For ffffffff-ffff-ffff-ffff-ffffffffffff\n            ['ffffffffffffffffffffffffffffffff', 'getClockSeq', 'ffff'],\n            ['ffffffffffffffffffffffffffffffff', 'getClockSeqHiAndReserved', 'ff'],\n            ['ffffffffffffffffffffffffffffffff', 'getClockSeqLow', 'ff'],\n            ['ffffffffffffffffffffffffffffffff', 'getNode', 'ffffffffffff'],\n            ['ffffffffffffffffffffffffffffffff', 'getTimeHiAndVersion', 'ffff'],\n            ['ffffffffffffffffffffffffffffffff', 'getTimeLow', 'ffffffff'],\n            ['ffffffffffffffffffffffffffffffff', 'getTimeMid', 'ffff'],\n            ['ffffffffffffffffffffffffffffffff', 'getTimestamp', 'fffffffffffffff'],\n            ['ffffffffffffffffffffffffffffffff', 'getVariant', 7],\n            ['ffffffffffffffffffffffffffffffff', 'getVersion', null],\n            ['ffffffffffffffffffffffffffffffff', 'isNil', false],\n            ['ffffffffffffffffffffffffffffffff', 'isMax', true],\n        ];\n    }\n\n    public function testSerializingFields(): void\n    {\n        $bytes = (string) hex2bin('b08c6fff7dc5e111cb210800200c9a66');\n        $fields = new Fields($bytes);\n\n        $serializedFields = serialize($fields);\n\n        /** @var Fields $unserializedFields */\n        $unserializedFields = unserialize($serializedFields);\n\n        $this->assertSame($fields->getBytes(), $unserializedFields->getBytes());\n    }\n}\n"
  },
  {
    "path": "tests/Guid/GuidBuilderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Guid;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\Guid\\GuidBuilder;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse RuntimeException;\n\nclass GuidBuilderTest extends TestCase\n{\n    public function testBuildThrowsException(): void\n    {\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $builder = Mockery::mock(GuidBuilder::class);\n        $builder->shouldAllowMockingProtectedMethods();\n        $builder->shouldReceive('buildFields')->andThrow(\n            RuntimeException::class,\n            'exception thrown'\n        );\n        $builder->shouldReceive('build')->passthru();\n\n        $this->expectException(UnableToBuildUuidException::class);\n        $this->expectExceptionMessage('exception thrown');\n\n        $builder->build($codec, 'foobar');\n    }\n}\n"
  },
  {
    "path": "tests/Math/BrickMathCalculatorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Math;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Math\\RoundingMode;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n\nclass BrickMathCalculatorTest extends TestCase\n{\n    public function testAdd(): void\n    {\n        $int1 = new IntegerObject(5);\n        $int2 = new IntegerObject(6);\n        $int3 = new IntegerObject(7);\n\n        $calculator = new BrickMathCalculator();\n\n        $result = $calculator->add($int1, $int2, $int3);\n\n        $this->assertSame('18', $result->toString());\n    }\n\n    public function testSubtract(): void\n    {\n        $int1 = new IntegerObject(5);\n        $int2 = new IntegerObject(6);\n        $int3 = new IntegerObject(7);\n\n        $calculator = new BrickMathCalculator();\n\n        $result = $calculator->subtract($int1, $int2, $int3);\n\n        $this->assertSame('-8', $result->toString());\n    }\n\n    public function testMultiply(): void\n    {\n        $int1 = new IntegerObject(5);\n        $int2 = new IntegerObject(6);\n        $int3 = new IntegerObject(7);\n\n        $calculator = new BrickMathCalculator();\n\n        $result = $calculator->multiply($int1, $int2, $int3);\n\n        $this->assertSame('210', $result->toString());\n    }\n\n    public function testDivide(): void\n    {\n        $int1 = new IntegerObject(1023);\n        $int2 = new IntegerObject(6);\n        $int3 = new IntegerObject(7);\n\n        $calculator = new BrickMathCalculator();\n\n        $result = $calculator->divide(RoundingMode::HALF_UP, 0, $int1, $int2, $int3);\n\n        $this->assertSame('24', $result->toString());\n    }\n\n    public function testFromBase(): void\n    {\n        $calculator = new BrickMathCalculator();\n\n        $result = $calculator->fromBase('ffffffffffffffffffff', 16);\n\n        $this->assertSame('1208925819614629174706175', $result->toString());\n    }\n\n    public function testToBase(): void\n    {\n        $intValue = new IntegerObject('1208925819614629174706175');\n        $calculator = new BrickMathCalculator();\n\n        $this->assertSame('ffffffffffffffffffff', $calculator->toBase($intValue, 16));\n    }\n\n    public function testToHexadecimal(): void\n    {\n        $intValue = new IntegerObject('1208925819614629174706175');\n        $calculator = new BrickMathCalculator();\n\n        $result = $calculator->toHexadecimal($intValue);\n\n        $this->assertSame('ffffffffffffffffffff', $result->toString());\n    }\n\n    public function testFromBaseThrowsException(): void\n    {\n        $calculator = new BrickMathCalculator();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('\"o\" is not a valid character in base 16');\n\n        $calculator->fromBase('foobar', 16);\n    }\n\n    public function testToBaseThrowsException(): void\n    {\n        $calculator = new BrickMathCalculator();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Base 1024 is out of range [2, 36]');\n\n        $calculator->toBase(new IntegerObject(42), 1024);\n    }\n}\n"
  },
  {
    "path": "tests/Nonstandard/FieldsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Nonstandard;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Nonstandard\\Fields;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Uuid;\n\nuse function hex2bin;\nuse function serialize;\nuse function str_replace;\nuse function unserialize;\n\nclass FieldsTest extends TestCase\n{\n    public function testConstructorThrowsExceptionIfNotSixteenByteString(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'The byte string must be 16 bytes long; received 6 bytes'\n        );\n\n        new Fields('foobar');\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     * @param non-empty-string $methodName\n     * @param non-empty-string | int | bool | null $expectedValue\n     *\n     * @dataProvider fieldGetterMethodProvider\n     */\n    public function testFieldGetterMethods(\n        string $uuid,\n        string $methodName,\n        bool | int | string | null $expectedValue,\n    ): void {\n        $bytes = (string) hex2bin(str_replace('-', '', $uuid));\n        $fields = new Fields($bytes);\n\n        $result = $fields->$methodName();\n\n        if ($result instanceof Hexadecimal) {\n            $this->assertSame($expectedValue, $result->toString());\n        } else {\n            $this->assertSame($expectedValue, $result);\n        }\n    }\n\n    /**\n     * @return array<array{0: non-empty-string, 1: non-empty-string, 2: non-empty-string | int | bool | null}>\n     */\n    public function fieldGetterMethodProvider(): array\n    {\n        return [\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getClockSeq', '0b21'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getClockSeqHiAndReserved', '0b'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getClockSeqLow', '21'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getNode', '0800200c9a66'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimeHiAndVersion', '91e1'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimeMid', 'c57d'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getVariant', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getVersion', null],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'isNil', false],\n            ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'isMax', false],\n        ];\n    }\n\n    public function testSerializingFields(): void\n    {\n        $bytes = (string) hex2bin(str_replace('-', '', 'ff6f8cb0-c57d-91e1-0b21-0800200c9a66'));\n        $fields = new Fields($bytes);\n\n        $serializedFields = serialize($fields);\n\n        /** @var Fields $unserializedFields */\n        $unserializedFields = unserialize($serializedFields);\n\n        $this->assertSame($fields->getBytes(), $unserializedFields->getBytes());\n    }\n}\n"
  },
  {
    "path": "tests/Nonstandard/UuidBuilderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Nonstandard;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\Nonstandard\\UuidBuilder;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse RuntimeException;\n\nclass UuidBuilderTest extends TestCase\n{\n    public function testBuildThrowsException(): void\n    {\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $builder = Mockery::mock(UuidBuilder::class);\n        $builder->shouldAllowMockingProtectedMethods();\n        $builder->shouldReceive('buildFields')->andThrow(\n            RuntimeException::class,\n            'exception thrown'\n        );\n        $builder->shouldReceive('build')->passthru();\n\n        $this->expectException(UnableToBuildUuidException::class);\n        $this->expectExceptionMessage('exception thrown');\n\n        $builder->build($codec, 'foobar');\n    }\n}\n"
  },
  {
    "path": "tests/Nonstandard/UuidV6Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Nonstandard;\n\nuse DateTimeImmutable;\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Lazy\\LazyUuidFromString;\nuse Ramsey\\Uuid\\Nonstandard\\UuidV6;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\n\nclass UuidV6Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV6 must represent a '\n            . 'version 6 (reordered time) UUID'\n        );\n\n        new UuidV6($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 2],\n            ['version' => 3],\n            ['version' => 4],\n            ['version' => 5],\n            ['version' => 7],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     *\n     * @dataProvider provideUuidV6WithOddMicroseconds\n     */\n    public function testGetDateTimeProperlyHandlesLongMicroseconds(string $uuid, string $expected): void\n    {\n        /** @var UuidV6 $object */\n        $object = Uuid::fromString($uuid);\n\n        $date = $object->getDateTime();\n\n        $this->assertInstanceOf(DateTimeImmutable::class, $date);\n        $this->assertSame($expected, $date->format('U.u'));\n    }\n\n    /**\n     * @return array<array{uuid: non-empty-string, expected: non-empty-string}>\n     */\n    public function provideUuidV6WithOddMicroseconds(): array\n    {\n        return [\n            [\n                'uuid' => '1b21dd21-4814-6000-9669-00007ffffffe',\n                'expected' => '1.677722',\n            ],\n            [\n                'uuid' => '1b21dd21-3714-6000-9669-00007ffffffe',\n                'expected' => '0.104858',\n            ],\n            [\n                'uuid' => '1b21dd21-3713-6000-9669-00007ffffffe',\n                'expected' => '0.105267',\n            ],\n            [\n                'uuid' => '1b21dd21-2e8a-6980-8d4f-acde48001122',\n                'expected' => '-1.000000',\n            ],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuidv6\n     * @param non-empty-string $uuidv1\n     *\n     * @dataProvider provideUuidV1UuidV6Equivalents\n     */\n    public function testToUuidV1(string $uuidv6, string $uuidv1): void\n    {\n        /** @var UuidV6 $uuid6 */\n        $uuid6 = Uuid::fromString($uuidv6);\n        $uuid1 = $uuid6->toUuidV1();\n\n        $this->assertSame($uuidv6, $uuid6->toString());\n        $this->assertSame($uuidv1, $uuid1->toString());\n\n        $this->assertSame(\n            $uuid6->getDateTime()->format('U.u'),\n            $uuid1->getDateTime()->format('U.u')\n        );\n    }\n\n    /**\n     * @param non-empty-string $uuidv6\n     * @param non-empty-string $uuidv1\n     *\n     * @dataProvider provideUuidV1UuidV6Equivalents\n     */\n    public function testFromUuidV1(string $uuidv6, string $uuidv1): void\n    {\n        /** @var LazyUuidFromString $uuid */\n        $uuid = Uuid::fromString($uuidv1);\n        $uuid1 = $uuid->toUuidV1();\n        $uuid6 = UuidV6::fromUuidV1($uuid1);\n\n        $this->assertSame($uuidv1, $uuid1->toString());\n        $this->assertSame($uuidv6, $uuid6->toString());\n\n        $this->assertSame(\n            $uuid1->getDateTime()->format('U.u'),\n            $uuid6->getDateTime()->format('U.u')\n        );\n    }\n\n    /**\n     * @return array<array{uuidv6: non-empty-string, uuidv1: non-empty-string}>\n     */\n    public function provideUuidV1UuidV6Equivalents(): array\n    {\n        return [\n            [\n                'uuidv6' => '1b21dd21-4814-6000-9669-00007ffffffe',\n                'uuidv1' => '14814000-1dd2-11b2-9669-00007ffffffe',\n            ],\n            [\n                'uuidv6' => '1b21dd21-3714-6000-9669-00007ffffffe',\n                'uuidv1' => '13714000-1dd2-11b2-9669-00007ffffffe',\n            ],\n            [\n                'uuidv6' => '1b21dd21-3713-6000-9669-00007ffffffe',\n                'uuidv1' => '13713000-1dd2-11b2-9669-00007ffffffe',\n            ],\n            [\n                'uuidv6' => '1b21dd21-2e8a-6980-8d4f-acde48001122',\n                'uuidv1' => '12e8a980-1dd2-11b2-8d4f-acde48001122',\n            ],\n        ];\n    }\n\n    public function testGetDateTimeThrowsException(): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => 6,\n            'getTimestamp' => new Hexadecimal('0'),\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $timeConverter = Mockery::mock(TimeConverterInterface::class, [\n            'convertTime' => new Time('0', '1234567'),\n        ]);\n\n        $uuid = new UuidV6($fields, $numberConverter, $codec, $timeConverter);\n\n        $this->expectException(DateTimeException::class);\n\n        $uuid->getDateTime();\n    }\n}\n"
  },
  {
    "path": "tests/Provider/Dce/SystemDceSecurityProviderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Provider\\Dce;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Exception\\DceSecurityException;\nuse Ramsey\\Uuid\\Provider\\Dce\\SystemDceSecurityProvider;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse phpmock\\mockery\\PHPMockery;\n\nuse function array_merge;\n\nclass SystemDceSecurityProviderTest extends TestCase\n{\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetUidThrowsExceptionIfShellExecDisabled(): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('foo bar shell_exec baz');\n\n        $provider = new SystemDceSecurityProvider();\n\n        // Test that we catch the exception multiple times, but the ini_get()\n        // function is called only once.\n        $caughtException = 0;\n\n        for ($i = 1; $i <= 5; $i++) {\n            try {\n                $provider->getUid();\n            } catch (DceSecurityException $e) {\n                $caughtException++;\n\n                $this->assertSame(\n                    'Unable to get a user identifier using the system DCE '\n                    . 'Security provider; please provide a custom identifier or '\n                    . 'use a different provider',\n                    $e->getMessage()\n                );\n            }\n        }\n\n        $this->assertSame(5, $caughtException);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetUidForPosixThrowsExceptionIfShellExecReturnsNull(): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn('Linux');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'shell_exec'\n        )->with('id -u')->once()->andReturnNull();\n\n        $provider = new SystemDceSecurityProvider();\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Unable to get a user identifier using the system DCE '\n            . 'Security provider; please provide a custom identifier or '\n            . 'use a different provider'\n        );\n\n        $provider->getUid();\n    }\n\n    /**\n     * @param mixed $value\n     *\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideWindowsBadValues\n     */\n    public function testGetUidForWindowsThrowsExceptionIfShellExecForWhoAmIReturnsBadValues($value): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn('Windows_NT');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'shell_exec'\n        )->with('whoami /user /fo csv /nh')->once()->andReturn($value);\n\n        $provider = new SystemDceSecurityProvider();\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Unable to get a user identifier using the system DCE '\n            . 'Security provider; please provide a custom identifier or '\n            . 'use a different provider'\n        );\n\n        $provider->getUid();\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideWindowsGoodWhoAmIValues\n     */\n    public function testGetUidForWindowsWhenShellExecForWhoAmIReturnsGoodValues(\n        string $value,\n        string $expectedId\n    ): void {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn('Windows_NT');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'shell_exec'\n        )->with('whoami /user /fo csv /nh')->once()->andReturn($value);\n\n        $provider = new SystemDceSecurityProvider();\n\n        $uid = $provider->getUid();\n\n        $this->assertSame($expectedId, $uid->toString());\n        $this->assertSame($uid, $provider->getUid());\n    }\n\n    /**\n     * @return array<array{value: non-empty-string, expectedId: non-empty-string}>\n     */\n    public function provideWindowsGoodWhoAmIValues(): array\n    {\n        return [\n            [\n                'value' => '\"Melilot Sackville\",\"S-1-5-21-7375663-6890924511-1272660413-2944159\"',\n                'expectedId' => '2944159',\n            ],\n            [\n                'value' => '\"Brutus Sandheaver\",\"S-1-3-12-1234525106-3567804255-30012867-1437\"',\n                'expectedId' => '1437',\n            ],\n            [\n                'value' => '\"Cora Rumble\",\"S-345\"',\n                'expectedId' => '345',\n            ],\n        ];\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider providePosixTestValues\n     */\n    public function testGetUidForPosixSystems(string $os, string $id): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn($os);\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'shell_exec'\n        )->with('id -u')->once()->andReturn($id);\n\n        $provider = new SystemDceSecurityProvider();\n\n        $uid = $provider->getUid();\n\n        $this->assertSame($id, $uid->toString());\n        $this->assertSame($uid, $provider->getUid());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetGidThrowsExceptionIfShellExecDisabled(): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('foo bar shell_exec baz');\n\n        $provider = new SystemDceSecurityProvider();\n\n        // Test that we catch the exception multiple times, but the ini_get()\n        // function is called only once.\n        $caughtException = 0;\n\n        for ($i = 1; $i <= 5; $i++) {\n            try {\n                $provider->getGid();\n            } catch (DceSecurityException $e) {\n                $caughtException++;\n\n                $this->assertSame(\n                    'Unable to get a group identifier using the system DCE '\n                    . 'Security provider; please provide a custom identifier or '\n                    . 'use a different provider',\n                    $e->getMessage()\n                );\n            }\n        }\n\n        $this->assertSame(5, $caughtException);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetGidForPosixThrowsExceptionIfShellExecReturnsNull(): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn('Linux');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'shell_exec'\n        )->with('id -g')->once()->andReturnNull();\n\n        $provider = new SystemDceSecurityProvider();\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Unable to get a group identifier using the system DCE '\n            . 'Security provider; please provide a custom identifier or '\n            . 'use a different provider'\n        );\n\n        $provider->getGid();\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider providePosixTestValues\n     */\n    public function testGetGidForPosixSystems(string $os, string $id): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn($os);\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'shell_exec'\n        )->with('id -g')->once()->andReturn($id);\n\n        $provider = new SystemDceSecurityProvider();\n\n        $gid = $provider->getGid();\n\n        $this->assertSame($id, $gid->toString());\n        $this->assertSame($gid, $provider->getGid());\n    }\n\n    /**\n     * @param mixed $value\n     *\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideWindowsBadValues\n     */\n    public function testGetGidForWindowsThrowsExceptionWhenShellExecForNetUserReturnsBadValues($value): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn('Windows_NT');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'shell_exec'\n        )->with('net user %username% | findstr /b /i \"Local Group Memberships\"')->once()->andReturn($value);\n\n        $provider = new SystemDceSecurityProvider();\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Unable to get a group identifier using the system DCE '\n            . 'Security provider; please provide a custom identifier or '\n            . 'use a different provider'\n        );\n\n        $provider->getGid();\n    }\n\n    /**\n     * @param mixed $value\n     *\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideWindowsBadGroupValues\n     */\n    public function testGetGidForWindowsThrowsExceptionWhenShellExecForWmicGroupGetReturnsBadValues($value): void\n    {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn('Windows_NT');\n\n        $shellExec = PHPMockery::mock('Ramsey\\Uuid\\Provider\\Dce', 'shell_exec');\n\n        $shellExec\n            ->with('net user %username% | findstr /b /i \"Local Group Memberships\"')\n            ->once()\n            ->andReturn('Local Group Memberships   *Users');\n\n        $shellExec\n            ->with(Mockery::pattern(\"/^wmic group get name,sid \\| findstr \\/b \\/i (\\\"|\\')Users(\\\"|\\')$/\"))\n            ->once()\n            ->andReturn($value);\n\n        $provider = new SystemDceSecurityProvider();\n\n        $this->expectException(DceSecurityException::class);\n        $this->expectExceptionMessage(\n            'Unable to get a group identifier using the system DCE '\n            . 'Security provider; please provide a custom identifier or '\n            . 'use a different provider'\n        );\n\n        $provider->getGid();\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideWindowsGoodNetUserAndWmicGroupValues\n     */\n    public function testGetGidForWindowsSucceeds(\n        string $netUserResponse,\n        string $wmicGroupResponse,\n        string $expectedGroup,\n        string $expectedId\n    ): void {\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'ini_get'\n        )->with('disable_functions')->once()->andReturn('nothing');\n\n        PHPMockery::mock(\n            'Ramsey\\Uuid\\Provider\\Dce',\n            'constant'\n        )->with('PHP_OS')->once()->andReturn('Windows_NT');\n\n        $shellExec = PHPMockery::mock('Ramsey\\Uuid\\Provider\\Dce', 'shell_exec');\n\n        $shellExec\n            ->with('net user %username% | findstr /b /i \"Local Group Memberships\"')\n            ->once()\n            ->andReturn($netUserResponse);\n\n        $shellExec\n            ->with(Mockery::pattern(\"/^wmic group get name,sid \\| findstr \\/b \\/i (\\\"|\\'){$expectedGroup}(\\\"|\\')$/\"))\n            ->once()\n            ->andReturn($wmicGroupResponse);\n\n        $provider = new SystemDceSecurityProvider();\n\n        $gid = $provider->getGid();\n\n        $this->assertSame($expectedId, $gid->toString());\n        $this->assertSame($gid, $provider->getGid());\n    }\n\n    /**\n     * @return array<array{\n     *     netUserResponse: non-empty-string,\n     *     wmicGroupResponse: non-empty-string,\n     *     expectedGroup: non-empty-string,\n     *     expectedId: non-empty-string,\n     * }>\n     */\n    public function provideWindowsGoodNetUserAndWmicGroupValues(): array\n    {\n        return [\n            [\n                'netUserResponse' => 'Local Group Memberships    *Administrators  *Users',\n                'wmicGroupResponse' => 'Administrators  S-1-5-32-544',\n                'expectedGroup' => 'Administrators',\n                'expectedId' => '544',\n            ],\n            [\n                'netUserResponse' => 'Local Group Memberships    Users',\n                'wmicGroupResponse' => 'Users  S-1-5-32-545',\n                'expectedGroup' => 'Users',\n                'expectedId' => '545',\n            ],\n            [\n                'netUserResponse' => 'Local Group Memberships    Guests  Nobody',\n                'wmicGroupResponse' => 'Guests  S-1-5-32-546',\n                'expectedGroup' => 'Guests',\n                'expectedId' => '546',\n            ],\n            [\n                'netUserResponse' => 'Local Group Memberships   Some Group  Another Group',\n                'wmicGroupResponse' => 'Some Group    S-1-5-80-19088743-1985229328-4294967295-1324',\n                'expectedGroup' => 'Some Group',\n                'expectedId' => '1324',\n            ],\n        ];\n    }\n\n    /**\n     * @return array<array{os: non-empty-string, id: non-empty-string}>\n     */\n    public function providePosixTestValues(): array\n    {\n        return [\n            ['os' => 'Darwin', 'id' => '1042'],\n            ['os' => 'FreeBSD', 'id' => '672'],\n            ['os' => 'GNU', 'id' => '1008'],\n            ['os' => 'Linux', 'id' => '567'],\n            ['os' => 'NetBSD', 'id' => '7234'],\n            ['os' => 'OpenBSD', 'id' => '2347'],\n            ['os' => 'OS400', 'id' => '1234'],\n        ];\n    }\n\n    /**\n     * @return array<array{value: string | null}>\n     */\n    public function provideWindowsBadValues(): array\n    {\n        return [\n            ['value' => null],\n            ['value' => 'foobar'],\n            ['value' => 'foo,bar,baz'],\n            ['value' => ''],\n            ['value' => '1234'],\n            ['value' => 'Local Group Memberships'],\n            ['value' => 'Local Group Memberships    ****  Foo'],\n        ];\n    }\n\n    /**\n     * @return array<array{value: string | null}>\n     */\n    public function provideWindowsBadGroupValues(): array\n    {\n        return array_merge(\n            $this->provideWindowsBadValues(),\n            [\n                ['value' => 'Users  Not a valid SID string'],\n                ['value' => 'Users  344aab9758bb0d018b93739e7893fb3a'],\n            ]\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Provider/Node/FallbackNodeProviderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Provider\\Node;\n\nuse Ramsey\\Uuid\\Exception\\NodeException;\nuse Ramsey\\Uuid\\Provider\\Node\\FallbackNodeProvider;\nuse Ramsey\\Uuid\\Provider\\Node\\RandomNodeProvider;\nuse Ramsey\\Uuid\\Provider\\Node\\StaticNodeProvider;\nuse Ramsey\\Uuid\\Provider\\Node\\SystemNodeProvider;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nclass FallbackNodeProviderTest extends TestCase\n{\n    public function testGetNodeCallsGetNodeOnEachProviderUntilNodeFound(): void\n    {\n        $providerWithNode = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n        $providerWithNode->expects($this->once())\n            ->method('getNode')\n            ->willReturn(new Hexadecimal('57764a07f756'));\n        $providerWithoutNode = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n        $providerWithoutNode->expects($this->once())\n            ->method('getNode')\n            ->willThrowException(new NodeException());\n\n        $provider = new FallbackNodeProvider([$providerWithoutNode, $providerWithNode]);\n        $provider->getNode();\n    }\n\n    public function testGetNodeReturnsNodeFromFirstProviderWithNode(): void\n    {\n        $providerWithoutNode = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n        $providerWithoutNode->expects($this->once())\n            ->method('getNode')\n            ->willThrowException(new NodeException());\n        $providerWithNode = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n        $providerWithNode->expects($this->once())\n            ->method('getNode')\n            ->willReturn(new Hexadecimal('57764a07f756'));\n        $anotherProviderWithoutNode = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n        $anotherProviderWithoutNode->expects($this->never())\n            ->method('getNode');\n\n        $provider = new FallbackNodeProvider([$providerWithoutNode, $providerWithNode, $anotherProviderWithoutNode]);\n        $node = $provider->getNode();\n\n        $this->assertSame('57764a07f756', $node->toString());\n    }\n\n    public function testGetNodeThrowsExceptionWhenNoNodesFound(): void\n    {\n        $providerWithoutNode = $this->getMockBuilder(NodeProviderInterface::class)->getMock();\n        $providerWithoutNode->method('getNode')\n            ->willThrowException(new NodeException());\n\n        $provider = new FallbackNodeProvider([$providerWithoutNode]);\n\n        $this->expectException(NodeException::class);\n        $this->expectExceptionMessage(\n            'Unable to find a suitable node provider'\n        );\n\n        $provider->getNode();\n    }\n\n    public function testSerializationOfNodeProviderCollection(): void\n    {\n        $staticNodeProvider = new StaticNodeProvider(new Hexadecimal('aabbccddeeff'));\n        $randomNodeProvider = new RandomNodeProvider();\n        $systemNodeProvider = new SystemNodeProvider();\n\n        /** @var list<NodeProviderInterface> $unserializedNodeProviderCollection */\n        $unserializedNodeProviderCollection = unserialize(serialize([\n            $staticNodeProvider,\n            $randomNodeProvider,\n            $systemNodeProvider,\n        ]));\n\n        foreach ($unserializedNodeProviderCollection as $nodeProvider) {\n            $this->assertInstanceOf(NodeProviderInterface::class, $nodeProvider);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Provider/Node/RandomNodeProviderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Provider\\Node;\n\nuse Exception;\nuse Ramsey\\Uuid\\Exception\\RandomSourceException;\nuse Ramsey\\Uuid\\Provider\\Node\\RandomNodeProvider;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse phpmock\\mockery\\PHPMockery;\n\nuse function bin2hex;\nuse function hex2bin;\nuse function hexdec;\nuse function sprintf;\nuse function substr;\n\nclass RandomNodeProviderTest extends TestCase\n{\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeUsesRandomBytes(): void\n    {\n        $bytes = hex2bin('38a675685d50');\n        $expectedNode = '39a675685d50';\n\n        PHPMockery::mock('Ramsey\\Uuid\\Provider\\Node', 'random_bytes')\n            ->once()\n            ->with(6)\n            ->andReturn($bytes);\n\n        $provider = new RandomNodeProvider();\n        $node = $provider->getNode();\n\n        $this->assertSame($expectedNode, $node->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeAlreadyHasMulticastBit(): void\n    {\n        $bytesHex = '4161a1ff5d50';\n        $bytes = hex2bin($bytesHex);\n\n        // We expect the same hex value for the node.\n        $expectedNode = $bytesHex;\n\n        PHPMockery::mock('Ramsey\\Uuid\\Provider\\Node', 'random_bytes')\n            ->once()\n            ->with(6)\n            ->andReturn($bytes);\n\n        $provider = new RandomNodeProvider();\n\n        $this->assertSame($expectedNode, $provider->getNode()->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeSetsMulticastBitForLowNodeValue(): void\n    {\n        $bytes = hex2bin('100000000001');\n        $expectedNode = '110000000001';\n\n        PHPMockery::mock('Ramsey\\Uuid\\Provider\\Node', 'random_bytes')\n            ->once()\n            ->with(6)\n            ->andReturn($bytes);\n\n        $provider = new RandomNodeProvider();\n\n        $this->assertSame($expectedNode, $provider->getNode()->toString());\n    }\n\n    public function testGetNodeAlwaysSetsMulticastBit(): void\n    {\n        $provider = new RandomNodeProvider();\n        $nodeHex = $provider->getNode();\n\n        // Convert what we got into bytes so that we can mask out everything\n        // except the multicast bit. If the multicast bit doesn't exist, this\n        // test will fail appropriately.\n        $nodeBytes = (string) hex2bin((string) $nodeHex);\n\n        // Split the node bytes for math on 32-bit systems.\n        $nodeMsb = substr($nodeBytes, 0, 3);\n        $nodeLsb = substr($nodeBytes, 3);\n\n        // Only set bits that match the mask so we can see that the multicast\n        // bit is always set.\n        $nodeMsb = sprintf('%06x', hexdec(bin2hex($nodeMsb)) & 0x010000);\n        $nodeLsb = sprintf('%06x', hexdec(bin2hex($nodeLsb)) & 0x000000);\n\n        // Recombine the node bytes.\n        $node = $nodeMsb . $nodeLsb;\n\n        $this->assertSame('010000000000', $node);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeThrowsExceptionWhenExceptionThrownByRandombytes(): void\n    {\n        PHPMockery::mock('Ramsey\\Uuid\\Provider\\Node', 'random_bytes')\n            ->once()\n            ->andThrow(new Exception('Could not gather sufficient random data'));\n\n        $provider = new RandomNodeProvider();\n\n        $this->expectException(RandomSourceException::class);\n        $this->expectExceptionMessage('Could not gather sufficient random data');\n\n        $provider->getNode();\n    }\n}\n"
  },
  {
    "path": "tests/Provider/Node/StaticNodeProviderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Provider\\Node;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Provider\\Node\\StaticNodeProvider;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nclass StaticNodeProviderTest extends TestCase\n{\n    /**\n     * @param non-empty-string $expectedNode\n     *\n     * @dataProvider provideNodeForTest\n     */\n    public function testStaticNode(Hexadecimal $node, string $expectedNode): void\n    {\n        $staticNode = new StaticNodeProvider($node);\n\n        $this->assertSame($expectedNode, $staticNode->getNode()->toString());\n    }\n\n    /**\n     * @return array<array{node: Hexadecimal, expectedNode: non-empty-string}>\n     */\n    public function provideNodeForTest(): array\n    {\n        return [\n            [\n                'node' => new Hexadecimal('0'),\n                'expectedNode' => '010000000000',\n            ],\n            [\n                'node' => new Hexadecimal('1'),\n                'expectedNode' => '010000000001',\n            ],\n            [\n                'node' => new Hexadecimal('f2ffffffffff'),\n                'expectedNode' => 'f3ffffffffff',\n            ],\n            [\n                'node' => new Hexadecimal('ffffffffffff'),\n                'expectedNode' => 'ffffffffffff',\n            ],\n        ];\n    }\n\n    public function testStaticNodeThrowsExceptionForTooLongNode(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Static node value cannot be greater than 12 hexadecimal characters'\n        );\n\n        new StaticNodeProvider(new Hexadecimal('1000000000000'));\n    }\n}\n"
  },
  {
    "path": "tests/Provider/Node/SystemNodeProviderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Provider\\Node;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Exception\\NodeException;\nuse Ramsey\\Uuid\\Provider\\Node\\SystemNodeProvider;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse phpmock\\spy\\Spy;\n\nuse function array_shift;\nuse function array_walk;\nuse function gettype;\nuse function is_array;\nuse function strlen;\nuse function vsprintf;\n\nuse const GLOB_NOSORT;\n\n/**\n * Tests for the SystemNodeProvider class\n *\n * The class under test make use of various native functions who's output is\n * dictated by which environment PHP runs on. Instead of having to run these\n * tests on each of these environments, the related functions are mocked. The\n * following functions are concerned:\n *\n * - glob\n * - constant\n * - passthru\n * - file_get_contents\n * - ini_get\n *\n * On Linux systems `glob` would normally provide one or more paths were mac\n * address can be retrieved (using `file_get_contents`). On non-linux systems,\n * or when the `glob` fails, `passthru` is used to read the mac address from the\n * command for the relevant environment as provided by `constant('PHP_OS')`.\n *\n * Please note that, in order to have robust tests, (the output of) these\n * functions should ALWAYS be mocked and the amount of times each function\n * should be run should ALWAYS be specified.\n *\n * This will make the tests more verbose but also more bullet-proof.\n */\nclass SystemNodeProviderTest extends TestCase\n{\n    private const MOCK_GLOB = 'glob';\n    private const MOCK_CONSTANT = 'constant';\n    private const MOCK_PASSTHRU = 'passthru';\n    private const MOCK_FILE_GET_CONTENTS = 'file_get_contents';\n    private const MOCK_INI_GET = 'ini_get';\n    private const MOCK_IS_READABLE = 'is_readable';\n\n    private const PROVIDER_NAMESPACE = 'Ramsey\\\\Uuid\\\\Provider\\\\Node';\n\n    /**\n     * @var Spy[]\n     */\n    private $functionProxies = [];\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideValidNetStatOutput\n     */\n    public function testGetNodeReturnsSystemNodeFromMacAddress(string $netstatOutput, string $expected): void\n    {\n        /* Arrange mocks for native functions */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function () use ($netstatOutput): void {\n                echo $netstatOutput;\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act upon the system under test */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n\n        /* Assert the result match expectations */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n\n        $this->assertSame($expected, $node->toString());\n\n        $message = vsprintf(\n            'Node should be a hexadecimal string of 12 characters. Actual node: %s (length: %s)',\n            [$node->toString(), strlen($node->toString()),]\n        );\n        $this->assertMatchesRegularExpression('/^[A-Fa-f0-9]{12}$/', $node->toString(), $message);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideInvalidNetStatOutput\n     */\n    public function testGetNodeShouldNotReturnsSystemNodeForInvalidMacAddress(string $netstatOutput): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function () use ($netstatOutput): void {\n                echo $netstatOutput;\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $exception = null;\n        $provider = new SystemNodeProvider();\n\n        try {\n            $provider->getNode();\n        } catch (NodeException $exception) {\n            // do nothing\n        }\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n        $this->assertInstanceOf(NodeException::class, $exception);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideNotationalFormats\n     */\n    public function testGetNodeReturnsNodeStrippedOfNotationalFormatting(string $formatted, string $expected): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function () use ($formatted): void {\n                echo \"\\n{$formatted}\\n\";\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n\n        $this->assertSame($expected, $node->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideInvalidNotationalFormats\n     */\n    public function testGetNodeDoesNotAcceptIncorrectNotationalFormatting(string $formatted): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function () use ($formatted): void {\n                echo \"\\n{$formatted}\\n\";\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $exception = null;\n        $provider = new SystemNodeProvider();\n\n        try {\n            $provider->getNode();\n        } catch (NodeException $exception) {\n            // do nothing\n        }\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n        $this->assertInstanceOf(NodeException::class, $exception);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeReturnsFirstMacAddressFound(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function (): void {\n                echo \"\\nAA-BB-CC-DD-EE-FF\\n00-11-22-33-44-55\\nFF-11-EE-22-DD-33\\n\";\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n\n        $this->assertSame('aabbccddeeff', $node->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeReturnsFalseWhenNodeIsNotFound(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function (): void {\n                echo 'some string that does not match the mac address';\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $exception = null;\n        $provider = new SystemNodeProvider();\n\n        try {\n            $provider->getNode();\n        } catch (NodeException $exception) {\n            // do nothing\n        }\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n        $this->assertInstanceOf(NodeException::class, $exception);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeWillNotExecuteSystemCallIfFailedFirstTime(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function (): void {\n                echo 'some string that does not match the mac address';\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $exception1 = null;\n        $exception2 = null;\n        $provider = new SystemNodeProvider();\n\n        try {\n            $provider->getNode();\n        } catch (NodeException $exception1) {\n            // do nothing\n        }\n\n        try {\n            $provider->getNode();\n        } catch (NodeException $exception2) {\n            // do nothing\n        }\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n        $this->assertInstanceOf(NodeException::class, $exception1);\n        $this->assertInstanceOf(NodeException::class, $exception2);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideCommandPerOs\n     */\n    public function testGetNodeGetsNetworkInterfaceConfig(string $os, string $command): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            'whatever',\n            ['mock address path'],\n            'whatever',\n            $os,\n            'nothing disabled',\n            true\n        );\n\n        /* Act */\n        $exception = null;\n        $provider = new SystemNodeProvider();\n\n        try {\n            $provider->getNode();\n        } catch (NodeException $exception) {\n            // do nothing\n        }\n\n        /* Assert */\n        $globBodyAssert = null;\n        $fileGetContentsAssert = null;\n        $isReadableAssert = null;\n        if ($os === 'Linux') {\n            $globBodyAssert = [['/sys/class/net/*/address', GLOB_NOSORT]];\n            $fileGetContentsAssert = ['mock address path'];\n            $isReadableAssert = $fileGetContentsAssert;\n        }\n        $this->assertMockFunctions(\n            $fileGetContentsAssert,\n            $globBodyAssert,\n            [$command],\n            ['PHP_OS'],\n            ['disable_functions'],\n            $isReadableAssert\n        );\n\n        $this->assertInstanceOf(NodeException::class, $exception);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeReturnsSameNodeUponSubsequentCalls(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function (): void {\n                echo \"\\nAA-BB-CC-DD-EE-FF\\n\";\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n        $node2 = $provider->getNode();\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n\n        $this->assertSame($node->toString(), $node2->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testSubsequentCallsToGetNodeDoNotRecallIfconfig(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            function (): void {\n                echo \"\\nAA-BB-CC-DD-EE-FF\\n\";\n            },\n            'NOT LINUX',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n        $node2 = $provider->getNode();\n\n        /* Assert */\n        $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']);\n\n        $this->assertSame($node->toString(), $node2->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     * @dataProvider provideCommandPerOs\n     */\n    public function testCallGetsysfsOnLinux(string $os, string $command): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            function () {\n                /** @var non-empty-list<string> $macs */\n                static $macs = [\"00:00:00:00:00:00\\n\", \"01:02:03:04:05:06\\n\"];\n\n                return array_shift($macs);\n            },\n            ['mock address path 1', 'mock address path 2'],\n            function (): void {\n                echo \"\\n01-02-03-04-05-06\\n\";\n            },\n            $os,\n            'nothing disabled',\n            true\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n\n        /* Assert */\n        $fileGetContentsAssert = null;\n        $globBodyAssert = null;\n        $passthruBodyAssert = [$command];\n        $constantBodyAssert = ['PHP_OS'];\n        $iniGetDisableFunctionsAssert = ['disable_functions'];\n        $isReadableAssert = null;\n\n        if ($os === 'Linux') {\n            $fileGetContentsAssert = [['mock address path 1'], ['mock address path 2']];\n            $globBodyAssert = [['/sys/class/net/*/address', GLOB_NOSORT]];\n            $passthruBodyAssert = null;\n            $constantBodyAssert = ['PHP_OS'];\n            $iniGetDisableFunctionsAssert = null;\n            $isReadableAssert = $fileGetContentsAssert;\n        }\n        $this->assertMockFunctions(\n            $fileGetContentsAssert,\n            $globBodyAssert,\n            $passthruBodyAssert,\n            $constantBodyAssert,\n            $iniGetDisableFunctionsAssert,\n            $isReadableAssert\n        );\n\n        $this->assertSame('010203040506', $node->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testCallGetsysfsOnLinuxWhenGlobReturnsFalse(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            false,\n            function (): void {\n                echo \"\\n01-02-03-04-05-06\\n\";\n            },\n            'Linux',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n\n        /* Assert */\n        $this->assertMockFunctions(\n            null,\n            [['/sys/class/net/*/address', GLOB_NOSORT]],\n            ['netstat -ie 2>&1'],\n            ['PHP_OS'],\n            ['disable_functions']\n        );\n\n        $this->assertSame('010203040506', $node->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testCallGetsysfsOnLinuxWhenGlobReturnsEmptyArray(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            [],\n            function (): void {\n                echo \"\\n01-02-03-04-05-06\\n\";\n            },\n            'Linux',\n            'nothing disabled'\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n\n        /* Assert */\n        $this->assertMockFunctions(\n            null,\n            [['/sys/class/net/*/address', GLOB_NOSORT]],\n            ['netstat -ie 2>&1'],\n            ['PHP_OS'],\n            ['disable_functions']\n        );\n\n        $this->assertSame('010203040506', $node->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testCallGetsysfsOnLinuxWhenGlobFilesAreNotReadable(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            ['mock address path 1', 'mock address path 2'],\n            function (): void {\n                echo \"\\n01-02-03-04-05-06\\n\";\n            },\n            'Linux',\n            'nothing disabled',\n            false\n        );\n\n        /* Act */\n        $provider = new SystemNodeProvider();\n        $node = $provider->getNode();\n\n        /* Assert */\n        $this->assertMockFunctions(\n            null,\n            [['/sys/class/net/*/address', GLOB_NOSORT]],\n            ['netstat -ie 2>&1'],\n            ['PHP_OS'],\n            ['disable_functions'],\n            ['mock address path 1', 'mock address path 2']\n        );\n\n        $this->assertSame('010203040506', $node->toString());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function testGetNodeReturnsFalseWhenPassthruIsDisabled(): void\n    {\n        /* Arrange */\n        $this->arrangeMockFunctions(\n            null,\n            null,\n            null,\n            'NOT LINUX',\n            'PASSTHRU,some_other_function'\n        );\n\n        /* Act */\n        $exception = null;\n        $provider = new SystemNodeProvider();\n\n        try {\n            $provider->getNode();\n        } catch (NodeException $exception) {\n            // do nothing\n        }\n\n        /* Assert */\n        $this->assertMockFunctions(\n            null,\n            null,\n            null,\n            ['PHP_OS'],\n            ['disable_functions']\n        );\n\n        $this->assertInstanceOf(NodeException::class, $exception);\n    }\n\n    /**\n     * Replaces the return value for functions with the given value or callback.\n     *\n     * @param callback|mixed|null $fileGetContentsBody\n     * @param callback|mixed|null $globBody\n     * @param callback|mixed|null $passthruBody\n     * @param callback|mixed|null $constantBody\n     * @param callback|mixed|null $iniGetDisableFunctionsBody\n     * @param callback|mixed|null $isReadableBody\n     */\n    private function arrangeMockFunctions(\n        $fileGetContentsBody,\n        $globBody,\n        $passthruBody,\n        $constantBody,\n        $iniGetDisableFunctionsBody,\n        $isReadableBody = true\n    ): void {\n        $mockFunction = [\n            self::MOCK_FILE_GET_CONTENTS => $fileGetContentsBody,\n            self::MOCK_GLOB => $globBody,\n            self::MOCK_PASSTHRU => $passthruBody,\n            self::MOCK_CONSTANT => $constantBody,\n            self::MOCK_INI_GET => $iniGetDisableFunctionsBody,\n            self::MOCK_IS_READABLE => $isReadableBody,\n        ];\n\n        array_walk($mockFunction, function ($body, $key): void {\n            if (!is_callable($body)) {\n                $body = function () use ($body) {\n                    return $body;\n                };\n            }\n\n            $spy = new Spy(self::PROVIDER_NAMESPACE, $key, $body);\n            $spy->enable();\n\n            $this->functionProxies[$key] = $spy;\n        });\n    }\n\n    /**\n     * Verifies that each function was called exactly once for each assert given.\n     *\n     * Provide a NULL to assert a function is never called.\n     *\n     * @param array<int, string>|array<int, array<int,string>>|null $fileGetContentsAssert\n     * @param array<int, array<int, int|string>>|null $globBodyAssert\n     * @param array<int, string>|array<int, array<int,string>>|null $passthruBodyAssert\n     * @param array<int, string>|array<int, array<int,string>>|null $constantBodyAssert\n     * @param array<int, string>|array<int, array<int,string>>|null $iniGetDisableFunctionsAssert\n     * @param array<int, string>|array<int, array<int,string>>|null $isReadableAssert\n     */\n    private function assertMockFunctions(\n        ?array $fileGetContentsAssert,\n        ?array $globBodyAssert,\n        ?array $passthruBodyAssert,\n        ?array $constantBodyAssert,\n        ?array $iniGetDisableFunctionsAssert,\n        ?array $isReadableAssert = null\n    ): void {\n        $mockFunctionAsserts = [\n            self::MOCK_FILE_GET_CONTENTS => $fileGetContentsAssert,\n            self::MOCK_GLOB => $globBodyAssert,\n            self::MOCK_PASSTHRU => $passthruBodyAssert,\n            self::MOCK_CONSTANT => $constantBodyAssert,\n            self::MOCK_INI_GET => $iniGetDisableFunctionsAssert,\n            self::MOCK_IS_READABLE => $isReadableAssert,\n        ];\n\n        array_walk($mockFunctionAsserts, function (mixed $asserts, string $key): void {\n            if ($asserts === null) {\n                // Assert the function was never invoked.\n                $this->assertEmpty($this->functionProxies[$key]->getInvocations());\n            } elseif (is_array($asserts)) { /** @phpstan-ignore function.alreadyNarrowedType */\n                // Assert there was at least one invocation for this function.\n                $this->assertNotEmpty($this->functionProxies[$key]->getInvocations());\n\n                $invokedArgs = [];\n                foreach ($this->functionProxies[$key]->getInvocations() as $invocation) {\n                    $invokedArgs[] = $invocation->getArguments();\n                }\n\n                foreach ($asserts as $assert) {\n                    // Assert these args were used to invoke the function.\n                    $assert = is_array($assert) ? $assert : [$assert];\n                    $this->assertContains($assert, $invokedArgs);\n                }\n            } else {\n                $error = vsprintf(\n                    'Given parameter for %s must be an array or NULL, \"%s\" given.',\n                    [$key, gettype($asserts)]\n                );\n\n                throw new InvalidArgumentException($error);\n            }\n        });\n    }\n\n    /**\n     * Provides the command that should be executed per supported OS\n     *\n     * @return array<string, array{0: non-empty-string, 1: non-empty-string}>\n     */\n    public function provideCommandPerOs(): array\n    {\n        return [\n            'windows' => ['Windows', 'ipconfig /all 2>&1'],\n            'mac' => ['Darwhat', 'ifconfig 2>&1'],\n            'linux' => ['Linux', 'netstat -ie 2>&1'],\n            'freebsd' => ['FreeBSD', 'netstat -i -f link 2>&1'],\n            'anything_else' => ['someotherxyz', 'netstat -ie 2>&1'],\n            'Linux when `glob` fails' => ['LIN', 'netstat -ie 2>&1'],\n        ];\n    }\n\n    /**\n     * Values that are NOT parsed to a mac address by the class under test\n     *\n     * @return array<string, array{0: non-empty-string}>\n     */\n    public function provideInvalidNetStatOutput(): array\n    {\n        return [\n            'Not an octal value' => [\n                \"The program 'netstat' is currently not installed. \" .\n                \"You can install it by typing:\\nsudo apt install net-tools\\n\",\n            ],\n            'One character too short' => [\"\\nA-BB-CC-DD-EE-FF\\n\"],\n            'One tuple too short' => [\"\\nBB-CC-DD-EE-FF\\n\"],\n            'With colon, with linebreak, without space' => [\"\\n:AA-BB-CC-DD-EE-FF\\n\"],\n            'With colon, without linebreak, with space' => [' : AA-BB-CC-DD-EE-FF'],\n            'With colon, without linebreak, without space' => [':AA-BB-CC-DD-EE-FF'],\n            'Without colon, without linebreak, without space' => ['AA-BB-CC-DD-EE-FF'],\n            'Without leading linebreak' => [\"AA-BB-CC-DD-EE-FF\\n\"],\n            'Without leading whitespace' => ['AA-BB-CC-DD-EE-FF '],\n            'Without trailing linebreak' => [\"\\nAA-BB-CC-DD-EE-FF\"],\n            'Without trailing whitespace' => [' AA-BB-CC-DD-EE-FF'],\n            'All zero MAC address' => ['00-00-00-00-00-00'],\n        ];\n    }\n\n    /**\n     * Provides notations that the class under test should NOT attempt to strip\n     *\n     * @return array<array{0: non-empty-string}>\n     */\n    public function provideInvalidNotationalFormats(): array\n    {\n        return [\n            ['01:23-45-67-89-ab'],\n            ['01:23:45-67-89-ab'],\n            ['01:23:45:67-89-ab'],\n            ['01:23:45:67:89-ab'],\n            ['01-23:45:67:89:ab'],\n            ['01-23-45:67:89:ab'],\n            ['01-23-45-67:89:ab'],\n            ['01-23-45-67-89:ab'],\n            ['00:00:00:00:00:00'],\n        ];\n    }\n\n    /**\n     * Provides mac addresses that the class under test should strip notational format from\n     *\n     * @return array<array{0: non-empty-string, 1: non-empty-string}>\n     */\n    public function provideNotationalFormats(): array\n    {\n        return [\n            ['01-23-45-67-89-ab', '0123456789ab'],\n            ['01:23:45:67:89:ab', '0123456789ab'],\n        ];\n    }\n\n    /**\n     * Values that are parsed to a mac address by the class under test\n     *\n     * @return array<string, array{0: non-empty-string, 1: non-empty-string}>\n     */\n    public function provideValidNetStatOutput(): array\n    {\n        return [\n            /* Full output of related command */\n            'Full output - Linux' => [\n                <<<'TXT'\n                    Kernel Interface table\n                    docker0   Link encap:Ethernet  HWaddr 01:23:45:67:89:ab\n                              inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0\n                              UP BROADCAST MULTICAST  MTU:1500  Metric:1\n                              RX packets:0 errors:0 dropped:0 overruns:0 frame:0\n                              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0\n                              collisions:0 txqueuelen:0\n                              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)\n\n                    enp3s0    Link encap:Ethernet  HWaddr fe:dc:ba:98:76:54\n                              inet addr:10.0.0.1  Bcast:10.0.0.255  Mask:255.255.255.0\n                              inet6 addr: ffee::ddcc:bbaa:9988:7766/64 Scope:Link\n                              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1\n                              RX packets:943077 errors:0 dropped:0 overruns:0 frame:0\n                              TX packets:2168039 errors:0 dropped:0 overruns:0 carrier:0\n                              collisions:0 txqueuelen:1000\n                              RX bytes:748596414 (748.5 MB)  TX bytes:2930448282 (2.9 GB)\n\n                    lo        Link encap:Local Loopback\n                              inet addr:127.0.0.1  Mask:255.0.0.0\n                              inet6 addr: ::1/128 Scope:Host\n                              UP LOOPBACK RUNNING  MTU:65536  Metric:1\n                              RX packets:8302 errors:0 dropped:0 overruns:0 frame:0\n                              TX packets:8302 errors:0 dropped:0 overruns:0 carrier:0\n                              collisions:0 txqueuelen:1000\n                              RX bytes:1094983 (1.0 MB)  TX bytes:1094983 (1.0 MB)\n                    TXT,\n                '0123456789ab',\n            ],\n            'Full output - MacOS' => [\n                <<<'TXT'\n                    lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384\n                        options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>\n                        inet 127.0.0.1 netmask 0xff000000\n                        inet6 ::1 prefixlen 128\n                        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1\n                        nd6 options=201<PERFORMNUD,DAD>\n                    gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280\n                    stf0: flags=0<> mtu 1280\n                    EHC29: flags=0<> mtu 0\n                    XHC20: flags=0<> mtu 0\n                    EHC26: flags=0<> mtu 0\n                    aa0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500\n                        options=10b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV>\n                        ether 00:00:00:00:00:00\n                        status: active\n                    en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500\n                        options=10b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV>\n                        ether 10:dd:b1:b4:e4:8e\n                        inet6 fe80::c70:76f5:aa1:5db1%en0 prefixlen 64 secured scopeid 0x7\n                        inet 10.53.8.112 netmask 0xfffffc00 broadcast 10.53.11.255\n                        nd6 options=201<PERFORMNUD,DAD>\n                        media: autoselect (1000baseT <full-duplex>)\n                        status: active\n                    en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500\n                        ether ec:35:86:38:c8:c2\n                        inet6 fe80::aa:d44f:5f5f:7fd4%en1 prefixlen 64 secured scopeid 0x8\n                        inet 10.53.17.196 netmask 0xfffffc00 broadcast 10.53.19.255\n                        nd6 options=201<PERFORMNUD,DAD>\n                        media: autoselect\n                        status: active\n                    p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304\n                        ether 0e:35:86:38:c8:c2\n                        media: autoselect\n                        status: inactive\n                    awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484\n                        ether ea:ab:ae:25:f5:d0\n                        inet6 fe80::e8ab:aeff:fe25:f5d0%awdl0 prefixlen 64 scopeid 0xa\n                        nd6 options=201<PERFORMNUD,DAD>\n                        media: autoselect\n                        status: active\n                    en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500\n                        options=60<TSO4,TSO6>\n                        ether 32:00:18:9b:dc:60\n                        media: autoselect <full-duplex>\n                        status: inactive\n                    en3: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500\n                        options=60<TSO4,TSO6>\n                        ether 32:00:18:9b:dc:61\n                        media: autoselect <full-duplex>\n                        status: inactive\n                    bridge0: flags=8822<BROADCAST,SMART,SIMPLEX,MULTICAST> mtu 1500\n                        options=63<RXCSUM,TXCSUM,TSO4,TSO6>\n                        ether 32:00:18:9b:dc:60\n                        Configuration:\n                            id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0\n                            maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200\n                            root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0\n                            ipfilter disabled flags 0x2\n                        member: en2 flags=3<LEARNING,DISCOVER>\n                                ifmaxaddr 0 port 11 priority 0 path cost 0\n                        member: en3 flags=3<LEARNING,DISCOVER>\n                                ifmaxaddr 0 port 12 priority 0 path cost 0\n                        media: <unknown type>\n                        status: inactive\n                    utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000\n                        options=6403<RXCSUM,TXCSUM,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>\n                        inet6 fe80::57c6:d692:9d41:d28f%utun0 prefixlen 64 scopeid 0xe\n                        nd6 options=201<PERFORMNUD,DAD>\n                    TXT,\n                '10ddb1b4e48e',\n            ],\n            'Full output - Window' => [\n                <<<'TXT'\n                    Windows IP Configuration\n\n                       Host Name . . . . . . . . . . . . : MSEDGEWIN10\n                       Primary Dns Suffix  . . . . . . . :\n                       Node Type . . . . . . . . . . . . : Hybrid\n                       IP Routing Enabled. . . . . . . . : No\n                       WINS Proxy Enabled. . . . . . . . : No\n                       DNS Suffix Search List. . . . . . : network.lan\n\n                    Some kind of adapter:\n\n                       Connection-specific DNS Suffix  . : network.foo\n                       Description . . . . . . . . . . . : Some Adapter\n                       Physical Address. . . . . . . . . : 00-00-00-00-00-00\n\n                    Ethernet adapter Ethernet:\n\n                       Connection-specific DNS Suffix  . : network.lan\n                       Description . . . . . . . . . . . : Intel(R) PRO/1000 MT Desktop Adapter\n                       Physical Address. . . . . . . . . : 08-00-27-B8-42-C6\n                       DHCP Enabled. . . . . . . . . . . : Yes\n                       Autoconfiguration Enabled . . . . : Yes\n                       Link-local IPv6 Address . . . . . : fe80::606a:ae33:7ce1:b5e9%3(Preferred)\n                       IPv4 Address. . . . . . . . . . . : 10.0.2.15(Preferred)\n                       Subnet Mask . . . . . . . . . . . : 255.255.255.0\n                       Lease Obtained. . . . . . . . . . : Tuesday, January 30, 2018 11:25:31 PM\n                       Lease Expires . . . . . . . . . . : Wednesday, January 31, 2018 11:25:27 PM\n                       Default Gateway . . . . . . . . . : 10.0.2.2\n                       DHCP Server . . . . . . . . . . . : 10.0.2.2\n                       DHCPv6 IAID . . . . . . . . . . . : 34078759\n                       DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-21-40-72-3F-08-00-27-B8-42-C6\n                       DNS Servers . . . . . . . . . . . : 10.0.2.3\n                       NetBIOS over Tcpip. . . . . . . . : Enabled\n\n                    Tunnel adapter isatap.network.lan:\n\n                       Media State . . . . . . . . . . . : Media disconnected\n                       Connection-specific DNS Suffix  . : network.lan\n                       Description . . . . . . . . . . . : Microsoft ISATAP Adapter\n                       Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0\n                       DHCP Enabled. . . . . . . . . . . : No\n                       Autoconfiguration Enabled . . . . : Yes\n                    TXT,\n                '080027b842c6',\n            ],\n            'Full output - FreeBSD' => [\n                <<<'TXT'\n                    Name    Mtu Network       Address              Ipkts Ierrs Idrop    Opkts Oerrs  Coll\n                    aa0       0 <Link#0>      00:00:00:00:00:00        0     0     0        0     0     0\n                    em0    1500 <Link#1>      08:00:27:71:a1:00    65514     0     0    42918     0     0\n                    em1    1500 <Link#2>      08:00:27:d0:60:a0     1199     0     0      535     0     0\n                    lo0   16384 <Link#3>      lo0                      4     0     0        4     0     0\n                    TXT,\n                '08002771a100',\n            ],\n\n            /* The single line that is relevant */\n            'Linux  - single line' => [\"\\ndocker0   Link encap:Ethernet  HWaddr 01:23:45:67:89:ab\\n\", '0123456789ab'],\n            'MacOS  - Single line ' => [\"\\nether 10:dd:b1:b4:e4:8e\\n\", '10ddb1b4e48e'],\n            'Window - single line' => [\"\\nPhysical Address. . . . . . . . . : 08-00-27-B8-42-C6\\n\", '080027b842c6'],\n\n            /* Minimal subsets of the single line to show the differences */\n            'with colon, with linebreak, with space' => [\"\\n : AA-BB-CC-DD-EE-FF\\n\", 'aabbccddeeff'],\n            'without colon, with linebreak, with space' => [\"\\n AA-BB-CC-DD-EE-FF \\n\", 'aabbccddeeff'],\n            'without colon, with linebreak, without space' => [\"\\nAA-BB-CC-DD-EE-FF\\n\", 'aabbccddeeff'],\n            'without colon, without linebreak, with space' => [' AA-BB-CC-DD-EE-FF ', 'aabbccddeeff'],\n\n            /* Other accepted variations */\n            'Actual mac - 1' => [\"\\n52:54:00:14:91:69\\n\", '525400149169'],\n            'Actual mac - 2' => [\"\\n00:16:3e:a9:73:f0\\n\", '00163ea973f0'],\n            'FF:FF:FF:FF:FF:FF' => [\"\\nFF:FF:FF:FF:FF:FF\\n\", 'ffffffffffff'],\n\n            /* Incorrect variations that are also accepted */\n            'Too long -- extra character' => [\"\\nABC-01-23-45-67-89\\n\", 'bc0123456789'],\n            'Too long -- extra tuple' => [\"\\n01-AA-BB-CC-DD-EE-FF\\n\", '01aabbccddee'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Provider/Time/FixedTimeProviderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Provider\\Time;\n\nuse Ramsey\\Uuid\\Provider\\Time\\FixedTimeProvider;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Time;\n\nclass FixedTimeProviderTest extends TestCase\n{\n    public function testGetTimeReturnsTime(): void\n    {\n        $time = new Time(1458844556, 200997);\n        $provider = new FixedTimeProvider($time);\n\n        $this->assertSame($time, $provider->getTime());\n    }\n\n    public function testGetTimeReturnsTimeAfterChange(): void\n    {\n        $time = new Time(1458844556, 200997);\n        $provider = new FixedTimeProvider($time);\n\n        $this->assertSame('1458844556', $provider->getTime()->getSeconds()->toString());\n        $this->assertSame('200997', $provider->getTime()->getMicroseconds()->toString());\n\n        $provider->setSec(1050804050);\n\n        $this->assertSame('1050804050', $provider->getTime()->getSeconds()->toString());\n        $this->assertSame('200997', $provider->getTime()->getMicroseconds()->toString());\n\n        $provider->setUsec(30192);\n\n        $this->assertSame('1050804050', $provider->getTime()->getSeconds()->toString());\n        $this->assertSame('30192', $provider->getTime()->getMicroseconds()->toString());\n\n        $this->assertNotSame($time, $provider->getTime());\n    }\n}\n"
  },
  {
    "path": "tests/Provider/Time/SystemTimeProviderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Provider\\Time;\n\nuse Ramsey\\Uuid\\Provider\\Time\\SystemTimeProvider;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Time;\n\nclass SystemTimeProviderTest extends TestCase\n{\n    public function testGetTimeUses(): void\n    {\n        $provider = new SystemTimeProvider();\n        $time = $provider->getTime();\n\n        /** @phpstan-ignore method.alreadyNarrowedType */\n        $this->assertInstanceOf(Time::class, $time);\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/FieldsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function hex2bin;\nuse function serialize;\nuse function str_replace;\nuse function unserialize;\n\nclass FieldsTest extends TestCase\n{\n    public function testConstructorThrowsExceptionIfNotSixteenByteString(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'The byte string must be 16 bytes long; received 6 bytes'\n        );\n\n        new Fields('foobar');\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     *\n     * @dataProvider nonRfc4122VariantProvider\n     */\n    public function testConstructorThrowsExceptionIfNotRfc4122Variant(string $uuid): void\n    {\n        $bytes = (string) hex2bin(str_replace('-', '', $uuid));\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant'\n        );\n\n        new Fields($bytes);\n    }\n\n    /**\n     * @return array<array{0: non-empty-string}>\n     */\n    public function nonRfc4122VariantProvider(): array\n    {\n        return [\n            ['ff6f8cb0-c57d-11e1-0b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-1b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-2b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-3b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-4b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-5b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-6b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-7b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-cb21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-db21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-eb21-0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-fb21-0800200c9a66'],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     *\n     * @dataProvider invalidVersionProvider\n     */\n    public function testConstructorThrowsExceptionIfInvalidVersion(string $uuid): void\n    {\n        $bytes = (string) hex2bin(str_replace('-', '', $uuid));\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version'\n        );\n\n        new Fields($bytes);\n    }\n\n    /**\n     * @return array<array{0: non-empty-string}>\n     */\n    public function invalidVersionProvider(): array\n    {\n        return [\n            ['ff6f8cb0-c57d-01e1-8b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-91e1-bb21-0800200c9a66'],\n            ['ff6f8cb0-c57d-a1e1-9b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-b1e1-ab21-0800200c9a66'],\n            ['ff6f8cb0-c57d-c1e1-ab21-0800200c9a66'],\n            ['ff6f8cb0-c57d-d1e1-ab21-0800200c9a66'],\n            ['ff6f8cb0-c57d-e1e1-ab21-0800200c9a66'],\n            ['ff6f8cb0-c57d-f1e1-ab21-0800200c9a66'],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     * @param non-empty-string $methodName\n     * @param non-empty-string | int | bool | null $expectedValue\n     *\n     * @dataProvider fieldGetterMethodProvider\n     */\n    public function testFieldGetterMethods(\n        string $uuid,\n        string $methodName,\n        bool | int | string | null $expectedValue,\n    ): void {\n        $bytes = (string) hex2bin(str_replace('-', '', $uuid));\n        $fields = new Fields($bytes);\n\n        $result = $fields->$methodName();\n\n        if ($result instanceof Hexadecimal) {\n            $this->assertSame($expectedValue, $result->toString());\n        } else {\n            $this->assertSame($expectedValue, $result);\n        }\n    }\n\n    /**\n     * @return array<array{0: non-empty-string, 1: non-empty-string, 2: non-empty-string | int | bool | null}>\n     */\n    public function fieldGetterMethodProvider(): array\n    {\n        return [\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeq', '1b21'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeqHiAndReserved', '9b'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeqLow', '21'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getNode', '0800200c9a66'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeHiAndVersion', '11e1'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeMid', 'c57d'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getVariant', 2],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getVersion', 1],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'isNil', false],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'isMax', false],\n\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeq', '2b21'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeqHiAndReserved', 'ab'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeqLow', '21'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getNode', '0800200c9a66'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeHiAndVersion', '41e1'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeMid', 'c57d'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getVariant', 2],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getVersion', 4],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'isNil', false],\n            ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'isMax', false],\n\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeq', '3b21'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeqHiAndReserved', 'bb'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeqLow', '21'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getNode', '0800200c9a66'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeHiAndVersion', '31e1'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeMid', 'c57d'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getVariant', 2],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getVersion', 3],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'isNil', false],\n            ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'isMax', false],\n\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeq', '0b21'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeqHiAndReserved', '8b'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeqLow', '21'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getNode', '0800200c9a66'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeHiAndVersion', '51e1'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeMid', 'c57d'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getVariant', 2],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getVersion', 5],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'isNil', false],\n            ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'isMax', false],\n\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getClockSeq', '0b21'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getClockSeqHiAndReserved', '8b'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getClockSeqLow', '21'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getNode', '0800200c9a66'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimeHiAndVersion', '61e1'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimeMid', 'c57d'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimestamp', 'ff6f8cb0c57d1e1'],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getVariant', 2],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getVersion', 6],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'isNil', false],\n            ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'isMax', false],\n\n            ['00000000-0000-0000-0000-000000000000', 'getClockSeq', '0000'],\n            ['00000000-0000-0000-0000-000000000000', 'getClockSeqHiAndReserved', '00'],\n            ['00000000-0000-0000-0000-000000000000', 'getClockSeqLow', '00'],\n            ['00000000-0000-0000-0000-000000000000', 'getNode', '000000000000'],\n            ['00000000-0000-0000-0000-000000000000', 'getTimeHiAndVersion', '0000'],\n            ['00000000-0000-0000-0000-000000000000', 'getTimeLow', '00000000'],\n            ['00000000-0000-0000-0000-000000000000', 'getTimeMid', '0000'],\n            ['00000000-0000-0000-0000-000000000000', 'getTimestamp', '000000000000000'],\n            ['00000000-0000-0000-0000-000000000000', 'getVariant', 0],\n            ['00000000-0000-0000-0000-000000000000', 'getVersion', null],\n            ['00000000-0000-0000-0000-000000000000', 'isNil', true],\n            ['00000000-0000-0000-0000-000000000000', 'isMax', false],\n\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getClockSeq', 'ffff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getClockSeqHiAndReserved', 'ff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getClockSeqLow', 'ff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getNode', 'ffffffffffff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeHiAndVersion', 'ffff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeLow', 'ffffffff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeMid', 'ffff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimestamp', 'fffffffffffffff'],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVariant', 7],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVersion', null],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isNil', false],\n            ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isMax', true],\n\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getClockSeq', '0400'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getClockSeqHiAndReserved', '84'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getClockSeqLow', '00'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getNode', '0242ac130003'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimeHiAndVersion', '21ea'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimeLow', '000001f5'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimeMid', '5cde'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimestamp', '1ea5cde00000000'],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getVariant', 2],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'getVersion', 2],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'isNil', false],\n            ['000001f5-5cde-21ea-8400-0242ac130003', 'isMax', false],\n\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getClockSeq', '1b21'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getClockSeqHiAndReserved', '9b'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getClockSeqLow', '21'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getNode', '0800200c9a66'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimeHiAndVersion', '71e1'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimeLow', '018339f0'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimeMid', '1b83'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimestamp', '000018339f01b83'],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getVariant', 2],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getVersion', 7],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'isNil', false],\n            ['018339f0-1b83-71e1-9b21-0800200c9a66', 'isMax', false],\n        ];\n    }\n\n    public function testSerializingFields(): void\n    {\n        $bytes = (string) hex2bin(str_replace('-', '', 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66'));\n        $fields = new Fields($bytes);\n\n        $serializedFields = serialize($fields);\n\n        /** @var Fields $unserializedFields */\n        $unserializedFields = unserialize($serializedFields);\n\n        $this->assertSame($fields->getBytes(), $unserializedFields->getBytes());\n    }\n\n    public function testSerializingFieldsWithOldFormat(): void\n    {\n        $fields = new Fields(\"\\xb3\\xcd\\x58\\x6a\\xe3\\xca\\x44\\xf3\\x98\\x8c\\xf4\\xd6\\x66\\xc1\\xbf\\x4d\");\n\n        $serializedFields = 'C:26:\"Ramsey\\Uuid\\Rfc4122\\Fields\":24:{s81YauPKRPOYjPTWZsG/TQ==}';\n\n        /** @var Fields $unserializedFields */\n        $unserializedFields = unserialize($serializedFields);\n\n        $this->assertSame($fields->getBytes(), $unserializedFields->getBytes());\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidBuilderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\StringCodec;\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Exception\\UnableToBuildUuidException;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Nonstandard\\UuidV6 as NonstandardUuidV6;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\MaxUuid;\nuse Ramsey\\Uuid\\Rfc4122\\NilUuid;\nuse Ramsey\\Uuid\\Rfc4122\\UuidBuilder;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV1;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV2;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV3;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV4;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV5;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV6;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV7;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV8;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nuse function hex2bin;\nuse function str_replace;\n\nclass UuidBuilderTest extends TestCase\n{\n    /**\n     * @param non-empty-string $uuid\n     * @param class-string $expectedClass\n     *\n     * @dataProvider provideBuildTestValues\n     */\n    public function testBuild(string $uuid, string $expectedClass, ?int $expectedVersion): void\n    {\n        $bytes = (string) hex2bin(str_replace('-', '', $uuid));\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n        $timeConverter = new GenericTimeConverter($calculator);\n        $builder = new UuidBuilder($numberConverter, $timeConverter);\n        $codec = new StringCodec($builder);\n\n        $result = $builder->build($codec, $bytes);\n\n        /** @var Fields $fields */\n        $fields = $result->getFields();\n\n        $this->assertInstanceOf($expectedClass, $result);\n        $this->assertSame($expectedVersion, $fields->getVersion());\n    }\n\n    /**\n     * @return array<array{uuid: non-empty-string, expectedClass: class-string, expectedVersion: int | null}>\n     */\n    public function provideBuildTestValues(): array\n    {\n        return [\n            [\n                'uuid' => '00000000-0000-0000-0000-000000000000',\n                'expectedClass' => NilUuid::class,\n                'expectedVersion' => null,\n            ],\n            [\n                'uuid' => 'ffffffff-ffff-ffff-ffff-ffffffffffff',\n                'expectedClass' => MaxUuid::class,\n                'expectedVersion' => null,\n            ],\n            [\n                'uuid' => 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV1::class,\n                'expectedVersion' => 1,\n            ],\n            [\n                'uuid' => 'ff6f8cb0-c57d-21e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV2::class,\n                'expectedVersion' => 2,\n            ],\n            [\n                'uuid' => 'ff6f8cb0-c57d-31e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV3::class,\n                'expectedVersion' => 3,\n            ],\n            [\n                'uuid' => 'ff6f8cb0-c57d-41e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV4::class,\n                'expectedVersion' => 4,\n            ],\n            [\n                'uuid' => 'ff6f8cb0-c57d-51e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV5::class,\n                'expectedVersion' => 5,\n            ],\n            [\n                'uuid' => 'ff6f8cb0-c57d-61e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV6::class,\n                'expectedVersion' => 6,\n            ],\n\n            // The same UUIDv6 will also be of the expected class type\n            // \\Ramsey\\Uuid\\Nonstandard\\UuidV6.\n            [\n                'uuid' => 'ff6f8cb0-c57d-61e1-9b21-0800200c9a66',\n                'expectedClass' => NonstandardUuidV6::class,\n                'expectedVersion' => 6,\n            ],\n\n            [\n                'uuid' => 'ff6f8cb0-c57d-71e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV7::class,\n                'expectedVersion' => 7,\n            ],\n\n            [\n                'uuid' => 'ff6f8cb0-c57d-81e1-9b21-0800200c9a66',\n                'expectedClass' => UuidV8::class,\n                'expectedVersion' => 8,\n            ],\n        ];\n    }\n\n    public function testBuildThrowsUnableToBuildException(): void\n    {\n        $bytes = (string) hex2bin(str_replace('-', '', 'ff6f8cb0-c57d-51e1-9b21-0800200c9a'));\n\n        $calculator = new BrickMathCalculator();\n        $numberConverter = new GenericNumberConverter($calculator);\n        $timeConverter = new GenericTimeConverter($calculator);\n        $builder = new UuidBuilder($numberConverter, $timeConverter);\n        $codec = new StringCodec($builder);\n\n        $this->expectException(UnableToBuildUuidException::class);\n        $this->expectExceptionMessage(\n            'The byte string must be 16 bytes long; received 15 bytes'\n        );\n\n        $builder->build($codec, $bytes);\n    }\n\n    public function testBuildThrowsUnableToBuildExceptionForIncorrectVersionFields(): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'isNil' => false,\n            'isMax' => false,\n            'getVersion' => 255,\n        ]);\n\n        $builder = Mockery::mock(UuidBuilder::class);\n        $builder->shouldAllowMockingProtectedMethods();\n        $builder->shouldReceive('buildFields')->andReturn($fields);\n        $builder->shouldReceive('build')->passthru();\n\n        $codec = Mockery::mock(StringCodec::class);\n\n        $this->expectException(UnableToBuildUuidException::class);\n        $this->expectExceptionMessage(\n            'The UUID version in the given fields is not supported by this UUID builder'\n        );\n\n        $builder->build($codec, 'foobar');\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV1Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse DateTimeImmutable;\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV1;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\n\nclass UuidV1Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV1 must represent a '\n            . 'version 1 (time-based) UUID'\n        );\n\n        new UuidV1($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 2],\n            ['version' => 3],\n            ['version' => 4],\n            ['version' => 5],\n            ['version' => 6],\n            ['version' => 7],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     * @param numeric-string $expected\n     *\n     * @dataProvider provideUuidV1WithOddMicroseconds\n     */\n    public function testGetDateTimeProperlyHandlesLongMicroseconds(string $uuid, string $expected): void\n    {\n        /** @var UuidV1 $object */\n        $object = Uuid::fromString($uuid);\n\n        $date = $object->getDateTime();\n\n        $this->assertInstanceOf(DateTimeImmutable::class, $date);\n        $this->assertSame($expected, $date->format('U.u'));\n    }\n\n    /**\n     * @return array<array{uuid: non-empty-string, expected: numeric-string}>\n     */\n    public function provideUuidV1WithOddMicroseconds(): array\n    {\n        return [\n            [\n                'uuid' => '14814000-1dd2-11b2-9669-00007ffffffe',\n                'expected' => '1.677722',\n            ],\n            [\n                'uuid' => '13714000-1dd2-11b2-9669-00007ffffffe',\n                'expected' => '0.104858',\n            ],\n            [\n                'uuid' => '13713000-1dd2-11b2-9669-00007ffffffe',\n                'expected' => '0.105267',\n            ],\n            [\n                'uuid' => '12e8a980-1dd2-11b2-8d4f-acde48001122',\n                'expected' => '-1.000000',\n            ],\n        ];\n    }\n\n    public function testGetDateTimeThrowsException(): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => 1,\n            'getTimestamp' => new Hexadecimal('0'),\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $timeConverter = Mockery::mock(TimeConverterInterface::class, [\n            'convertTime' => new Time('0', '1234567'),\n        ]);\n\n        $uuid = new UuidV1($fields, $numberConverter, $codec, $timeConverter);\n\n        $this->expectException(DateTimeException::class);\n\n        $uuid->getDateTime();\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV2Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse DateTimeInterface;\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\Number\\GenericNumberConverter;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Generator\\DceSecurityGenerator;\nuse Ramsey\\Uuid\\Generator\\DefaultTimeGenerator;\nuse Ramsey\\Uuid\\Math\\BrickMathCalculator;\nuse Ramsey\\Uuid\\Provider\\Dce\\SystemDceSecurityProvider;\nuse Ramsey\\Uuid\\Provider\\Node\\StaticNodeProvider;\nuse Ramsey\\Uuid\\Provider\\Time\\FixedTimeProvider;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV2;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidFactory;\n\nuse const PHP_VERSION_ID;\n\nclass UuidV2Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV2 must represent a '\n            . 'version 2 (DCE Security) UUID'\n        );\n\n        new UuidV2($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 3],\n            ['version' => 4],\n            ['version' => 5],\n            ['version' => 6],\n            ['version' => 7],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n\n    /**\n     * @dataProvider provideLocalDomainAndIdentifierForTests\n     */\n    public function testGetLocalDomainAndIdentifier(\n        int $domain,\n        IntegerObject $identifier,\n        Time $time,\n        int $expectedDomain,\n        string $expectedDomainName,\n        string $expectedIdentifier,\n        string $expectedTimestamp,\n        string $expectedTime\n    ): void {\n        $calculator = new BrickMathCalculator();\n        $genericConverter = new GenericTimeConverter($calculator);\n        $numberConverter = new GenericNumberConverter($calculator);\n        $nodeProvider = new StaticNodeProvider(new Hexadecimal('1234567890ab'));\n        $timeProvider = new FixedTimeProvider($time);\n        $timeGenerator = new DefaultTimeGenerator($nodeProvider, $genericConverter, $timeProvider);\n        $dceProvider = new SystemDceSecurityProvider();\n        $dceGenerator = new DceSecurityGenerator($numberConverter, $timeGenerator, $dceProvider);\n\n        $factory = new UuidFactory();\n        $factory->setTimeGenerator($timeGenerator);\n        $factory->setDceSecurityGenerator($dceGenerator);\n\n        /** @var UuidV2 $uuid */\n        $uuid = $factory->uuid2($domain, $identifier);\n\n        /** @var FieldsInterface $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertSame($expectedDomain, $uuid->getLocalDomain());\n        $this->assertSame($expectedDomainName, $uuid->getLocalDomainName());\n        $this->assertInstanceOf(IntegerObject::class, $uuid->getLocalIdentifier());\n        $this->assertSame($expectedIdentifier, $uuid->getLocalIdentifier()->toString());\n        $this->assertSame($expectedTimestamp, $fields->getTimestamp()->toString());\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n        $this->assertSame($expectedTime, $uuid->getDateTime()->format('U.u'));\n        $this->assertSame('1334567890ab', $fields->getNode()->toString());\n    }\n\n    /**\n     * @return array<array{\n     *     domain: int,\n     *     identifier: IntegerObject,\n     *     time: Time,\n     *     expectedDomain: int,\n     *     expectedDomainName: non-empty-string,\n     *     expectedIdentifier: non-empty-string,\n     *     expectedTimestamp: non-empty-string,\n     *     expectedTime: non-empty-string,\n     * }>\n     */\n    public function provideLocalDomainAndIdentifierForTests(): array\n    {\n        // https://github.com/php/php-src/issues/7758\n        $isGH7758Fixed = PHP_VERSION_ID >= 80107;\n\n        return [\n            [\n                'domain' => Uuid::DCE_DOMAIN_PERSON,\n                'identifier' => new IntegerObject('12345678'),\n                'time' => new Time(0, 0),\n                'expectedDomain' => 0,\n                'expectedDomainName' => 'person',\n                'expectedIdentifier' => '12345678',\n                'expectedTimestamp' => '1b21dd200000000',\n                'expectedTime' => $isGH7758Fixed ? '-33.276237' : '-32.723763',\n            ],\n            [\n                'domain' => Uuid::DCE_DOMAIN_GROUP,\n                'identifier' => new IntegerObject('87654321'),\n                'time' => new Time(0, 0),\n                'expectedDomain' => 1,\n                'expectedDomainName' => 'group',\n                'expectedIdentifier' => '87654321',\n                'expectedTimestamp' => '1b21dd200000000',\n                'expectedTime' => $isGH7758Fixed ? '-33.276237' : '-32.723763',\n            ],\n            [\n                'domain' => Uuid::DCE_DOMAIN_ORG,\n                'identifier' => new IntegerObject('1'),\n                'time' => new Time(0, 0),\n                'expectedDomain' => 2,\n                'expectedDomainName' => 'org',\n                'expectedIdentifier' => '1',\n                'expectedTimestamp' => '1b21dd200000000',\n                'expectedTime' => $isGH7758Fixed ? '-33.276237' : '-32.723763',\n            ],\n            [\n                'domain' => Uuid::DCE_DOMAIN_PERSON,\n                'identifier' => new IntegerObject('0'),\n                'time' => new Time(1583208664, 444109),\n                'expectedDomain' => 0,\n                'expectedDomainName' => 'person',\n                'expectedIdentifier' => '0',\n                'expectedTimestamp' => '1ea5d0500000000',\n                'expectedTime' => '1583208664.444109',\n            ],\n            [\n                'domain' => Uuid::DCE_DOMAIN_PERSON,\n                'identifier' => new IntegerObject('2147483647'),\n                'time' => new Time(1583208879, 500000),\n                'expectedDomain' => 0,\n                'expectedDomainName' => 'person',\n                'expectedIdentifier' => '2147483647',\n                // This time is the same as in the previous test because of the\n                // loss of precision by setting the lowest 32 bits to zeros.\n                'expectedTimestamp' => '1ea5d0500000000',\n                'expectedTime' => '1583208664.444109',\n            ],\n            [\n                'domain' => Uuid::DCE_DOMAIN_PERSON,\n                'identifier' => new IntegerObject('4294967295'),\n                'time' => new Time(1583208879, 500000),\n                'expectedDomain' => 0,\n                'expectedDomainName' => 'person',\n                'expectedIdentifier' => '4294967295',\n                // This time is the same as in the previous test because of the\n                // loss of precision by setting the lowest 32 bits to zeros.\n                'expectedTimestamp' => '1ea5d0500000000',\n                'expectedTime' => '1583208664.444109',\n            ],\n            [\n                'domain' => Uuid::DCE_DOMAIN_PERSON,\n                'identifier' => new IntegerObject('4294967295'),\n                'time' => new Time(1583209093, 940838),\n                'expectedDomain' => 0,\n                'expectedDomainName' => 'person',\n                'expectedIdentifier' => '4294967295',\n                // This time is the same as in the previous test because of the\n                // loss of precision by setting the lowest 32 bits to zeros.\n                'expectedTimestamp' => '1ea5d0500000000',\n                'expectedTime' => '1583208664.444109',\n            ],\n            [\n                'domain' => Uuid::DCE_DOMAIN_PERSON,\n                'identifier' => new IntegerObject('4294967295'),\n                'time' => new Time(1583209093, 940839),\n                'expectedDomain' => 0,\n                'expectedDomainName' => 'person',\n                'expectedIdentifier' => '4294967295',\n                'expectedTimestamp' => '1ea5d0600000000',\n                'expectedTime' => '1583209093.940838',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV3Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV3;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass UuidV3Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV3 must represent a '\n            . 'version 3 (name-based, MD5-hashed) UUID'\n        );\n\n        new UuidV3($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 2],\n            ['version' => 4],\n            ['version' => 5],\n            ['version' => 6],\n            ['version' => 7],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV4Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV4;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass UuidV4Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV4 must represent a '\n            . 'version 4 (random) UUID'\n        );\n\n        new UuidV4($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 2],\n            ['version' => 3],\n            ['version' => 5],\n            ['version' => 6],\n            ['version' => 7],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV5Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV5;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass UuidV5Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV5 must represent a '\n            . 'version 5 (named-based, SHA1-hashed) UUID'\n        );\n\n        new UuidV5($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 2],\n            ['version' => 3],\n            ['version' => 4],\n            ['version' => 6],\n            ['version' => 7],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV6Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse DateTimeImmutable;\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Lazy\\LazyUuidFromString;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV6;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\n\nclass UuidV6Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV6 must represent a '\n            . 'version 6 (reordered time) UUID'\n        );\n\n        new UuidV6($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 2],\n            ['version' => 3],\n            ['version' => 4],\n            ['version' => 5],\n            ['version' => 7],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     * @param non-empty-string $expected\n     *\n     * @dataProvider provideUuidV6WithOddMicroseconds\n     */\n    public function testGetDateTimeProperlyHandlesLongMicroseconds(string $uuid, string $expected): void\n    {\n        /** @var UuidV6 $object */\n        $object = Uuid::fromString($uuid);\n\n        $date = $object->getDateTime();\n\n        $this->assertInstanceOf(DateTimeImmutable::class, $date);\n        $this->assertSame($expected, $date->format('U.u'));\n    }\n\n    /**\n     * @return array<array{uuid: non-empty-string, expected: non-empty-string}>\n     */\n    public function provideUuidV6WithOddMicroseconds(): array\n    {\n        return [\n            [\n                'uuid' => '1b21dd21-4814-6000-9669-00007ffffffe',\n                'expected' => '1.677722',\n            ],\n            [\n                'uuid' => '1b21dd21-3714-6000-9669-00007ffffffe',\n                'expected' => '0.104858',\n            ],\n            [\n                'uuid' => '1b21dd21-3713-6000-9669-00007ffffffe',\n                'expected' => '0.105267',\n            ],\n            [\n                'uuid' => '1b21dd21-2e8a-6980-8d4f-acde48001122',\n                'expected' => '-1.000000',\n            ],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuidv6\n     * @param non-empty-string $uuidv1\n     *\n     * @dataProvider provideUuidV1UuidV6Equivalents\n     */\n    public function testToUuidV1(string $uuidv6, string $uuidv1): void\n    {\n        /** @var UuidV6 $uuid6 */\n        $uuid6 = Uuid::fromString($uuidv6);\n        $uuid1 = $uuid6->toUuidV1();\n\n        $this->assertSame($uuidv6, $uuid6->toString());\n        $this->assertSame($uuidv1, $uuid1->toString());\n\n        $this->assertSame(\n            $uuid6->getDateTime()->format('U.u'),\n            $uuid1->getDateTime()->format('U.u')\n        );\n    }\n\n    /**\n     * @param non-empty-string $uuidv6\n     * @param non-empty-string $uuidv1\n     *\n     * @dataProvider provideUuidV1UuidV6Equivalents\n     */\n    public function testFromUuidV1(string $uuidv6, string $uuidv1): void\n    {\n        /** @var LazyUuidFromString $uuid */\n        $uuid = Uuid::fromString($uuidv1);\n        $uuid1 = $uuid->toUuidV1();\n        $uuid6 = UuidV6::fromUuidV1($uuid1);\n\n        $this->assertSame($uuidv1, $uuid1->toString());\n        $this->assertSame($uuidv6, $uuid6->toString());\n\n        $this->assertSame(\n            $uuid1->getDateTime()->format('U.u'),\n            $uuid6->getDateTime()->format('U.u')\n        );\n    }\n\n    /**\n     * @return array<array{uuidv6: non-empty-string, uuidv1: non-empty-string}>\n     */\n    public function provideUuidV1UuidV6Equivalents(): array\n    {\n        return [\n            [\n                'uuidv6' => '1b21dd21-4814-6000-9669-00007ffffffe',\n                'uuidv1' => '14814000-1dd2-11b2-9669-00007ffffffe',\n            ],\n            [\n                'uuidv6' => '1b21dd21-3714-6000-9669-00007ffffffe',\n                'uuidv1' => '13714000-1dd2-11b2-9669-00007ffffffe',\n            ],\n            [\n                'uuidv6' => '1b21dd21-3713-6000-9669-00007ffffffe',\n                'uuidv1' => '13713000-1dd2-11b2-9669-00007ffffffe',\n            ],\n            [\n                'uuidv6' => '1b21dd21-2e8a-6980-8d4f-acde48001122',\n                'uuidv1' => '12e8a980-1dd2-11b2-8d4f-acde48001122',\n            ],\n        ];\n    }\n\n    public function testGetDateTimeThrowsException(): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => 6,\n            'getTimestamp' => new Hexadecimal('0'),\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $timeConverter = Mockery::mock(TimeConverterInterface::class, [\n            'convertTime' => new Time('0', '1234567'),\n        ]);\n\n        $uuid = new UuidV6($fields, $numberConverter, $codec, $timeConverter);\n\n        $this->expectException(DateTimeException::class);\n\n        $uuid->getDateTime();\n    }\n\n    /**\n     * @link https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#appendix-B.1\n     */\n    public function testUsingDraftPeabodyUuidV6TestVector(): void\n    {\n        $testVector = '1EC9414C-232A-6B00-B3C8-9E6BDECED846';\n\n        /** @var UuidV6 $uuidv6 */\n        $uuidv6 = Uuid::fromString($testVector);\n\n        $uuidv1 = $uuidv6->toUuidV1();\n\n        /** @var FieldsInterface $fields */\n        $fields = $uuidv6->getFields();\n\n        $this->assertSame('1ec9414c', $fields->getTimeLow()->toString());\n        $this->assertSame('232a', $fields->getTimeMid()->toString());\n        $this->assertSame('6b00', $fields->getTimeHiAndVersion()->toString());\n        $this->assertSame('b3', $fields->getClockSeqHiAndReserved()->toString());\n        $this->assertSame('c8', $fields->getClockSeqLow()->toString());\n        $this->assertSame('9e6bdeced846', $fields->getNode()->toString());\n        $this->assertSame(1645557742, $uuidv6->getDateTime()->getTimestamp());\n\n        $this->assertSame(\n            'c232ab00-9414-11ec-b3c8-9e6bdeced846',\n            $uuidv1->toString(),\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV7Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse DateTimeImmutable;\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV7;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\n\nclass UuidV7Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Fields used to create a UuidV7 must represent a '\n            . 'version 7 (Unix Epoch time) UUID'\n        );\n\n        new UuidV7($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 2],\n            ['version' => 3],\n            ['version' => 4],\n            ['version' => 5],\n            ['version' => 6],\n            ['version' => 8],\n            ['version' => 9],\n        ];\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     *\n     * @dataProvider provideUuidV7WithMicroseconds\n     */\n    public function testGetDateTimeProperlyHandlesMicroseconds(string $uuid, string $expected): void\n    {\n        /** @var UuidV7 $object */\n        $object = Uuid::fromString($uuid);\n\n        $date = $object->getDateTime();\n\n        $this->assertInstanceOf(DateTimeImmutable::class, $date);\n        $this->assertSame($expected, $date->format('U.u'));\n    }\n\n    /**\n     * @return array<array{uuid: string, expected: numeric-string}>\n     */\n    public function provideUuidV7WithMicroseconds(): array\n    {\n        return [\n            [\n                'uuid' => '00000000-0001-71b2-9669-00007ffffffe',\n                'expected' => '0.001000',\n            ],\n            [\n                'uuid' => '00000000-000f-71b2-9669-00007ffffffe',\n                'expected' => '0.015000',\n            ],\n            [\n                'uuid' => '00000000-0064-71b2-9669-00007ffffffe',\n                'expected' => '0.100000',\n            ],\n            [\n                'uuid' => '00000000-03e7-71b2-9669-00007ffffffe',\n                'expected' => '0.999000',\n            ],\n            [\n                'uuid' => '00000000-03e8-71b2-9669-00007ffffffe',\n                'expected' => '1.000000',\n            ],\n            [\n                'uuid' => '00000000-03e9-71b2-9669-00007ffffffe',\n                'expected' => '1.001000',\n            ],\n        ];\n    }\n\n    public function testGetDateTimeThrowsException(): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => 7,\n            'getTimestamp' => new Hexadecimal('0'),\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n\n        $timeConverter = Mockery::mock(TimeConverterInterface::class, [\n            'convertTime' => new Time('0', '1234567'),\n        ]);\n\n        $uuid = new UuidV7($fields, $numberConverter, $codec, $timeConverter);\n\n        $this->expectException(DateTimeException::class);\n\n        $uuid->getDateTime();\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/UuidV8Test.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV8;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nclass UuidV8Test extends TestCase\n{\n    /**\n     * @dataProvider provideTestVersions\n     */\n    public function testConstructorThrowsExceptionWhenFieldsAreNotValidForType(int $version): void\n    {\n        $fields = Mockery::mock(FieldsInterface::class, [\n            'getVersion' => $version,\n        ]);\n\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $codec = Mockery::mock(CodecInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Fields used to create a UuidV8 must represent a version 8 (custom format) UUID');\n\n        new UuidV8($fields, $numberConverter, $codec, $timeConverter);\n    }\n\n    /**\n     * @return array<array{version: int}>\n     */\n    public function provideTestVersions(): array\n    {\n        return [\n            ['version' => 0],\n            ['version' => 1],\n            ['version' => 2],\n            ['version' => 3],\n            ['version' => 4],\n            ['version' => 5],\n            ['version' => 6],\n            ['version' => 7],\n            ['version' => 9],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/ValidatorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Ramsey\\Uuid\\Rfc4122\\Validator;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nuse function array_merge;\nuse function in_array;\nuse function strtoupper;\n\nclass ValidatorTest extends TestCase\n{\n    /**\n     * @dataProvider provideValuesForValidation\n     */\n    public function testValidate(string $value, bool $expected): void\n    {\n        $variations = [];\n        $variations[] = $value;\n        $variations[] = 'urn:uuid:' . $value;\n        $variations[] = '{' . $value . '}';\n\n        foreach ($variations as $variation) {\n            $variations[] = strtoupper($variation);\n        }\n\n        $validator = new Validator();\n\n        foreach ($variations as $variation) {\n            $this->assertSame(\n                $expected,\n                $validator->validate($variation),\n                sprintf(\n                    'Expected \"%s\" to be %s',\n                    $variation,\n                    $expected ? 'valid' : 'not valid',\n                ),\n            );\n        }\n    }\n\n    /**\n     * @return array<array{value: string, expected: bool}>\n     */\n    public function provideValuesForValidation(): array\n    {\n        $hexMutations = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];\n        $trueVersions = [1, 2, 3, 4, 5, 6, 7, 8];\n        $trueVariants = [8, 9, 'a', 'b'];\n\n        $testValues = [];\n\n        foreach ($hexMutations as $version) {\n            foreach ($hexMutations as $variant) {\n                $testValues[] = [\n                    'value' => \"ff6f8cb0-c57d-{$version}1e1-{$variant}b21-0800200c9a66\",\n                    'expected' => in_array($variant, $trueVariants, true) && in_array($version, $trueVersions, true),\n                ];\n            }\n        }\n\n        return array_merge($testValues, [\n            [\n                'value' => 'zf6f8cb0-c57d-11e1-9b21-0800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => '3f6f8cb0-c57d-11e1-9b21-0800200c9a6',\n                'expected' => false,\n            ],\n            [\n                'value' => 'af6f8cb-c57d-11e1-9b21-0800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => 'af6f8cb0c57d11e19b210800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => 'ff6f8cb0-c57da-51e1-9b21-0800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => \"ff6f8cb0-c57d-11e1-1b21-0800200c9a66\\n\",\n                'expected' => false,\n            ],\n            [\n                'value' => \"\\nff6f8cb0-c57d-11e1-1b21-0800200c9a66\",\n                'expected' => false,\n            ],\n            [\n                'value' => \"\\nff6f8cb0-c57d-11e1-1b21-0800200c9a66\\n\",\n                'expected' => false,\n            ],\n            [\n                'value' => '00000000-0000-0000-0000-000000000000',\n                'expected' => true,\n            ],\n            [\n                'value' => 'ffffffff-ffff-ffff-ffff-ffffffffffff',\n                'expected' => true,\n            ],\n            [\n                'value' => 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF',\n                'expected' => true,\n            ],\n        ]);\n    }\n\n    public function testGetPattern(): void\n    {\n        $expectedPattern = '\\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-'\n            . '[1-8][0-9A-Fa-f]{3}-[ABab89][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\\z';\n\n        $validator = new Validator();\n\n        $this->assertSame($expectedPattern, $validator->getPattern());\n    }\n}\n"
  },
  {
    "path": "tests/Rfc4122/VariantTraitTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Rfc4122;\n\nuse Mockery;\nuse Ramsey\\Uuid\\Exception\\InvalidBytesException;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Rfc4122\\VariantTrait;\nuse Ramsey\\Uuid\\Test\\TestCase;\n\nuse function hex2bin;\nuse function str_replace;\n\nclass VariantTraitTest extends TestCase\n{\n    /**\n     * @dataProvider invalidBytesProvider\n     */\n    public function testGetVariantThrowsExceptionForWrongNumberOfBytes(string $bytes): void\n    {\n        /** @var Fields $trait */\n        $trait = Mockery::mock(VariantTrait::class, [\n            'getBytes' => $bytes,\n            'isMax' => false,\n            'isNil' => false,\n        ]);\n\n        $this->expectException(InvalidBytesException::class);\n        $this->expectExceptionMessage('Invalid number of bytes');\n\n        $trait->getVariant();\n    }\n\n    /**\n     * @return array<array{0: non-empty-string}>\n     */\n    public function invalidBytesProvider(): array\n    {\n        return [\n            ['not16Bytes_abcd'],\n            ['not16Bytes_abcdef'],\n        ];\n    }\n\n    /**\n     * @dataProvider uuidVariantProvider\n     */\n    public function testGetVariant(string $uuid, int $expectedVariant): void\n    {\n        $bytes = (string) hex2bin(str_replace('-', '', $uuid));\n\n        /** @var Fields $trait */\n        $trait = Mockery::mock(VariantTrait::class, [\n            'getBytes' => $bytes,\n            'isMax' => false,\n            'isNil' => false,\n        ]);\n\n        $this->assertSame($expectedVariant, $trait->getVariant());\n    }\n\n    /**\n     * @return array<array{0: non-empty-string, 1: int}>\n     */\n    public function uuidVariantProvider(): array\n    {\n        return [\n            ['ff6f8cb0-c57d-11e1-0b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-1b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-2b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-3b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-4b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-5b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-6b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-7b21-0800200c9a66', 0],\n            ['ff6f8cb0-c57d-11e1-8b21-0800200c9a66', 2],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 2],\n            ['ff6f8cb0-c57d-11e1-ab21-0800200c9a66', 2],\n            ['ff6f8cb0-c57d-11e1-bb21-0800200c9a66', 2],\n            ['ff6f8cb0-c57d-11e1-cb21-0800200c9a66', 6],\n            ['ff6f8cb0-c57d-11e1-db21-0800200c9a66', 6],\n            ['ff6f8cb0-c57d-11e1-eb21-0800200c9a66', 7],\n            ['ff6f8cb0-c57d-11e1-fb21-0800200c9a66', 7],\n\n            // The following are the same UUIDs in GUID byte order. Dashes have\n            // been removed in the tests to distinguish these from string\n            // representations, which are never in GUID byte order.\n            ['b08c6fff7dc5e1110b210800200c9a66', 0],\n            ['b08c6fff7dc5e1111b210800200c9a66', 0],\n            ['b08c6fff7dc5e1112b210800200c9a66', 0],\n            ['b08c6fff7dc5e1113b210800200c9a66', 0],\n            ['b08c6fff7dc5e1114b210800200c9a66', 0],\n            ['b08c6fff7dc5e1115b210800200c9a66', 0],\n            ['b08c6fff7dc5e1116b210800200c9a66', 0],\n            ['b08c6fff7dc5e1117b210800200c9a66', 0],\n            ['b08c6fff7dc5e1118b210800200c9a66', 2],\n            ['b08c6fff7dc5e1119b210800200c9a66', 2],\n            ['b08c6fff7dc5e111ab210800200c9a66', 2],\n            ['b08c6fff7dc5e111bb210800200c9a66', 2],\n            ['b08c6fff7dc5e111cb210800200c9a66', 6],\n            ['b08c6fff7dc5e111db210800200c9a66', 6],\n            ['b08c6fff7dc5e111eb210800200c9a66', 7],\n            ['b08c6fff7dc5e111fb210800200c9a66', 7],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/TestCase.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse Mockery;\nuse PHPUnit\\Framework\\TestCase as PhpUnitTestCase;\n\nuse function current;\nuse function pack;\nuse function unpack;\n\nclass TestCase extends PhpUnitTestCase\n{\n    protected function tearDown(): void\n    {\n        parent::tearDown();\n        Mockery::close();\n    }\n\n    public static function isLittleEndianSystem(): bool\n    {\n        /** @var int[] $unpacked */\n        $unpacked = unpack('v', pack('S', 0x00FF));\n\n        return current($unpacked) === 0x00FF;\n    }\n}\n"
  },
  {
    "path": "tests/Type/DecimalTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Type;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Decimal;\n\nuse function json_encode;\nuse function serialize;\nuse function sprintf;\nuse function unserialize;\n\nclass DecimalTest extends TestCase\n{\n    /**\n     * @param int|float|string|Decimal $value\n     *\n     * @dataProvider provideDecimal\n     */\n    public function testDecimalValueType($value, string $expected, bool $expectedIsNegative): void\n    {\n        $decimal = new Decimal($value);\n\n        $this->assertSame($expected, $decimal->toString());\n        $this->assertSame($expected, (string) $decimal);\n        $this->assertSame($expectedIsNegative, $decimal->isNegative());\n    }\n\n    /**\n     * @return array<array{value: int|float|string|Decimal, expected: string, expectedIsNegative: bool}>\n     */\n    public function provideDecimal(): array\n    {\n        return [\n            [\n                'value' => '-11386878954224802805705605120',\n                'expected' => '-11386878954224802805705605120',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => '-9223372036854775808',\n                'expected' => '-9223372036854775808',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -99986838650880,\n                'expected' => '-99986838650880',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -4294967296,\n                'expected' => '-4294967296',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -2147483649,\n                'expected' => '-2147483649',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -123456.0,\n                'expected' => '-123456',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -1.00000000000001,\n                'expected' => '-1',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -1,\n                'expected' => '-1',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => '-1',\n                'expected' => '-1',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => 0,\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => -0,\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '-0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '+0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 1,\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '1',\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '+1',\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 1.00000000000001,\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 123456.0,\n                'expected' => '123456',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 2147483648,\n                'expected' => '2147483648',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 4294967294,\n                'expected' => '4294967294',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 99965363767850,\n                'expected' => '99965363767850',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '9223372036854775808',\n                'expected' => '9223372036854775808',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '11386878954224802805705605120',\n                'expected' => '11386878954224802805705605120',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => -9223372036854775809,\n                'expected' => '-9.2233720368548E+18',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => 9223372036854775808,\n                'expected' => '9.2233720368548E+18',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => -123456.789,\n                'expected' => '-123456.789',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -1.0000000000001,\n                'expected' => '-1.0000000000001',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -0.5,\n                'expected' => '-0.5',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => 0.5,\n                'expected' => '0.5',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 1.0000000000001,\n                'expected' => '1.0000000000001',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 123456.789,\n                'expected' => '123456.789',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '-0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '+0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => -0.00000000,\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 0.00000000,\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => -0.0001,\n                'expected' => '-0.0001',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => 0.0001,\n                'expected' => '0.0001',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => -0.00001,\n                'expected' => '-1.0E-5',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => 0.00001,\n                'expected' => '1.0E-5',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '+1234.56',\n                'expected' => '1234.56',\n                'expectedIsNegative' => false,\n            ],\n        ];\n    }\n\n    /**\n     * @param int|float|string $value\n     *\n     * @dataProvider provideDecimalBadValues\n     */\n    public function testDecimalTypeThrowsExceptionForBadValues($value): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a signed decimal or a string containing only '\n            . 'digits 0-9 and, optionally, a decimal point or sign (+ or -)'\n        );\n\n        new Decimal($value);\n    }\n\n    /**\n     * @return array<array{0: int|float|string}>\n     */\n    public function provideDecimalBadValues(): array\n    {\n        return [\n            ['123abc'],\n            ['abc123'],\n            ['foobar'],\n            ['123.456a'],\n            ['+abcd'],\n            ['-0012.a'],\n        ];\n    }\n\n    /**\n     * @param float|int|string|Decimal $value\n     *\n     * @dataProvider provideDecimal\n     */\n    public function testSerializeUnserializeDecimal($value, string $expected): void\n    {\n        $decimal = new Decimal($value);\n        $serializedDecimal = serialize($decimal);\n\n        /** @var Decimal $unserializedDecimal */\n        $unserializedDecimal = unserialize($serializedDecimal);\n\n        $this->assertSame($expected, $unserializedDecimal->toString());\n    }\n\n    /**\n     * @param float|int|string|Decimal $value\n     *\n     * @dataProvider provideDecimal\n     */\n    public function testJsonSerialize($value, string $expected): void\n    {\n        $decimal = new Decimal($value);\n        $expectedJson = sprintf('\"%s\"', $expected);\n\n        $this->assertSame($expectedJson, json_encode($decimal));\n    }\n}\n"
  },
  {
    "path": "tests/Type/HexadecimalTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Type;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\n\nuse function json_encode;\nuse function serialize;\nuse function sprintf;\nuse function unserialize;\n\nclass HexadecimalTest extends TestCase\n{\n    /**\n     * @dataProvider provideHex\n     */\n    public function testHexadecimalType(string $value, string $expected): void\n    {\n        $hexadecimal = new Hexadecimal($value);\n\n        $this->assertSame($expected, $hexadecimal->toString());\n        $this->assertSame($expected, (string) $hexadecimal);\n    }\n\n    /**\n     * @return array<array{value: string, expected: string}>\n     */\n    public function provideHex(): array\n    {\n        return [\n            [\n                'value' => '0xFFFF',\n                'expected' => 'ffff',\n            ],\n            [\n                'value' => '0123456789abcdef',\n                'expected' => '0123456789abcdef',\n            ],\n            [\n                'value' => 'ABCDEF',\n                'expected' => 'abcdef',\n            ],\n        ];\n    }\n\n    /**\n     * @dataProvider provideHexBadValues\n     */\n    public function testHexadecimalTypeThrowsExceptionForBadValues(string $value): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a hexadecimal number'\n        );\n\n        new Hexadecimal($value);\n    }\n\n    /**\n     * @return array<array{0: string}>\n     */\n    public function provideHexBadValues(): array\n    {\n        return [\n            ['-123456.789'],\n            ['123456.789'],\n            ['foobar'],\n            ['0xfoobar'],\n        ];\n    }\n\n    /**\n     * @dataProvider provideHex\n     */\n    public function testSerializeUnserializeHexadecimal(string $value, string $expected): void\n    {\n        $hexadecimal = new Hexadecimal($value);\n        $serializedHexadecimal = serialize($hexadecimal);\n\n        /** @var Hexadecimal $unserializedHexadecimal */\n        $unserializedHexadecimal = unserialize($serializedHexadecimal);\n\n        $this->assertSame($expected, $unserializedHexadecimal->toString());\n    }\n\n    /**\n     * @dataProvider provideHex\n     */\n    public function testJsonSerialize(string $value, string $expected): void\n    {\n        $hexadecimal = new Hexadecimal($value);\n        $expectedJson = sprintf('\"%s\"', $expected);\n\n        $this->assertSame($expectedJson, json_encode($hexadecimal));\n    }\n}\n"
  },
  {
    "path": "tests/Type/IntegerTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Type;\n\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\n\nuse function json_encode;\nuse function serialize;\nuse function sprintf;\nuse function unserialize;\n\nclass IntegerTest extends TestCase\n{\n    /**\n     * @param int|float|string|IntegerObject $value\n     *\n     * @dataProvider provideInteger\n     */\n    public function testIntegerType($value, string $expected, bool $expectedIsNegative): void\n    {\n        $integer = new IntegerObject($value);\n\n        $this->assertSame($expected, $integer->toString());\n        $this->assertSame($expected, (string) $integer);\n        $this->assertSame($expectedIsNegative, $integer->isNegative());\n    }\n\n    /**\n     * @return array<array{value: int|float|string|IntegerObject, expected: string, expectedIsNegative: bool}>\n     */\n    public function provideInteger(): array\n    {\n        return [\n            [\n                'value' => '-11386878954224802805705605120',\n                'expected' => '-11386878954224802805705605120',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => '-9223372036854775808',\n                'expected' => '-9223372036854775808',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -99986838650880,\n                'expected' => '-99986838650880',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -4294967296,\n                'expected' => '-4294967296',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -2147483649,\n                'expected' => '-2147483649',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -123456.0,\n                'expected' => '-123456',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -1.00000000000001,\n                'expected' => '-1',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => -1,\n                'expected' => '-1',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => '-1',\n                'expected' => '-1',\n                'expectedIsNegative' => true,\n            ],\n            [\n                'value' => 0,\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => -0,\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '-0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '+0',\n                'expected' => '0',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 1,\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '1',\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '+1',\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 1.00000000000001,\n                'expected' => '1',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 123456.0,\n                'expected' => '123456',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 2147483648,\n                'expected' => '2147483648',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 4294967294,\n                'expected' => '4294967294',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => 99965363767850,\n                'expected' => '99965363767850',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '9223372036854775808',\n                'expected' => '9223372036854775808',\n                'expectedIsNegative' => false,\n            ],\n            [\n                'value' => '11386878954224802805705605120',\n                'expected' => '11386878954224802805705605120',\n                'expectedIsNegative' => false,\n            ],\n        ];\n    }\n\n    /**\n     * @param int|float|string $value\n     *\n     * @dataProvider provideIntegerBadValues\n     */\n    public function testIntegerTypeThrowsExceptionForBadValues($value): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Value must be a signed integer or a string containing only '\n            . 'digits 0-9 and, optionally, a sign (+ or -)'\n        );\n\n        new IntegerObject($value);\n    }\n\n    /**\n     * @return array<array{0: int|float|string}>\n     */\n    public function provideIntegerBadValues(): array\n    {\n        return [\n            [-9223372036854775809], // String value is \"-9.2233720368548E+18\"\n            [-123456.789],\n            [-1.0000000000001],\n            [-0.5],\n            [0.5],\n            [1.0000000000001],\n            [123456.789],\n            [9223372036854775808], // String value is \"9.2233720368548E+18\"\n            ['123abc'],\n            ['abc123'],\n            ['foobar'],\n        ];\n    }\n\n    /**\n     * @param int|float|string|IntegerObject $value\n     *\n     * @dataProvider provideInteger\n     */\n    public function testSerializeUnserializeInteger($value, string $expected): void\n    {\n        $integer = new IntegerObject($value);\n        $serializedInteger = serialize($integer);\n\n        /** @var IntegerObject $unserializedInteger */\n        $unserializedInteger = unserialize($serializedInteger);\n\n        $this->assertSame($expected, $unserializedInteger->toString());\n    }\n\n    /**\n     * @param int|float|string|IntegerObject $value\n     *\n     * @dataProvider provideInteger\n     */\n    public function testJsonSerialize($value, string $expected): void\n    {\n        $integer = new IntegerObject($value);\n        $expectedJson = sprintf('\"%s\"', $expected);\n\n        $this->assertSame($expectedJson, json_encode($integer));\n    }\n}\n"
  },
  {
    "path": "tests/Type/TimeTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Type;\n\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerObject;\nuse Ramsey\\Uuid\\Type\\Time;\n\nuse function json_encode;\nuse function serialize;\nuse function unserialize;\n\nclass TimeTest extends TestCase\n{\n    /**\n     * @param int|float|string|IntegerObject $seconds\n     * @param int|float|string|IntegerObject|null $microseconds\n     *\n     * @dataProvider provideTimeValues\n     */\n    public function testTime($seconds, $microseconds): void\n    {\n        $params = [$seconds];\n        $timeString = (string) $seconds;\n\n        if ($microseconds !== null) {\n            $params[] = $microseconds;\n            $timeString .= sprintf('.%06s', (string) $microseconds);\n        } else {\n            $timeString .= '.000000';\n        }\n\n        $time = new Time(...$params);\n\n        $this->assertSame((string) $seconds, $time->getSeconds()->toString());\n\n        $this->assertSame(\n            (string) $microseconds ?: '0',\n            $time->getMicroseconds()->toString()\n        );\n\n        $this->assertSame($timeString, (string) $time);\n    }\n\n    /**\n     * @return array<array{seconds: int|float|string|IntegerObject, microseconds: int|float|string|IntegerObject|null}>\n     */\n    public function provideTimeValues(): array\n    {\n        return [\n            [\n                'seconds' => 103072857659,\n                'microseconds' => null,\n            ],\n            [\n                'seconds' => -12219292800,\n                'microseconds' => 1234,\n            ],\n        ];\n    }\n\n    /**\n     * @param int|float|string|IntegerObject $seconds\n     * @param int|float|string|IntegerObject|null $microseconds\n     *\n     * @dataProvider provideTimeValues\n     */\n    public function testSerializeUnserializeTime($seconds, $microseconds): void\n    {\n        $params = [$seconds];\n        if ($microseconds !== null) {\n            $params[] = $microseconds;\n        }\n\n        $time = new Time(...$params);\n        $serializedTime = serialize($time);\n\n        /** @var Time $unserializedTime */\n        $unserializedTime = unserialize($serializedTime);\n\n        $this->assertSame((string) $seconds, $unserializedTime->getSeconds()->toString());\n\n        $this->assertSame(\n            (string) $microseconds ?: '0',\n            $unserializedTime->getMicroseconds()->toString()\n        );\n    }\n\n    public function testUnserializeOfInvalidValueException(): void\n    {\n        $invalidSerialization = 'C:21:\"Ramsey\\\\Uuid\\\\Type\\\\Time\":13:{{\"foo\":\"bar\"}}';\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage('Attempted to unserialize an invalid value');\n\n        unserialize($invalidSerialization);\n    }\n\n    /**\n     * @param int|float|string|IntegerObject $seconds\n     * @param int|float|string|IntegerObject|null $microseconds\n     *\n     * @dataProvider provideTimeValues\n     */\n    public function testJsonSerialize($seconds, $microseconds): void\n    {\n        $time = [\n            'seconds' => (string) $seconds,\n            'microseconds' => (string) $microseconds ?: '0',\n        ];\n\n        $expectedJson = json_encode($time);\n\n        $params = [$seconds];\n        if ($microseconds !== null) {\n            $params[] = $microseconds;\n        }\n\n        $time = new Time(...$params);\n\n        $this->assertSame($expectedJson, json_encode($time));\n    }\n}\n"
  },
  {
    "path": "tests/UuidFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse DateTime;\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Mockery;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Builder\\UuidBuilderInterface;\nuse Ramsey\\Uuid\\Codec\\CodecInterface;\nuse Ramsey\\Uuid\\Converter\\NumberConverterInterface;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\FeatureSet;\nuse Ramsey\\Uuid\\Generator\\DceSecurityGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\DefaultNameGenerator;\nuse Ramsey\\Uuid\\Generator\\NameGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorInterface;\nuse Ramsey\\Uuid\\Generator\\TimeGeneratorInterface;\nuse Ramsey\\Uuid\\Provider\\NodeProviderInterface;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\UuidFactory;\nuse Ramsey\\Uuid\\Validator\\ValidatorInterface;\n\nuse function hex2bin;\nuse function strtoupper;\n\nclass UuidFactoryTest extends TestCase\n{\n    public function testParsesUuidCorrectly(): void\n    {\n        $factory = new UuidFactory();\n\n        $uuid = $factory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString());\n        $this->assertSame(hex2bin('ff6f8cb0c57d11e19b210800200c9a66'), $uuid->getBytes());\n    }\n\n    public function testParsesGuidCorrectly(): void\n    {\n        $factory = new UuidFactory(new FeatureSet(true));\n\n        $uuid = $factory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString());\n        $this->assertSame(hex2bin('b08c6fff7dc5e1119b210800200c9a66'), $uuid->getBytes());\n    }\n\n    public function testFromStringParsesUuidInLowercase(): void\n    {\n        $uuidString = 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66';\n        $uuidUpper = strtoupper($uuidString);\n        $factory = new UuidFactory(new FeatureSet(true));\n\n        $uuid = $factory->fromString($uuidUpper);\n\n        $this->assertSame($uuidString, $uuid->toString());\n    }\n\n    public function testGettersReturnValueFromFeatureSet(): void\n    {\n        $codec = Mockery::mock(CodecInterface::class);\n        $nodeProvider = Mockery::mock(NodeProviderInterface::class);\n        $randomGenerator = Mockery::mock(RandomGeneratorInterface::class);\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n        $timeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n        $unixTimeGenerator = Mockery::mock(TimeGeneratorInterface::class);\n        $nameGenerator = Mockery::mock(NameGeneratorInterface::class);\n        $dceSecurityGenerator = Mockery::mock(DceSecurityGeneratorInterface::class);\n        $numberConverter = Mockery::mock(NumberConverterInterface::class);\n        $builder = Mockery::mock(UuidBuilderInterface::class);\n        $validator = Mockery::mock(ValidatorInterface::class);\n\n        $featureSet = Mockery::mock(FeatureSet::class, [\n            'getCodec' => $codec,\n            'getNodeProvider' => $nodeProvider,\n            'getRandomGenerator' => $randomGenerator,\n            'getTimeConverter' => $timeConverter,\n            'getTimeGenerator' => $timeGenerator,\n            'getNameGenerator' => $nameGenerator,\n            'getDceSecurityGenerator' => $dceSecurityGenerator,\n            'getNumberConverter' => $numberConverter,\n            'getBuilder' => $builder,\n            'getValidator' => $validator,\n            'getUnixTimeGenerator' => $unixTimeGenerator,\n        ]);\n\n        $uuidFactory = new UuidFactory($featureSet);\n        $this->assertSame(\n            $codec,\n            $uuidFactory->getCodec(),\n            'getCodec did not return CodecInterface from FeatureSet'\n        );\n\n        $this->assertSame(\n            $nodeProvider,\n            $uuidFactory->getNodeProvider(),\n            'getNodeProvider did not return NodeProviderInterface from FeatureSet'\n        );\n\n        $this->assertSame(\n            $randomGenerator,\n            $uuidFactory->getRandomGenerator(),\n            'getRandomGenerator did not return RandomGeneratorInterface from FeatureSet'\n        );\n\n        $this->assertSame(\n            $timeGenerator,\n            $uuidFactory->getTimeGenerator(),\n            'getTimeGenerator did not return TimeGeneratorInterface from FeatureSet'\n        );\n    }\n\n    public function testSettersSetValueForGetters(): void\n    {\n        $uuidFactory = new UuidFactory();\n\n        /** @var MockObject & CodecInterface $codec */\n        $codec = $this->getMockBuilder(CodecInterface::class)->getMock();\n        $uuidFactory->setCodec($codec);\n        $this->assertSame($codec, $uuidFactory->getCodec());\n\n        /** @var MockObject & TimeGeneratorInterface $timeGenerator */\n        $timeGenerator = $this->getMockBuilder(TimeGeneratorInterface::class)->getMock();\n        $uuidFactory->setTimeGenerator($timeGenerator);\n        $this->assertSame($timeGenerator, $uuidFactory->getTimeGenerator());\n\n        /** @var MockObject & NumberConverterInterface $numberConverter */\n        $numberConverter = $this->getMockBuilder(NumberConverterInterface::class)->getMock();\n        $uuidFactory->setNumberConverter($numberConverter);\n        $this->assertSame($numberConverter, $uuidFactory->getNumberConverter());\n\n        /** @var MockObject & UuidBuilderInterface $uuidBuilder */\n        $uuidBuilder = $this->getMockBuilder(UuidBuilderInterface::class)->getMock();\n        $uuidFactory->setUuidBuilder($uuidBuilder);\n        $this->assertSame($uuidBuilder, $uuidFactory->getUuidBuilder());\n    }\n\n    /**\n     * @dataProvider provideDateTime\n     */\n    public function testFromDateTime(\n        DateTimeInterface $dateTime,\n        ?Hexadecimal $node,\n        ?int $clockSeq,\n        string $expectedUuidFormat,\n        string $expectedTime\n    ): void {\n        $factory = new UuidFactory();\n\n        $uuid = $factory->fromDateTime($dateTime, $node, $clockSeq);\n\n        $this->assertStringMatchesFormat($expectedUuidFormat, $uuid->toString());\n        $this->assertSame($expectedTime, $uuid->getDateTime()->format('U.u'));\n    }\n\n    /**\n     * @return array<array{0: DateTimeInterface, 1: Hexadecimal | null, 2: int | null, 3: string, 4: string}>\n     */\n    public function provideDateTime(): array\n    {\n        return [\n            [\n                new DateTimeImmutable('2012-07-04 02:14:34.491000'),\n                null,\n                null,\n                'ff6f8cb0-c57d-11e1-%s',\n                '1341368074.491000',\n            ],\n            [\n                new DateTimeImmutable('1582-10-16 16:34:04'),\n                new Hexadecimal('0800200c9a66'),\n                15137,\n                '0901e600-0154-1000-%cb21-0800200c9a66',\n                '-12219146756.000000',\n            ],\n            [\n                new DateTime('5236-03-31 21:20:59.999999'),\n                new Hexadecimal('00007ffffffe'),\n                1641,\n                'ff9785f6-ffff-1fff-%c669-00007ffffffe',\n                '103072857659.999999',\n            ],\n            [\n                new DateTime('1582-10-15 00:00:00'),\n                new Hexadecimal('00007ffffffe'),\n                1641,\n                '00000000-0000-1000-%c669-00007ffffffe',\n                '-12219292800.000000',\n            ],\n            [\n                new DateTimeImmutable('@103072857660.684697'),\n                new Hexadecimal('0'),\n                0,\n                'fffffffa-ffff-1fff-%c000-000000000000',\n                '103072857660.684697',\n            ],\n            [\n                new DateTimeImmutable('5236-03-31 21:21:00.684697'),\n                null,\n                null,\n                'fffffffa-ffff-1fff-%s',\n                '103072857660.684697',\n            ],\n        ];\n    }\n\n    public function testFactoryReturnsDefaultNameGenerator(): void\n    {\n        $factory = new UuidFactory();\n\n        $this->assertInstanceOf(DefaultNameGenerator::class, $factory->getNameGenerator());\n    }\n\n    public function testFactoryReturnsSetNameGenerator(): void\n    {\n        $factory = new UuidFactory();\n\n        $this->assertInstanceOf(DefaultNameGenerator::class, $factory->getNameGenerator());\n\n        $nameGenerator = Mockery::mock(NameGeneratorInterface::class);\n        $factory->setNameGenerator($nameGenerator);\n\n        $this->assertSame($nameGenerator, $factory->getNameGenerator());\n    }\n}\n"
  },
  {
    "path": "tests/UuidTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test;\n\nuse BadMethodCallException;\nuse Brick\\Math\\BigDecimal;\nuse Brick\\Math\\RoundingMode;\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Mockery;\nuse Mockery\\MockInterface;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Ramsey\\Uuid\\Builder\\DefaultUuidBuilder;\nuse Ramsey\\Uuid\\Codec\\StringCodec;\nuse Ramsey\\Uuid\\Codec\\TimestampFirstCombCodec;\nuse Ramsey\\Uuid\\Codec\\TimestampLastCombCodec;\nuse Ramsey\\Uuid\\Converter\\Number\\BigNumberConverter;\nuse Ramsey\\Uuid\\Converter\\TimeConverterInterface;\nuse Ramsey\\Uuid\\Exception\\DateTimeException;\nuse Ramsey\\Uuid\\Exception\\InvalidArgumentException;\nuse Ramsey\\Uuid\\Exception\\InvalidUuidStringException;\nuse Ramsey\\Uuid\\Exception\\UnsupportedOperationException;\nuse Ramsey\\Uuid\\FeatureSet;\nuse Ramsey\\Uuid\\Generator\\CombGenerator;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorFactory;\nuse Ramsey\\Uuid\\Generator\\RandomGeneratorInterface;\nuse Ramsey\\Uuid\\Guid\\Guid;\nuse Ramsey\\Uuid\\Lazy\\LazyUuidFromString;\nuse Ramsey\\Uuid\\Provider\\Node\\RandomNodeProvider;\nuse Ramsey\\Uuid\\Provider\\Time\\FixedTimeProvider;\nuse Ramsey\\Uuid\\Rfc4122\\Fields;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV1;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Time;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidFactory;\nuse Ramsey\\Uuid\\UuidFactoryInterface;\nuse Ramsey\\Uuid\\UuidInterface;\nuse Ramsey\\Uuid\\Validator\\GenericValidator;\nuse Ramsey\\Uuid\\Validator\\ValidatorInterface;\nuse Stringable;\nuse stdClass;\n\nuse function base64_decode;\nuse function base64_encode;\nuse function gmdate;\nuse function hex2bin;\nuse function json_encode;\nuse function serialize;\nuse function str_pad;\nuse function strlen;\nuse function strtotime;\nuse function strtoupper;\nuse function substr;\nuse function uniqid;\nuse function unserialize;\nuse function usleep;\n\nclass UuidTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Uuid::setFactory(new UuidFactory());\n    }\n\n    public function testFromString(): void\n    {\n        $this->assertSame(\n            'ff6f8cb0-c57d-11e1-9b21-0800200c9a66',\n            Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66')\n                ->toString()\n        );\n    }\n\n    public function testFromHexadecimal(): void\n    {\n        $hex = new Hexadecimal('0x1EA78DEB37CE625E8F1A025041000001');\n        $uuid = Uuid::fromHexadecimal($hex);\n        $this->assertInstanceOf(Uuid::class, $uuid);\n        $this->assertEquals('1ea78deb-37ce-625e-8f1a-025041000001', $uuid->toString());\n    }\n\n    public function testFromHexadecimalShort(): void\n    {\n        $hex = new Hexadecimal('0x1EA78DEB37CE625E8F1A0250410000');\n\n        $this->expectException(InvalidUuidStringException::class);\n        $this->expectExceptionMessage('Invalid UUID string:');\n\n        Uuid::fromHexadecimal($hex);\n    }\n\n    public function testFromHexadecimalThrowsWhenMethodDoesNotExist(): void\n    {\n        $factory = Mockery::mock(UuidFactoryInterface::class);\n        Uuid::setFactory($factory);\n\n        $hex = new Hexadecimal('0x1EA78DEB37CE625E8F1A025041000001');\n\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('The method fromHexadecimal() does not exist on the provided factory');\n\n        Uuid::fromHexadecimal($hex);\n    }\n\n    /**\n     * Tests that UUID and GUID's have the same textual representation but not\n     * the same binary representation.\n     */\n    public function testFromGuidString(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        Uuid::setFactory(new UuidFactory(new FeatureSet(true)));\n\n        $guid = Guid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        // UUID's and GUID's share the same textual representation.\n        $this->assertSame($uuid->toString(), $guid->toString());\n\n        // But not the same binary representation.\n        $this->assertNotSame($uuid->getBytes(), $guid->getBytes());\n    }\n\n    public function testFromStringWithCurlyBraces(): void\n    {\n        $uuid = Uuid::fromString('{ff6f8cb0-c57d-11e1-9b21-0800200c9a66}');\n        $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString());\n    }\n\n    public function testFromStringWithInvalidUuidString(): void\n    {\n        $this->expectException(InvalidUuidStringException::class);\n        $this->expectExceptionMessage('Invalid UUID string:');\n\n        Uuid::fromString('ff6f8cb0-c57d-11e1-9b21');\n    }\n\n    public function testFromStringWithLeadingNewLine(): void\n    {\n        $this->expectException(InvalidUuidStringException::class);\n        $this->expectExceptionMessage('Invalid UUID string:');\n\n        Uuid::fromString(\"\\nd0d5f586-21d1-470c-8088-55c8857728dc\");\n    }\n\n    public function testFromStringWithTrailingNewLine(): void\n    {\n        $this->expectException(InvalidUuidStringException::class);\n        $this->expectExceptionMessage('Invalid UUID string:');\n\n        Uuid::fromString(\"d0d5f586-21d1-470c-8088-55c8857728dc\\n\");\n    }\n\n    public function testFromStringWithUrn(): void\n    {\n        $uuid = Uuid::fromString('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString());\n    }\n\n    public function testFromStringWithEmptyString(): void\n    {\n        $this->expectException(InvalidUuidStringException::class);\n        $this->expectExceptionMessage('Invalid UUID string: ');\n\n        Uuid::fromString('');\n    }\n\n    public function testFromStringUppercase(): void\n    {\n        $uuid = Uuid::fromString('FF6F8CB0-C57D-11E1-9B21-0800200C9A66');\n        $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString());\n    }\n\n    public function testFromStringLazyUuidFromUppercase(): void\n    {\n        $this->assertInstanceOf(LazyUuidFromString::class, Uuid::fromString('FF6F8CB0-C57D-11E1-9B21-0800200C9A66'));\n    }\n\n    public function testFromStringWithNilUuid(): void\n    {\n        $uuid = Uuid::fromString(Uuid::NIL);\n\n        /** @var Fields $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertSame('00000000-0000-0000-0000-000000000000', $uuid->toString());\n        $this->assertTrue($fields->isNil());\n        $this->assertFalse($fields->isMax());\n    }\n\n    public function testFromStringWithMaxUuid(): void\n    {\n        $uuid = Uuid::fromString(Uuid::MAX);\n\n        /** @var Fields $fields */\n        $fields = $uuid->getFields();\n\n        $this->assertSame('ffffffff-ffff-ffff-ffff-ffffffffffff', $uuid->toString());\n        $this->assertFalse($fields->isNil());\n        $this->assertTrue($fields->isMax());\n    }\n\n    public function testGetBytes(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame(16, strlen($uuid->getBytes()));\n        $this->assertSame('/2+MsMV9EeGbIQgAIAyaZg==', base64_encode($uuid->getBytes()));\n    }\n\n    public function testGetClockSeqHiAndReserved(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('155', $uuid->getClockSeqHiAndReserved());\n    }\n\n    public function testGetClockSeqHiAndReservedHex(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('9b', $uuid->getClockSeqHiAndReservedHex());\n    }\n\n    public function testGetClockSeqLow(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('33', $uuid->getClockSeqLow());\n    }\n\n    public function testGetClockSeqLowHex(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('21', $uuid->getClockSeqLowHex());\n    }\n\n    public function testGetClockSequence(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('6945', $uuid->getClockSequence());\n    }\n\n    public function testGetClockSequenceHex(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('1b21', $uuid->getClockSequenceHex());\n    }\n\n    public function testGetDateTime(): void\n    {\n        // Check a recent date\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('2012-07-04T02:14:34+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('1341368074.491000', $uuid->getDateTime()->format('U.u'));\n\n        // Check an old date\n        $uuid = Uuid::fromString('0901e600-0154-1000-9b21-0800200c9a66');\n        $this->assertSame('1582-10-16T16:34:04+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('-12219146756.000000', $uuid->getDateTime()->format('U.u'));\n\n        // Check a future date\n        $uuid = Uuid::fromString('ff9785f6-ffff-1fff-9669-00007ffffffe');\n        $this->assertSame('5236-03-31T21:20:59+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('103072857659.999999', $uuid->getDateTime()->format('U.u'));\n\n        // Check the last possible time supported by v1 UUIDs\n        // See inline comments in\n        // {@see \\Ramsey\\Uuid\\Test\\Converter\\Time\\GenericTimeConverterTest::provideCalculateTime()}\n        $uuid = Uuid::fromString('fffffffa-ffff-1fff-8b1e-acde48001122');\n        $this->assertSame('5236-03-31T21:21:00+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('103072857660.684697', $uuid->getDateTime()->format('U.u'));\n\n        // Check the oldest date\n        $uuid = Uuid::fromString('00000000-0000-1000-9669-00007ffffffe');\n        $this->assertSame('1582-10-15T00:00:00+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('-12219292800.000000', $uuid->getDateTime()->format('U.u'));\n\n        // The Unix epoch\n        $uuid = Uuid::fromString('13814000-1dd2-11b2-9669-00007ffffffe');\n        $this->assertSame('1970-01-01T00:00:00+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('0.000000', $uuid->getDateTime()->format('U.u'));\n    }\n\n    public function testGetDateTimeForUuidV6(): void\n    {\n        // Check a recent date\n        $uuid = Uuid::fromString('1e1c57df-f6f8-6cb0-9b21-0800200c9a66');\n        $this->assertSame('2012-07-04T02:14:34+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('1341368074.491000', $uuid->getDateTime()->format('U.u'));\n\n        // Check an old date\n        $uuid = Uuid::fromString('00001540-901e-6600-9b21-0800200c9a66');\n        $this->assertSame('1582-10-16T16:34:04+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('-12219146756.000000', $uuid->getDateTime()->format('U.u'));\n\n        // Check a future date\n        $uuid = Uuid::fromString('ffffffff-f978-65f6-9669-00007ffffffe');\n        $this->assertSame('5236-03-31T21:20:59+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('103072857659.999999', $uuid->getDateTime()->format('U.u'));\n\n        // Check the last possible time supported by UUIDs\n        // See inline comments in\n        // {@see \\Ramsey\\Uuid\\Test\\Converter\\Time\\GenericTimeConverterTest::provideCalculateTime()}\n        $uuid = Uuid::fromString('ffffffff-ffff-6ffa-8b1e-acde48001122');\n        $this->assertSame('5236-03-31T21:21:00+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('103072857660.684697', $uuid->getDateTime()->format('U.u'));\n\n        // Check the oldest date\n        $uuid = Uuid::fromString('00000000-0000-6000-9669-00007ffffffe');\n        $this->assertSame('1582-10-15T00:00:00+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('-12219292800.000000', $uuid->getDateTime()->format('U.u'));\n\n        // The Unix epoch\n        $uuid = Uuid::fromString('1b21dd21-3814-6000-9669-00007ffffffe');\n        $this->assertSame('1970-01-01T00:00:00+00:00', $uuid->getDateTime()->format('c'));\n        $this->assertSame('0.000000', $uuid->getDateTime()->format('U.u'));\n    }\n\n    public function testGetDateTimeFromNonVersion1Uuid(): void\n    {\n        // Using a version 4 UUID to test\n        $uuid = Uuid::fromString('bf17b594-41f2-474f-bf70-4c90220f75de');\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage('Not a time-based UUID');\n\n        $uuid->getDateTime();\n    }\n\n    public function testGetFields(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        $this->assertInstanceOf(FieldsInterface::class, $uuid->getFields());\n    }\n\n    public function testGetFieldsHex(): void\n    {\n        $fields = [\n            'time_low' => 'ff6f8cb0',\n            'time_mid' => 'c57d',\n            'time_hi_and_version' => '11e1',\n            'clock_seq_hi_and_reserved' => '9b',\n            'clock_seq_low' => '21',\n            'node' => '0800200c9a66',\n        ];\n\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        $this->assertSame($fields, $uuid->getFieldsHex());\n    }\n\n    public function testGetLeastSignificantBits(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        $this->assertSame('11178224546741000806', $uuid->getLeastSignificantBits());\n    }\n\n    public function testGetLeastSignificantBitsHex(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        $this->assertSame('9b210800200c9a66', $uuid->getLeastSignificantBitsHex());\n    }\n\n    public function testGetMostSignificantBits(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        $this->assertSame('18406084892941947361', $uuid->getMostSignificantBits());\n    }\n\n    public function testGetMostSignificantBitsHex(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('ff6f8cb0c57d11e1', $uuid->getMostSignificantBitsHex());\n    }\n\n    public function testGetNode(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('8796630719078', $uuid->getNode());\n    }\n\n    public function testGetNodeHex(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('0800200c9a66', $uuid->getNodeHex());\n    }\n\n    public function testGetTimeHiAndVersion(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('4577', $uuid->getTimeHiAndVersion());\n    }\n\n    public function testGetTimeHiAndVersionHex(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('11e1', $uuid->getTimeHiAndVersionHex());\n    }\n\n    public function testGetTimeLow(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('4285500592', $uuid->getTimeLow());\n    }\n\n    public function testGetTimeLowHex(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('ff6f8cb0', $uuid->getTimeLowHex());\n    }\n\n    public function testGetTimeMid(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('50557', $uuid->getTimeMid());\n    }\n\n    public function testGetTimeMidHex(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('c57d', $uuid->getTimeMidHex());\n    }\n\n    public function testGetTimestamp(): void\n    {\n        // Check for a recent date\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('135606608744910000', $uuid->getTimestamp());\n\n        // Check for an old date\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('0901e600-0154-1000-9b21-0800200c9a66');\n        $this->assertSame('1460440000000', $uuid->getTimestamp());\n    }\n\n    public function testGetTimestampHex(): void\n    {\n        // Check for a recent date\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('1e1c57dff6f8cb0', $uuid->getTimestampHex());\n\n        // Check for an old date\n        $uuid = Uuid::fromString('0901e600-0154-1000-9b21-0800200c9a66');\n        $this->assertSame('00001540901e600', $uuid->getTimestampHex());\n    }\n\n    public function testGetTimestampFromNonVersion1Uuid(): void\n    {\n        // Using a version 4 UUID to test\n        /** @var Uuid $uuid */\n        $uuid = Uuid::fromString('bf17b594-41f2-474f-bf70-4c90220f75de');\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage('Not a time-based UUID');\n\n        $uuid->getTimestamp();\n    }\n\n    public function testGetTimestampHexFromNonVersion1Uuid(): void\n    {\n        // Using a version 4 UUID to test\n        $uuid = Uuid::fromString('bf17b594-41f2-474f-bf70-4c90220f75de');\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage('Not a time-based UUID');\n\n        $uuid->getTimestampHex();\n    }\n\n    public function testGetUrn(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->getUrn());\n    }\n\n    /**\n     * @param non-empty-string $uuid\n     *\n     * @dataProvider provideVariousVariantUuids\n     */\n    public function testGetVariantForVariousVariantUuids(string $uuid, int $variant): void\n    {\n        $uuid = Uuid::fromString($uuid);\n        $this->assertSame($variant, $uuid->getVariant());\n    }\n\n    /**\n     * @return array<array{0: non-empty-string, 1: int}>\n     */\n    public function provideVariousVariantUuids(): array\n    {\n        return [\n            ['ff6f8cb0-c57d-11e1-0b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-1b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-2b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-3b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-4b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-5b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-6b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-7b21-0800200c9a66', Uuid::RESERVED_NCS],\n            ['ff6f8cb0-c57d-11e1-8b21-0800200c9a66', Uuid::RFC_4122],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', Uuid::RFC_4122],\n            ['ff6f8cb0-c57d-11e1-ab21-0800200c9a66', Uuid::RFC_4122],\n            ['ff6f8cb0-c57d-11e1-bb21-0800200c9a66', Uuid::RFC_4122],\n            ['ff6f8cb0-c57d-11e1-cb21-0800200c9a66', Uuid::RESERVED_MICROSOFT],\n            ['ff6f8cb0-c57d-11e1-db21-0800200c9a66', Uuid::RESERVED_MICROSOFT],\n            ['ff6f8cb0-c57d-11e1-eb21-0800200c9a66', Uuid::RESERVED_FUTURE],\n            ['ff6f8cb0-c57d-11e1-fb21-0800200c9a66', Uuid::RESERVED_FUTURE],\n        ];\n    }\n\n    public function testGetVersionForVersion1(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame(1, $uuid->getVersion());\n    }\n\n    public function testGetVersionForVersion2(): void\n    {\n        $uuid = Uuid::fromString('6fa459ea-ee8a-2ca4-894e-db77e160355e');\n        $this->assertSame(2, $uuid->getVersion());\n    }\n\n    public function testGetVersionForVersion3(): void\n    {\n        $uuid = Uuid::fromString('6fa459ea-ee8a-3ca4-894e-db77e160355e');\n        $this->assertSame(3, $uuid->getVersion());\n    }\n\n    public function testGetVersionForVersion4(): void\n    {\n        $uuid = Uuid::fromString('6fabf0bc-603a-42f2-925b-d9f779bd0032');\n        $this->assertSame(4, $uuid->getVersion());\n    }\n\n    public function testGetVersionForVersion5(): void\n    {\n        $uuid = Uuid::fromString('886313e1-3b8a-5372-9b90-0c9aee199e5d');\n        $this->assertSame(5, $uuid->getVersion());\n    }\n\n    public function testToString(): void\n    {\n        // Check with a recent date\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString());\n        $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', (string) $uuid);\n        $this->assertSame(\n            'ff6f8cb0-c57d-11e1-9b21-0800200c9a66',\n            (static fn (Stringable $uuid) => (string) $uuid)($uuid)\n        );\n\n        // Check with an old date\n        $uuid = Uuid::fromString('0901e600-0154-1000-9b21-0800200c9a66');\n        $this->assertSame('0901e600-0154-1000-9b21-0800200c9a66', $uuid->toString());\n        $this->assertSame('0901e600-0154-1000-9b21-0800200c9a66', (string) $uuid);\n        $this->assertSame(\n            '0901e600-0154-1000-9b21-0800200c9a66',\n            (static fn (Stringable $uuid) => (string) $uuid)($uuid)\n        );\n    }\n\n    public function testUuid1(): void\n    {\n        $uuid = Uuid::uuid1();\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n    }\n\n    public function testUuid1WithNodeAndClockSequence(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::uuid1('0800200c9a66', 0x1669);\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n        $this->assertSame('5737', $uuid->getClockSequence());\n        $this->assertSame('8796630719078', $uuid->getNode());\n        $this->assertSame('9669-0800200c9a66', substr($uuid->toString(), 19));\n    }\n\n    public function testUuid1WithHexadecimalObjectNodeAndClockSequence(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::uuid1(new Hexadecimal('0800200c9a66'), 0x1669);\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n        $this->assertSame('5737', $uuid->getClockSequence());\n        $this->assertSame('8796630719078', $uuid->getNode());\n        $this->assertSame('9669-0800200c9a66', substr($uuid->toString(), 19));\n    }\n\n    public function testUuid1WithHexadecimalNode(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::uuid1('7160355e');\n\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n        $this->assertSame('00007160355e', $uuid->getNodeHex());\n        $this->assertSame('1902130526', $uuid->getNode());\n    }\n\n    public function testUuid1WithHexadecimalObjectNode(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::uuid1(new Hexadecimal('7160355e'));\n\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n        $this->assertSame('00007160355e', $uuid->getNodeHex());\n        $this->assertSame('1902130526', $uuid->getNode());\n    }\n\n    public function testUuid1WithMixedCaseHexadecimalNode(): void\n    {\n        /** @var Uuid $uuid */\n        $uuid = Uuid::uuid1('71B0aD5e');\n\n        $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n        $this->assertSame('000071b0ad5e', $uuid->getNodeHex());\n        $this->assertSame('1907404126', $uuid->getNode());\n    }\n\n    public function testUuid1WithOutOfBoundsNode(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid node value');\n\n        Uuid::uuid1('9223372036854775808');\n    }\n\n    public function testUuid1WithNonHexadecimalNode(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid node value');\n\n        Uuid::uuid1('db77e160355g');\n    }\n\n    public function testUuid1WithNon48bitNumber(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid node value');\n\n        Uuid::uuid1('db77e160355ef');\n    }\n\n    public function testUuid1WithRandomNode(): void\n    {\n        Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true)));\n\n        $uuid = Uuid::uuid1();\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n    }\n\n    public function testUuid1WithUserGeneratedRandomNode(): void\n    {\n        $uuid = Uuid::uuid1(new Hexadecimal((string) (new RandomNodeProvider())->getNode()));\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(1, $uuid->getVersion());\n    }\n\n    public function testUuid6(): void\n    {\n        $uuid = Uuid::uuid6();\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(6, $uuid->getVersion());\n    }\n\n    public function testUuid6WithNodeAndClockSequence(): void\n    {\n        $uuid = Uuid::uuid6(new Hexadecimal('0800200c9a66'), 0x1669);\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(6, $uuid->getVersion());\n        $this->assertSame('1669', $uuid->getClockSequenceHex());\n        $this->assertSame('0800200c9a66', $uuid->getNodeHex());\n        $this->assertSame('9669-0800200c9a66', substr($uuid->toString(), 19));\n    }\n\n    public function testUuid6WithHexadecimalNode(): void\n    {\n        $uuid = Uuid::uuid6(new Hexadecimal('7160355e'));\n\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(6, $uuid->getVersion());\n        $this->assertSame('00007160355e', $uuid->getNodeHex());\n    }\n\n    public function testUuid6WithMixedCaseHexadecimalNode(): void\n    {\n        $uuid = Uuid::uuid6(new Hexadecimal('71B0aD5e'));\n\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(6, $uuid->getVersion());\n        $this->assertSame('000071b0ad5e', $uuid->getNodeHex());\n    }\n\n    public function testUuid6WithOutOfBoundsNode(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid node value');\n\n        Uuid::uuid6(new Hexadecimal('9223372036854775808'));\n    }\n\n    public function testUuid6WithNon48bitNumber(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid node value');\n\n        Uuid::uuid6(new Hexadecimal('db77e160355ef'));\n    }\n\n    public function testUuid6WithRandomNode(): void\n    {\n        Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true)));\n\n        $uuid = Uuid::uuid6();\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(6, $uuid->getVersion());\n    }\n\n    public function testUuid6WithUserGeneratedRandomNode(): void\n    {\n        $uuid = Uuid::uuid6(new Hexadecimal((string) (new RandomNodeProvider())->getNode()));\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(6, $uuid->getVersion());\n    }\n\n    public function testUuid7(): void\n    {\n        $uuid = Uuid::uuid7();\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(7, $uuid->getVersion());\n    }\n\n    public function testUuid7ThrowsExceptionForUnsupportedFactory(): void\n    {\n        /** @var UuidFactoryInterface&MockInterface $factory */\n        $factory = Mockery::mock(UuidFactoryInterface::class);\n\n        Uuid::setFactory($factory);\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage('The provided factory does not support the uuid7() method');\n\n        Uuid::uuid7();\n    }\n\n    public function testUuid7WithDateTime(): void\n    {\n        $dateTime = new DateTimeImmutable('@281474976710.655');\n\n        $uuid = Uuid::uuid7($dateTime);\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(7, $uuid->getVersion());\n        $this->assertSame(\n            '10889-08-02T05:31:50.655+00:00',\n            $uuid->getDateTime()->format(DateTimeInterface::RFC3339_EXTENDED),\n        );\n    }\n\n    public function testUuid7SettingTheClockBackwards(): void\n    {\n        $dates = [\n            new DateTimeImmutable('now'),\n            new DateTimeImmutable('last year'),\n            new DateTimeImmutable('1979-01-01 00:00:00.000000'),\n        ];\n\n        foreach ($dates as $dateTime) {\n            $previous = Uuid::uuid7($dateTime);\n            for ($i = 0; $i < 25; $i++) {\n                $uuid = Uuid::uuid7($dateTime);\n                $this->assertGreaterThan(0, $uuid->compareTo($previous));\n                $this->assertSame($dateTime->format('Y-m-d H:i'), $uuid->getDateTime()->format('Y-m-d H:i'));\n                $previous = $uuid;\n            }\n        }\n    }\n\n    public function testUuid7WithMinimumDateTime(): void\n    {\n        $dateTime = new DateTimeImmutable('1979-01-01 00:00:00.000000');\n\n        $uuid = Uuid::uuid7($dateTime);\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(7, $uuid->getVersion());\n        $this->assertSame(\n            '1979-01-01T00:00:00.000+00:00',\n            $uuid->getDateTime()->format(DateTimeInterface::RFC3339_EXTENDED),\n        );\n    }\n\n    public function testUuid7EachUuidIsMonotonicallyIncreasing(): void\n    {\n        $previous = Uuid::uuid7();\n\n        for ($i = 0; $i < 25; $i++) {\n            $uuid = Uuid::uuid7();\n            $now = gmdate('Y-m-d H:i');\n            $this->assertGreaterThan(0, $uuid->compareTo($previous));\n            $this->assertSame($now, $uuid->getDateTime()->format('Y-m-d H:i'));\n            $previous = $uuid;\n        }\n    }\n\n    public function testUuid7EachUuidFromSameDateTimeIsMonotonicallyIncreasing(): void\n    {\n        $dateTime = new DateTimeImmutable();\n        $previous = Uuid::uuid7($dateTime);\n\n        for ($i = 0; $i < 25; $i++) {\n            $uuid = Uuid::uuid7($dateTime);\n            $this->assertGreaterThan(0, $uuid->compareTo($previous));\n            $this->assertSame($dateTime->format('Y-m-d H:i'), $uuid->getDateTime()->format('Y-m-d H:i'));\n            $previous = $uuid;\n        }\n    }\n\n    public function testUuid8(): void\n    {\n        $uuid = Uuid::uuid8(\"\\x00\\x11\\x22\\x33\\x44\\x55\\x66\\x77\\x88\\x99\\xaa\\xbb\\xcc\\xdd\\xee\\xff\");\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(8, $uuid->getVersion());\n    }\n\n    public function testUuid8ThrowsExceptionForUnsupportedFactory(): void\n    {\n        /** @var UuidFactoryInterface&MockInterface $factory */\n        $factory = Mockery::mock(UuidFactoryInterface::class);\n\n        Uuid::setFactory($factory);\n\n        $this->expectException(UnsupportedOperationException::class);\n        $this->expectExceptionMessage('The provided factory does not support the uuid8() method');\n\n        /** @phpstan-ignore staticMethod.resultUnused */\n        Uuid::uuid8(\"\\x00\\x11\\x22\\x33\\x44\\x55\\x66\\x77\\x88\\x99\\xaa\\xbb\\xcc\\xdd\\xee\\xff\");\n    }\n\n    /**\n     * Tests known version-3 UUIDs\n     *\n     * Taken from the Python UUID tests in\n     * http://hg.python.org/cpython/file/2f4c4db9aee5/Lib/test/test_uuid.py\n     *\n     * @param non-empty-string $uuid\n     * @param non-empty-string $ns\n     * @param non-empty-string $name\n     *\n     * @dataProvider provideUuid3WithKnownUuids\n     */\n    public function testUuid3WithKnownUuids(string $uuid, string $ns, string $name): void\n    {\n        $uobj1 = Uuid::uuid3($ns, $name);\n        $uobj2 = Uuid::uuid3(Uuid::fromString($ns), $name);\n\n        $this->assertSame(2, $uobj1->getVariant());\n        $this->assertSame(3, $uobj1->getVersion());\n        $this->assertSame(Uuid::fromString($uuid)->toString(), $uobj1->toString());\n        $this->assertTrue($uobj1->equals($uobj2));\n    }\n\n    /**\n     * @return array<array{uuid: non-empty-string, ns: non-empty-string, name: non-empty-string}>\n     */\n    public function provideUuid3WithKnownUuids(): array\n    {\n        return [\n            [\n                'uuid' => '6fa459ea-ee8a-3ca4-894e-db77e160355e',\n                'ns' => Uuid::NAMESPACE_DNS,\n                'name' => 'python.org',\n            ],\n            [\n                'uuid' => '9fe8e8c4-aaa8-32a9-a55c-4535a88b748d',\n                'ns' => Uuid::NAMESPACE_URL,\n                'name' => 'http://python.org/',\n            ],\n            [\n                'uuid' => 'dd1a1cef-13d5-368a-ad82-eca71acd4cd1',\n                'ns' => Uuid::NAMESPACE_OID,\n                'name' => '1.3.6.1',\n            ],\n            [\n                'uuid' => '658d3002-db6b-3040-a1d1-8ddd7d189a4d',\n                'ns' => Uuid::NAMESPACE_X500,\n                'name' => 'c=ca',\n            ],\n        ];\n    }\n\n    public function testUuid4(): void\n    {\n        $uuid = Uuid::uuid4();\n        $this->assertSame(2, $uuid->getVariant());\n        $this->assertSame(4, $uuid->getVersion());\n    }\n\n    /**\n     * Tests that generated UUID's using timestamp last COMB are sequential\n     */\n    public function testUuid4TimestampLastComb(): void\n    {\n        $mock = $this->getMockBuilder(RandomGeneratorInterface::class)->getMock();\n        $mock->expects($this->any())\n            ->method('generate')\n            ->willReturnCallback(function (int $length) {\n                // Makes first fields of UUIDs equal\n                return hex2bin(str_pad('', $length * 2, '0'));\n            });\n\n        $factory = new UuidFactory();\n        $generator = new CombGenerator($mock, $factory->getNumberConverter());\n        $codec = new TimestampLastCombCodec($factory->getUuidBuilder());\n        $factory->setRandomGenerator($generator);\n        $factory->setCodec($codec);\n\n        $previous = $factory->uuid4();\n\n        for ($i = 0; $i < 1000; $i++) {\n            usleep(100);\n            $uuid = $factory->uuid4();\n            $this->assertGreaterThan($previous->toString(), $uuid->toString());\n\n            $previous = $uuid;\n        }\n    }\n\n    /**\n     * Tests that generated UUID's using timestamp first COMB are sequential\n     */\n    public function testUuid4TimestampFirstComb(): void\n    {\n        $mock = $this->getMockBuilder(RandomGeneratorInterface::class)->getMock();\n        $mock->expects($this->any())\n            ->method('generate')\n            ->willReturnCallback(function (int $length) {\n                // Makes first fields of UUIDs equal\n                return hex2bin(str_pad('', $length * 2, '0'));\n            });\n\n        $factory = new UuidFactory();\n        $generator = new CombGenerator($mock, $factory->getNumberConverter());\n        $codec = new TimestampFirstCombCodec($factory->getUuidBuilder());\n        $factory->setRandomGenerator($generator);\n        $factory->setCodec($codec);\n\n        $previous = $factory->uuid4();\n\n        for ($i = 0; $i < 1000; $i++) {\n            usleep(100);\n            $uuid = $factory->uuid4();\n            $this->assertGreaterThan($previous->toString(), $uuid->toString());\n\n            $previous = $uuid;\n        }\n    }\n\n    /**\n     * Test that COMB UUID's have a version 4 flag\n     */\n    public function testUuid4CombVersion(): void\n    {\n        $factory = new UuidFactory();\n        $generator = new CombGenerator(\n            (new RandomGeneratorFactory())->getGenerator(),\n            $factory->getNumberConverter()\n        );\n\n        $factory->setRandomGenerator($generator);\n\n        $uuid = $factory->uuid4();\n\n        $this->assertSame(4, $uuid->getVersion());\n    }\n\n    /**\n     * Tests known version-5 UUIDs\n     *\n     * Taken from the Python UUID tests in\n     * http://hg.python.org/cpython/file/2f4c4db9aee5/Lib/test/test_uuid.py\n     *\n     * @param non-empty-string $uuid\n     * @param non-empty-string $ns\n     * @param non-empty-string $name\n     *\n     * @dataProvider provideUuid5WithKnownUuids\n     */\n    public function testUuid5WithKnownUuids(string $uuid, string $ns, string $name): void\n    {\n        $uobj1 = Uuid::uuid5($ns, $name);\n        $uobj2 = Uuid::uuid5(Uuid::fromString($ns), $name);\n\n        $this->assertSame(2, $uobj1->getVariant());\n        $this->assertSame(5, $uobj1->getVersion());\n        $this->assertSame(Uuid::fromString($uuid)->toString(), $uobj1->toString());\n        $this->assertTrue($uobj1->equals($uobj2));\n    }\n\n    /**\n     * @return array<array{uuid: non-empty-string, ns: non-empty-string, name: non-empty-string}>\n     */\n    public function provideUuid5WithKnownUuids(): array\n    {\n        return [\n            [\n                'uuid' => '886313e1-3b8a-5372-9b90-0c9aee199e5d',\n                'ns' => Uuid::NAMESPACE_DNS,\n                'name' => 'python.org',\n            ],\n            [\n                'uuid' => '4c565f0d-3f5a-5890-b41b-20cf47701c5e',\n                'ns' => Uuid::NAMESPACE_URL,\n                'name' => 'http://python.org/',\n            ],\n            [\n                'uuid' => '1447fa61-5277-5fef-a9b3-fbc6e44f4af3',\n                'ns' => Uuid::NAMESPACE_OID,\n                'name' => '1.3.6.1',\n            ],\n            [\n                'uuid' => 'cc957dd1-a972-5349-98cd-874190002798',\n                'ns' => Uuid::NAMESPACE_X500,\n                'name' => 'c=ca',\n            ],\n        ];\n    }\n\n    public function testCompareTo(): void\n    {\n        // $uuid1 and $uuid2 are identical\n        $uuid1 = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $uuid2 = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        // The next three UUIDs are used for comparing msb and lsb in\n        // the compareTo() method\n\n        // msb are less than $uuid4, lsb are greater than $uuid5\n        $uuid3 = Uuid::fromString('44cca71e-d13d-11e1-a959-c8bcc8a476f4');\n\n        // msb are greater than $uuid3, lsb are equal to those in $uuid3\n        $uuid4 = Uuid::fromString('44cca71e-d13d-11e2-a959-c8bcc8a476f4');\n\n        // msb are equal to those in $uuid3, lsb are less than in $uuid3\n        $uuid5 = Uuid::fromString('44cca71e-d13d-11e1-a959-c8bcc8a476f3');\n\n        $this->assertSame(0, $uuid1->compareTo($uuid2));\n        $this->assertSame(0, $uuid2->compareTo($uuid1));\n        $this->assertSame(-1, $uuid3->compareTo($uuid4));\n        $this->assertSame(1, $uuid4->compareTo($uuid3));\n        $this->assertSame(-1, $uuid5->compareTo($uuid3));\n        $this->assertSame(1, $uuid3->compareTo($uuid5));\n    }\n\n    public function testCompareToReturnsZeroWhenDifferentCases(): void\n    {\n        $uuidString = 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66';\n        // $uuid1 and $uuid2 are identical\n        $uuid1 = Uuid::fromString($uuidString);\n        $uuid2 = Uuid::fromString(strtoupper($uuidString));\n\n        $this->assertSame(0, $uuid1->compareTo($uuid2));\n        $this->assertSame(0, $uuid2->compareTo($uuid1));\n    }\n\n    public function testEqualsReturnsTrueWhenDifferentCases(): void\n    {\n        $uuidString = 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66';\n        // $uuid1 and $uuid2 are identical\n        $uuid1 = Uuid::fromString($uuidString);\n        $uuid2 = Uuid::fromString(strtoupper($uuidString));\n\n        $this->assertTrue($uuid1->equals($uuid2));\n        $this->assertTrue($uuid2->equals($uuid1));\n    }\n\n    public function testEquals(): void\n    {\n        $uuid1 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'python.org');\n        $uuid2 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'python.org');\n        $uuid3 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'php.net');\n\n        $this->assertTrue($uuid1->equals($uuid2));\n        $this->assertFalse($uuid1->equals($uuid3));\n        $this->assertFalse($uuid1->equals(new stdClass()));\n    }\n\n    public function testCalculateUuidTime(): void\n    {\n        $timeOfDay = new FixedTimeProvider(new Time(1348845514, 277885));\n\n        $featureSet = new FeatureSet();\n        $featureSet->setTimeProvider($timeOfDay);\n\n        // For usec = 277885\n        Uuid::setFactory(new UuidFactory($featureSet));\n        $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669);\n\n        $this->assertSame('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA);\n        $this->assertSame('c4dbe7e2', $uuidA->getTimeLowHex());\n        $this->assertSame('097f', $uuidA->getTimeMidHex());\n        $this->assertSame('11e2', $uuidA->getTimeHiAndVersionHex());\n\n        // For usec = 0\n        $timeOfDay->setUsec(0);\n        $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669);\n\n        $this->assertSame('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB);\n        $this->assertSame('c4b18100', $uuidB->getTimeLowHex());\n        $this->assertSame('097f', $uuidB->getTimeMidHex());\n        $this->assertSame('11e2', $uuidB->getTimeHiAndVersionHex());\n\n        // For usec = 999999\n        $timeOfDay->setUsec(999999);\n        $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669);\n\n        $this->assertSame('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC);\n        $this->assertSame('c54a1776', $uuidC->getTimeLowHex());\n        $this->assertSame('097f', $uuidC->getTimeMidHex());\n        $this->assertSame('11e2', $uuidC->getTimeHiAndVersionHex());\n    }\n\n    public function testCalculateUuidTimeUpperLowerBounds(): void\n    {\n        // 5235-03-31T21:20:59+00:00\n        $timeOfDay = new FixedTimeProvider(new Time('103072857659', '999999'));\n\n        $featureSet = new FeatureSet();\n        $featureSet->setTimeProvider($timeOfDay);\n\n        Uuid::setFactory(new UuidFactory($featureSet));\n        $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669);\n\n        $this->assertSame('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA);\n        $this->assertSame('ff9785f6', $uuidA->getTimeLowHex());\n        $this->assertSame('ffff', $uuidA->getTimeMidHex());\n        $this->assertSame('1fff', $uuidA->getTimeHiAndVersionHex());\n\n        // 1582-10-15T00:00:00+00:00\n        $timeOfDay = new FixedTimeProvider(new Time('-12219292800', '0'));\n\n        $featureSet->setTimeProvider($timeOfDay);\n\n        Uuid::setFactory(new UuidFactory($featureSet));\n        $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669);\n\n        $this->assertSame('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB);\n        $this->assertSame('00000000', $uuidB->getTimeLowHex());\n        $this->assertSame('0000', $uuidB->getTimeMidHex());\n        $this->assertSame('1000', $uuidB->getTimeHiAndVersionHex());\n    }\n\n    /**\n     * Iterates over a 3600-second period and tests to ensure that, for each\n     * second in the period, the 32-bit and 64-bit versions of the UUID match\n     */\n    public function test32BitMatch64BitForOneHourPeriod(): void\n    {\n        $currentTime = strtotime('2012-12-11T00:00:00+00:00');\n        $endTime = $currentTime + 3600;\n\n        $timeOfDay = new FixedTimeProvider(new Time($currentTime, 0));\n\n        $smallIntFeatureSet = new FeatureSet(false, true);\n        $smallIntFeatureSet->setTimeProvider($timeOfDay);\n\n        $smallIntFactory = new UuidFactory($smallIntFeatureSet);\n\n        $featureSet = new FeatureSet();\n        $featureSet->setTimeProvider($timeOfDay);\n\n        $factory = new UuidFactory($featureSet);\n\n        while ($currentTime <= $endTime) {\n            foreach ([0, 50000, 250000, 500000, 750000, 999999] as $usec) {\n                $timeOfDay->setSec($currentTime);\n                $timeOfDay->setUsec($usec);\n\n                $uuid32 = $smallIntFactory->uuid1(0x00007ffffffe, 0x1669);\n                $uuid64 = $factory->uuid1(0x00007ffffffe, 0x1669);\n\n                $this->assertTrue(\n                    $uuid32->equals($uuid64),\n                    'Breaks at ' . gmdate('r', $currentTime)\n                        . \"; 32-bit: {$uuid32->toString()}, 64-bit: {$uuid64->toString()}\"\n                );\n\n                // Assert that the time matches\n                $usecAdd = BigDecimal::of($usec)->dividedBy('1000000', 14, RoundingMode::HALF_UP);\n                $testTime = BigDecimal::of($currentTime)->plus($usecAdd)->toScale(0, RoundingMode::DOWN);\n                $this->assertSame((string) $testTime, (string) $uuid64->getDateTime()->getTimestamp());\n                $this->assertSame((string) $testTime, (string) $uuid32->getDateTime()->getTimestamp());\n            }\n\n            $currentTime++;\n        }\n    }\n\n    /**\n     * This method should respond to the result of the factory\n     */\n    public function testIsValid(): void\n    {\n        $argument = uniqid('passed argument ');\n\n        /** @var MockObject & ValidatorInterface $validator */\n        $validator = $this->getMockBuilder(ValidatorInterface::class)->getMock();\n        $validator->expects($this->once())->method('validate')->with($argument)->willReturn(true);\n\n        /** @var UuidFactory $factory */\n        $factory = Uuid::getFactory();\n        $factory->setValidator($validator);\n\n        $this->assertTrue(Uuid::isValid($argument));\n\n        // reset the static validator\n        $factory->setValidator(new GenericValidator());\n    }\n\n    public function testUsingNilAsValidUuid(): void\n    {\n        self::assertSame(\n            '0cb17687-6ec7-324b-833a-f1d101a7edb7',\n            Uuid::uuid3(Uuid::NIL, 'randomtext')\n                ->toString()\n        );\n        self::assertSame(\n            '3b24c15b-1273-5628-ade4-fc67c6ede500',\n            Uuid::uuid5(Uuid::NIL, 'randomtext')\n                ->toString()\n        );\n    }\n\n    public function testFromBytes(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $bytes = $uuid->getBytes();\n\n        $fromBytesUuid = Uuid::fromBytes($bytes);\n\n        $this->assertTrue($uuid->equals($fromBytesUuid));\n    }\n\n    public function testGuidBytesMatchesUuidWithSameString(): void\n    {\n        $uuidFactory = new UuidFactory(new FeatureSet(false));\n        $guidFactory = new UuidFactory(new FeatureSet(true));\n\n        $uuid = $uuidFactory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $bytes = $uuid->getBytes();\n\n        // Swap the order of the bytes for a GUID.\n        $guidBytes = $bytes[3] . $bytes[2] . $bytes[1] . $bytes[0];\n        $guidBytes .= $bytes[5] . $bytes[4];\n        $guidBytes .= $bytes[7] . $bytes[6];\n        $guidBytes .= substr($bytes, 8);\n\n        $guid = $guidFactory->fromBytes($guidBytes);\n\n        $this->assertSame($uuid->toString(), $guid->toString());\n        $this->assertTrue($uuid->equals($guid));\n    }\n\n    public function testGuidBytesProducesSameGuidString(): void\n    {\n        $guidFactory = new UuidFactory(new FeatureSet(true));\n\n        $guid = $guidFactory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $bytes = $guid->getBytes();\n\n        $parsedGuid = $guidFactory->fromBytes($bytes);\n\n        $this->assertSame($guid->toString(), $parsedGuid->toString());\n        $this->assertTrue($guid->equals($parsedGuid));\n    }\n\n    public function testFromBytesArgumentTooShort(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        Uuid::fromBytes('thisisveryshort');\n    }\n\n    public function testFromBytesArgumentTooLong(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        Uuid::fromBytes('thisisabittoolong');\n    }\n\n    public function testFromInteger(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $integer = $uuid->getInteger()->toString();\n\n        $fromIntegerUuid = Uuid::fromInteger($integer);\n\n        $this->assertTrue($uuid->equals($fromIntegerUuid));\n    }\n\n    public function testFromDateTime(): void\n    {\n        /** @var UuidV1 $uuid */\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-8b21-0800200c9a66');\n        $dateTime = $uuid->getDateTime();\n\n        $fromDateTimeUuid = Uuid::fromDateTime($dateTime, new Hexadecimal('0800200c9a66'), 2849);\n\n        $this->assertTrue($uuid->equals($fromDateTimeUuid));\n    }\n\n    /**\n     * This test ensures that Ramsey\\Uuid passes the same test cases\n     * as the Python UUID library.\n     *\n     * @param non-empty-string $string\n     * @param non-empty-string $curly\n     * @param non-empty-string $hex\n     * @param non-empty-string $bytes\n     * @param non-empty-string $int\n     * @param string[] $fields\n     * @param non-empty-string $urn\n     * @param non-empty-string $time\n     * @param non-empty-string $clockSeq\n     *\n     * @dataProvider providePythonTests\n     */\n    public function testUuidPassesPythonTests(\n        string $string,\n        string $curly,\n        string $hex,\n        string $bytes,\n        string $int,\n        array $fields,\n        string $urn,\n        string $time,\n        string $clockSeq,\n        int $variant,\n        ?int $version\n    ): void {\n        $uuids = [\n            Uuid::fromString($string),\n            Uuid::fromString($curly),\n            Uuid::fromString($hex),\n            Uuid::fromBytes(base64_decode($bytes)),\n            Uuid::fromString($urn),\n            Uuid::fromInteger($int),\n        ];\n\n        /** @var UuidInterface $uuid */\n        foreach ($uuids as $uuid) {\n            $this->assertSame($string, $uuid->toString());\n            $this->assertSame($hex, $uuid->getHex()->toString());\n            $this->assertSame(base64_decode($bytes), $uuid->getBytes());\n            $this->assertSame($int, $uuid->getInteger()->toString());\n            $this->assertSame($fields, $uuid->getFieldsHex());\n            $this->assertSame($fields['time_low'], $uuid->getTimeLowHex());\n            $this->assertSame($fields['time_mid'], $uuid->getTimeMidHex());\n            $this->assertSame($fields['time_hi_and_version'], $uuid->getTimeHiAndVersionHex());\n            $this->assertSame($fields['clock_seq_hi_and_reserved'], $uuid->getClockSeqHiAndReservedHex());\n            $this->assertSame($fields['clock_seq_low'], $uuid->getClockSeqLowHex());\n            $this->assertSame($fields['node'], $uuid->getNodeHex());\n            $this->assertSame($urn, $uuid->getUrn());\n            if ($uuid->getVersion() === 1) {\n                $this->assertSame($time, $uuid->getTimestampHex());\n            }\n            $this->assertSame($clockSeq, $uuid->getClockSequenceHex());\n            $this->assertSame($variant, $uuid->getVariant());\n            $this->assertSame($version, $uuid->getVersion());\n        }\n    }\n\n    /**\n     * Taken from the Python UUID tests in\n     * http://hg.python.org/cpython/file/2f4c4db9aee5/Lib/test/test_uuid.py\n     *\n     * @return array<array{\n     *     string: non-empty-string,\n     *     curly: non-empty-string,\n     *     hex: non-empty-string,\n     *     bytes: non-empty-string,\n     *     int: non-empty-string,\n     *     fields: array<string, string>,\n     *     urn: non-empty-string,\n     *     time: non-empty-string,\n     *     clock_seq: non-empty-string,\n     *     variant: int,\n     *     version: int | null,\n     * }>\n     */\n    public function providePythonTests(): array\n    {\n        // This array is taken directly from the Python tests, more or less.\n        return [\n            [\n                'string' => '00000000-0000-0000-0000-000000000000',\n                'curly' => '{00000000-0000-0000-0000-000000000000}',\n                'hex' => '00000000000000000000000000000000',\n                'bytes' => 'AAAAAAAAAAAAAAAAAAAAAA==',\n                'int' => '0',\n                'fields' => [\n                    'time_low' => '00000000',\n                    'time_mid' => '0000',\n                    'time_hi_and_version' => '0000',\n                    'clock_seq_hi_and_reserved' => '00',\n                    'clock_seq_low' => '00',\n                    'node' => '000000000000',\n                ],\n                'urn' => 'urn:uuid:00000000-0000-0000-0000-000000000000',\n                'time' => '0',\n                'clock_seq' => '0000',\n                'variant' => Uuid::RESERVED_NCS,\n                'version' => null,\n            ],\n            [\n                'string' => '00010203-0405-0607-0809-0a0b0c0d0e0f',\n                'curly' => '{00010203-0405-0607-0809-0a0b0c0d0e0f}',\n                'hex' => '000102030405060708090a0b0c0d0e0f',\n                'bytes' => 'AAECAwQFBgcICQoLDA0ODw==',\n                'int' => '5233100606242806050955395731361295',\n                'fields' => [\n                    'time_low' => '00010203',\n                    'time_mid' => '0405',\n                    'time_hi_and_version' => '0607',\n                    'clock_seq_hi_and_reserved' => '08',\n                    'clock_seq_low' => '09',\n                    'node' => '0a0b0c0d0e0f',\n                ],\n                'urn' => 'urn:uuid:00010203-0405-0607-0809-0a0b0c0d0e0f',\n                'time' => '607040500010203',\n                'clock_seq' => '0809',\n                'variant' => Uuid::RESERVED_NCS,\n                'version' => null,\n            ],\n            [\n                'string' => '02d9e6d5-9467-382e-8f9b-9300a64ac3cd',\n                'curly' => '{02d9e6d5-9467-382e-8f9b-9300a64ac3cd}',\n                'hex' => '02d9e6d59467382e8f9b9300a64ac3cd',\n                'bytes' => 'Atnm1ZRnOC6Pm5MApkrDzQ==',\n                'int' => '3789866285607910888100818383505376205',\n                'fields' => [\n                    'time_low' => '02d9e6d5',\n                    'time_mid' => '9467',\n                    'time_hi_and_version' => '382e',\n                    'clock_seq_hi_and_reserved' => '8f',\n                    'clock_seq_low' => '9b',\n                    'node' => '9300a64ac3cd',\n                ],\n                'urn' => 'urn:uuid:02d9e6d5-9467-382e-8f9b-9300a64ac3cd',\n                'time' => '82e946702d9e6d5',\n                'clock_seq' => '0f9b',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_HASH_MD5,\n            ],\n            [\n                'string' => '12345678-1234-5678-1234-567812345678',\n                'curly' => '{12345678-1234-5678-1234-567812345678}',\n                'hex' => '12345678123456781234567812345678',\n                'bytes' => 'EjRWeBI0VngSNFZ4EjRWeA==',\n                'int' => '24197857161011715162171839636988778104',\n                'fields' => [\n                    'time_low' => '12345678',\n                    'time_mid' => '1234',\n                    'time_hi_and_version' => '5678',\n                    'clock_seq_hi_and_reserved' => '12',\n                    'clock_seq_low' => '34',\n                    'node' => '567812345678',\n                ],\n                'urn' => 'urn:uuid:12345678-1234-5678-1234-567812345678',\n                'time' => '678123412345678',\n                'clock_seq' => '1234',\n                'variant' => Uuid::RESERVED_NCS,\n                'version' => null,\n            ],\n            [\n                'string' => '6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n                'curly' => '{6ba7b810-9dad-11d1-80b4-00c04fd430c8}',\n                'hex' => '6ba7b8109dad11d180b400c04fd430c8',\n                'bytes' => 'a6e4EJ2tEdGAtADAT9QwyA==',\n                'int' => '143098242404177361603877621312831893704',\n                'fields' => [\n                    'time_low' => '6ba7b810',\n                    'time_mid' => '9dad',\n                    'time_hi_and_version' => '11d1',\n                    'clock_seq_hi_and_reserved' => '80',\n                    'clock_seq_low' => 'b4',\n                    'node' => '00c04fd430c8',\n                ],\n                'urn' => 'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n                'time' => '1d19dad6ba7b810',\n                'clock_seq' => '00b4',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_TIME,\n            ],\n            [\n                'string' => '6ba7b811-9dad-11d1-80b4-00c04fd430c8',\n                'curly' => '{6ba7b811-9dad-11d1-80b4-00c04fd430c8}',\n                'hex' => '6ba7b8119dad11d180b400c04fd430c8',\n                'bytes' => 'a6e4EZ2tEdGAtADAT9QwyA==',\n                'int' => '143098242483405524118141958906375844040',\n                'fields' => [\n                    'time_low' => '6ba7b811',\n                    'time_mid' => '9dad',\n                    'time_hi_and_version' => '11d1',\n                    'clock_seq_hi_and_reserved' => '80',\n                    'clock_seq_low' => 'b4',\n                    'node' => '00c04fd430c8',\n                ],\n                'urn' => 'urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8',\n                'time' => '1d19dad6ba7b811',\n                'clock_seq' => '00b4',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_TIME,\n            ],\n            [\n                'string' => '6ba7b812-9dad-11d1-80b4-00c04fd430c8',\n                'curly' => '{6ba7b812-9dad-11d1-80b4-00c04fd430c8}',\n                'hex' => '6ba7b8129dad11d180b400c04fd430c8',\n                'bytes' => 'a6e4Ep2tEdGAtADAT9QwyA==',\n                'int' => '143098242562633686632406296499919794376',\n                'fields' => [\n                    'time_low' => '6ba7b812',\n                    'time_mid' => '9dad',\n                    'time_hi_and_version' => '11d1',\n                    'clock_seq_hi_and_reserved' => '80',\n                    'clock_seq_low' => 'b4',\n                    'node' => '00c04fd430c8',\n                ],\n                'urn' => 'urn:uuid:6ba7b812-9dad-11d1-80b4-00c04fd430c8',\n                'time' => '1d19dad6ba7b812',\n                'clock_seq' => '00b4',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_TIME,\n            ],\n            [\n                'string' => '6ba7b814-9dad-11d1-80b4-00c04fd430c8',\n                'curly' => '{6ba7b814-9dad-11d1-80b4-00c04fd430c8}',\n                'hex' => '6ba7b8149dad11d180b400c04fd430c8',\n                'bytes' => 'a6e4FJ2tEdGAtADAT9QwyA==',\n                'int' => '143098242721090011660934971687007695048',\n                'fields' => [\n                    'time_low' => '6ba7b814',\n                    'time_mid' => '9dad',\n                    'time_hi_and_version' => '11d1',\n                    'clock_seq_hi_and_reserved' => '80',\n                    'clock_seq_low' => 'b4',\n                    'node' => '00c04fd430c8',\n                ],\n                'urn' => 'urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8',\n                'time' => '1d19dad6ba7b814',\n                'clock_seq' => '00b4',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_TIME,\n            ],\n            [\n                'string' => '7d444840-9dc0-11d1-b245-5ffdce74fad2',\n                'curly' => '{7d444840-9dc0-11d1-b245-5ffdce74fad2}',\n                'hex' => '7d4448409dc011d1b2455ffdce74fad2',\n                'bytes' => 'fURIQJ3AEdGyRV/9znT60g==',\n                'int' => '166508041112410060672666770310773930706',\n                'fields' => [\n                    'time_low' => '7d444840',\n                    'time_mid' => '9dc0',\n                    'time_hi_and_version' => '11d1',\n                    'clock_seq_hi_and_reserved' => 'b2',\n                    'clock_seq_low' => '45',\n                    'node' => '5ffdce74fad2',\n                ],\n                'urn' => 'urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2',\n                'time' => '1d19dc07d444840',\n                'clock_seq' => '3245',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_TIME,\n            ],\n            [\n                'string' => 'e902893a-9d22-3c7e-a7b8-d6e313b71d9f',\n                'curly' => '{e902893a-9d22-3c7e-a7b8-d6e313b71d9f}',\n                'hex' => 'e902893a9d223c7ea7b8d6e313b71d9f',\n                'bytes' => '6QKJOp0iPH6nuNbjE7cdnw==',\n                'int' => '309723290945582129846206211755626405279',\n                'fields' => [\n                    'time_low' => 'e902893a',\n                    'time_mid' => '9d22',\n                    'time_hi_and_version' => '3c7e',\n                    'clock_seq_hi_and_reserved' => 'a7',\n                    'clock_seq_low' => 'b8',\n                    'node' => 'd6e313b71d9f',\n                ],\n                'urn' => 'urn:uuid:e902893a-9d22-3c7e-a7b8-d6e313b71d9f',\n                'time' => 'c7e9d22e902893a',\n                'clock_seq' => '27b8',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_HASH_MD5,\n            ],\n            [\n                'string' => 'eb424026-6f54-4ef8-a4d0-bb658a1fc6cf',\n                'curly' => '{eb424026-6f54-4ef8-a4d0-bb658a1fc6cf}',\n                'hex' => 'eb4240266f544ef8a4d0bb658a1fc6cf',\n                'bytes' => '60JAJm9UTvik0Ltlih/Gzw==',\n                'int' => '312712571721458096795100956955942831823',\n                'fields' => [\n                    'time_low' => 'eb424026',\n                    'time_mid' => '6f54',\n                    'time_hi_and_version' => '4ef8',\n                    'clock_seq_hi_and_reserved' => 'a4',\n                    'clock_seq_low' => 'd0',\n                    'node' => 'bb658a1fc6cf',\n                ],\n                'urn' => 'urn:uuid:eb424026-6f54-4ef8-a4d0-bb658a1fc6cf',\n                'time' => 'ef86f54eb424026',\n                'clock_seq' => '24d0',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_RANDOM,\n            ],\n            [\n                'string' => 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6',\n                'curly' => '{f81d4fae-7dec-11d0-a765-00a0c91e6bf6}',\n                'hex' => 'f81d4fae7dec11d0a76500a0c91e6bf6',\n                'bytes' => '+B1Prn3sEdCnZQCgyR5r9g==',\n                'int' => '329800735698586629295641978511506172918',\n                'fields' => [\n                    'time_low' => 'f81d4fae',\n                    'time_mid' => '7dec',\n                    'time_hi_and_version' => '11d0',\n                    'clock_seq_hi_and_reserved' => 'a7',\n                    'clock_seq_low' => '65',\n                    'node' => '00a0c91e6bf6',\n                ],\n                'urn' => 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6',\n                'time' => '1d07decf81d4fae',\n                'clock_seq' => '2765',\n                'variant' => Uuid::RFC_4122,\n                'version' => Uuid::UUID_TYPE_TIME,\n            ],\n            [\n                'string' => 'fffefdfc-fffe-fffe-fffe-fffefdfcfbfa',\n                'curly' => '{fffefdfc-fffe-fffe-fffe-fffefdfcfbfa}',\n                'hex' => 'fffefdfcfffefffefffefffefdfcfbfa',\n                'bytes' => '//79/P/+//7//v/+/fz7+g==',\n                'int' => '340277133821575024845345576078114880506',\n                'fields' => [\n                    'time_low' => 'fffefdfc',\n                    'time_mid' => 'fffe',\n                    'time_hi_and_version' => 'fffe',\n                    'clock_seq_hi_and_reserved' => 'ff',\n                    'clock_seq_low' => 'fe',\n                    'node' => 'fffefdfcfbfa',\n                ],\n                'urn' => 'urn:uuid:fffefdfc-fffe-fffe-fffe-fffefdfcfbfa',\n                'time' => 'ffefffefffefdfc',\n                'clock_seq' => '3ffe',\n                'variant' => Uuid::RESERVED_FUTURE,\n                'version' => null,\n            ],\n            [\n                'string' => 'ffffffff-ffff-ffff-ffff-ffffffffffff',\n                'curly' => '{ffffffff-ffff-ffff-ffff-ffffffffffff}',\n                'hex' => 'ffffffffffffffffffffffffffffffff',\n                'bytes' => '/////////////////////w==',\n                'int' => '340282366920938463463374607431768211455',\n                'fields' => [\n                    'time_low' => 'ffffffff',\n                    'time_mid' => 'ffff',\n                    'time_hi_and_version' => 'ffff',\n                    'clock_seq_hi_and_reserved' => 'ff',\n                    'clock_seq_low' => 'ff',\n                    'node' => 'ffffffffffff',\n                ],\n                'urn' => 'urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff',\n                'time' => 'fffffffffffffff',\n                // Python's tests think the clock sequence should be\n                // 0x3fff because of the bit shifting performed on this field.\n                // However, since all the bits in this UUID are defined as being\n                // set to one, we will consider the clock sequence as 0xffff,\n                // which all bits set to one.\n                'clock_seq' => 'ffff',\n                'variant' => Uuid::RESERVED_FUTURE,\n                'version' => null,\n            ],\n        ];\n    }\n\n    /**\n     * @covers Ramsey\\Uuid\\Uuid::jsonSerialize\n     */\n    public function testJsonSerialize(): void\n    {\n        $uuid = Uuid::uuid1();\n\n        $this->assertSame('\"' . $uuid->toString() . '\"', json_encode($uuid));\n    }\n\n    public function testSerialize(): void\n    {\n        $uuid = Uuid::uuid4();\n        $serialized = serialize($uuid);\n\n        /** @var UuidInterface $unserializedUuid */\n        $unserializedUuid = unserialize($serialized);\n\n        $this->assertTrue($uuid->equals($unserializedUuid));\n    }\n\n    public function testSerializeWithOldStringFormat(): void\n    {\n        $serialized = 'C:26:\"Ramsey\\Uuid\\Rfc4122\\UuidV4\":36:{b3cd586a-e3ca-44f3-988c-f4d666c1bf4d}';\n\n        /** @var UuidInterface $unserializedUuid */\n        $unserializedUuid = unserialize($serialized);\n\n        $this->assertSame('b3cd586a-e3ca-44f3-988c-f4d666c1bf4d', $unserializedUuid->toString());\n    }\n\n    public function testUuid3WithEmptyNamespace(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid UUID string:');\n\n        /** @phpstan-ignore staticMethod.resultUnused */\n        Uuid::uuid3('', '');\n    }\n\n    public function testUuid3WithEmptyName(): void\n    {\n        $uuid = Uuid::uuid3(Uuid::NIL, '');\n\n        $this->assertSame('4ae71336-e44b-39bf-b9d2-752e234818a5', $uuid->toString());\n    }\n\n    public function testUuid3WithZeroName(): void\n    {\n        $uuid = Uuid::uuid3(Uuid::NIL, '0');\n\n        $this->assertSame('19826852-5007-3022-a72a-212f66e9fac3', $uuid->toString());\n    }\n\n    public function testUuid5WithEmptyNamespace(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid UUID string:');\n\n        /** @phpstan-ignore staticMethod.resultUnused */\n        Uuid::uuid5('', '');\n    }\n\n    public function testUuid5WithEmptyName(): void\n    {\n        $uuid = Uuid::uuid5(Uuid::NIL, '');\n\n        $this->assertSame('e129f27c-5103-5c5c-844b-cdf0a15e160d', $uuid->toString());\n    }\n\n    public function testUuid5WithZeroName(): void\n    {\n        $uuid = Uuid::uuid5(Uuid::NIL, '0');\n\n        $this->assertSame('b6c54489-38a0-5f50-a60a-fd8d76219cae', $uuid->toString());\n    }\n\n    /**\n     * @depends testGetVersionForVersion1\n     */\n    public function testUuidVersionConstantForVersion1(): void\n    {\n        $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_TIME);\n    }\n\n    /**\n     * @depends testGetVersionForVersion2\n     */\n    public function testUuidVersionConstantForVersion2(): void\n    {\n        $uuid = Uuid::fromString('6fa459ea-ee8a-2ca4-894e-db77e160355e');\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_DCE_SECURITY);\n    }\n\n    /**\n     * @depends testGetVersionForVersion3\n     */\n    public function testUuidVersionConstantForVersion3(): void\n    {\n        $uuid = Uuid::fromString('6fa459ea-ee8a-3ca4-894e-db77e160355e');\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_HASH_MD5);\n    }\n\n    /**\n     * @depends testGetVersionForVersion4\n     */\n    public function testUuidVersionConstantForVersion4(): void\n    {\n        $uuid = Uuid::fromString('6fabf0bc-603a-42f2-925b-d9f779bd0032');\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_RANDOM);\n    }\n\n    /**\n     * @depends testGetVersionForVersion5\n     */\n    public function testUuidVersionConstantForVersion5(): void\n    {\n        $uuid = Uuid::fromString('886313e1-3b8a-5372-9b90-0c9aee199e5d');\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_HASH_SHA1);\n    }\n\n    public function testUuidVersionConstantForVersion6(): void\n    {\n        $uuid = Uuid::fromString('886313e1-3b8a-6372-9b90-0c9aee199e5d');\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_PEABODY);\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_REORDERED_TIME);\n    }\n\n    public function testUuidVersionConstantForVersion7(): void\n    {\n        $uuid = Uuid::fromString('886313e1-3b8a-7372-9b90-0c9aee199e5d');\n        $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_UNIX_TIME);\n    }\n\n    public function testGetDateTimeThrowsExceptionWhenDateTimeCannotParseDate(): void\n    {\n        $numberConverter = new BigNumberConverter();\n        $timeConverter = Mockery::mock(TimeConverterInterface::class);\n\n        $timeConverter\n            ->shouldReceive('convertTime')\n            ->once()\n            ->andReturn(new Time(1234567890, '1234567'));\n\n        $builder = new DefaultUuidBuilder($numberConverter, $timeConverter);\n        $codec = new StringCodec($builder);\n\n        $factory = new UuidFactory();\n        $factory->setCodec($codec);\n\n        $uuid = $factory->fromString('b1484596-25dc-11ea-978f-2e728ce88125');\n\n        $this->expectException(DateTimeException::class);\n        $this->expectExceptionMessage(\n            'Failed to parse time string (@1234567890.1234567) at position 18 (7): Unexpected character'\n        );\n\n        $uuid->getDateTime();\n    }\n\n    /**\n     * @param array<int | string> $args\n     *\n     * @dataProvider provideStaticMethods\n     */\n    public function testStaticCreationMethodsReturnSpecificUuidInstances(\n        string $staticMethod,\n        array $args = []\n    ): void {\n        $this->assertInstanceOf(LazyUuidFromString::class, Uuid::$staticMethod(...$args));\n    }\n\n    /**\n     * @param array<int | string> $args\n     *\n     * @dataProvider provideStaticMethods\n     */\n    public function testUuidInstancesBuiltFromStringAreEquivalentToTheirGeneratedCounterparts(\n        string $staticMethod,\n        array $args = []\n    ): void {\n        /** @var UuidInterface $generated */\n        $generated = Uuid::$staticMethod(...$args);\n\n        self::assertSame(\n            (string) $generated,\n            (string) Uuid::fromString($generated->toString())\n        );\n    }\n\n    /**\n     * @param array<int | string> $args\n     *\n     * @dataProvider provideStaticMethods\n     */\n    public function testUuidInstancesBuiltFromBytesAreEquivalentToTheirGeneratedCounterparts(\n        string $staticMethod,\n        array $args = []\n    ): void {\n        /** @var UuidInterface $generated */\n        $generated = Uuid::$staticMethod(...$args);\n\n        self::assertSame(\n            (string) $generated,\n            (string) Uuid::fromBytes($generated->getBytes())\n        );\n    }\n\n    /**\n     * @return array<array{0: string, 1?: array<int | string>}>\n     */\n    public function provideStaticMethods(): array\n    {\n        return [\n            ['uuid1'],\n            ['uuid2', [Uuid::DCE_DOMAIN_PERSON]],\n            ['uuid3', [Uuid::NIL, 'foobar']],\n            ['uuid4'],\n            ['uuid5', [Uuid::NIL, 'foobar']],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Validator/GenericValidatorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Test\\Validator;\n\nuse Ramsey\\Uuid\\Test\\TestCase;\nuse Ramsey\\Uuid\\Validator\\GenericValidator;\n\nuse function array_merge;\nuse function strtoupper;\n\nclass GenericValidatorTest extends TestCase\n{\n    /**\n     * @dataProvider provideValuesForValidation\n     */\n    public function testValidate(string $value, bool $expected): void\n    {\n        $variations = [];\n        $variations[] = $value;\n        $variations[] = 'urn:uuid:' . $value;\n        $variations[] = '{' . $value . '}';\n\n        foreach ($variations as $variation) {\n            $variations[] = strtoupper($variation);\n        }\n\n        $validator = new GenericValidator();\n\n        foreach ($variations as $variation) {\n            $this->assertSame($expected, $validator->validate($variation));\n        }\n    }\n\n    /**\n     * @return array<array{value: string, expected: bool}>\n     */\n    public function provideValuesForValidation(): array\n    {\n        $hexMutations = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];\n\n        $testValues = [];\n\n        foreach ($hexMutations as $version) {\n            foreach ($hexMutations as $variant) {\n                $testValues[] = [\n                    'value' => \"ff6f8cb0-c57d-{$version}1e1-{$variant}b21-0800200c9a66\",\n                    'expected' => true,\n                ];\n            }\n        }\n\n        return array_merge($testValues, [\n            [\n                'value' => 'zf6f8cb0-c57d-11e1-9b21-0800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => '3f6f8cb0-c57d-11e1-9b21-0800200c9a6',\n                'expected' => false,\n            ],\n            [\n                'value' => 'af6f8cb-c57d-11e1-9b21-0800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => 'af6f8cb0c57d11e19b210800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => 'ff6f8cb0-c57da-51e1-9b21-0800200c9a66',\n                'expected' => false,\n            ],\n            [\n                'value' => \"ff6f8cb0-c57d-11e1-1b21-0800200c9a66\\n\",\n                'expected' => false,\n            ],\n            [\n                'value' => \"\\nff6f8cb0-c57d-11e1-1b21-0800200c9a66\",\n                'expected' => false,\n            ],\n            [\n                'value' => \"\\nff6f8cb0-c57d-11e1-1b21-0800200c9a66\\n\",\n                'expected' => false,\n            ],\n        ]);\n    }\n\n    public function testGetPattern(): void\n    {\n        $expectedPattern = '\\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\z';\n\n        $validator = new GenericValidator();\n\n        $this->assertSame($expectedPattern, $validator->getPattern());\n    }\n}\n"
  },
  {
    "path": "tests/benchmark/GuidConversionBench.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Benchmark;\n\nuse Ramsey\\Uuid\\FeatureSet;\nuse Ramsey\\Uuid\\Guid\\Guid;\nuse Ramsey\\Uuid\\UuidFactory;\nuse Ramsey\\Uuid\\UuidInterface;\n\nfinal class GuidConversionBench\n{\n    private const UUID_BYTES = [\n        \"\\x1e\\x94\\x42\\x33\\x98\\x10\\x41\\x38\\x96\\x22\\x56\\xe1\\xf9\\x0c\\x56\\xed\",\n    ];\n\n    private UuidInterface $uuid;\n\n    public function __construct()\n    {\n        $factory = new UuidFactory(new FeatureSet(useGuids: true));\n\n        $this->uuid = $factory->fromBytes(self::UUID_BYTES[0]);\n\n        assert($this->uuid instanceof Guid);\n    }\n\n    public function benchStringConversionOfGuid(): void\n    {\n        $this->uuid->toString();\n    }\n}\n"
  },
  {
    "path": "tests/benchmark/NonLazyUuidConversionBench.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Benchmark;\n\nuse Ramsey\\Uuid\\UuidFactory;\nuse Ramsey\\Uuid\\UuidInterface;\n\nfinal class NonLazyUuidConversionBench\n{\n    private const UUID_BYTES = [\n        \"\\x1e\\x94\\x42\\x33\\x98\\x10\\x41\\x38\\x96\\x22\\x56\\xe1\\xf9\\x0c\\x56\\xed\",\n    ];\n\n    private UuidInterface $uuid;\n\n    public function __construct()\n    {\n        $factory = new UuidFactory();\n\n        $this->uuid = $factory->fromBytes(self::UUID_BYTES[0]);\n    }\n\n    public function benchStringConversionOfUuid(): void\n    {\n        $this->uuid->toString();\n    }\n}\n"
  },
  {
    "path": "tests/benchmark/UuidFieldExtractionBench.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Benchmark;\n\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\n\nfinal class UuidFieldExtractionBench\n{\n    /** @var UuidInterface */\n    private $uuid;\n\n    public function __construct()\n    {\n        $this->uuid = Uuid::fromString('0ae0cac5-2a40-465c-99ed-3d331b7cf72a');\n    }\n\n    public function benchGetFields(): void\n    {\n        $this->uuid->getFields();\n    }\n\n    public function benchGetFields10Times(): void\n    {\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n        $this->uuid->getFields();\n    }\n\n    public function benchGetHex(): void\n    {\n        $this->uuid->getHex();\n    }\n\n    public function benchGetHex10Times(): void\n    {\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n        $this->uuid->getHex();\n    }\n\n    public function benchGetInteger(): void\n    {\n        $this->uuid->getInteger();\n    }\n\n    public function benchGetInteger10Times(): void\n    {\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n        $this->uuid->getInteger();\n    }\n}\n"
  },
  {
    "path": "tests/benchmark/UuidGenerationBench.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Benchmark;\n\nuse DateTimeImmutable;\nuse Ramsey\\Uuid\\Provider\\Node\\StaticNodeProvider;\nuse Ramsey\\Uuid\\Type\\Hexadecimal;\nuse Ramsey\\Uuid\\Type\\Integer as IntegerIdentifier;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\n\nfinal class UuidGenerationBench\n{\n    /** @var Hexadecimal */\n    private $node;\n    /** @var int */\n    private $clockSequence;\n    /** @var IntegerIdentifier */\n    private $localIdentifier;\n    /** @var UuidInterface */\n    private $namespace;\n\n    public function __construct()\n    {\n        $this->node = (new StaticNodeProvider(new Hexadecimal('121212121212')))\n            ->getNode();\n        $this->clockSequence = 16383;\n        $this->localIdentifier = new IntegerIdentifier(5);\n        $this->namespace = Uuid::fromString('c485840e-9389-4548-a276-aeecd9730e50');\n    }\n\n    public function benchUuid1GenerationWithoutParameters(): void\n    {\n        Uuid::uuid1();\n    }\n\n    public function benchUuid1GenerationWithNode(): void\n    {\n        Uuid::uuid1($this->node);\n    }\n\n    public function benchUuid1GenerationWithNodeAndClockSequence(): void\n    {\n        Uuid::uuid1($this->node, $this->clockSequence);\n    }\n\n    public function benchUuid2GenerationWithDomainAndLocalIdentifier(): void\n    {\n        Uuid::uuid2(Uuid::DCE_DOMAIN_ORG, $this->localIdentifier);\n    }\n\n    public function benchUuid2GenerationWithDomainAndLocalIdentifierAndNode(): void\n    {\n        Uuid::uuid2(Uuid::DCE_DOMAIN_ORG, $this->localIdentifier, $this->node);\n    }\n\n    public function benchUuid2GenerationWithDomainAndLocalIdentifierAndNodeAndClockSequence(): void\n    {\n        Uuid::uuid2(Uuid::DCE_DOMAIN_ORG, $this->localIdentifier, $this->node, 63);\n    }\n\n    public function benchUuid3Generation(): void\n    {\n        Uuid::uuid3($this->namespace, 'name');\n    }\n\n    public function benchUuid4Generation(): void\n    {\n        Uuid::uuid4();\n    }\n\n    public function benchUuid5Generation(): void\n    {\n        Uuid::uuid5($this->namespace, 'name');\n    }\n\n    public function benchUuid6GenerationWithoutParameters(): void\n    {\n        Uuid::uuid6();\n    }\n\n    public function benchUuid6GenerationWithNode(): void\n    {\n        Uuid::uuid6($this->node);\n    }\n\n    public function benchUuid6GenerationWithNodeAndClockSequence(): void\n    {\n        Uuid::uuid6($this->node, $this->clockSequence);\n    }\n\n    public function benchUuid7Generation(): void\n    {\n        Uuid::uuid7();\n    }\n\n    public function benchUuid7GenerationWithDateTime(): void\n    {\n        Uuid::uuid7(new DateTimeImmutable('@1663203901.667000'));\n    }\n}\n"
  },
  {
    "path": "tests/benchmark/UuidSerializationBench.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Benchmark;\n\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function array_map;\nuse function serialize;\n\nfinal class UuidSerializationBench\n{\n    private const TINY_UUID = '00000000-0000-0000-0000-000000000001';\n    private const HUGE_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\n    private const UUIDS_TO_BE_SHORTENED = [\n        '0ae0cac5-2a40-465c-99ed-3d331b7cf72a',\n        '5759b9ce-07b5-4e89-b33a-f864317a2951',\n        '20c8664e-81a8-498d-9e98-444973ef3122',\n        '16fcbcf3-bb47-4227-90bd-3485d60510c3',\n        'fa83ae94-38e0-4903-bc6a-0a3eca6e9ef5',\n        '51c9e011-0429-4d77-a753-702bd67dcd84',\n        '1bd8857a-d6d7-4bd6-8734-b3dfedbcda7b',\n        '7aa38b71-37c3-4561-9b2e-ca227f1c9c55',\n        'e6b8854c-435c-4bb1-b6ad-1800b5d3e6bb',\n        '4e2b0031-8b09-46e2-8244-3814c46a2f53',\n        'bedd0850-da1a-4808-95c4-25fef0abbaa7',\n        '516b9052-d6fb-4828-bfc1-dffdef2d56d2',\n        '5d60a7e7-9139-4779-9f28-e6316b9fe3b7',\n        '65aa3d74-c1fb-4bdd-9a00-ce88a5270c57',\n        '27c2e339-74ed-49a7-a3c4-1a0172e9f945',\n        'e89b7727-4847-41ab-98d7-4148216eea8c',\n        'd79efaf3-b5dc-43a0-b3a5-c492155a7e0d',\n        'ee9ee6e7-5b7d-4e18-ab88-ce03d569305f',\n        'fe90c911-c13b-4103-bf33-16757aa87ff5',\n        '4d7ff67a-0074-4195-95d7-cf8b84eba079',\n        'abe5d378-d021-4905-93f4-0e76a7848365',\n        '19d21907-d121-4d85-8a34-a65d04ce8977',\n        'c421b8ad-33a4-42aa-b0cc-8f5f94b2cff7',\n        'f3dbbe55-3c80-453e-ab39-a6fe5001a7fc',\n        'f48d3eb2-6060-458f-809f-b5e887f9a17f',\n        'd189e406-de29-4889-8470-7bfa0d020c0c',\n        '71627018-9f21-4034-aafe-4c8b17151217',\n        '0c6a9278-0963-4460-9cae-6dc6f5420f4f',\n        'c833ac35-cce0-4315-8df3-3ed76656a548',\n        '78e94126-1d0a-472a-9b99-37840784318f',\n        '6e684707-ce4b-42df-8a77-71e57b54b581',\n        '811df139-e7a3-4cd8-b778-c81494d239ee',\n        'c263c5d8-c166-4599-9219-3e975e506f45',\n        'b31e7c5d-95ba-41d4-bc29-e6357c96f005',\n        '16ae2983-7f8f-4eee-9afb-6d4617836a01',\n        'ecbbfac7-f92a-4b41-996e-3e4724aa0e23',\n        '2c6b3db9-a5ee-4425-a837-8880a86faaa0',\n        '3d67a99a-b39a-4295-b7f8-0bf71ead5b2d',\n        'ca421bb7-ad73-41ea-9648-70073862ad5a',\n        '5ba156fa-853d-460f-a884-ca8dd3a27314',\n        '42a4359a-1df2-4086-b454-7477dbb726ff',\n        '7db9517b-f6ba-4bcf-ae26-6a88a7dbb034',\n        'bc758bd6-eb50-425b-ada1-07e6bb312032',\n        '254cf6d0-696d-4ff0-b579-ac3b633f03c0',\n        'f8f34b37-4c71-4177-bac5-6b99bb1929af',\n        'b0cc6179-f2b1-4ddf-8fe2-2251c3d935a3',\n        '333ad834-fa3b-4cf4-b9ba-fdb1c481c497',\n        '011fc3bc-a97d-4535-8cb0-81766e361e78',\n        'acf2262b-4ccf-4f1d-b5c1-5e44641884c6',\n        '6bf661b1-2f85-4277-8dba-6552141e7e42',\n        'a76df66b-8c50-488f-b4e7-4f4d3c05afff',\n        'b5c5df47-f939-4536-a340-442bf00bd70d',\n        'd4914d41-0011-49fb-a1c2-fe69108e4983',\n        'efd5fa37-b0de-43b0-9fe7-1b7a7a6523f8',\n        '6048f863-7faa-43f2-8202-4b349ae34810',\n        '659a0024-fa05-4068-aed0-e61239554b6d',\n        '6ec80af3-0415-429e-91e9-8491ab5745c0',\n        '0e6f754c-0533-4336-b4f0-e2e35518efa1',\n        '47469672-7e55-4316-b5d4-c458e43d2404',\n        '0c5ad756-a823-4a3f-8449-840fac080f45',\n        '8f8345da-1dd9-499b-bda5-57100bb305d5',\n        '4a31d059-e375-4571-9d28-ea0de51740e7',\n        'ed7fb50c-1b3a-4594-920b-9a461abce57c',\n        '3d8fe6f6-e603-44c0-b550-3568523c3224',\n        '809259bc-7912-427a-a975-7298ee5626db',\n        'ec88d77e-5612-466c-b269-ad146abd70d0',\n        'bd308a10-8073-45ae-9bfb-9a663ad5dd10',\n        '83a6a4cc-3079-46d8-9263-8f57af4fd4c7',\n        '557f0041-7e7f-447c-988c-eafa6e396915',\n        '6ad0fa1c-7425-41e9-9b74-19c4935750a2',\n        'a9193e21-e529-43cf-9421-6ed09b59d86e',\n        '2a09f6e6-4fb2-4da0-97bf-6f32858ba977',\n        'd66e0940-087f-4e71-8292-fc38e306d9f7',\n        '0dfc58b3-d591-40be-803d-e17a52e5d262',\n        'a46c6902-de10-45cc-8dac-600d68860532',\n        '5200f9dc-b967-4d1e-ab01-51c726c152ba',\n        'acd8498b-ee8b-4d58-b0ef-c353fb1b5a45',\n        '36adf355-cccc-406f-a814-6333ec4e31bf',\n        'd6d64c6f-8388-4de3-9db1-de07f02071b6',\n        'daf3fde9-41d0-422f-a0e3-8c7a93a77091',\n        '160f4fac-a229-4169-893e-4e9e6864c098',\n        '170c4be9-1fe6-4838-8a77-dee364ae9a95',\n        '2864fed0-868c-4bd1-a3fa-ae3bb3de20f4',\n        '8ea6639c-36dc-463c-8299-8f9a12b10898',\n        '626bef95-2f24-47c2-a792-f06e8f13a11e',\n        'ede75c44-5a1d-484c-942d-87407f27db23',\n        '966ec42b-0bf7-4923-9672-7a41fee377bc',\n        '399d7ce6-b28f-4751-ac50-73e31b079f22',\n        'ab2b4086-e181-4f02-aee1-a94afed40b50',\n        '3cfc33a6-73f7-49f7-9c01-fbcf84e604d0',\n        '40cf06c6-74ca-4016-b388-17dc0334770d',\n        '58f9ecd3-14ab-4100-b32a-cc2622f06c81',\n        'a5c35e34-5d05-4724-bb6c-613b5d306a18',\n        '5133ae3e-e38b-47fa-a3dc-965c738be792',\n        '594acd2f-7100-4b2b-8b8a-6097cb1cec3d',\n        '08b3da92-6b32-43d8-9fdd-53eaa996d649',\n        '93dcdc27-ab2c-4828-9074-4876ee7ab257',\n        '8260a154-23cc-4510-a5df-cc5119f457fb',\n        '732a6571-9729-4935-92be-1a74b3242636',\n        'c15f5581-e047-45b7-a36f-dfef4e7ba4bb',\n    ];\n    /** @var UuidInterface */\n    private $tinyUuid;\n    /** @var UuidInterface */\n    private $hugeUuid;\n    /** @var UuidInterface */\n    private $uuid;\n    /**\n     * @var non-empty-list<UuidInterface>\n     */\n    private $promiscuousUuids;\n    /** @var string */\n    private $serializedTinyUuid;\n    /** @var string */\n    private $serializedHugeUuid;\n    /** @var string */\n    private $serializedUuid;\n    /**\n     * @var non-empty-list<string>\n     */\n    private $serializedPromiscuousUuids;\n\n    public function __construct()\n    {\n        $this->tinyUuid = Uuid::fromString(self::TINY_UUID);\n        $this->hugeUuid = Uuid::fromString(self::HUGE_UUID);\n        $this->uuid = Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0]);\n        $this->promiscuousUuids = array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED);\n        $this->serializedTinyUuid = serialize(Uuid::fromString(self::TINY_UUID));\n        $this->serializedHugeUuid = serialize(Uuid::fromString(self::HUGE_UUID));\n        $this->serializedUuid = serialize(Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0]));\n        $this->serializedPromiscuousUuids = array_map(\n            'serialize',\n            array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED)\n        );\n    }\n\n    public function benchSerializationOfTinyUuid(): void\n    {\n        serialize($this->tinyUuid);\n    }\n\n    public function benchSerializationOfHugeUuid(): void\n    {\n        serialize($this->hugeUuid);\n    }\n\n    public function benchSerializationOfUuid(): void\n    {\n        serialize($this->uuid);\n    }\n\n    public function benchSerializationOfPromiscuousUuids(): void\n    {\n        array_map('serialize', $this->promiscuousUuids);\n    }\n\n    public function benchDeSerializationOfTinyUuid(): void\n    {\n        unserialize($this->serializedTinyUuid);\n    }\n\n    public function benchDeSerializationOfHugeUuid(): void\n    {\n        unserialize($this->serializedHugeUuid);\n    }\n\n    public function benchDeSerializationOfUuid(): void\n    {\n        unserialize($this->serializedUuid);\n    }\n\n    public function benchDeSerializationOfPromiscuousUuids(): void\n    {\n        array_map('unserialize', $this->serializedPromiscuousUuids);\n    }\n}\n"
  },
  {
    "path": "tests/benchmark/UuidStringConversionBench.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\Benchmark;\n\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\n\nuse function array_map;\n\nfinal class UuidStringConversionBench\n{\n    private const TINY_UUID = '00000000-0000-0000-0000-000000000001';\n    private const HUGE_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\n    private const UUIDS_TO_BE_SHORTENED = [\n        '0ae0cac5-2a40-465c-99ed-3d331b7cf72a',\n        '5759b9ce-07b5-4e89-b33a-f864317a2951',\n        '20c8664e-81a8-498d-9e98-444973ef3122',\n        '16fcbcf3-bb47-4227-90bd-3485d60510c3',\n        'fa83ae94-38e0-4903-bc6a-0a3eca6e9ef5',\n        '51c9e011-0429-4d77-a753-702bd67dcd84',\n        '1bd8857a-d6d7-4bd6-8734-b3dfedbcda7b',\n        '7aa38b71-37c3-4561-9b2e-ca227f1c9c55',\n        'e6b8854c-435c-4bb1-b6ad-1800b5d3e6bb',\n        '4e2b0031-8b09-46e2-8244-3814c46a2f53',\n        'bedd0850-da1a-4808-95c4-25fef0abbaa7',\n        '516b9052-d6fb-4828-bfc1-dffdef2d56d2',\n        '5d60a7e7-9139-4779-9f28-e6316b9fe3b7',\n        '65aa3d74-c1fb-4bdd-9a00-ce88a5270c57',\n        '27c2e339-74ed-49a7-a3c4-1a0172e9f945',\n        'e89b7727-4847-41ab-98d7-4148216eea8c',\n        'd79efaf3-b5dc-43a0-b3a5-c492155a7e0d',\n        'ee9ee6e7-5b7d-4e18-ab88-ce03d569305f',\n        'fe90c911-c13b-4103-bf33-16757aa87ff5',\n        '4d7ff67a-0074-4195-95d7-cf8b84eba079',\n        'abe5d378-d021-4905-93f4-0e76a7848365',\n        '19d21907-d121-4d85-8a34-a65d04ce8977',\n        'c421b8ad-33a4-42aa-b0cc-8f5f94b2cff7',\n        'f3dbbe55-3c80-453e-ab39-a6fe5001a7fc',\n        'f48d3eb2-6060-458f-809f-b5e887f9a17f',\n        'd189e406-de29-4889-8470-7bfa0d020c0c',\n        '71627018-9f21-4034-aafe-4c8b17151217',\n        '0c6a9278-0963-4460-9cae-6dc6f5420f4f',\n        'c833ac35-cce0-4315-8df3-3ed76656a548',\n        '78e94126-1d0a-472a-9b99-37840784318f',\n        '6e684707-ce4b-42df-8a77-71e57b54b581',\n        '811df139-e7a3-4cd8-b778-c81494d239ee',\n        'c263c5d8-c166-4599-9219-3e975e506f45',\n        'b31e7c5d-95ba-41d4-bc29-e6357c96f005',\n        '16ae2983-7f8f-4eee-9afb-6d4617836a01',\n        'ecbbfac7-f92a-4b41-996e-3e4724aa0e23',\n        '2c6b3db9-a5ee-4425-a837-8880a86faaa0',\n        '3d67a99a-b39a-4295-b7f8-0bf71ead5b2d',\n        'ca421bb7-ad73-41ea-9648-70073862ad5a',\n        '5ba156fa-853d-460f-a884-ca8dd3a27314',\n        '42a4359a-1df2-4086-b454-7477dbb726ff',\n        '7db9517b-f6ba-4bcf-ae26-6a88a7dbb034',\n        'bc758bd6-eb50-425b-ada1-07e6bb312032',\n        '254cf6d0-696d-4ff0-b579-ac3b633f03c0',\n        'f8f34b37-4c71-4177-bac5-6b99bb1929af',\n        'b0cc6179-f2b1-4ddf-8fe2-2251c3d935a3',\n        '333ad834-fa3b-4cf4-b9ba-fdb1c481c497',\n        '011fc3bc-a97d-4535-8cb0-81766e361e78',\n        'acf2262b-4ccf-4f1d-b5c1-5e44641884c6',\n        '6bf661b1-2f85-4277-8dba-6552141e7e42',\n        'a76df66b-8c50-488f-b4e7-4f4d3c05afff',\n        'b5c5df47-f939-4536-a340-442bf00bd70d',\n        'd4914d41-0011-49fb-a1c2-fe69108e4983',\n        'efd5fa37-b0de-43b0-9fe7-1b7a7a6523f8',\n        '6048f863-7faa-43f2-8202-4b349ae34810',\n        '659a0024-fa05-4068-aed0-e61239554b6d',\n        '6ec80af3-0415-429e-91e9-8491ab5745c0',\n        '0e6f754c-0533-4336-b4f0-e2e35518efa1',\n        '47469672-7e55-4316-b5d4-c458e43d2404',\n        '0c5ad756-a823-4a3f-8449-840fac080f45',\n        '8f8345da-1dd9-499b-bda5-57100bb305d5',\n        '4a31d059-e375-4571-9d28-ea0de51740e7',\n        'ed7fb50c-1b3a-4594-920b-9a461abce57c',\n        '3d8fe6f6-e603-44c0-b550-3568523c3224',\n        '809259bc-7912-427a-a975-7298ee5626db',\n        'ec88d77e-5612-466c-b269-ad146abd70d0',\n        'bd308a10-8073-45ae-9bfb-9a663ad5dd10',\n        '83a6a4cc-3079-46d8-9263-8f57af4fd4c7',\n        '557f0041-7e7f-447c-988c-eafa6e396915',\n        '6ad0fa1c-7425-41e9-9b74-19c4935750a2',\n        'a9193e21-e529-43cf-9421-6ed09b59d86e',\n        '2a09f6e6-4fb2-4da0-97bf-6f32858ba977',\n        'd66e0940-087f-4e71-8292-fc38e306d9f7',\n        '0dfc58b3-d591-40be-803d-e17a52e5d262',\n        'a46c6902-de10-45cc-8dac-600d68860532',\n        '5200f9dc-b967-4d1e-ab01-51c726c152ba',\n        'acd8498b-ee8b-4d58-b0ef-c353fb1b5a45',\n        '36adf355-cccc-406f-a814-6333ec4e31bf',\n        'd6d64c6f-8388-4de3-9db1-de07f02071b6',\n        'daf3fde9-41d0-422f-a0e3-8c7a93a77091',\n        '160f4fac-a229-4169-893e-4e9e6864c098',\n        '170c4be9-1fe6-4838-8a77-dee364ae9a95',\n        '2864fed0-868c-4bd1-a3fa-ae3bb3de20f4',\n        '8ea6639c-36dc-463c-8299-8f9a12b10898',\n        '626bef95-2f24-47c2-a792-f06e8f13a11e',\n        'ede75c44-5a1d-484c-942d-87407f27db23',\n        '966ec42b-0bf7-4923-9672-7a41fee377bc',\n        '399d7ce6-b28f-4751-ac50-73e31b079f22',\n        'ab2b4086-e181-4f02-aee1-a94afed40b50',\n        '3cfc33a6-73f7-49f7-9c01-fbcf84e604d0',\n        '40cf06c6-74ca-4016-b388-17dc0334770d',\n        '58f9ecd3-14ab-4100-b32a-cc2622f06c81',\n        'a5c35e34-5d05-4724-bb6c-613b5d306a18',\n        '5133ae3e-e38b-47fa-a3dc-965c738be792',\n        '594acd2f-7100-4b2b-8b8a-6097cb1cec3d',\n        '08b3da92-6b32-43d8-9fdd-53eaa996d649',\n        '93dcdc27-ab2c-4828-9074-4876ee7ab257',\n        '8260a154-23cc-4510-a5df-cc5119f457fb',\n        '732a6571-9729-4935-92be-1a74b3242636',\n        'c15f5581-e047-45b7-a36f-dfef4e7ba4bb',\n    ];\n    /** @var UuidInterface */\n    private $tinyUuid;\n    /** @var UuidInterface */\n    private $hugeUuid;\n    /** @var UuidInterface */\n    private $uuid;\n    /**\n     * @var non-empty-list<UuidInterface>\n     */\n    private $promiscuousUuids;\n    /**\n     * @var non-empty-string\n     */\n    private $tinyUuidBytes;\n    /**\n     * @var non-empty-string\n     */\n    private $hugeUuidBytes;\n    /**\n     * @var non-empty-string\n     */\n    private $uuidBytes;\n    /**\n     * @var non-empty-list<non-empty-string>\n     */\n    private $promiscuousUuidsBytes;\n\n    public function __construct()\n    {\n        $this->tinyUuid = Uuid::fromString(self::TINY_UUID);\n        $this->hugeUuid = Uuid::fromString(self::HUGE_UUID);\n        $this->uuid = Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0]);\n        $this->promiscuousUuids = array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED);\n        $this->tinyUuidBytes = $this->tinyUuid->getBytes();\n        $this->hugeUuidBytes = $this->hugeUuid->getBytes();\n        $this->uuidBytes = $this->uuid->getBytes();\n        $this->promiscuousUuidsBytes = array_map(static function (UuidInterface $uuid): string {\n            return $uuid->getBytes();\n        }, $this->promiscuousUuids);\n    }\n\n    public function benchCreationOfTinyUuidFromString(): void\n    {\n        Uuid::fromString(self::TINY_UUID);\n    }\n\n    public function benchCreationOfHugeUuidFromString(): void\n    {\n        Uuid::fromString(self::HUGE_UUID);\n    }\n\n    public function benchCreationOfUuidFromString(): void\n    {\n        Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0]);\n    }\n\n    public function benchCreationOfPromiscuousUuidsFromString(): void\n    {\n        array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED);\n    }\n\n    public function benchCreationOfTinyUuidFromBytes(): void\n    {\n        Uuid::fromBytes($this->tinyUuidBytes);\n    }\n\n    public function benchCreationOfHugeUuidFromBytes(): void\n    {\n        Uuid::fromBytes($this->hugeUuidBytes);\n    }\n\n    public function benchCreationOfUuidFromBytes(): void\n    {\n        Uuid::fromBytes($this->uuidBytes);\n    }\n\n    public function benchCreationOfPromiscuousUuidsFromBytes(): void\n    {\n        array_map([Uuid::class, 'fromBytes'], $this->promiscuousUuidsBytes);\n    }\n\n    public function benchStringConversionOfTinyUuid(): void\n    {\n        $this->tinyUuid->toString();\n    }\n\n    public function benchStringConversionOfHugeUuid(): void\n    {\n        $this->hugeUuid->toString();\n    }\n\n    public function benchStringConversionOfUuid(): void\n    {\n        $this->uuid->toString();\n    }\n\n    public function benchStringConversionOfPromiscuousUuids(): void\n    {\n        array_map(static function (UuidInterface $uuid): string {\n            return $uuid->toString();\n        }, $this->promiscuousUuids);\n    }\n\n    public function benchBytesConversionOfTinyUuid(): void\n    {\n        $this->tinyUuid->getBytes();\n    }\n\n    public function benchBytesConversionOfHugeUuid(): void\n    {\n        $this->hugeUuid->getBytes();\n    }\n\n    public function benchBytesConversionOfUuid(): void\n    {\n        $this->uuid->getBytes();\n    }\n\n    public function benchBytesConversionOfPromiscuousUuids(): void\n    {\n        array_map(static function (UuidInterface $uuid): string {\n            return $uuid->getBytes();\n        }, $this->promiscuousUuids);\n    }\n}\n"
  },
  {
    "path": "tests/bootstrap.php",
    "content": "<?php\n\n/**\n * Test bootstrap\n *\n * @codingStandardsIgnoreFile\n */\n\n// Ensure floating-point precision is set to 14 (the default) for tests.\nini_set('precision', '14');\n\nrequire_once __DIR__ . '/../vendor/autoload.php';\n"
  },
  {
    "path": "tests/static-analysis/UuidIsImmutable.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\StaticAnalysis;\n\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\n\n/**\n * This is a static analysis fixture to verify that the API signature\n * of a UUID allows for pure operations. Almost all methods will seem to be\n * redundant or trivial: that's normal, we're just verifying the\n * transitivity of immutable type signatures.\n *\n * Please note that this does not guarantee that the internals of the UUID\n * library are pure/safe, but just that the declared API to the outside world\n * is seen as immutable.\n */\nfinal class UuidIsImmutable\n{\n    public static function pureCompareTo(UuidInterface $a, UuidInterface $b): int\n    {\n        return $a->compareTo($b);\n    }\n\n    public static function pureEquals(UuidInterface $a, ?object $b): bool\n    {\n        return $a->equals($b);\n    }\n\n    /**\n     * @return mixed[]\n     */\n    public static function pureGetters(UuidInterface $a): array\n    {\n        return [\n            $a->getBytes(),\n            $a->getNumberConverter(),\n            $a->getHex(),\n            $a->getFieldsHex(),\n            $a->getClockSeqHiAndReservedHex(),\n            $a->getClockSeqLowHex(),\n            $a->getClockSequenceHex(),\n            $a->getDateTime(),\n            $a->getInteger(),\n            $a->getLeastSignificantBitsHex(),\n            $a->getMostSignificantBitsHex(),\n            $a->getNodeHex(),\n            $a->getTimeHiAndVersionHex(),\n            $a->getTimeLowHex(),\n            $a->getTimeMidHex(),\n            $a->getTimestampHex(),\n            $a->getUrn(),\n            $a->getVariant(),\n            $a->getVersion(),\n            $a->toString(),\n            $a->__toString(),\n        ];\n    }\n\n    /**\n     * @return UuidInterface[]|bool[]\n     */\n    public static function pureStaticUuidApi(): array\n    {\n        $id = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');\n\n        return [\n            Uuid::fromBytes($id->getBytes()),\n            Uuid::fromInteger($id->getInteger()->toString()),\n            Uuid::isValid('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'),\n        ];\n    }\n\n    public static function uuid3IsPure(): UuidInterface\n    {\n        return Uuid::uuid3(\n            Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'),\n            'Look ma! I am a pure function!'\n        );\n    }\n\n    public static function uuid5IsPure(): UuidInterface\n    {\n        return Uuid::uuid5(\n            Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'),\n            'Look ma! I am a pure function!'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/static-analysis/UuidIsNeverEmpty.php",
    "content": "<?php\n\n/**\n * This file is part of the ramsey/uuid library\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>\n * @license http://opensource.org/licenses/MIT MIT\n */\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\StaticAnalysis;\n\nuse Ramsey\\Uuid\\UuidInterface;\n\n/**\n * This is a static analysis fixture to verify that the API signature\n * of a UUID does not return empty strings for methods that never will do so.\n */\nfinal class UuidIsNeverEmpty\n{\n    /** @return non-empty-string */\n    public function bytesAreNeverEmpty(UuidInterface $uuid): string\n    {\n        return $uuid->getBytes();\n    }\n\n    /** @return non-empty-string */\n    public function stringIsNeverEmpty(UuidInterface $uuid): string\n    {\n        return $uuid->toString();\n    }\n}\n"
  },
  {
    "path": "tests/static-analysis/ValidUuidIsNonEmpty.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Ramsey\\Uuid\\StaticAnalysis;\n\nuse InvalidArgumentException;\nuse Ramsey\\Uuid\\Uuid;\n\nfinal class ValidUuidIsNonEmpty\n{\n    /** @return non-empty-string */\n    public function validUuidsAreNotEmpty(string $input): string\n    {\n        if (Uuid::isValid($input)) {\n            return $input;\n        }\n\n        throw new InvalidArgumentException('Not a UUID');\n    }\n\n    /**\n     * @param non-empty-string $input\n     *\n     * @return non-empty-string\n     */\n    public function givenNonEmptyInputAssertionRemainsValid(string $input): string\n    {\n        if (Uuid::isValid($input)) {\n            return $input;\n        }\n\n        throw new InvalidArgumentException('Not a UUID');\n    }\n\n    public function givenInvalidInputValueRemainsAString(string $input): string\n    {\n        if (Uuid::isValid($input)) {\n            return 'It Worked!';\n        }\n\n        return $input;\n    }\n}\n"
  },
  {
    "path": "tests/static-analysis/stubs.php",
    "content": "<?php\n\n/**\n * Stubs for static analysis\n *\n * @codingStandardsIgnoreFile\n */\n\nif (!defined('UUID_TYPE_DEFAULT')) {\n    define('UUID_TYPE_DEFAULT', 0);\n}\nif (!defined('UUID_TYPE_TIME')) {\n    define('UUID_TYPE_TIME', 1);\n}\nif (!defined('UUID_TYPE_RANDOM')) {\n    define('UUID_TYPE_RANDOM', 4);\n}\nif (!function_exists('uuid_create')) {\n    function uuid_create(int $uuid_type=UUID_TYPE_DEFAULT): string {} // @phpstan-ignore-line\n}\nif (!function_exists('uuid_generate_md5')) {\n    function uuid_generate_md5(string $uuid_ns, string $name): string {} // @phpstan-ignore-line\n}\nif (!function_exists('uuid_generate_sha1')) {\n    function uuid_generate_sha1(string $uuid_ns, string $name): string {} // @phpstan-ignore-line\n}\nif (!function_exists('uuid_parse')) {\n    function uuid_parse(string $uuid): string {} // @phpstan-ignore-line\n}\n"
  }
]